我正在使用d3作为我的图表库,在图形图之后,当我悬停鼠标时,我无法在数据点看到任何值,但在HTML控制台中我可以看到事件被触发。
我希望在我悬停时看到日期和价值,但我不知道如何处理它,因为我对d3很新。
下面的是我编码的小片段:
dataNest.forEach(function (d, i) {
svgVar.selectAll("path")
.data(dataNest)
.enter()
.append("path")
.attr("class", "line")
.style("stroke", function () { // Add the colours dynamically
return d.color = color(d.key);})
.on("mouseover", tooltip)
.attr("d", function(d) { return pricelineVar(d.values); })
.attr("fill","none");
function tooltip(d,i)
{
svgVar.style("left", d3.event.pageX + "px")
.style("top", d3.event.pageY + "px")
.style("display", "inline-block")
.html(" x:"+ d.date );
}
完整代码
import { Component, OnInit, Input } from '@angular/core';
import * as d3 from "d3"
import * as d3Scale from 'd3-scale';
import * as d3Shape from 'd3-shape';
import * as d3Array from 'd3-array';
import * as d3Axis from 'd3-axis';
import {timeParse} from "d3-time-format";
@Component({
selector: 'app-d3graph',
template: `
<h2>{{subtitle}}</h2>
`
})
export class D3graphComponent implements OnInit {
@Input() storeIntraffic: string;
@Input() dateForD3: string;
@Input() peopleInSumStr: string;
title: string = 'D3.js with Angular 2!';
subtitle: string = 'Line Chart';
peopleInSumArr: any[];
private margin = {top: 20, right: 20, bottom: 30, left: 50};
private width: number;
private height: number;
private x: any;
private y: any;
private svg: any;
private priceline: any;
private line: d3Shape.Line<[number, number]>;
d3Data: any;
dashboard_date: any;
myArray: any[];
groupName: string;
data: any;
constructor() {
this.margin = { top: 30, right: 20, bottom: 70, left: 50 },
this.width = 1300 - this.margin.left - this.margin.right,
this.height = 800 - this.margin.top - this.margin.bottom;
}
ngOnInit() { }
ngAfterViewChecked() {
if (this.storeIntraffic !== undefined && typeof this.storeIntraffic === 'string') {
this.data = JSON.parse(this.peopleInSumStr);
this.peopleInSumArr = JSON.parse(this.peopleInSumStr);
this.dashboard_date = this.dateForD3;
// this.dashboard_date = this.dateForD3;
// console.log('d3 this.peopleInSumArr', this.peopleInSumStr);
// this.peopleInSumArr = JSON.parse(this.peopleInSumStr);
// console.log('d3 this.peopleInSumArr jajdjhdhjd', this.peopleInSumArr);
// console.log('this.dateForD3', this.dateForD3);
// this.storeIntraffic_plot();
this.initSvg();
this.initAxis();
this.drawAxis();
this.drawLine();
}
}
private initSvg() {
d3.select("svg").remove();
this.svg = d3.select("#svgcontainer")
.append("svg")
.attr("width", this.width + this.margin.left + this.margin.right)
.attr("height", this.height + this.margin.top + this.margin.bottom)
.append("g")
.attr("transform",
"translate(" + this.margin.left + "," + this.margin.top + ")")
.attr("stroke-width", 2);
}
private initAxis() {
// Parse the date / time
var parseDate = timeParse("%b %Y");
// Set the ranges
this.x = d3Scale.scaleTime().range([0, this.width]);
this.y = d3Scale.scaleLinear().range([this.height, 0]);
}
private drawAxis() {
var X = this.x;
var Y = this.y;
// Define the line
this.priceline = d3Shape.line()
.x(function (d) { return X(new Date(d.date)); })
.y(function (d) { return Y(d.peoplesum); });
}
private drawLine() {
var mindate = new Date(this.dashboard_date['startTime']),
maxdate = new Date(this.dashboard_date['endTime']);
this.x.domain(d3.extent([mindate, maxdate]));
// Scale the range of the data
var svgVar = this.svg;
var pricelineVar = this.priceline;
var margin = this.margin;
var height = this.height;
this.y.domain([0, d3.max(this.data, function (d) { return d.peoplesum; })]);
console.log("this.data", this.data);
// Nest the entries by symbol
var dataNest = d3.nest()
.key(function (d) { return d.storeid;})
.entries(this.data);
// set the colour scale
var color = d3.scaleOrdinal(d3.schemeCategory10);
var legendSpace = this.width / dataNest.length; // spacing for the legend
// Loop through each symbol / key
var tooltip = d3.select("body").append("div").style("display", "none");
function enableTooltip(d) {
tooltip.html("x:" + d.date)
.style("left", d3.event.pageX + "px")
.style("top", d3.event.pageY + "px")
.style("display", null);
}
dataNest.forEach(function (d, i) {
svgVar.selectAll("path")
.data(dataNest)
.enter()
.append("path")
.on("mouseover", enableTooltip)
.attr("d", function(d) { return pricelineVar(d.values); })
.attr("fill", "none");
// Add the Legend
svgVar.append("text")
.attr("x", (legendSpace / 2) + i * legendSpace) // space legend
.attr("y", height + (margin.bottom / 2) + 5)
.attr("class", "legend") // style the legend
.style("fill", function () { // Add the colours dynamically
return d.color = color(d.key);
})
.text(d.key)
.attr("stroke-width", 3)
});
console.log("after", dataNest);
// Add the X Axis
this.svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + this.height + ")")
.call(d3.axisBottom(this.x));
// Add the Y Axis
this.svg.append("g")
.attr("class", "axis")
.call(d3.axisLeft(this.y));
}
}
答案 0 :(得分:-1)
要在鼠标悬停期间获取tootltip,首先必须定义一个显示为无的工具提示。
var tooltip = d3.select("body").append("div").style("display", "none");
然后在mouseover事件期间启用工具提示并绑定数据以显示在工具提示中。
function enableTooltip(d) {
tooltip.html("x:" + d.date)
.style("left", d3.event.pageX + "px")
.style("top", d3.event.pageY + "px")
.style("display", null);
}
你不需要forEach来迭代数组。 d3 data()负责处理。
svgVar.selectAll("path")
.data(this.data)
.enter()
.append("path")
.on("mouseover", enableTooltip)
.attr("d", function(d) { return pricelineVar(d.values); })
.attr("fill", "none");
svgVar.selectAll("text")
.data(this.data)
.enter()
.append("text")
.attr("x", (legendSpace / 2) + i * legendSpace)
.attr("y", height + (margin.bottom / 2) + 5)
.attr("class", "legend")
.style("fill", function () {
return d.color = color(d.key);
})
.text(d.key)
.attr("stroke-width", 3);