使用 Angular 个组件填充从 D3 视觉对象触发的工具提示

Using Angular components to populate tooltips triggered from D3 visuals

我有一个 Angular CLI 应用程序,它显示许多 D3.v5 视觉对象。我想在这些 D3 显示上添加的一些工具提示非常重要,我想利用 Angular 的模板和数据绑定的强大功能。

我能找到的唯一远程连接资源是 https://github.com/andyperlitch/ngx-d3-tooltip。我检查了代码。它相当过时,依赖于 D3 v4 和 Angular v5.

您将如何使用 Angular 组件作为 D3 上下文中的数据驱动工具提示?

我不是 d3 专家,所以我从这个开始:http://bl.ocks.org/williaster/af5b855651ffe29bdca1

并从那里开始工作。

这是工作闪电战:https://stackblitz.com/edit/angular-ivy-vrq5p6?file=src%2Fapp%2Fchart.component.ts

所以我写了一个基本组件,它接收一些数据并用 d3 渲染散点图。

该组件在图表容器上方有一个工具提示容器,如下所示:

<div class="tooltip" *ngIf="toolTipTmp && hovered" [ngStyle]="ttPos">
  <ng-container *ngTemplateOutlet="toolTipTmp.tmp; context: {$implicit: hovered}"></ng-container>
</div>

该组件具有相应的属性:

  @ContentChild(ChartTooltipDirective)
  toolTipTmp: ChartTooltipDirective

  hovered?: any
  ttPos = {
    "left.px": 0,
    "top.px": 0
  }

这里的子内容是一个公开模板的简单指令:

@Directive({
  selector: "[chart-tooltip]"
})
export class ChartTooltipDirective {
  constructor(public tmp: TemplateRef<any>) {}
}

然后渲染函数链接到这些鼠标进入和鼠标离开函数:

  var tipMouseover = (d) => {
      this.hovered = d;
      this.ttPos["left.px"] = d3.event.pageX + 15;
      this.ttPos["top.px"] = d3.event.pageY - 28;
  };
  // tooltip mouseout event handler
  var tipMouseout = (d) => {
      this.hovered = undefined;
  };

  ....

    .on("mouseover", tipMouseover)
    .on("mouseout", tipMouseout);

基本上它只是设置悬停元素和工具提示的位置。

这里的概念是你设置悬停的任何元素并设置工具提示在组件上的位置,并使用该信息来显示和定位工具提示,然后将悬停的元素提供给模板上下文,并使用一些模板定义为您的图表组件的内容子项,因此您可以定义您喜欢的任何模板。

你很容易在你的模板中使用它:

<my-chart [data]="data" xLabel="Sugar" yLabel="Calories">
  <ng-template chart-tooltip let-d>
    {{d.cereal}}
    <br>
    <span>{{d.manufacturer}}</span>
    <br>
    <b>{{d.sugar}}</b> sugar, <b>{{d.calories}}</b> calories
  </ng-template>
</my-chart>

只需应用您的指令并编写您的工具提示模板。这样,您几乎可以充分利用 angular 模板和工具提示组件。

我试着让它尽可能通用,但同样,我不是 d3 专家。

编辑:

此处根据您提供的图表进行了调整:

https://stackblitz.com/edit/angular-deviation-chart-gradient-x23a9r?file=src%2Fapp%2Fdeviation-chart%2Fdeviation-chart.component.ts