我目前正在处理d3js多重图表,该多重图表具有一个工具提示,可详细显示图表中的数据。对于该图表,我还有一个下拉列表,用于选择数据并允许更改图表上显示的内容。问题:当我更改内容时,图形上的曲线数可能会变化,并且如果我显示3条曲线的数据,然后更改为2条曲线的数据,则第三条曲线的标签仍会显示在工具提示上。 >
我尝试使用.remove()清除工具提示的内容,但是它完全删除了我的工具提示,不再显示。
这是我的代码:
var keys = data.columns.slice(1);
var parseTime = d3.timeParse("%Y%m%d"),
formatDate = d3.timeFormat("%Y-%m-%d"),
bisectDate = d3.bisector(d => d.date).left,
formatValue = d3.format(",.0f");
data.forEach(function(d) {
d.date = parseTime(d.date);
return d;
})
var svgMultichart = d3.select("#multichart"),
margin = {top: 15, right: 35, bottom: 15, left: 35},
widthMultichart = +svgMultichart.attr("width") - margin.left - margin.right,
heightMultichart = +svgMultichart.attr("height") - margin.top - margin.bottom;
var x = d3.scaleTime()
.rangeRound([margin.left, widthMultichart - margin.right])
.domain(d3.extent(data, d => d.date))
var y = d3.scaleLinear()
.rangeRound([heightMultichart - margin.bottom, margin.top]);
var z = d3.scaleOrdinal(d3.schemeCategory10);
var line = d3.line()
.curve(d3.curveCardinal)
.x(d => x(d.date))
.y(d => y(d.degrees));
svgMultichart.append("g")
.attr("class","x-axis")
.attr("transform", "translate(0," + (heightMultichart - margin.bottom) + ")")
.call(d3.axisBottom(x).tickFormat(d3.timeFormat("%b")));
svgMultichart.append("g")
.attr("class", "y-axis")
.attr("transform", "translate(" + margin.left + ",0)");
var focus = svgMultichart.append("g")
.attr("class", "focus")
.style("display", "none");
focus.append("line").attr("class", "lineHover")
.style("stroke", "#999")
.attr("stroke-width", 1)
.style("shape-rendering", "crispEdges")
.style("opacity", 0.5)
.attr("y1", -heightMultichart)
.attr("y2",0);
focus.append("text").attr("class", "lineHoverDate")
.attr("text-anchor", "middle")
.attr("font-size", 12);
var overlay = svgMultichart.append("rect")
.attr("class", "overlay")
.attr("x", margin.left)
.attr("width", widthMultichart - margin.right - margin.left)
.attr("height", heightMultichart)
update(d3.select('#selectbox').property('value'), 0);
function update(input, speed) {
var copy = keys.filter(f => f.includes(input))
var param = copy.map(function(id) {
return {
id: id,
values: data.map(d => {return {date: d.date, degrees: +d[id]}})
};
});
y.domain([
d3.min(param, d => d3.min(d.values, c => c.degrees)),
d3.max(param, d => d3.max(d.values, c => c.degrees))
]).nice();
svgMultichart.selectAll(".y-axis").transition()
.duration(speed)
.call(d3.axisLeft(y).tickSize(-widthMultichart + margin.right + margin.left))
var parametre = svgMultichart.selectAll(".param")
.data(param);
console.log(focus)
parametre.exit().remove();
parametre.enter().insert("g", ".focus").append("path")
.attr("class", "line param")
.style("stroke", d => z(d.id))
.merge(parametre)
.transition().duration(speed)
.attr("d", d => line(d.values))
tooltip(d3.select('#selectbox').property('value'),copy);
}
function tooltip(input,copy) {
var labels = focus.selectAll(".lineHoverText").data(function(d){
return keys.filter(f => f.includes(input))
});
labels.enter().append("text")
.attr("class", "lineHoverText")
.style("fill", d => z(d))
.attr("text-anchor", "start")
.attr("font-size",12)
.attr("dy", (_, i) => 1 + i * 2 + "em")
.merge(labels);
var circles = focus.selectAll(".hoverCircle")
.data(copy)
circles.enter().append("circle")
.attr("class", "hoverCircle")
.style("fill", d => z(d))
.attr("r", 2.5)
.merge(circles);
svgMultichart.selectAll(".overlay")
.on("mouseover", function() { focus.style("display", null); })
.on("mouseout", function() { focus.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;
focus.select(".lineHover")
.attr("transform", "translate(" + x(d.date) + "," + heightMultichart + ")");
focus.select(".lineHoverDate")
.attr("transform",
"translate(" + x(d.date) + "," + (heightMultichart + margin.bottom) + ")")
.text(formatDate(d.date));
focus.selectAll(".hoverCircle")
.attr("cy", e => y(d[e]))
.attr("cx", x(d.date));
focus.selectAll(".lineHoverText")
.attr("transform",
"translate(" + (x(d.date)) + "," + heightMultichart / 2.5 + ")")
.text(e => e + " - " + formatValue(d[e]));
x(d.date) > (widthMultichart - widthMultichart / 4)
? focus.selectAll("text.lineHoverText")
.attr("text-anchor", "end")
.attr("dx", -10)
: focus.selectAll("text.lineHoverText")
.attr("text-anchor", "start")
.attr("dx", 10)
}
}
var selectbox = d3.select("#selectbox")
.on("change", function() {
update(this.value, 750);
})