我用 d3.js 制作了多折线图可视化。但是有这么多行(每一行都是我的数据集上的一列),它显然不可读。所以我想要一个复选框,用户可以在其中选择他想要显示的行。我的问题是,在我看到的所有教程中,我需要手动编写要在复选框中显示的每一列的名称...有没有办法自动获取复选框中的所有变量?
举个例子,我想要这样的结果:https://d3-graph-gallery.com/graph/line_select.html
目前我只有一个在图表上显示所有变量的脚本,并且我不知道需要添加什么。
我把我的代码留给你它的当前状态:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test pollen avec code D3 Graph Gallery</title>
<style>
body {
font: 12px sans-serif;
}
.axis path,
axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
x.axis path {
display: none;
}
.line {
fill: none;
stroke: steelblue; stroke-width: 1.5px;
}
</style>
</head>
<body>
<h1 style="margin: 2em;">Concentration pollinique au Luxembourg, 1992-2018</h1>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<script>
const margin = {top: 20, right: 80, bottom: 30, left: 100},
width = 1200 - margin. left - margin. right,
height = 500 - margin.top - margin. bottom;
// formater date
const parseDate = d3. time.format("%Y-%m-%d").parse;
const x = d3.time.scale()
.range ([0, width]);
const y = d3.scale. linear()
.range ( [height, 0]);
const color = d3. scale. category10();
// axes x et y avec leur orientation
const xAxis = d3. svg.axis ()
.scale (x)
.orient ("bottom");
const yAxis = d3. svg.axis ()
.scale (y)
.orient ("left");
const line = d3.svg.line()
.interpolate ("basis")
.x(function(d) { return x(d. date); })
.y(function(d) { return y(d.concentration); });
let 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 + ")");
d3.csv ("pollen_tri.csv", function(error, data) {
color.domain (d3.keys (data[0]).filter(function (key) { return key !== "date"; }));
data.forEach(function(d) {
d.date = parseDate (d.date);
});
var plants = color.domain().map (function (name) {
return {
name: name,
values: data.map(function (d) {
return {date: d.date, concentration: +d [name]};
})
};
});
x.domain (d3.extent (data, function(d) { return d.date; }));
y.domain([
d3.min(plants, function(c) { return d3.min(c.values, function(v) {return v.concentration;}); }),
d3.max(plants, function(c) { return d3.max(c.values, function(v) { return v.concentration;});})
]);
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")
.text ("Concentration (pollens/m3)");
var plant = svg.selectAll(".plant")
.data(plants)
.enter()
.append ("g")
.attr("class", "plant");
plant.append("path")
.attr("class", "line")
.attr("d", function(d) { return line(d.values); })
.style("stroke", function(d) { return color(d.name); });
});
</script>
</body>
</html>
最后,这是我的 csv 文件的示例:
日期 | 安布罗西亚 | 艾蒿 | 菊科 | 桤木 | 桦木 | 杜鹃花科 | 鹅耳枥 | 栗 | 栎属 | 藜 | 柏科 | 宏碁 | 白蜡树 | 禾本科 | 水青冈 | 灯芯草科 | 七叶树 | 落叶松 | 榛属 | 核桃 | 伞形科 | 榆树 | 荨麻 | 酸模 | 胡杨 | 松科 | 车前草 | 悬铃木 | 柳 | 莎草科 | 凤尾花 | 接骨木 | 蒂利亚 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1992-01-01 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1992-01-02 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1992-01-03 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1992-01-04 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1992-01-05 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1992-01-06 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1992-01-07 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1992-01-08 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1992-01-09 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
这是如何自动创建显示/隐藏线条的复选框的示例。
我使用了普通的 Javascript,但你可以使用 d3 做同样的事情。
<input type="checkbox">
)。要获取下拉菜单,请使用 <select>
和 <option>
。
共有三个步骤:
<path>
。换句话说,它可以让我们从植物名称中查找 SVG <path>
。我更改的代码:
const mapPlantNameToSvgPath = {};
plant.append("path")
.attr("class", "line")
.attr("d", function (d) { return line(d.values); })
.style("stroke", function (d) { return color(d.name); })
//
// https://d3js.org/d3-selection/control-flow#selection_each
.each(function (d) {
const svgPath = this;
const plantName = d.name;
mapPlantNameToSvgPath[plantName] = svgPath;
})
color.domain().forEach(function (plantName) {
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label
const label = document.createElement("label");
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox
const checkbox = document.createElement("input");
checkbox.setAttribute("type", "checkbox");
checkbox.setAttribute("checked", "true");
checkbox.addEventListener("change", function () {
const svgPath = mapPlantNameToSvgPath[plantName];
// https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/visibility
if (checkbox.checked) {
svgPath.setAttribute("visibility", "visible");
} else {
svgPath.setAttribute("visibility", "hidden");
}
});
label.append(checkbox);
label.append(document.createTextNode(plantName));
document.body.append(document.createElement("br"));
document.body.append(label);
});
屏幕截图(csv 文件中包含虚假数据):