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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.