首页 文章

如何将工具提示添加到以打字稿和角度编写的折线图中

提问于
浏览
1

我在d3js v4中有一个用打字稿写的折线图 . 现在我需要为每个数据点添加工具提示 . 该项目是有角度的,我对它很新 . 为了添加工具提示,我在折线图的顶部制作了一个散点图并显示了这些点 . 我已经在component.ts文件中处理了onmouseover和onmouseout事件,但是没有显示工具提示 . 代码如下:

import {Component, ElementRef, Input, OnChanges, OnInit, ViewChild} from '@angular/core';
import {RegressionValue} from '../../models/RegressionResult';
import * as d3 from 'd3';


@Component({
  selector: 'app-line-chart',
  templateUrl: './line-chart.component.html',
  styleUrls: ['./line-chart.component.css']
})
export class LineChartComponent implements OnInit, OnChanges {

  @ViewChild('chart') private chartContainer: ElementRef;
  @Input() private data: Array<RegressionValue>;
  private margin: any = {top: 20, right: 20, bottom: 30, left: 50};
  private chart: any;
  private width: number;
  private height: number;
  private xScale: any;
  private yScale: any;
  private lineGenerator: any;

  constructor() { }

  ngOnInit() {
    this.createChart();
    if (this.data) {
      this.updateChart();
    }
  }

  ngOnChanges() {
    if (this.chart) {
      this.updateChart();
    }
  }

  createChart() {
    const element = this.chartContainer.nativeElement;
    this.width = element.offsetWidth - this.margin.left - this.margin.right;
    this.height = element.offsetHeight - this.margin.top - this.margin.bottom;
    const svg = d3.select(element).append('svg')
      .attr('width', element.offsetWidth)
      .attr('height', element.offsetHeight);

    this.chart = svg.append('g')
      .attr('transform', `translate(${this.margin.left}, ${this.margin.top})`);

    this.xScale = d3.scaleTime().rangeRound([0, this.width]);
    this.yScale = d3.scaleLinear().rangeRound([this.height, 0]);

  }

  private makeYGridlines() {
    return d3.axisLeft(this.yScale).ticks(5);
  }

  private makeXGridlines() {
    return d3.axisBottom(this.xScale).ticks(5);
  }

  updateChart() {
    this.lineGenerator = d3.line<RegressionValue>()
      .x(d => this.xScale(d.date))
      .y(d => this.yScale(d.prediction));

    this.xScale.domain(d3.extent(this.data, (d) => d.date));
    this.yScale.domain(d3.extent(this.data, (d) => +d.prediction));

    this.chart.append('g')
      .attr('class', 'grid')
      .attr('transform', 'translate(0,' + this.height + ')')
      .call(this.makeXGridlines().tickSize(-this.height).tickFormat(''));

    this.chart.append('g')
      .attr('class', 'grid')
      .call(this.makeYGridlines().tickSize(-this.width).tickFormat(''));

    const div = this.chart.append('div')
      .attr('class', 'tooltip')
      .style('opacity', 0);

    this.chart.append('path')
      .datum(this.data)
      .attr('fill', 'none')
      .attr('stroke', 'steelblue')
      .attr('stroke-linejoin', 'round')
      .attr('stroke-linecap', 'round')
      .attr('stroke-width', 1.5)
      .attr('d', this.lineGenerator);

    this.chart.selectAll('dot')
      .data(this.data)
      .enter()
      .append('circle')
      .attr('cx', (d) => this.xScale(d.date) )
      .attr('cy', (d) => this.yScale(d.prediction) )
      .attr('r', 2)
      .on('mouseover', (d) => {
                div.transition()
                   .duration(200)
                   .style('opacity', .9);
                div.html('a tooltip 
' + d.date +'
' + d.prediction) .style('left', (d3.event.pageX) + 'px') .style('top', (d3.event.pageY - 28) + 'px'); }) .on('mouseout', (d) => { div.transition() .duration(500) .style('opacity', 0); }); this.chart.append('g') .attr('transform', 'translate(0,' + this.height + ')') .call(d3.axisBottom(this.xScale)); this.chart.append('g') .call(d3.axisLeft(this.yScale)); } }

数据格式是日期,预测 .

我之前用JavaScript用d3js编写的图表完成了它,但现在它是打字稿,似乎它的工作方式不同 . 我感谢任何指导我需要做的帮助 .

结果如下:

enter image description here

我不断检查控制台,那里没有错误 . 但是IDE正在显示我正在改变div元素的innerhtml的部分的错误('工具提示
' + d.date +'
'd.prediction) . 如果您需要更多数据,请告诉我 . 非常感谢你 .

1 回答

  • 1

    两个问题: - div 无法添加到 svg 元素但只能添加到body - 使用Angular Styles in component for D3.js do not show in angular 2中的技术来确保Angular将 component.css 样式应用于您的组件

    更换

    @Component({
      selector: 'app-line-chart',
      templateUrl: './line-chart.component.html',
      styleUrls: ['./line-chart.component.css']
    })
    
    const div = this.chart.append('div')
          .attr('class', 'tooltip')
          .style('opacity', 0);
    

    通过

    @Component({
      selector: 'app-line-chart',
      templateUrl: './line-chart.component.html',
      styleUrls: ['./line-chart.component.css'],
      encapsulation: ViewEncapsulation.Emulated
    })
     const div = d3.select("body").append('div')
          .attr('class', 'tooltip')
          .style('opacity', 0);
    

相关问题