1

I want to use ApexCharts as a means of visualization in Angular. ng-apexcharts is the npm package that acts as a wrapper. Because the default tooltip of ApexCharts doesn't fit my design, I'd like to make a custom tooltip component.

A custom tooltip can be specified the following way:

HTML:

<apx-chart ... [tooltip]="tooltip"></apx-chart>

TypeScript:

@Component({...})

export class LineChartComponent implements OnInit {

  tooltip: ApexTooltip = {
    custom: ({ series, seriesIndex, dataPointIndex, w }) => {
      return "<div>Custom tooltip HTML</div>"
    }
  };
  ...
}

I have the following problem:

When trying to define a template like this as the tooltip HTML

`<div class="SOME_CLASS"><mat-card>${SOME_VALUE}</mat-card></div>`

and adding this to the component's CSS file

.SOME_CLASS {
  color: red;
}

the class property and a non-HTML component like mat-card won't translate to the appropriate representations in the DOM. The string is just pasted instead. The HTML-structure can be found here.

What would be a way to make Angular bind this template correctly?

PS: I don't have access to the tooltip component so specifying

<tooltip [innerHtml]="SOME_VARIABLE"></tooltip>

won't work either.

1
  • 3
    You can't. Angular templates must be compiled. It would be possible if the tooltip accepted a TemplateRef, that you could then defined with <ng-template>. Commented Dec 14, 2019 at 14:27

2 Answers 2

1

Thanks to JB Nizet's comment I managed to implement the desired functionality. The solution was to define a ng-template in the component's HTML like this:

<apx-chart ... [tooltip]="tooltip"></apx-chart>
<ng-template #tooltipTemplate>
  <div>
    ~
    <mat-card>TEST</mat-card>
  </div>
</ng-template>

Then I had to implement TemplateRef to reference the template and create an EmbeddedView which I could then use to get the HTML of my ng-template:

export class LineChartComponent implements OnInit {
  @ViewChild("tooltipTemplate", { static: true }) tooltipTemplate: TemplateRef<any>;

  tooltipViewRef: EmbeddedViewRef<any>;

  tooltip: ApexTooltip = {
    custom: ({ series, i, j, w }) => {
      const dynamic = series[i][j].toString();
      return this.tooltipViewRef.rootNodes[0].outerHTML.replace("~", dynamic);
    }
  };

  ...

  ngOnInit() {
    this.tooltipViewRef = this.tooltipTemplate.createEmbeddedView(
      "tooltipTemplate"
    );
  }
}

This gets only the first element inside the ng-template. I used a symbol ~ to be able to display dynamic content because the template is static.

Note that Font Awesome icons inside the template won't work. I haven't figured out a way to implement them yet.

Sign up to request clarification or add additional context in comments.

Comments

0

What you want to do is partially possible. If you look at the API of the ApexChart, you can see that the tooltip input accepts a type ApexTooltip. This type allows you to specify a property custom for which you need to provide a function that returns the desired HTML per point. This way, you can provide your own HTML. But bindings will as there is no way to pass in a template but only a string that seems to be rendered as inner HTML. Honestly, this API is very different from a usual angular approach.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.