gpt4 book ai didi

javascript - d3.js 从对象中的值创建堆积条形图

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

下面的代码将在名为“数据”的对象数组中创建单个值的条形图。如何使用数据集合来创建堆积条形图?

设置边距

 var w = 700;
var h = 500;
var margin = {
top: 58,
bottom: 120,
left: 60,
right: 40
};
var width = w - margin.left - margin.right;
var height = h - margin.top - margin.bottom;

定义数据

 data =[
{ name: "Subway", carbs: "480", fat: "400", protein: "120", sum: "1000"},
{ name: "Steak & Potatos", carbs: "900", fat: "350", protein: "200", sum: "1450"},
{ name: "Sausage", carbs: "50", fat: "350", protein: "80", sum: "480"}
];

我希望条形的高度是碳水化合物、脂肪、蛋白质值的总和,但每个值的颜色不同。定义 x

 var x = d3.scale.ordinal()
.domain(data.map(function(e){
return e.name;
}))
.rangeBands([0,width]);

定义y。这是我认为我需要帮助的地方

 var y = d3.scale.linear()
.domain([0, d3.max(data, function(d,i){

return parseInt(d.carbs) ;
})])
.range([height, 0]);

以上将给我一个具有单一值(碳水化合物)的栏。但我真正想做的是创建一个堆积条形图。任何帮助将不胜感激。

在下面发布的答案“z 是你的色阶,它将决定你的矩形看起来像什么”之后添加

 var z = d3.scale.ordinal()
.range(["#ff0", "#f00", "#0ff"])
.domain(["carbs", "fat", "protein"]);

这是绘制图表的plot函数

 function plot(params){

this.append('g')
.call(params.gridlines)
.classed('gridline', true)
.attr('transform','translate(0,0)');

this.selectAll('bar')
.data(params.data)
.enter()
.append('rect')
.classed('bar', true)
.attr('x', function(d,i){
return x(d.name)
})
.attr('y',function(d,i){
return y(d.carbs);
})
.attr('width', function(d){
return x.rangeBand();
})
.attr('height', function(d,i){
return height - y(d.carbs)
})
.style('fill',function(d,i){
return ordinal_color_scale(i);
});

this.selectAll('.bar_label')
.data(params.data)
.enter()
.append('text')
.classed('bar_label', true)
.attr('x', function(d,i){
return x(d.name) + (x.rangeBand()/2);
})
.attr('dx', 0)
.attr('y', function(d,i){
return y(d.carbs);
})
.attr('dy', -6)
.text(function(d){
return d.carbs;
});

this.append('g')
.classed('x axis', true)
.style('fill', '#ffd000')
.attr('transform','translate('+ 0 +','+ height +')')
.call(params.axis.x)
.selectAll('text')
.style('text-anchor','end')
.attr( 'dx', -8)
.attr('dy',8)
.attr('transform','translate(0,0) rotate(-45)');

this.append('g')
.classed('y axis', true)
.style('fill', '#ffd000')
.attr('transform','translate(0,0)')
.call(params.axis.y);
}

plot.call(chart, {
data: data,
axis: {
x: x_axis,
y: y_axis
},
gridlines: y_gridlines
});

我不明白的是如何在图表的条形图中绘制 z 变量。

最佳答案

y 的域确实是这里的错误所在。该范围需要考虑所有变量,而不仅仅是碳水化合物。换句话说,你的 max函数需要考虑所有属性的总和。

var y = d3.scale.linear()
.domain([0, d3.max(data, function(d,i){
return parseInt(d.sum);
})])
.range([height, 0]);

这是因为,最终,您的条形图将与所有属性的总和一样高(因为它是堆叠条形图)

然后您将需要使用 stack 当您实际绘制 <rect> 时起作用元素。每个栏将包含 3 <rect>元素(一个用于碳水化合物、脂肪和蛋白质,一个堆叠在另一个之上)您没有为此发布任何代码,但它很可能看起来像:

// z is your color scale here which will decide what your rectangles look like
var z = d3.scaleOrdinal()
.range(["#<colorForCarbs>", "#<colorForFat>", "#<colorForProtein>"])
.domain(["carbs", "fat", "protein"]);

g.selectAll(".serie")
.data(stack.keys(["carbs", "fat", "protein"])(data))
.enter().append("g")
.attr("class", "serie")
.attr("fill", function(d) { return z(d.key); })
.selectAll("rect")
.data(function(d) { return d; })
.enter().append("rect")
.attr(class, 'bar')
.attr("x", function(d) { return x(d.data.name); })
.attr("y", function(d) { return y(d[1]); })
.attr("height", function(d) { return y(d[0]) - y(d[1]); })
.attr("width", x.bandwidth());

例如,示例中的“系列”是与“碳水化合物”相关的所有矩形(与包含碳水化合物、脂肪和蛋白质的 3 个矩形的堆栈相反)。

如果您遗漏了什么,这个示例应该会为您提供所需的一切:http://bl.ocks.org/mbostock/3886208

编辑

根据您更新的问题,这是您应该使用 z 比例的代码部分

this.selectAll('bar')
.data(params.data)
.enter()
.append('rect')
.classed('bar', true)
.attr('x', function(d,i){
return x(d.name)
})
.attr('y',function(d,i){
return y(d.carbs);
})
.attr('width', function(d){
return x.rangeBand();
})
.attr('height', function(d,i){
return height - y(d.carbs)
})
.style('fill',function(d,i){
return ordinal_color_scale(i);
});

取而代之的是,使用

var stack = d3.stack(); 
g.selectAll(".serie")
.data(stack.keys(["carbs", "fat", "protein"])(data))
.enter().append("g")
.attr("class", "serie")
.attr("fill", function(d) { return z(d.key); })
.selectAll("rect")
.data(function(d) { return d; })
.enter()
.append("rect")
.attr("x", function(d) { return x(d.data.name); })
.attr("y", function(d) { return y(d[1]); })
.attr("height", function(d) { return y(d[0]) - y(d[1]); })
.attr("width", x.rangeBand());

关于javascript - d3.js 从对象中的值创建堆积条形图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40518438/

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