我创建了一个多系列折线图并尝试根据this stackoverflow answer添加工具提示,但工具提示不起作用,我无法弄清楚我的代码有什么问题。
var margin = {
top: 20,
right: 30,
bottom: 30,
left: 40
},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var z = d3.scale.category20c();
var svg = d3.select("body").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 + ")");
var parseDate = d3.time.format("%Y-%m-%dT%H:%M:%SZ");
var data = [{
label: "a",
data: [
[
"2016-02-02T11:34:03Z",
0
],
[
"2016-02-04T11:34:03Z",
0
],
[
"2016-02-06T11:34:03Z",
0
],
[
"2016-02-08T11:34:03Z",
0
],
[
"2016-02-10T11:34:03Z",
0
],
[
"2016-02-12T11:34:03Z",
0
],
[
"2016-02-14T11:34:03Z",
0
],
[
"2016-02-16T11:34:03Z",
0
],
[
"2016-02-18T11:34:03Z",
0
],
[
"2016-02-20T11:34:03Z",
0
],
[
"2016-02-22T11:34:03Z",
0.3735178379850471
],
[
"2016-02-24T11:34:03Z",
0
],
[
"2016-02-26T11:34:03Z",
0
],
[
"2016-02-28T11:34:03Z",
0
],
[
"2016-03-01T11:34:03Z",
0
]
]
}, {
label: "b",
data: [
[
"2016-02-02T11:34:03Z",
0
],
[
"2016-02-04T11:34:03Z",
0
],
[
"2016-02-06T11:34:03Z",
0
],
[
"2016-02-08T11:34:03Z",
0
],
[
"2016-02-10T11:34:03Z",
0
],
[
"2016-02-12T11:34:03Z",
0
],
[
"2016-02-14T11:34:03Z",
0
],
[
"2016-02-16T11:34:03Z",
0
],
[
"2016-02-18T11:34:03Z",
0
],
[
"2016-02-20T11:34:03Z",
0
],
[
"2016-02-22T11:34:03Z",
0.25810614839315693
],
[
"2016-02-24T11:34:03Z",
0
],
[
"2016-02-26T11:34:03Z",
0
],
[
"2016-02-28T11:34:03Z",
0
],
[
"2016-03-01T11:34:03Z",
0
]
]
}];
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.interpolate("monotone")
.x(function(d) {
return x(parseDate.parse(d[0]));
})
.y(function(d) {
return y(d[1]);
});
var ary = [];
data.forEach(function(d) {
ary.push(d.data);
});
x.domain(d3.extent(d3.merge(ary), function(d) {
return parseDate.parse(d[0]);
}));
y.domain([
d3.min(data, function(c) {
return d3.min(c.data, function(v) {
return v[1];
});
}),
d3.max(data, function(c) {
return d3.max(c.data, function(v) {
return v[1];
});
})
]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
var series = svg.selectAll(".series")
.data(data)
.enter().append("g")
.attr("class", "series");
series.append("path")
.attr("class", "line")
.attr("d", function(d) {
return line(d.data);
})
.style("stroke", function(d, i) {
return z(i);
});
series.append("text")
.datum(function(d) {
return {
label: d.label,
data: d.data[d.data.length - 1]
};
})
.attr("transform", function(d) {
return "translate(" + x(parseDate.parse(d.data[0])) + "," + y(d.data[1]) + ")";
})
.attr("x", 3)
.attr("dy", ".35em");
var mouseG = svg.append("g")
.attr("class", "mouse-over-effects");
mouseG.append("path") // this is the black vertical line to follow mouse
.attr("class", "mouse-line")
.style("stroke", "black")
.style("stroke-width", "1px")
.style("opacity", "0");
var lines = document.getElementsByClassName('line');
var mousePerLine = mouseG.selectAll('.mouse-per-line')
.data(data)
.enter()
.append("g")
.attr("class", "mouse-per-line");
mousePerLine.append("circle")
.attr("r", 7)
.style("stroke", function(d, i) {
return z(i);
})
.style("fill", "none")
.style("stroke-width", "1px")
.style("opacity", "0");
mousePerLine.append("text")
.attr("transform", "translate(10,3)");
mouseG.append('svg:rect') // append a rect to catch mouse movements on canvas
.attr('width', width) // can't catch mouse events on a g element
.attr('height', height)
.attr('fill', 'none')
.attr('pointer-events', 'all')
.on('mouseout', function() { // 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', function() { // 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', function() { // mouse moving over canvas
var mouse = d3.mouse(this);
d3.select(".mouse-line")
.attr("d", function() {
var d = "M" + mouse[0] + "," + height;
d += " " + mouse[0] + "," + 0;
return d;
});
d3.selectAll(".mouse-per-line")
.attr("transform", function(d, i) {
console.log(width / mouse[0])
var xDate = x.invert(mouse[0]),
bisect = d3.bisector(function(d) {
return d[0];
}).right;
var idx = bisect(d.values, xDate);
var beginning = 0,
end = lines[i].getTotalLength(),
target = null;
while (true) {
target = Math.floor((beginning + end) / 2);
var pos = lines[i].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
}
d3.select(this).select('text')
.text(y.invert(pos.y).toFixed(2));
return "translate(" + mouse[0] + "," + pos.y + ")";
});
});
&#13;
text.inner-circle {
font-weight: 400;
font-size: 12px;
text-transform: uppercase;
}
text.inner-text {
font-weight: 400;
font-size: 36px;
font-family: 'Metric Regular', 'Metric';
text-align: center;
font-style: normal;
text-transform: uppercase;
}
path {
stroke: steelblue;
stroke-width: 2;
fill: none;
}
.axis path,
.axis line {
fill: none;
stroke: grey;
stroke-width: 2;
shape-rendering: crispEdges;
}
.grid .tick {
stroke: lightgrey;
stroke-opacity: 0.7;
shape-rendering: crispEdges;
}
.grid path {
stroke-width: 0;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;
请帮我弄清楚我犯了什么错误以及如何解决它。任何帮助表示赞赏!
答案 0 :(得分:1)
该错误来自
行 var idx = bisect(d.data, xDate);
应该是以下内容:
{{1}}