簡體   English   中英

d3.js-多系列折線圖工具提示問題

[英]d3.js - Multi series line chart tool tip issue

我是d3.js的新手,它從堆棧溢出中獲得了以下代碼。 我已經根據需要定制了它。 但是,當添加工具提示時,它不會根據鼠標的移動而移動,並且在y軸的頂部僅顯示日期。 我需要按順序顯示工具提示日期:date -newline- OP:一些值-newline- IP:一些值-newline- Pharmacy:一些值-newline- Total:OP + IP + Pharmacy,鼠標懸停在行上。

TSV文件和代碼如下。 提前致謝。

html文件

</!DOCTYPE html>
<html>
<head>

<style>

body {
  font: 10px sans-serif;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}


.line {
  fill: none;
  stroke: steelblue;
  stroke-width: 1.5px;
}

</style>
 <script type="text/javascript" src="assets/js/plugins/visualization/d3/d3.min.js"></script>
</head>
<body>
<div id="revenueStati"></div>
<script>
linchart();
function linchart(){
var margin = {top: 20, right: 80, bottom: 30, left: 50},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var parseDate = d3.time.format("%Y%m%d").parse;
var formatDate = d3.time.format("%d-%b")
 var bisectDate = d3.bisector(function(d) { return d.date; }).left
var x = d3.time.scale()
    .range([0, width]);

var y = d3.scale.linear()
    .range([height-10, 0]);

var color = d3.scale.category10();

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom").ticks(7);

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left");

var line = d3.svg.line()
    .interpolate("basis")
    .x(function(d) { return x(d.date); })
    .y(function(d) { return y(d.temperature); });

var svg = d3.select("#revenueStati").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");





d3.tsv("data.tsv", function(error, data) {
  if (error) throw error;

  color.domain(d3.keys(data[0]).filter(function(key) { return key !== "date"; }));

  data.forEach(function(d) {
    d.date = parseDate(d.date);
  });

  var cities = color.domain().map(function(name) {
    return {
      name: name,
      values: data.map(function(d) {
        return {date: d.date, temperature: +d[name]};
      })
    };
  });

  x.domain(d3.extent(data, function(d) { return d.date; }));

  y.domain([
    d3.min(cities, function(c) { return d3.min(c.values, function(v) { return v.temperature; }); }),
    d3.max(cities, function(c) { return d3.max(c.values, function(v) { return v.temperature; }); })
  ]);

  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em")
      .style("text-anchor", "end");

  var city = svg.selectAll(".city")
      .data(cities)
    .enter().append("g")
      .attr("class", "city");

  city.append("path")
      .attr("class", "line")
      .attr("d", function(d) { return line(d.values); })
      .style("stroke", function(d) { return color(d.name); });

  city.append("text")
      .datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; })
      .attr("transform", function(d) { return "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")"; })
      .attr("x", 3)
      .attr("dy", ".35em")
      .text(function(d) { return d.name; });

      //// - tooltip


city = svg.append("g") 
    .style("display", "none");
      // append the x line
    city.append("line")
        .attr("class", "x")
        .style("stroke", "blue")
        .style("stroke-dasharray", "3,3")
        .style("opacity", 0.5)
        .attr("y1", 0)
        .attr("y2", height);

    // append the y line
    city.append("line")
        .attr("class", "y")
        .style("stroke", "blue")
        .style("stroke-dasharray", "3,3")
        .style("opacity", 0.5)
        .attr("x1", width)
        .attr("x2", width);

    // append the circle at the intersection
    city.append("circle")
        .attr("class", "y")
        .style("fill", "none")
        .style("stroke", "blue")
        .attr("r", 4);

    // place the value at the intersection
    city.append("text")
        .attr("class", "y1")
        .style("stroke", "white")
        .style("stroke-width", "3.5px")
        .style("opacity", 0.8)
        .attr("dx", 8)
        .attr("dy", "-.3em");
    city.append("text")
        .attr("class", "y2")
        .attr("dx", 8)
        .attr("dy", "-.3em");

    // place the date at the intersection
    city.append("text")
        .attr("class", "y3")
        .style("stroke", "white")
        .style("stroke-width", "3.5px")
        .style("opacity", 0.8)
        .attr("dx", 8)
        .attr("dy", "1em");
    city.append("text")
        .attr("class", "y4")
        .attr("dx", 8)
        .attr("dy", "1em");

    // append the rectangle to capture mouse
    svg.append("rect")
        .attr("width", width)
        .attr("height", height)
        .style("fill", "none")
        .style("pointer-events", "all")
        .on("mouseover", function() { city.style("display", null); })
        .on("mouseout", function() { city.style("display", "none"); })
        .on("mousemove", mousemove);

    function mousemove() {
    var x0 = x.invert(d3.mouse(this)[0]),
        i = bisectDate(data, x0, 1),
        d0 = data[i - 1],
        d1 = data[i],
        d = x0 - d0.date > d1.date - x0 ? d1 : d0;

    city.select("circle.y")
        .attr("transform",
              "translate(" + x(d.date) + "," +
                             y(d.close) + ")");

    city.select("text.y1")
        .attr("transform",
              "translate(" + x(d.date) + "," +
                             y(d.close) + ")")
        .text(d.close);

    city.select("text.y2")
        .attr("transform",
              "translate(" + x(d.date) + "," +
                             y(d.close) + ")")
        .text(d.close);

    city.select("text.y3")
        .attr("transform",
              "translate(" + x(d.date) + "," +
                             y(d.close) + ")")
        .text(formatDate(d.date));

    city.select("text.y4")
        .attr("transform",
              "translate(" + x(d.date) + "," +
                             y(d.close) + ")")
        .text(formatDate(d.date));

    city.select(".x")
        .attr("transform",
              "translate(" + x(d.date) + "," +
                             y(d.close) + ")")
                   .attr("y2", height - y(d.close));

    city.select(".y")
        .attr("transform",
              "translate(" + width * -1 + "," +
                             y(d.close) + ")")
                   .attr("x2", width + width);
  }

});
}

</script>
</body>

</html>

data.tsv文件

date    OP  IP  Pharmacy
20160406    46905.00    10360.00    52558.00
20160407    45415.00    10910.00    46665.00
20160408    69770.00    10935.00    46377.00
20160409    58455.00    29900.00    37352.00
20160410    10345.00    7200.00 22971.00
20160411    48680.00    14535.00    46482.00
20160412    42452.00    16270.00    34859.00

演示圖

您的代碼摘自具有一個數據系列的示例,並且您有多個系列:

重要的開始在這里:

var x0 = x.invert(d3.mouse(this)[0]),
    i = bisectDate(data, x0, 1),
    d0 = data[i - 1],
    d1 = data[i],
    d = x0 - d0.date > d1.date - x0 ? d1 : d0;

city.select("circle.y")
    .attr("transform",
          "translate(" + x(d.date) + "," +  // based on date
                         y(d.close) + ")"); // you need find y value 
                                            // d.close is not defined

您有3個意甲。 您可以在某個日期取最大值,並在那里畫一個圓圈:

var ymax = d3.max([+d["OP"],+d["IP"],+d["Pharmacy"]])
var xm = x(d.date);
var ym = y(ymax);

city.select("circle.y")
    .attr("transform",
          "translate(" + xm + "," +
                         ym + ")");

或者,繪制三個圓圈,每個系列一個:

city.select("circle.y")
    .attr("transform",
          "translate(" + xm + "," +
                         y(+d["OP"]) + ")");

city.select("circle.y")
    .attr("transform",
          "translate(" + xm + "," +
                         y(+d["IP"]) + ")");

city.select("circle.y")
    .attr("transform",
          "translate(" + xm + "," +
                         y(+d["Pharmacy"]) + ")");

現在您知道如何計算(x,y)了,可以使用標簽制作水平和垂直虛線。

這是偽操作代碼 我已讓您完成作業:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM