gpt4 book ai didi

javascript - 获取条形图中每个 y 轴的唯一最大值

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

在我下面的代码中,我附加了多个 svg 元素并从中获取了 3 个不同的图表。

我遇到的问题是,从每个 y 轴的 y.domain() 评估的最大值是我所有数据的最大值。

是否有一些聪明的方法来获取每个 svg 的最大值并将其设置为每个 y 轴的最大值,或者我是否必须制作 3 个不同的 y 尺度?

代码如下:

var data = [
{category: "Apples", total: 10, goal: 8},
{category: "Oranges", total: 20, goal: 18},
{category: "Bananas", total: 20, goal: 25},
];

chart(data);

function chart(result) {

var margin = {bottom: 25, right: 25, top: 25, left: 25},
width = 180 - margin.left - margin.right,
height = 230 - margin.top - margin.bottom;

var svg = d3.select("#chart").selectAll("svg")
.data(result)
.enter().append("svg")
.attr("width", width)
.attr("height", height)

var x = d3.scaleBand()
.range([margin.left, width - margin.right])
.domain(["Total", "Goal"])
.padding(.1)
.paddingOuter(.2)

var y = d3.scaleLinear()
.range([height - margin.bottom, margin.top])
.domain([0, d3.max(result, d => Math.max(d.total, d.goal))]).nice()

var xAxis = g => g
.attr("transform", "translate(0," + (height - margin.bottom) + ")")
.call(d3.axisBottom(x).tickSizeOuter(0))

var yAxis = g => g
.attr("transform", "translate(" + margin.left + ",0)")
.call(d3.axisLeft(y))

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

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

var total = svg.append("rect")
.attr("fill", "steelblue")
.attr("width", x.bandwidth())
.attr("x", x("Total"))
.attr("y", function() {
var d = d3.select(this.parentNode).datum()
return y(d.total)
})
.attr("height", function() {
var d = d3.select(this.parentNode).datum()
return y(0) - y(d.total)
})

var goal = svg.append("rect")
.attr("fill", "orange")
.attr("width", x.bandwidth())
.attr("x", x("Goal"))
.attr("y", function() {
var d = d3.select(this.parentNode).datum()
return y(d.goal)
})
.attr("height", function() {
var d = d3.select(this.parentNode).datum()
return y(0) - y(d.goal)
})

var text = svg.append("text")
.attr("dx", width / 2)
.attr("dy", 15)
.attr("text-anchor", "middle")
.text(function() {
return d3.select(this.parentNode).datum().category
})
}
<meta charset ="utf-8">
<script src="https://d3js.org/d3.v5.min.js "></script>

<div id="chart"></div>

最佳答案

我认为这里最好的想法是重构您的代码,以根据您传递给它的数据创建特定的 SVG。但是,鉴于您现在拥有的代码, 惯用的 D3 解决方案正在使用 local variables .

实际上,根据 Mike Bostock 的说法...

For instance, when rendering small multiples of time-series data, you might want the same x-scale for all charts but distinct y-scales to compare the relative performance of each metric.

...局部变量是您具体情况的解决方案!

所以,您只需要设置本地...

var local = d3.local();

svg.each(function(d) {
var y = local.set(this, d3.scaleLinear()
.range([height - margin.bottom, margin.top])
.domain([0, Math.max(d.total, d.goal)]).nice())
});

... 并使用它来创建轴和条。例如:

.attr("y", function(d) {
return local.get(this)(d.total);
})

请记住,您不需要 var d = d3.select(this.parentNode).datum() 来获取数据!

这是您的代码,其中包含这些更改:

var data = [{
category: "Apples",
total: 10,
goal: 8
},
{
category: "Oranges",
total: 20,
goal: 18
},
{
category: "Bananas",
total: 20,
goal: 25
},
];

var local = d3.local();

chart(data);

function chart(result) {

var margin = {
bottom: 25,
right: 25,
top: 25,
left: 25
},
width = 180 - margin.left - margin.right,
height = 230 - margin.top - margin.bottom;

var svg = d3.select("#chart").selectAll("svg")
.data(result)
.enter().append("svg")
.attr("width", width)
.attr("height", height)

var x = d3.scaleBand()
.range([margin.left, width - margin.right])
.domain(["Total", "Goal"])
.padding(.1)
.paddingOuter(.2);

svg.each(function(d) {
var y = local.set(this, d3.scaleLinear()
.range([height - margin.bottom, margin.top])
.domain([0, Math.max(d.total, d.goal)]).nice())
});

var xAxis = g => g
.attr("transform", "translate(0," + (height - margin.bottom) + ")")
.call(d3.axisBottom(x).tickSizeOuter(0))



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

svg.each(function() {
var y = local.get(this);
var yAxis = g => g
.attr("transform", "translate(" + margin.left + ",0)")
.call(d3.axisLeft(y));
d3.select(this).append("g")
.attr("class", "y-axis")
.call(yAxis);
})

var total = svg.append("rect")
.attr("fill", "steelblue")
.attr("width", x.bandwidth())
.attr("x", x("Total"))
.attr("y", function(d) {
return local.get(this)(d.total);
})
.attr("height", function(d) {
return local.get(this)(0) - local.get(this)(d.total)
})

var goal = svg.append("rect")
.attr("fill", "orange")
.attr("width", x.bandwidth())
.attr("x", x("Goal"))
.attr("y", function(d) {
return local.get(this)(d.goal)
})
.attr("height", function(d) {
return local.get(this)(0) - local.get(this)(d.goal)
})

var text = svg.append("text")
.attr("dx", width / 2)
.attr("dy", 15)
.attr("text-anchor", "middle")
.text(function() {
return d3.select(this.parentNode).datum().category
})
}
<meta charset="utf-8">
<script src="https://d3js.org/d3.v5.min.js "></script>

<div id="chart"></div>

关于javascript - 获取条形图中每个 y 轴的唯一最大值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52555845/

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