Search code examples
angularc3.jsvmware-clarityclarity

Chart doesn't draw inside expandable row of clarity datagrid


This seems more of Clarity (vmware) question than angular, but I believe, we can solve this somehow Angular way as well or may be I am missing some important Angular lifecycle which can solve this.

I am using "expandable rows" from clarity datagrid: https://vmware.github.io/clarity/documentation/v0.11/datagrid/expandable-rows

I can put any text, under a row and it displays well, but when I put a chart inside the row, it doesn't work.

When I put same chart at top of the table it works well:

<div class="" id="chart"></div>

But when I put this under expanded column, it doesn't work:

<clr-dg-row-detail *clrIfExpanded>
       Why chart doesn't display here
       <div class="" id="chart"></div>
 </clr-dg-row-detail>

Any Clarity expert can help me here please. Here is my stackblitz. https://stackblitz.com/edit/clarity-datagrid-basic-ky6yze?file=app%2Fapp.component.html Please let me know if you need more information:


Solution

  • You are using c3 which accesses native elements directly to draw the charts. This doesn't play well with Angular and you will hit countless issues (server-side rendering will crash, charts will just not display in some cases like they do here, etc). I highly recommend you write a wrapper component or directive for your c3 charts, that takes the data and some options as input and draws the chart in ngAfterViewInit().

    Here is a rough example of what it would look like: https://stackblitz.com/edit/c3-chart-example?file=app%2Fchart.directive.ts.

    To give you a comprehensive explanation, your problem here is that you are drawing the c3 chart on an element that doesn't exist. The *clrIfExpanded structural directive, just like *ngIf, only creates the elements inside when they're displayed. They simply don't exist until the row is expanded, but you draw the chart on initialization only. With the directive solution, each chart is drawn only when it needs to be displayed, at which point the element exists.

    Finally, also note that all your charts elements had the same HTML id, which isn't valid HTML. The reason it worked is because c3 is forgiving and allows you to draw on all of them at the same time, instead of just querying for the first element with that id. With the version using a directive, there is no id involved anymore, I just bind to the element itself.