抱歉,如果我的问题可能非常基础,但我自学了,如果不了解 javascript 的基础知识,很难继续
为了简化我的问题,假设我的数据如下所示:
country, value1, value2,
US, 100, 50,
UK, 30, 20,
Germany, 40, 30,
France, 20, 10
我想制作一个保管箱,其中 value1 和 value2 是选项。因此,当用户在下拉框中选择 value1 选项时,将仅显示 value1 的可视化。
所以我写了一些伪代码,如下面的根据输入过滤数据。
function update() {
var selected = menu.property("value");
data.filter((d) => return d3.keys(d[0]) === selected; )}
听起来还好吗?或者有什么需要修复的?
另外,过滤完数据后,我还需要对数据进行一些操作。所以我需要国家属性以及 value1 或 value2。有谁知道过滤时如何保留国家属性?
谢谢,
最佳答案
严格来说你不需要过滤,你可以只选择你希望可视化的数据属性:
首先,让我们根据您拥有的列制作选择菜单,d3.csv 将生成如下所示的数组:
var data = [
{"country":"US", "value1": 100, "value2": 50},
{"country":"UK", "value1": 30, "value2": 20},
{"country":"Germany", "value1": 40, "value2": 30},
{"country":"France", "value1": 20, "value2": 10}
];
现在我们可以获得列,如果使用 d3.csv 我们可以使用 data.columns
访问列。由于我们不希望将国家/地区作为选项,而只希望将值作为选项,因此我们可以使用 data.columns.slice(1)
将其切掉。 我只是在代码片段中使用了一个 javascript 对象,所以我使用 d3.keys(data[0]).slice(1)
来实现相同的效果。
现在我们可以根据数据集中有多少个值创建一个下拉列表:
// Create a select element
var select = d3.select("body")
.append("select")
.on("change", function() {
// Log value it is changed to:
console.log(this.value);
})
// Add an initial option:
select.append("option")
.html("Select Value:")
// Add the columns as options:
var options = select.selectAll(null)
.data(values)
.enter()
.append("option")
.text(function(d) { return d; });
这给了我们这个:
var data = [
{"country":"US", "value1": 100, "value2": 50},
{"country":"UK", "value1": 30, "value2": 20},
{"country":"Germany", "value1": 40, "value2": 30},
{"country":"France", "value1": 20, "value2": 10}
];
// Get the columns.
var values = d3.keys(data[0])
.slice(1);
// Create a select element
var select = d3.select("body")
.append("select")
.on("change", function() {
console.log(this.value);
})
// Add an initial option:
select.append("option")
.html("Select Value:")
// Add the options:
var options = select.selectAll(null)
.data(values)
.enter()
.append("option")
.text(function(d) { return d; });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
现在我们可以使用 on change 函数将属性名称传递给更新函数(作为参数,或者像我在下面所做的那样,利用回调函数的 this
是触发事件的元素)。该更新函数将采用该属性并使用它来修改可视化:
例如:
select.on("change", update)
function update() {
var property = this.value; // this is the element.
// .... scale modification eg: scale.domain(d3.extent(data, function(d) { return d[property]; }))
// .... enter/update/exit cycle
// Use property to shape visualization, eg:
updateSelection.attr("property", function(d) { return scale(d[property]); })
如果您需要根据属性细化比例或更改可视化类型,可以在此函数中执行。当然,您仍然可以在此处访问所有数据的属性,因此您仍然可以使用其他属性来修改可视化(比如在工具提示中)。
下面我创建了一个简单的可视化,更改下拉菜单更新图表(虽然很简单,没有比例修改,但为了适应初始选项的选择(不代表数据的属性)我'我们在缩放值时使用了 d[property] || 0
,这会优雅地移除可视化)。
var data = [
{"country":"US", "value1": 100, "value2": 50},
{"country":"UK", "value1": 30, "value2": 20},
{"country":"Germany", "value1": 40, "value2": 30},
{"country":"France", "value1": 20, "value2": 10}
];
// Get the columns.
var values = d3.keys(data[0])
.slice(1);
// Create a select element
var select = d3.select("body")
.append("select")
.on("change", update)
// Add an initial option:
select.append("option")
.html("Select Value:")
// Add the options:
var options = select.selectAll(null)
.data(values)
.enter()
.append("option")
.text(function(d) { return d; });
// Create an SVG
var svg = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 400);
// Spice it up with some scales:
var x = d3.scaleBand()
.domain(data.map(function(d) { return d.country; }))
.range([0,500])
var y = d3.scaleLinear()
.domain([0,100])
.range([150,0])
// Specify an Update function to create and update visualization elements:
function update() {
var value = this.value;
var bars = svg.selectAll("rect")
.data(data);
bars.enter().append("rect")
.attr("x", function(d) { return x(d.country); })
.attr("width", x.bandwidth())
.attr("y", 150)
.attr("height",0)
.merge(bars)
.transition()
.attr("height", function(d) { return 150 - y(d[value] || 0); })
.attr("y", function(d) { return y(d[value] || 0); });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
关于javascript - d3/javascript 根据输入过滤数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52119854/