javascript - D3.js:多折线图中的线条在更新时未正确转换(位置和颜色)
问题描述
我有多个多线图表,用户可以使用页面顶部的单选按钮在它们之间移动。JSFiddle:https ://jsfiddle.net/etonblue/wh07bk1u/6/ 。我在换行时遇到两个问题:
- 更新时不会删除某些行。例如,如果您单击“Annual Enrollment Change %”单选按钮,您可以在底部附近看到两条绿线(没有点的那些),它们是“Current Ratio”图表中的“剩余”。更新功能正确地使用新数据来绘制新的绿线(带点的线),而不是转换/删除旧的绿线。在其他情况下,您也可以通过不同的线条看到这一点(例如,点击偿债覆盖率,然后点击 Aggregated 3-Year Total Margin - 绿色线和不带点的粉色线)。我仍在尝试确定模式,但我的假设是这是由于我更新线条的方式。编辑:添加更多代码
我的初始图表:
var initialChart = function(m){
var selectMetric = nestData.filter(d => d.key == m);
var metricGroup = svg.selectAll(".metricGroup")
.data(selectMetric, d => d ? d.key : this.key)
.enter()
.append("g")
.attr("class", "metricGroup")
.each(function(d){
x.domain([(d.value.ymin - .5), (d.value.ymax + .5)])
y.domain([(ydom[(m-1)][0]), (ydom[(m-1)][1])])
})
var lineGroup = metricGroup.selectAll(".lineGroup")
.attr("class", "lineGroup")
.data(d => d.value.school)
.enter()
lineGroup.append("path")
.attr("d", d => line(d.values))
.attr("class", "line " + "slash" + m)
.attr('id', function (d) {
return d.key.replace(/\s+/g, '') + m;
})
.attr("transform", `translate(0, 0)`)
.attr("fill", "none")
.attr("stroke", d => color(d.key))
.attr("stroke-linecap", "round")
.attr("stroke-linejoin", "round")
.attr("stroke-width", 2)
lineGroup.selectAll("circle")
.data(d => d.values)
.enter()
.append("circle")
.attr("class", "dot " + "dab" + m)
.attr('id', function (d) {
return d.school.replace(/\s+/g, '') + m;
})
.attr("cx", d => x(d.year))
.attr("cy", 0)
.style('fill', d => color(d.school))
.transition()
.delay(function(d,i){return(i*2)})
.duration(500)
.attr("r", 4)
.attr("cx", d => x(d.year))
.attr("cy", d => d.mval < y.domain()[0] ? y(y.domain()[0]) : d.mval > y.domain()[1] ? y(y.domain()[1]) : y(d.mval))
var xAxis = svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).ticks(8).tickFormat(d3.format("d")))
.call(g => {
g.selectAll("text")
.style("text-anchor", "middle")
.attr('fill', '#A9A9A9')
g.selectAll("line")
.attr('stroke', '#A9A9A9')
g.select(".domain")
.attr('stroke', '#A9A9A9')
})
var yAxis = svg.append("g")
.attr("class", "y axis")
.attr("transform", `translate(0, 0)`)
.call(d3.axisLeft(y).ticks(28, "s").tickSize(-width).tickFormat(d3.format(",.2f")))
.call(g => {
g.selectAll("text")
.attr('fill', '#A9A9A9')
g.selectAll("line")
.attr('stroke', '#A9A9A9')
.attr('stroke-width', 0.7)
.attr('opacity', 0.3)
g.select(".domain").remove()
})
.append('text')
.attr("transform", "rotate(-90)")
.attr("y", 0 - 60)
.attr("x", 0 - (height / 2))
.attr("dy", "1em")
.attr("fill", "#A9A9A9")
.style("text-anchor", "middle")
.text(yname[m-1])
.attr("class", "y axis label")
}
更新功能:
var updateChart = function(m){
var selectMetric = nestData.filter(d => d.key == m);
var metricGroup = svg.selectAll(".metricGroup")
.data(selectMetric, d => d ? d.key : this.key)
.enter()
.append("g")
.attr("class", "metricGroup")
.each(function(d){
x.domain([(d.value.ymin - .5), (d.value.ymax + .5)])
y.domain([-2,20])
})
var lineGroup = metricGroup.selectAll(".lineGroup")
.attr("class", "lineGroup")
.data(d => d.value.school)
.enter()
lineGroup.append("path")
.attr("d", d => line(d.values))
.attr("class", "line")
.attr('id', function (d) {return d.key.replace(/\s+/g, '');})
.attr("transform", `translate(0, 0)`)
.attr("fill", "none")
.attr("stroke", d => color(d.key))
.attr("stroke-width", 2)
- 我遇到的另一个问题似乎与我的图例/onClick/onMouseout 功能有关。如果单击每个度量单选按钮,所有颜色(线和点)都会正确绘制。但是,如果您单击其中一个图例标签、鼠标移出,然后通过单击不同的单选按钮移动到不同的图表,则许多“线”以不正确的颜色绘制,并且它们保持不正确的颜色,直到您移动您的鼠标移出图例。我再次试图追踪为什么会发生这种情况(以及为什么它会影响某些行而不影响其他行),但到目前为止还没有运气。
设置颜色:
var schoolnames = allData.map(d => d.school).filter((value, index, self) => self.indexOf(value) === index)
var color = d3.scaleOrdinal()
.domain(schoolnames)
.range(["#393b79","#5254a3","#6b6ecf","#9c9ede","#637939","#8ca252","#b5cf6b","#cedb9c","#8c6d31","#bd9e39","#e7ba52","#e7cb94","#843c39","#ad494a","#d6616b","#6baed6","#9ecae1","#c6dbef","#e6550d","#fd8d3c","#e7969c","#7b4173","#a55194","#ce6dbd","#de9ed6","#3182bd","#fdae6b","#fdd0a2","#31a354","#74c476","#a1d99b","#c7e9c0","#756bb1","#9e9ac8","#bcbddc","#dadaeb"])
“onClick”函数(没有工具提示代码)。请注意,工具提示在浏览器中工作正常,但在 JSFiddle 中没有正确定位。
function onClick(sel) {
svg.selectAll(".line")
.transition().duration(200)
.style("stroke", "lightgrey")
.style("opacity", "0.2")
svg.selectAll(".dot")
.transition().duration(200)
.style("fill", "lightgrey")
.style("opacity", "0.2")
svg.selectAll("#" + sel.replace(/\s+/g, '')).raise()
.transition()
.select('.line')
.style("stroke", function(d) {return color(sel)})
.attr("stroke-width", 3)
.style("opacity", "1")
// do separate line and dot selections do anything? //
.select('.dot')
.style("fill", function(d) {return color(sel)})
.style("opacity", "1")
d3.select('#key').selectAll('li')
.select(d => d===sel?this:null)
.transition().duration(200)
.style('background', '#ededed')
}
onMouseout 函数:
function onMouseout (sel) {
svg.selectAll(".line")
.transition()
.duration(200).delay(50)
.style("stroke", function(d) {
return color(d.key)
})
.attr("stroke-width", 2)
.style("opacity", "1")
svg.selectAll(".dot")
.transition().duration(200).delay(50)
.style("fill", function(d) {
return color(d.school)
})
.style("opacity", "1")
d3.select('#key').selectAll('li')
.select(d => d===sel?this:null)
.transition().duration(500)
.style('background', '#ffffff')
}
任何建议,将不胜感激。
解决方案
推荐阅读
- c++ - 编译器调用复制操作符而不是移动操作符
- jsp - 在 JBoss 中部署的 JSP 文件从文件夹中消失
- java - Telegram Bot 无需用户交互即可发送消息
- java - 在 Nifi 中创建自定义处理器并发送到 PublishKafka
- c# - 将 SubMenuItems 动态添加到 SubMenu
- javascript - javascript d3中的running_total是什么意思?
- python - 无法在 Python 中使用 Selenium 抓取正确数量的视频和图像
- android - Android 在两个堆叠视图旁边显示一个方形图像视图
- sql-server - XML Cdata 格式和变量输入 TSQL
- c++ - 使用“std::enable_if_t”“已定义函数模板”