[英]d3.js - Multi series line chart tool tip issue
I am new to d3.js got the following code from stack overflow. 我是d3.js的新手,它从堆栈溢出中获得了以下代码。 I had customized it according to my needs.
我已经根据需要定制了它。 But when adding tool tip it is not moving according to the mouse movement and also only date is showing on top of y axis.
但是,当添加工具提示时,它不会根据鼠标的移动而移动,并且在y轴的顶部仅显示日期。 I need to display tool tip in the order Date: date -newline- OP: some value -newline- IP: some value -newline- Pharmacy: some value -newline- Total: OP+IP+Pharmacy where mouse is hover on the line.
我需要按顺序显示工具提示日期:date -newline- OP:一些值-newline- IP:一些值-newline- Pharmacy:一些值-newline- Total:OP + IP + Pharmacy,鼠标悬停在行上。
TSV file and code is as follows. TSV文件和代码如下。 Thanks in advance.
提前致谢。
html file 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 file 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
You code is take from examples with One data serie and you have multiple series: 您的代码摘自具有一个数据系列的示例,并且您有多个系列:
The important start here: 重要的开始在这里:
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
You have 3 serie. 您有3个意甲。 You could take the max value at some date and draw the circle there:
您可以在某个日期取最大值,并在那里画一个圆圈:
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 + ")");
Or, draw three circles, one for each series: 或者,绘制三个圆圈,每个系列一个:
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"]) + ")");
Now you know how to calulate (x,y) you can do the horizontal & vertical dashed lines with labels. 现在您知道如何计算(x,y)了,可以使用标签制作水平和垂直虚线。
Here's s psudoworking code . 这是伪操作代码 。 I've let you complete it as homework :)
我已让您完成作业:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.