We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

accumulationchart in dashboard panel

hi,


I have tried different waysof getting a ejs-accumulationchart working inside a panelmodel, but I can't get it to show up within the panel, any idea how? (outside the panel works fine, checked if im not missing anything).

TS
  legendSettings: object = { visible: false }
  pieData: object[] = [
    { x: 'Jan', y: 3, text: 'Jan: 3' }, { x: 'Feb', y: 3.5, text: 'Feb: 3.5' },
    { x: 'Mar', y: 7, text: 'Mar: 7' }, { x: 'Apr', y: 13.5, text: 'Apr: 13.5' },
    { x: 'May', y: 19, text: 'May: 19' }, { x: 'Jun', y: 23.5, text: 'Jun: 23.5' },
    { x: 'Jul', y: 26, text: 'Jul: 26' }, { x: 'Aug', y: 25, text: 'Aug: 25' },
    { x: 'Sep', y: 21, text: 'Sep: 21' }, { x: 'Oct', y: 15, text: 'Oct: 15' },
    { x: 'Nov', y: 9, text: 'Nov: 9' }, { x: 'Dec', y: 3.5, text: 'Dec: 3.5' }
  ];

  panels: PanelModel[] = [
    { "sizeX": 2, "sizeY": 2, "row": 0, "col": 0, content: `<ejs-accumulationchart id="chart-container" [legendSettings]='legendSettings'><e-accumulation-series-collection><e-accumulation-series [dataSource]='pieData' xName='x' yName='y'></e-accumulation-series></e-accumulation-series-collection></ejs-accumulationchart>` },
]

HTML
<div class="control-section">
  <ejs-dashboardlayout id='dashboardLayout' [cellSpacing]='cellSpacing'
                       [panels]='panels'
                       [columns]="6"
                       [cellAspectRatio]='aspectRatio'>
  </ejs-dashboardlayout>
</div>



12 Replies

KR Keerthana Rajendran Syncfusion Team June 5, 2019 07:50 AM UTC

Hi Laurens,  
 
Thank you for contacting Syncfusion support.  
 
We checked your code and it seems you have rendered ejs-accumulationchart with angular code (ejs) directly in content property of panel in TS file. We suggest you to render the “ejs-accumulationchart” inside dashboard panel using ng-template as shown in the below code 
 
<ejs-dashboardlayout id='dashboardLayout' [cellSpacing]='cellSpacing' 
                       [panels]='panels' 
                       [columns]="6" 
                       [cellAspectRatio]='aspectRatio'> 
                         <e-panels> 
            <e-panel [sizeX]="2" [sizeY]="2" [row]="0" [col]="0"> 
                <ng-template #header> 
                    <div>Product usage ratio</div> 
                </ng-template> 
                <ng-template #content> 
                    <div id="column"> 
                       <ejs-accumulationchart id="chart-container" [legendSettings]='legendSettings'><e-accumulation-series-collection><e-accumulation-series [dataSource]='pieData' xName='x' yName='y'></e-accumulation-series></e-accumulation-series-collection></ejs-accumulationchart> 
                    </div> 
                </ng-template> 
            </e-panel> 
    </e-panels> 
 </ejs-dashboardlayout> 
 
 
Please refer to the below given sample 
 
 
Please refer to the below given UG link  
 
 
Else , you can also render the accumulation chart using the typescript code in TS file 
 
Regards, 
Keerthana. 



LA Laurens Albers June 5, 2019 08:30 AM UTC

Hi,

thank you for your update,

The reason for putting it directly putting in the property in .ts file is because of the possible usage of drag& drop with state maintenance where I would have to remember the the current positions of the panels(PanelModel) and its contents and possible different size. Would it not be easier to save & restore it that way?

greetings,

Laurens



AB Ashokkumar Balasubramanian Syncfusion Team June 6, 2019 12:32 PM UTC

Hi Laurens, 
 
Yes, you can get the panel settings like, size, position and id of the panels using serialize method. However, we do not return the content in this method, so you need to update the content for the panels. As mentioned in our previous update, the content must either be html string format or processed into html string as we have parsed the content as html element in the Dashboard source. We have demonstrated this in our documentation site. Please find the link below, 
 
 
Please let us know, if you have any concerns on this. 
 
Regards, 
Ashokkumar B. 
 



LA Laurens Albers June 11, 2019 09:55 AM UTC

Hi,

Based upon your documentation, I implented a piechart into a panel(see example 1) which works fine, the second part(see example2) is what I "want". 
There are 2 possible solutions to replace the header + content of  a panel, preferable number 1.

1.  Using the example 2(fill object directly) can you give the correct translation when comparing example 1(default) vs example 2? Then I got what I need(store, save etc). 
1.a When translating any idea why the angular material classes are not getting seen using this method, but the css-classes "do"?

2.  Another solution would be to retrieve the contents of the ng-template(s) header+ content and save the "it", but getHtmlId/name/class etc trying to find the panels doesnt seem to work. If , you know how, then i'll know 'what' to replace.

your serialize method works fine btw for the rest of the data.



-------> EXAMPLE 1

.HTML
<ejs-dashboardlayout max id='dashboardLayout' #dashLayout [cellSpacing]='cellSpacing'
                           [columns]="6"
                           [cellAspectRatio]='aspectRatio'
<e-panels>
          <e-panel [sizeX]="2" [sizeY]="2" [row]="2" [col]="2">
            <ng-template #header>
              <div style="float: left">{{block1}}</div>
              <div style="float: right">
                <button style="margin-right: -10px; margin-top: -20px" class="mat-settings-button" mat-icon-button (click)="openDialog(1)">
                  <mat-icon>settings</mat-icon>
                </button>
                <button style="margin-right: -20px; margin-top: -20px" class="mat-settings-button" mat-icon-button (click)="remove(1)">
                  <mat-icon>clear</mat-icon>
                </button>
              </div>
            </ng-template>
            <ng-template #content>
              <ejs-accumulationchart id="pieChart1" [legendSettings]='legendSettings'>
                <e-accumulation-series-collection>
                  <e-accumulation-series [dataSource]='pieData' xName='x' yName='y' innerRadius="0%" radius="100%">
                  </e-accumulation-series>
                </e-accumulation-series-collection>
              </ejs-accumulationchart>
            </ng-template>
          </e-panel>
        </e-panels>
      </ejs-dashboardlayout>

.TS
 panels: PanelModel[] = []
  cellSpacing: number[] = [10, 10];
  aspectRatio: any = 100 / 80;
  block1: string = "example1";



-------> EXAMPLE 2

.HTML
  <ejs-dashboardlayout max id='dashboardLayout' #dashLayout [cellSpacing]='cellSpacing'
                           [columns]="6"
                           [cellAspectRatio]='aspectRatio'
                           [panels]="panels">
  </ejs-dashboardlayout>

.TS
 block1: string = "example1";
 cellSpacing: number[] = [10, 10];
 aspectRatio: any = 100 / 80;
 panels: PanelModel[] = [
    {
      "sizeX": 2,
      "sizeY": 1,
      "row": 0,
      "col": 2,
      header: `<div style="float: left">${this.block1}</div><div style="float: right"><button style="margin-right: -10px; margin-top: -20px" class="mat-settings-button" mat-icon-button (click)="openDialog(1)"><mat-icon>settings</mat-icon></button><button style="margin-right: -20px; margin-top: -20px" class="mat-settings-button" mat-icon-button (click)="remove(1)"><mat-icon>clear</mat-icon></button></div>`,
      content: `<ng-template><ejs-accumulationchart id="pieChart1" [legendSettings]="legendSettings"><e-accumulation-series-collection><e-accumulation-series [dataSource]="pieData" xName="x" yName="y" innerRadius="0%" radius="100%"></e-accumulation-series>  </e-accumulation-series-collection>  </ejs-accumulationchart></ng-template>`
    }
]


AB Ashokkumar Balasubramanian Syncfusion Team June 12, 2019 04:09 PM UTC

Hi Laurens, 
 
Please find the details for your queries below, 
 
Query - 1: “Example 1 vs Example 2“ 
 
In the content property of Dashboard Layout, you need to give the content as HTML string format. Since you have directly defined the content as an angular component it will not be rendered as we have parsed the content as HTML string inside the Dashboard Layout. This is the reason your second example is not working.  
 
Query -2: “Angular material classed not returned“ 
 
We are not able to understand your query properly. From where are the angular material classed not getting displayed? Please provide us more details on this query so that we can check and provide you a solution for it. 
 
Query -3: “Retrieving the contents of ngtemplate“ 
 
As explained in query-1, we parse the content property as HTML string only. So, even if you retrieve the ng-template, it would not be possible to re-render it in the Dashboard Layout’s content property.  
 
The reason for not able to re-render the custom component in angular is because we can re-render a component that is already present in the DOM. And by returning the component or using its selector, it is not possible to reinitialize it. 
 
However, your requirement of dynamically saving and restoring components in the panel content can be achieved by rendering the components using ngIf property.  
We have prepared a sample based on this for your reference. In this sample, we have rendered Grid and Chart components inside the ngTemplate of the Dashboard Layout panels and set ngIf conditions for it. On button click, we have changed the ngIf conditions which initializes alternate components in the panels. Please find the sample below, 
 
 
Please let us know if you have any concerns. 
 
Regards, 
Ashokkumar B. 



LA Laurens Albers June 13, 2019 12:59 PM UTC

Hi,

Regarding Query 1 - The 'html string format', i'm having some issues getting this visually on the screen.
Using DOMParser i parsed the string to a document containing the data in the body property as a HTMLElement. But this doesnt work, except for adding
 .innerHTML which returns me the old string again as the child from "body". Am i missing something? or should i do something else to parse it correctly?

  line1: string = 'text'
  header: HTMLElement | string;
  body: HTMLElement | string;
  panels: PanelModel[];

ngOnInit() {
//string
    let strHeader =  `<div id="header" style="float: left">${this.line1}</div><div style="float: right"><button style="margin-right: -10px; margin-top: -20px" mat-icon-button (click)="openDialog(1)"><mat-icon>settings</mat-icon></button><button style="margin-right: -20px; margin-top: -20px" mat-icon-button (click)="remove(1)"><mat-icon>clear</mat-icon></button></div>`;
    let strBody =  '<ejs-accumulationchart id="pieChart1" [legendSettings]="legendSettings"><e-accumulation-series-collection><e-accumulation-series [dataSource]="pieData" xName="x" yName="y" innerRadius="0%" radius="100%"></e-accumulation-series>  </e-accumulation-series-collection>  </ejs-accumulationchart>';



     //header formatted
    const dom1 = new DOMParser().parseFromString(strHeader, "text/html");
    this.header = dom1.body.innerHTML; //dom1.body -> HTMLELEMENT
    console.log(this.header);

    //content formatted
    const dom2 = new DOMParser().parseFromString(strBody, "text/html");
    this.body = dom2.body.innerHTML; //dom2.body -> HTMLELEMENT
    console.log(this.body);

    //panel
    this.panels = [
      {
        "id": 'Panel1',
        "sizeX": 2,
        "sizeY": 2,
        "row": 0,
        "col": 0,
        header: this.header,
        content: this.body
      }
    ];
  }

Regarding Query 2 - based upon the code above(header property). In the panel in the right uppercorner of the panel there are (hidden, until hovering) buttons with angular material attribute The material icons aren't appearing upon rendering using this method. This only works when i use example1 of the previous question(hardcoded html). But this is something probably related to the html string not being set properly.


LA Laurens Albers June 13, 2019 01:54 PM UTC

Regarding Query 3 - ngIf is a great option, but It wont work in the environment that i'm trying to set up.

My usage for the dashboard is the following, the user can:
- Save & restore the state -> so serialize method + content is needed.
- Panels can be added or deleted -> possible
- Panels are interchangeable. -> possible
- Panel content can use the same component, but different data . -> should be possible.

So as you can see the first 3 options together require an panelsproperty(object[]) that can grow or shrink  and be adjusted depending on the request. 


AB Ashokkumar Balasubramanian Syncfusion Team June 14, 2019 03:29 PM UTC

Hi Laurens, 
 
Please find the responses for your queries below, 
 
Query -1: “Issues when assigning html string data to dashboard panel content” 
 
We checked your query and provided code and we can see that you have directly parsed the angular chart component that is used for initialization. On using this code, we will process it in our source-level and render the entire Chart component in the DOM. Since you have directly parsed the initializing code, the component will not be rendered properly. This is the reason for this issue. You need to provide the entire chart component’s Dom element into the content property of the Dashboard Layout in order to render it. You can achieve this by initializing storing the chart element’s outerHTML element in a variable and directly assign this string to the content property of the Dashboard Layout.  
 
let strBody = document.getElementById('chartData').outerHTML; 
var panels = this.Dashboard.serialize(); 
panels[0].content = (this.data) ? strBody : strBody1; 
this.Dashboard.panels = panels; 
 
We have prepared a sample for your reference. In this sample, we have stored the outerHTML of two charts rendered in the Dashboard Panel and assigned them to the panel contents. Similarly you can store these content data and use it for updating the Dashboard panel contents dynamically. 
 
Please find the sample below, 
 
 
Currently while updating the html string for the angular component directly in the content we are facing issue on resizing. We will validate this and update you the further details. 
 
Query -2: “Angular material attribute not updating in header property of Dashboard Layout” 
 
As like the content property the header property also accepts only html string. As you have directly given the angular component here, it is not getting rendered properly. This can be resolved as like the solution we provided to query – 1. We have included these changes in the above provided sample itself. Please check it for your reference. 
 
Query – 3: “ngIf will not work in your environment” 
 
The solution we provided above for query – 1 will resolve this issue for you as using that method you can update both the panel data and content. 
 
Please let us know, if you have any concerns. 
 
Regards, 
Ashokkumar B. 



LA Laurens Albers June 17, 2019 02:40 PM UTC

Thank you for your response, 

But this would require me setting the panel content beforehand in html. ->  document.getElementById('chartHeader').outerHTML;

If you wanted to do the following -> add a panel, then choose body("content") for that panel, or change an existing "content" to something else that's not hardcoded. 
This would not work?

Adding, editing and removing panels dynamically is a requirement. 


AB Ashokkumar Balasubramanian Syncfusion Team June 18, 2019 11:35 AM UTC

Hi Laurens, 
 
As explained by us previously this is the behavior of the Dashboard Layout. If you need to update content dynamically then you need to store the content in HTML format either manually or by getting it from DOM and updating it in the Dashboard Layout’s content property. When adding content dynamically it must be accessed from somewhere so, in that place store it in html format so that it can be directly assigned to the content property. 
 
Please let us know your availability for web meeting so that we can clear your queries regarding this behavior. 
 
Regards, 
Ashokkumar B. 



LA Laurens Albers June 21, 2019 01:13 PM UTC

Hi, 


Thanks for you response/feedback. I'm using the solution based upon your javascript section.  Creating an instance of a panel and then adding it. I can fill the content dynamically this way.

example:
 let panel: PanelModel =
    {
      'id': 'Panel' + current,
      'sizeX': 2,
      'sizeY': 2,
     'content: 'something'
etc..
this.dashboard.addPanel(panel);

then append to child of #content(using id), this works fine.

I have another issue though based upon your stackblitz.

When you're replacing the header in your example, the buttons in the header section are "blocked", the functions are not being called. I have the same issue when adding/replacing panels. You can try this yourself, click  the "change panel content" and press one of the buttons in the header. It will not trigger.

Any idea what is going on?

greetings,

Laurens 





AB Ashokkumar Balasubramanian Syncfusion Team June 24, 2019 11:47 AM UTC

Hi Laurens, 
 
While copying, cloning or importing an element from the DOM, it will lose reference to all its events binded to it. The reason is because this only performs a shallow copy of the node element. So, you would need to manually bind events to these elements after re-rendering them in the DOM. 
 
We have prepared a sample for your reference. In this sample, we have reinitialized the header contents on button click and then bound the corresponding events to them by storing them in a separate method. Please find the sample below, 
 
 
Please let us know, if you have any concerns. 
 
Regards, 
Ashokkumar B. 


Loader.
Up arrow icon