[英]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.