Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/412.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript d3:鼠标悬停事件时,多系列折线图上每行的工具提示_Javascript_Angularjs_D3.js_Typescript - Fatal编程技术网

Javascript d3:鼠标悬停事件时,多系列折线图上每行的工具提示

Javascript d3:鼠标悬停事件时,多系列折线图上每行的工具提示,javascript,angularjs,d3.js,typescript,Javascript,Angularjs,D3.js,Typescript,我在Angular 2应用程序中使用d3绘制图表。现在我有了一个多系列的折线图,所以当我将鼠标悬停在垂直位置时,我尝试在每一行添加工具提示 export class LineGraphDirective { private host; private svg; private margin; private width; private height; private xScale; // D3 scale in X private yScale; // D3 sca

我在Angular 2应用程序中使用d3绘制图表。现在我有了一个多系列的折线图,所以当我将鼠标悬停在垂直位置时,我尝试在每一行添加工具提示

export class LineGraphDirective {
  private host;
  private svg;
  private margin;
  private width;
  private height;
  private xScale; // D3 scale in X
  private yScale; // D3 scale in Y
  private zScale; // D3 color scale
  private xAxis;
  private yAxis;
  private line;
  private htmlElement:HTMLElement;
  private parseDate;
  private ds;

  constructor(private element:ElementRef) {
    this.htmlElement = this.element.nativeElement;
    this.host = d3.select(this.element.nativeElement);
    this.parseDate = d3.timeParse('%Y-%m-%d');
    let data = [];
    this.ngOnChanges(data);
  }

  /**
   * Every time the @Input is updated, rebuild the chart
   **/
  ngOnChanges(data):void {
    this.setup(data);
    this.initData(data);
    this.buildSVG();
    this.scaleAxis(data);
    this.populate();
    this.drawXAxis();
    this.drawYAxis();
    this.zoomEventHandler();
    this.addVerticalLineTooltip();
  }

  private setup(data):void {}

  private initData(data) {}

  /**
   *  build  SVG element using the configurations
   **/
  private buildSVG():void {}

  private scaleAxis(data) {}


  /**
   * Create x axis
   **/
  private drawXAxis():void {}

  /**
   *create y axis
   **/
  private drawYAxis():void {}

  /**
   * Populate the graphs
   **/
  private populate():void {}

  private addVerticalLineTooltip() {
    // append a g for all the mouse over nonsense
    let mouseG = this.svg.append("g")
      .attr("class", "mouse-over-effects");

    // this is the vertical line
    mouseG.append("path")
      .attr("class", "mouse-line")
      .style("stroke", "black")
      .style("stroke-width", "1px")
      .style("opacity", "0");

    // keep a reference to all our lines
    let lines = document.getElementsByClassName('line');

    // here's a g for each circle and text on the line
    let mousePerLine = mouseG.selectAll('.mouse-per-line')
      .data(this.ds)
      .enter()
      .append("g")
      .attr("class", "mouse-per-line");

    // the circle
    mousePerLine.append("circle")
      .attr("r", 7)
      .style("stroke", (d) => {
        return this.zScale(d.name);
      })
      .style("fill", "none")
      .style("stroke-width", "1px")
      .style("opacity", "0");

    // the text
    mousePerLine.append("text")
      .attr("transform", "translate(10,3)");

    // rect to capture mouse movements
    mouseG.append('svg:rect')
      .attr('width', this.width)
      .attr('height', this.height)
      .attr('fill', 'none')
      .attr('pointer-events', 'all')
      .on('mouseout', () => { // on mouse out hide line, circles and text
        d3.select(".mouse-line")
          .style("opacity", "0");
        d3.selectAll(".mouse-per-line circle")
          .style("opacity", "0");
        d3.selectAll(".mouse-per-line text")
          .style("opacity", "0");
      })
      .on('mouseover', () => { // on mouse in show line, circles and text
        d3.select(".mouse-line")
          .style("opacity", "1");
        d3.selectAll(".mouse-per-line circle")
          .style("opacity", "1");
        d3.selectAll(".mouse-per-line text")
          .style("opacity", "1");
      })
      .on('mousemove', () => { // mouse moving over canvas
        let mouse = d3.mouse(d3.event.currentTarget);
        console.log(lines);

        // move the vertical line
        d3.select(".mouse-line")
          .attr("d", () => {
            let d = "M" + mouse[0] + "," + this.height;
            d += " " + mouse[0] + "," + 0;
            return d;
          });

        // position the circle and text
        d3.selectAll(".mouse-per-line")
          .attr("transform", (d, i) => {
            console.log(i);
            let beginning = 0,
              end = d3.select(lines[i]).node().getTotalLength(),
              target,
              pos;

            while (true) {
              target = Math.floor((beginning + end) / 2);
              pos = d3.select(lines[i]).node().getPointAtLength(target);
              if ((target === end || target === beginning) && pos.x !== mouse[0]) {
                break;
              }
              if (pos.x > mouse[0])      end = target;
              else if (pos.x < mouse[0]) beginning = target;
              else break; //position found
            }
            console.log(this.yScale.invert(pos.y).toFixed(2));

            // update the text with y value
            d3.select(this).select('text') // **Error this.querySelector is not a function
              .text(this.yScale.invert(pos.y).toFixed(2));

            // return position
            return "translate(" + mouse[0] + "," + pos.y + ")";
          });
      });
  }
}
上面的控制台日志在鼠标悬停事件中正确打印Y轴值

任何建议


谢谢大家!

我已经根据您的要求在多系列折线图上创建了工具提示,效果很好

您需要对代码进行一些更改,以设置下面示例链接中工具提示的位置

参见这里的示例

你可以这样做

d3.selectAll(".mouse-per-line")
      .attr("transform", (d, i, f) => {
        console.log(i);
        let beginning = 0,
          end = d3.select(lines[i]).node().getTotalLength(),
          target,
          pos;

        while (true) {
          target = Math.floor((beginning + end) / 2);
          pos = d3.select(lines[i]).node().getPointAtLength(target);
          if ((target === end || target === beginning) && pos.x !== mouse[0]) {
            break;
          }
          if (pos.x > mouse[0])      end = target;
          else if (pos.x < mouse[0]) beginning = target;
          else break; //position found
        }
        console.log(this.yScale.invert(pos.y).toFixed(2));

        // update the text with y value
        d3.select(f[i]).select('text') // **Error this.querySelector is not a function
          .text(this.yScale.invert(pos.y).toFixed(2));

        // return position
        return "translate(" + mouse[0] + "," + pos.y + ")";
      });
d3.全选(“.每行鼠标”)
.attr(“变换”,(d,i,f)=>{
控制台日志(i);
让开始=0,
end=d3.select(行[i]).node().getTotalLength(),
目标,,
销售时点情报系统;
while(true){
目标=数学楼层((开始+结束)/2);
pos=d3.select(行[i]).node().getPointAtLength(目标);
如果((目标==结束| |目标==开始)&&pos.x!==鼠标[0]){
打破
}
如果(pos.x>鼠标[0])结束=目标;
否则,如果(位置x<鼠标[0])开始=目标;
else break;//找到位置
}
console.log(此.yScale.invert(位置y).toFixed(2));
//用y值更新文本
d3.select(f[i]).select('text')/**错误此.querySelector不是函数
.text(此.yScale.invert(位置y).toFixed(2));
//返回位置
返回“translate”(“+mouse[0]+”,“+pos.y+”);
});

在OP中添加一些关于错误的细节,然后建议代码会更好
d3.selectAll(".mouse-per-line")
      .attr("transform", (d, i, f) => {
        console.log(i);
        let beginning = 0,
          end = d3.select(lines[i]).node().getTotalLength(),
          target,
          pos;

        while (true) {
          target = Math.floor((beginning + end) / 2);
          pos = d3.select(lines[i]).node().getPointAtLength(target);
          if ((target === end || target === beginning) && pos.x !== mouse[0]) {
            break;
          }
          if (pos.x > mouse[0])      end = target;
          else if (pos.x < mouse[0]) beginning = target;
          else break; //position found
        }
        console.log(this.yScale.invert(pos.y).toFixed(2));

        // update the text with y value
        d3.select(f[i]).select('text') // **Error this.querySelector is not a function
          .text(this.yScale.invert(pos.y).toFixed(2));

        // return position
        return "translate(" + mouse[0] + "," + pos.y + ")";
      });