gpt4 book ai didi

javascript - 调整发散堆积条形图以使用一般更新模式

转载 作者:行者123 更新时间:2023-11-29 18:52:33 24 4
gpt4 key购买 nike

我一直在使用可用的堆叠条形图示例 here使用以下代码:

var data = [
{month: "Q1-2016", apples: 3840, bananas: 1920, cherries: -1960, dates: -400},
{month: "Q2-2016", apples: 1600, bananas: 1440, cherries: -960, dates: -400},
{month: "Q3-2016", apples: 640, bananas: 960, cherries: -640, dates: -600},
{month: "Q4-2016", apples: 320, bananas: 480, cherries: -640, dates: -400}
];

var series = d3.stack()
.keys(["apples", "bananas", "cherries", "dates"])
.offset(d3.stackOffsetDiverging)
(data);

var svg = d3.select("svg"),
margin = {top: 20, right: 30, bottom: 30, left: 60},
width = +svg.attr("width"),
height = +svg.attr("height");

var x = d3.scaleBand()
.domain(data.map(function(d) { return d.month; }))
.rangeRound([margin.left, width - margin.right])
.padding(0.1);

var y = d3.scaleLinear()
.domain([d3.min(series, stackMin), d3.max(series, stackMax)])
.rangeRound([height - margin.bottom, margin.top]);

var z = d3.scaleOrdinal(d3.schemeCategory10);

svg.append("g")
.selectAll("g")
.data(series)
.enter().append("g")
.attr("fill", function(d) { return z(d.key); })
.selectAll("rect")
.data(function(d) { return d; })
.enter().append("rect")
.attr("width", x.bandwidth)
.attr("x", function(d) { return x(d.data.month); })
.attr("y", function(d) { return y(d[1]); })
.attr("height", function(d) { return y(d[0]) - y(d[1]); })

svg.append("g")
.attr("transform", "translate(0," + y(0) + ")")
.call(d3.axisBottom(x));

svg.append("g")
.attr("transform", "translate(" + margin.left + ",0)")
.call(d3.axisLeft(y));

function stackMin(serie) {
return d3.min(serie, function(d) { return d[0]; });
}

function stackMax(serie) {
return d3.max(serie, function(d) { return d[1]; });
}

示例中的代码不支持转换或重绘,因此我一直在尝试应用 general update pattern 的原则添加到它以便我可以在我的应用程序中使用它。

我不熟悉 D3v4,“附加”的性质让我很困惑。我在同一个附加方法链中看到两个“输入”,所以我试图将它们分离到它们自己的声明中,例如:

var join1 = .selectAll("g")
.data(series)

var join2Update = .selectAll("rect")
.data(function(d) { return d; })

var join2Enter= join2.enter()

join2Enter
.append("rect")
.merge(join2Update)
.transition()
.attr("width", x.bandwidth)
.attr("x", function(d) { return x(d.data.month); })
.attr("y", function(d) { return y(d[1]); })
.attr("height", function(d) { return y(d[0]) - y(d[1]); })

但它除了打破排行榜外并没有太大作用!坦率地说,我对整件事有点迷茫,非常感谢任何帮助。

最佳答案

我对您的代码进行了一些更改以使其可更新,我会指出我所做的一些更改,如果还有其他不清楚的地方,您可以直接询问。

我所做的主要更改是,为了简单起见,在我们的数据集中我们有两个类别,这样我们就可以像这样根据输入更新我们的数据

var keys = ["apples" + input, "bananas" + input];

这里的输入变量最初是这样选择的

var input = d3.selectAll(".opt").property("value");

当我们手动更新它时,我们会得到这样的新数据

d3.selectAll(".opt").on("change", function() {
update(data, this.value)
})

我们创建了一个包含 series 数据集的 bar 组,然后用另一个变量引用它,而不是直接将 g 元素附加到 rect 上。

var barGroups = svg.selectAll("g.layer")
.data(series);

barGroups.exit().remove();

barGroups.enter().insert("g", ".x-axis")
.classed('layer', true);

这是您之前提到的代码的更新模式部分:

var bars = svg.selectAll("g.layer").selectAll("rect")
.data(function(d) { return d; });

bars.exit().remove();

bars = bars
.enter()
.append("rect")
.attr("width", x.bandwidth())
.attr("x", d => x(d.data.month))
.merge(bars)

bars.transition().duration(750)
.attr("y", d => y(d[1]))
.attr("height", d => Math.abs(y(d[0])) - y(d[1]));

应该就是这样,看看下面的代码片段,看看它是如何工作的。

var data = [
{month: "Q1-2016", apples_1: -400, bananas_1: 920, apples_2: -196, bananas_2: 840},
{month: "Q2-2016", apples_1: -400, bananas_1: 440, apples_2: -960, bananas_2: 600},
{month: "Q3-2016", apples_1: -600, bananas_1: 960, apples_2: -640, bananas_2: 640},
{month: "Q4-2016", apples_1: -400, bananas_1: 480, apples_2: -640, bananas_2: 320}
];

var margin = {top: 35, right: 145, bottom: 35, left: 45},
width = 650 - margin.left - margin.right,
height = 450 - margin.top - margin.bottom;

var svg = d3.select("#chart")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform","translate(" + margin.left + "," + margin.top + ")");

var x = d3.scaleBand()
.rangeRound([0, width])
.padding(0.1);

var y = d3.scaleLinear()
.rangeRound([height, 0]);

var z = d3.scaleOrdinal()
.range(["steelblue","darkorange"]);

svg.append("g")
.attr("class","x-axis");

svg.append("g")
.attr("class", "y-axis");

var input = d3.selectAll(".opt").property("value");

d3.selectAll(".opt").on("change", function() {
update(data, this.value)
})

update(data, input);

function update(data, input) {

var keys = ["apples" + input, "bananas" + input];

var series = d3.stack()
.keys(keys)
.offset(d3.stackOffsetDiverging)
(data);

x.domain(data.map(d => d.month));

y.domain([
d3.min(series, stackMin),
d3.max(series, stackMax)
]).nice();

var barGroups = svg.selectAll("g.layer")
.data(series);

barGroups.exit().remove();

barGroups.enter().insert("g", ".x-axis")
.classed('layer', true);

svg.selectAll("g.layer")
.transition().duration(750)
.attr("fill", d => z(d.key));

var bars = svg.selectAll("g.layer").selectAll("rect")
.data(function(d) { return d; });

bars.exit().remove();

bars = bars
.enter()
.append("rect")
.attr("width", x.bandwidth())
.attr("x", d => x(d.data.month))
.merge(bars)

bars.transition().duration(750)
.attr("y", d => y(d[1]))
.attr("height", d => Math.abs(y(d[0])) - y(d[1]));

svg.selectAll(".x-axis").transition().duration(750)
.attr("transform", "translate(0," + y(0) + ")")
.call(d3.axisBottom(x));

svg.selectAll(".y-axis").transition().duration(750)
.call(d3.axisLeft(y));

function stackMin(serie) {
return d3.min(serie, function(d) { return d[0]; });
}

function stackMax(serie) {
return d3.max(serie, function(d) { return d[1]; });
}

}
body {
margin: auto;
width: 850px;
}
<meta charset ="utf-8">

<script src="https://d3js.org/d3.v5.min.js"></script>
select something
<select class="opt">
<option value="_1">1</option>
<option value="_2">2</option>
</select><br>

<svg id="chart"></svg>

关于javascript - 调整发散堆积条形图以使用一般更新模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50756034/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com