首页 > 解决方案 > 将鼠标悬停在多线图上时没有工具提示

问题描述

我使用 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));

  }
  }

标签: javascriptangulard3.js

解决方案


要在鼠标悬停期间获得提示,首先您必须定义一个显示为无的提示。

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);
}

您不需要 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);

推荐阅读