我在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 <br/>' + d.date +'<br/>' + 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编写的图表完成了它,但现在它是打字稿,似乎它的工作方式不同。我感谢任何指导我需要做的帮助。
结果如下:
我不断检查控制台,那里没有错误。但IDE正在显示我正在更改div元素的innerhtml的部分的错误(&#39;工具提示
&#39; + d.date +&#39;
&#39; + d.prediction)。如果您需要更多数据,请告诉我。非常感谢你。
答案 0 :(得分:1)
两个问题:
- div
无法添加到svg
元素,只能添加到正文
- 使用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);