未能使用 d3 更新图例数据,已更改数据的输入为空
failed to use d3 to update legend data, entering is empty for changed data
我有一个“添加数据集”按钮,单击它后图例应显示更改后的数据集,一切都很好。我还有一个带有图例的点击事件,所以当我点击图例时,数据集被删除,我在样式上加上一条线,这就是问题所在,当我使用添加按钮添加另一个数据集时,删除的数据集图例应更改为新的数据集编号。控制台显示数据正确,但图例没有变化。我已经遵循了一些教程并且完全遵循了它,但仍然明白这一点,我已经为此工作了几个小时,我需要一些帮助,谢谢
let jsonObj = [{
category: "Jan",
values: [{
value: 9,
source: "dataset1",
},
{
value: 8,
source: "dataset2",
},
],
},
{
category: "Feb",
values: [{
value: 15,
source: "dataset1",
},
{
value: 21,
source: "dataset2",
},
],
},
];
// function for adding data
let counter = 2;
const add_set = (arr) => {
const ran = () => Math.floor(Math.random() * 15 + 1);
const add = (arr) => {
counter++;
arr.map((i) =>
i.values.push({
value: ran(),
source: `dataset${counter}`
})
);
};
add(arr);
};
//initial variables
let svg, totalWidth, totalHeight, legend;
const setup = () => {
totalWidth = 100;
totalHeight = 100;
svg = d3
.select("body")
.append("svg")
.attr("width", totalWidth)
.attr("height", totalHeight);
};
const draw = (data) => {
//No.6 set lengend
legend = svg
.selectAll(".legend")
.data(data[0].values.map((d) => d.source));
console.log(data[0].values.map((d) => d.source));
let entering = legend.enter();
let newLegend = entering
.append("g")
.attr("class", "legend")
.attr("transform", (d, i) => "translate(0," + i * 20 + ")")
.append("text")
.attr("x", totalWidth)
.attr("y", 9)
.style("text-anchor", "end")
.text((d) => d);
entering.text((d) => d);
let exiting = legend.exit();
exiting.remove();
newLegend.on("click", function(e, d) {
jsonObj.forEach((i) => {
i.values = i.values.filter((s) => s.source != d);
});
newLegend
.filter((x) => x === d)
.style("text-decoration", "line-through");
});
};
setup();
draw(jsonObj);
const update = () => {
add_set(jsonObj);
draw(jsonObj);
};
<script src="https://d3js.org/d3.v6.min.js"></script>
<button onclick="update()">Add dataset</button>
以下解决方案正是您所要求的。
我不删除任何节点,因为您总是 re-use 它们。
entering
节点和newLegend
节点之间也有区别——一个有实际内容,另一个只是一种空数组。
let jsonObj = [{
category: "Jan",
values: [{
value: 9,
source: "dataset1",
},
{
value: 8,
source: "dataset2",
},
],
},
{
category: "Feb",
values: [{
value: 15,
source: "dataset1",
},
{
value: 21,
source: "dataset2",
},
],
},
];
// function for adding data
let counter = 2;
const add_set = (arr) => {
const ran = () => Math.floor(Math.random() * 15 + 1);
const add = (arr) => {
counter++;
arr.map((i) =>
i.values.push({
value: ran(),
source: `dataset${counter}`
})
);
};
add(arr);
};
//initial variables
let svg, totalWidth, totalHeight, legend;
const setup = () => {
totalWidth = 100;
totalHeight = 100;
svg = d3
.select("body")
.append("svg")
.attr("width", totalWidth)
.attr("height", totalHeight);
};
const draw = (data) => {
//No.6 set lengend
legend = svg
.selectAll(".legend")
.data(data[0].values.map((d) => d.source));
console.log(data[0].values.map((d) => d.source));
legend.exit().remove();
let newLegend = legend.enter()
.append("g")
.attr("class", "legend")
.attr("transform", (d, i) => "translate(0," + i * 20 + ")");
newLegend
.append("text")
.datum((d) => d)
.attr("x", totalWidth)
.attr("y", 9)
.style("text-anchor", "end")
.on("click", function(e, d) {
jsonObj.forEach((i) => {
i.values = i.values.filter((s) => s.source != d);
});
newLegend
.filter((x) => x === d)
.style("text-decoration", "line-through");
});
legend = newLegend.merge(legend);
legend
.style("text-decoration", null)
.select("text")
.text((d) => d);
};
setup();
draw(jsonObj);
const update = () => {
add_set(jsonObj);
draw(jsonObj);
};
<script src="https://d3js.org/d3.v6.min.js"></script>
<button onclick="update()">Add dataset</button>
我有一个“添加数据集”按钮,单击它后图例应显示更改后的数据集,一切都很好。我还有一个带有图例的点击事件,所以当我点击图例时,数据集被删除,我在样式上加上一条线,这就是问题所在,当我使用添加按钮添加另一个数据集时,删除的数据集图例应更改为新的数据集编号。控制台显示数据正确,但图例没有变化。我已经遵循了一些教程并且完全遵循了它,但仍然明白这一点,我已经为此工作了几个小时,我需要一些帮助,谢谢
let jsonObj = [{
category: "Jan",
values: [{
value: 9,
source: "dataset1",
},
{
value: 8,
source: "dataset2",
},
],
},
{
category: "Feb",
values: [{
value: 15,
source: "dataset1",
},
{
value: 21,
source: "dataset2",
},
],
},
];
// function for adding data
let counter = 2;
const add_set = (arr) => {
const ran = () => Math.floor(Math.random() * 15 + 1);
const add = (arr) => {
counter++;
arr.map((i) =>
i.values.push({
value: ran(),
source: `dataset${counter}`
})
);
};
add(arr);
};
//initial variables
let svg, totalWidth, totalHeight, legend;
const setup = () => {
totalWidth = 100;
totalHeight = 100;
svg = d3
.select("body")
.append("svg")
.attr("width", totalWidth)
.attr("height", totalHeight);
};
const draw = (data) => {
//No.6 set lengend
legend = svg
.selectAll(".legend")
.data(data[0].values.map((d) => d.source));
console.log(data[0].values.map((d) => d.source));
let entering = legend.enter();
let newLegend = entering
.append("g")
.attr("class", "legend")
.attr("transform", (d, i) => "translate(0," + i * 20 + ")")
.append("text")
.attr("x", totalWidth)
.attr("y", 9)
.style("text-anchor", "end")
.text((d) => d);
entering.text((d) => d);
let exiting = legend.exit();
exiting.remove();
newLegend.on("click", function(e, d) {
jsonObj.forEach((i) => {
i.values = i.values.filter((s) => s.source != d);
});
newLegend
.filter((x) => x === d)
.style("text-decoration", "line-through");
});
};
setup();
draw(jsonObj);
const update = () => {
add_set(jsonObj);
draw(jsonObj);
};
<script src="https://d3js.org/d3.v6.min.js"></script>
<button onclick="update()">Add dataset</button>
以下解决方案正是您所要求的。 我不删除任何节点,因为您总是 re-use 它们。
entering
节点和newLegend
节点之间也有区别——一个有实际内容,另一个只是一种空数组。
let jsonObj = [{
category: "Jan",
values: [{
value: 9,
source: "dataset1",
},
{
value: 8,
source: "dataset2",
},
],
},
{
category: "Feb",
values: [{
value: 15,
source: "dataset1",
},
{
value: 21,
source: "dataset2",
},
],
},
];
// function for adding data
let counter = 2;
const add_set = (arr) => {
const ran = () => Math.floor(Math.random() * 15 + 1);
const add = (arr) => {
counter++;
arr.map((i) =>
i.values.push({
value: ran(),
source: `dataset${counter}`
})
);
};
add(arr);
};
//initial variables
let svg, totalWidth, totalHeight, legend;
const setup = () => {
totalWidth = 100;
totalHeight = 100;
svg = d3
.select("body")
.append("svg")
.attr("width", totalWidth)
.attr("height", totalHeight);
};
const draw = (data) => {
//No.6 set lengend
legend = svg
.selectAll(".legend")
.data(data[0].values.map((d) => d.source));
console.log(data[0].values.map((d) => d.source));
legend.exit().remove();
let newLegend = legend.enter()
.append("g")
.attr("class", "legend")
.attr("transform", (d, i) => "translate(0," + i * 20 + ")");
newLegend
.append("text")
.datum((d) => d)
.attr("x", totalWidth)
.attr("y", 9)
.style("text-anchor", "end")
.on("click", function(e, d) {
jsonObj.forEach((i) => {
i.values = i.values.filter((s) => s.source != d);
});
newLegend
.filter((x) => x === d)
.style("text-decoration", "line-through");
});
legend = newLegend.merge(legend);
legend
.style("text-decoration", null)
.select("text")
.text((d) => d);
};
setup();
draw(jsonObj);
const update = () => {
add_set(jsonObj);
draw(jsonObj);
};
<script src="https://d3js.org/d3.v6.min.js"></script>
<button onclick="update()">Add dataset</button>