d3.js节点没有正确退出 [英] d3.js nodes are not exiting properly
问题描述
所以这里。我花了相当多的时间在这一个 - 而且真的很累 - 所以希望一些愚蠢的事情没有让我失望。
so here goes. I've spent quite some time on this one - and am really tired - so hopefully something silly hasn't eluded me.
我正在使用一个数据集创建一些线条在图表中。之后,使用图例我想隐藏线条同时也改变数据集 - 所以改变不透明度不会削减它。
I am using a dataset to create a few lines in a chart. After that, using a legend I want to hide lines while also changing the dataset - so changing opacity won't cut it.
我按照在数据集中的每个对象添加一个键的路径,并将其设置为false,以便能够过滤隐藏的对象。但是,它无法正常工作,因为我无法正确退出()行。完全删除行并再次绑定数据集可以完成工作,但会将行颜色映射到图例项。
I followed the path of adding a key enabled on each object in my dataset and set it to false in order to be able to filter objects to hide. However, It doesn't work as expected since I cannot exit() the lines properly. Removing the lines completely and binding the dataset again gets the job done but messes with the mapping of the line colors to the legend items.
问题出在 redraw()
函数。
希望有人能够整理这个噩梦!
Hopefully someone is able to sort out this nightmare!
https://jsfiddle.net/2en21Lqh/2/
我已经创建了一个小提琴
I have created a fiddle
推荐答案
这是您的代码重构了以下修复:
Here's your code refactored with the following fixes:
- 简化初始绘制并重画为单一功能。
- 正确处理输入,更新,退出
- 引入键功能 a>修复数据绑定(保持数据唯一)
- 使用
d.key
代替索引(to修复 - 修正了一些一般的代码质量问题(缺少var关键字,筛选选择而不是数据等)
- Condensed initial draw and redraw into single function.
- Properly handled enter, update, exit pattern in this single function.
- Introduced key function to fix data binding (keep it unique to the data).
- Use
d.key
for colors instead of index (to fix the wandering colors). - Fixed some general code quality issues (missing var keywords, filtering on selection instead of data, etc...)
我没有使用透明度切换行,尽管这样也可以。
I did not "toggle" the lines using opacity, although that would work as well.
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
<script data-require="jquery@3.0.0" data-semver="3.0.0" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script>
<style>
.line-chart {
width: 800px;
height: 200px;
}
.d3-axis {
font-family: 'Arial', sans-serif;
font-size: 10px;
}
.d3-line {
fill: none;
stroke-width: 2px;
}
.d3-axis path {
fill: none;
stroke: #e6e6e6;
shape-rendering: crispEdges;
opacity: 0; // remove axes
}
.d3-axis line {
fill: none;
stroke: #eee;
shape-rendering: crispEdges;
}
ul li {
display: inline-block;
margin-left: 10px;
}
.color-square {
display: block;
float: left;
margin-right: 3px;
width: 20px;
height: 20px;
border: 1px solid #000;
}
</style>
</head>
<body>
<div class="line-chart"></div>
<ul class="legend"></ul>
<script>
var data = [{
"name": "line1",
"date": "2016-10-07T23:59:07Z",
"value": 67
}, {
"name": "line1",
"date": "2016-10-15T11:35:32Z",
"value": 57
}, {
"name": "line1",
"date": "2017-02-09T07:13:41Z",
"value": 11
}, {
"name": "line1",
"date": "2016-11-16T21:18:03Z",
"value": 12
}, {
"name": "line1",
"date": "2016-05-01T03:08:22Z",
"value": 71
}, {
"name": "line1",
"date": "2016-10-01T08:15:08Z",
"value": 64
}, {
"name": "line1",
"date": "2016-07-27T09:58:43Z",
"value": 25
}, {
"name": "line1",
"date": "2016-04-15T12:20:35Z",
"value": 15
}, {
"name": "line1",
"date": "2016-11-01T11:51:14Z",
"value": 69
}, {
"name": "line1",
"date": "2016-10-05T23:27:50Z",
"value": 12
}, {
"name": "line1",
"date": "2016-11-11T21:53:45Z",
"value": 87
}, {
"name": "line1",
"date": "2017-01-22T17:22:10Z",
"value": 10
}, {
"name": "line1",
"date": "2016-07-18T23:33:03Z",
"value": 27
}, {
"name": "line1",
"date": "2017-01-04T14:35:53Z",
"value": 6
}, {
"name": "line1",
"date": "2016-11-10T07:17:06Z",
"value": 91
}, {
"name": "line1",
"date": "2016-04-18T00:40:18Z",
"value": 56
}, {
"name": "line1",
"date": "2016-06-23T11:27:18Z",
"value": 22
}, {
"name": "line1",
"date": "2016-08-10T12:53:00Z",
"value": 18
}, {
"name": "line1",
"date": "2016-09-02T17:24:51Z",
"value": 89
}, {
"name": "line1",
"date": "2016-06-08T03:09:20Z",
"value": 27
}, {
"name": "line1",
"date": "2016-10-30T17:54:30Z",
"value": 38
}, {
"name": "line1",
"date": "2017-01-22T01:56:44Z",
"value": 99
}, {
"name": "line1",
"date": "2016-06-02T19:58:44Z",
"value": 48
}, {
"name": "line1",
"date": "2016-07-12T01:04:56Z",
"value": 68
}, {
"name": "line1",
"date": "2016-09-23T07:30:45Z",
"value": 11
}, {
"name": "line1",
"date": "2016-11-08T05:18:12Z",
"value": 29
}, {
"name": "line1",
"date": "2017-01-24T03:46:43Z",
"value": 19
}, {
"name": "line2",
"date": "2016-04-17T06:36:39Z",
"value": 44
}, {
"name": "line2",
"date": "2016-03-27T17:40:29Z",
"value": 29
}, {
"name": "line2",
"date": "2016-09-13T02:11:44Z",
"value": 55
}, {
"name": "line2",
"date": "2016-12-24T10:47:49Z",
"value": 54
}, {
"name": "line2",
"date": "2016-11-12T21:17:27Z",
"value": 74
}, {
"name": "line2",
"date": "2016-07-17T10:18:03Z",
"value": 55
}, {
"name": "line2",
"date": "2016-10-15T10:46:42Z",
"value": 24
}, {
"name": "line2",
"date": "2016-08-25T12:10:23Z",
"value": 63
}, {
"name": "line2",
"date": "2017-01-22T18:08:27Z",
"value": 88
}, {
"name": "line2",
"date": "2016-05-04T09:47:14Z",
"value": 44
}, {
"name": "line2",
"date": "2016-10-19T18:45:20Z",
"value": 74
}, {
"name": "line2",
"date": "2017-01-16T19:03:01Z",
"value": 46
}, {
"name": "line2",
"date": "2017-01-03T18:05:28Z",
"value": 32
}, {
"name": "line2",
"date": "2016-09-22T14:32:07Z",
"value": 93
}, {
"name": "line2",
"date": "2016-08-26T16:07:09Z",
"value": 22
}, {
"name": "line2",
"date": "2016-08-12T07:03:45Z",
"value": 52
}, {
"name": "line2",
"date": "2016-10-09T11:12:56Z",
"value": 52
}, {
"name": "line2",
"date": "2016-10-11T00:13:01Z",
"value": 39
}, {
"name": "line2",
"date": "2016-10-23T16:35:20Z",
"value": 58
}, {
"name": "line2",
"date": "2016-07-06T05:18:24Z",
"value": 95
}, {
"name": "line2",
"date": "2017-02-03T08:49:39Z",
"value": 51
}, {
"name": "line2",
"date": "2016-07-21T00:03:27Z",
"value": 100
}, {
"name": "line2",
"date": "2016-08-27T07:23:05Z",
"value": 71
}, {
"name": "line3",
"date": "2016-11-11T21:53:45Z",
"value": 87
}, {
"name": "line3",
"date": "2017-01-22T17:22:10Z",
"value": 220
}, {
"name": "line3",
"date": "2016-07-18T23:33:03Z",
"value": 24
}, {
"name": "line3",
"date": "2017-01-04T14:35:53Z",
"value": 65
}, {
"name": "line3",
"date": "2016-11-10T07:17:06Z",
"value": 9
}, {
"name": "line3",
"date": "2016-04-18T00:40:18Z",
"value": 54
}, {
"name": "line3",
"date": "2016-06-23T11:27:18Z",
"value": 72
}, {
"name": "line3",
"date": "2016-08-10T12:53:00Z",
"value": 88
}, {
"name": "line3",
"date": "2016-09-02T17:24:51Z",
"value": 89
}, {
"name": "line3",
"date": "2016-06-08T03:09:20Z",
"value": 27
}, {
"name": "line3",
"date": "2016-10-30T17:54:30Z",
"value": 38
}, {
"name": "line3",
"date": "2017-01-22T01:56:44Z",
"value": 99
}, {
"name": "line3",
"date": "2016-06-02T19:58:44Z",
"value": 48
}, {
"name": "line3",
"date": "2016-07-12T01:04:56Z",
"value": 68
}, {
"name": "line3",
"date": "2016-09-23T07:30:45Z",
"value": 51
}, {
"name": "line3",
"date": "2016-11-08T05:18:12Z",
"value": 49
}, {
"name": "line3",
"date": "2017-01-24T03:46:43Z",
"value": 89
}, {
"name": "line3",
"date": "2016-04-17T06:36:39Z",
"value": 54
}, {
"name": "line3",
"date": "2016-03-27T17:40:29Z",
"value": 27
}, {
"name": "line3",
"date": "2016-09-13T02:11:44Z",
"value": 58
}, {
"name": "line3",
"date": "2016-12-24T10:47:49Z",
"value": 24
}, {
"name": "line3",
"date": "2016-11-12T21:17:27Z",
"value": 54
}, {
"name": "line3",
"date": "2016-07-17T10:18:03Z",
"value": 55
}, {
"name": "line3",
"date": "2016-10-15T10:46:42Z",
"value": 24
}, {
"name": "line3",
"date": "2016-08-25T12:10:23Z",
"value": 63
}]
margin = {
top: 20,
right: 20,
bottom: 20,
left: 30
};
var containerwidth = $('.line-chart').width(),
containerheight = $('.line-chart').height();
var width = containerwidth - margin.left - margin.right,
height = containerheight - margin.top - margin.bottom;
var parseTime = d3.timeParse("%Y-%m-%dT%H:%M:%SZ")
data.forEach(function(d) {
d.date = parseTime(d.date);
d.value = +d.value;
});
function sortByDateAscending(a, b) {
return a.date - b.date;
}
dataset = data.sort(sortByDateAscending);
var dataGroup = d3.nest()
.key(function(d) {
return d.name;
})
.entries(data);
dataGroup.forEach(function(d) {
d.enabled = true;
});
var svg = d3.select('.line-chart')
.append('svg')
.attr('width', containerwidth)
.attr('height', containerheight)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
var x = d3.scaleTime().range([0, width]),
y = d3.scaleLinear().range([height, 0]);
var colorScale = d3.scaleOrdinal(d3.schemeCategory10);
var xAxis = d3.axisBottom(x).ticks(20).tickSizeInner(2).tickSizeOuter(0);
var yAxis = d3.axisLeft(y).ticks(5).tickSizeInner(-width).tickSizeOuter(0);
var xAxisGroup = svg.append('g').attr('class', 'x d3-axis').attr('transform', 'translate(0,' + height + ')');
var yAxisGroup = svg.append('g').attr('class', 'y d3-axis').attr('transform', 'translate(0,0)');
var line = d3.line()
.x(function(d) {
return x(d.date);
}).y(function(d) {
return y(d.value);
});
var legendItem = d3.select(".legend")
.selectAll("li")
.data(dataGroup)
.enter()
.append("li")
.on('click', function(d) {
d.enabled = !d.enabled;
redraw();
});
legendItem
.append("span")
.attr("class", "color-square")
.style("background", function(d, i) {
return colorScale(d.key);
});
legendItem
.append("span")
.text(function(d) {
return (d.values[0].name)
});
redraw();
function redraw() {
var fData = dataGroup.filter(function(d) {
return d.enabled;
});
y.domain([
d3.min(fData, function(c) {
return d3.min(c.values, function(d) {
return d.value;
});
}),
d3.max(fData, function(c) {
return d3.max(c.values, function(d) {
return d.value;
});
})
]);
x.domain([
d3.min(fData, function(c) {
return d3.min(c.values, function(d) {
return d.date;
});
}),
d3.max(fData, function(c) {
return d3.max(c.values, function(d) {
return d.date;
});
})
]);
xAxisGroup.call(xAxis);
yAxisGroup.call(yAxis);
// update selection
lines = svg.selectAll(".d3-group")
.data(fData, function(d) {
return d.key
});
// exit the whole group
lines
.exit().remove();
// enter selection
linesEnter = lines
.enter()
.append("g")
.attr("class", "d3-group");
// add path on enter
linesEnter.append("path")
.attr("class", "d3-line");
// add text on enter
linesEnter.append("text")
.attr("class", "my-label")
.attr("x", function(d,i){
return i * 100;
})
.attr("y", 10);
// update + enter
lines = lines.merge(linesEnter);
// adjust label
lines.select(".my-label")
.text(function(d,i){
return "hi Mom " + d.key;
});
// adjust path
lines.select(".d3-line")
.attr('d', function(d) {
return line(d.values);
})
.style("stroke", function(d, i) {
return colorScale(d.key);
});
}
</script>
</body>
</html>
这篇关于d3.js节点没有正确退出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!