gpt4 book ai didi

javascript - D3 中使用内部 JSON 变量的堆叠条形图

转载 作者:行者123 更新时间:2023-12-03 04:56:47 24 4
gpt4 key购买 nike

因此尝试在 D3.js 中创建堆叠条形图。我已经让轴工作了,但是图表数据没有显示,有什么想法我哪里出错了吗?

JS:

var svg = d3.select("#recovery__table"),
margin = {top: 20, right: 20, bottom: 30, left: 40},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom,
aspect = width/height,
g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

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

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

var z = d3.scaleOrdinal()
.range(["#717C8B", "#7FDDC3", "#39B3CD"]);

var stack = d3.stack();

data.forEach(function(d) {
d.year = d['trades.closed_half_year_year'];
d.loss = d['loss'];
d.recovered = d['recovered'];
d.recovery = d['in_recovery'];
d.total = d.loss + d.recovery + d.recovered;
});

var div = d3.select("body").append("div")
.attr("class", "tooltip3")
.style("opacity", "0");

x.domain(data.map(function(d) { return d.year; }));
y.domain([0, d3.max(data, function(d) { return d.total; })]).nice();
z.domain(d3.keys(data[0]).filter(function(key){ return key == 'loss' && key == 'recovered' && key == 'in_recovery' }));

g.selectAll(".serie")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("fill", function(d){ return z(d.keys); })
.attr("x", function(d) { return x(d.year); })
.attr("width", x.bandwidth())
.attr("y", function(d) { return y(d.total); })
.attr("height", function(d) { return y[0] - y[1]; })
.on("mouseover", function(d) {
var value = parseInt($(this).attr('data-value'));
div.transition()
.duration(200)
.style("opacity", .5);
div.html(d.data.year + "<br/>£" + total.formatMoney())
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
;

g.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.attr('x', 20)
.call(d3.axisBottom(x));

g.append("g")
.attr("class", "axis axis--y")
.call(d3.axisLeft(y).ticks(5, "s"))
.append("text")
.attr("x", 2)
.attr("y", y(y.ticks(10).pop()))
.attr("dy", "0.35em")
.attr("text-anchor", "start")
.attr("fill", "#000");

var legend = g.selectAll(".legend")
.data(data)
.enter().append("g")
.attr('width', 100)
.attr("class", "legend")
.attr('transform', function(d, i) {
var horz = 100*i; // NEW
var vert = 0;
if (horz >= width) {
horz = 100 * (i - 3);
vert = 40;
}

return 'translate(' + horz + ',' + vert + ')'; // NEW
})
.style("font", "10px sans-serif");

legend.append("rect")
.attr("x", "33%")
.attr("width", 18)
.attr("height", 18)
.attr("fill", z);

legend.append("text")
.attr("x", "43%")
.attr("y", 9)
.attr("dy", ".35em")
.attr("text-anchor", "end")
.text(function(d) { return d; });

JSON 示例

[{"trades.closed_half_year_year":"2017","auctioncollectioninfos.total_advanced_amount_delinquent_and_collection_completed_gbp_daily":"£0.00","auctioncollectioninfos.total_crystallized_loss_gbp_daily":"£0.00","auctioncollectioninfos.total_outstanding_amount_delinquent_gbp_daily":"£","auctioncollectioninfos.total_advanced_amount_delinquent_gbp_daily":"£0.00","loss":"£0.00","recovered":"£0.00","in_recovery":"£0"},
{"trades.closed_half_year_year":"2016","auctioncollectioninfos.total_advanced_amount_delinquent_and_collection_completed_gbp_daily":"£123,456.78","auctioncollectioninfos.total_crystallized_loss_gbp_daily":"£0.00","auctioncollectioninfos.total_outstanding_amount_delinquent_gbp_daily":"£1,234,234","auctioncollectioninfos.total_advanced_amount_delinquent_gbp_daily":"£1,321,245.56","loss":"£0.00","recovered":"£457,468.31","in_recovery":"£1,890,567"},
{"trades.closed_half_year_year":"2015","auctioncollectioninfos.total_advanced_amount_delinquent_and_collection_completed_gbp_daily":"£3,345,768.54","auctioncollectioninfos.total_crystallized_loss_gbp_daily":"£555,555.08","auctioncollectioninfos.total_outstanding_amount_delinquent_gbp_daily":"£321,321","auctioncollectioninfos.total_advanced_amount_delinquent_gbp_daily":"£3,321,321.32","loss":"£456,324.33","recovered":"£2,324,234.345","in_recovery":"£333,333"}]

本质上,需要将丢失、恢复和恢复堆栈到图表上,但如前所述,没有数据加载到图表上。

有什么想法吗?

最佳答案

有一个小问题,您使用的数据是 JSON,因此对象将以字符串形式接收值,您必须将它们正确解析为数字。将字符串解析为数字的简单方法如下:

d.loss = +d['loss'];

但即使我们这样做了,您的数据仍然会出现问题。为什么?因为数据集中的某些数字已格式化:

"loss":"£456,324.33" 

所以如果你想尝试做这样的事情:

d.total = d.loss + d.in_recovery + d.recovered;

您将得到一个无效值,因为我们可能会发出如下所示的操作:

d.total = "£456,324.33" + 0 + "£4,324.33"  // "£456,324.330£4,324.33"

这将改变我们图表中的尺度。

y.domain([0, d3.max(data, function(d) {
return d.total;
})]).nice(); // spooky domain here :S

让我们处理值的格式(假设值始终按照您提供的 JSON 中呈现的方式进行格式化):

data.forEach(function(d) {
d.year = +d['trades.closed_half_year_year'];
d.loss = typeof d.loss === 'number' ? d.loss : +d['loss'].replace(/£|,/g, '')
d.recovered = typeof d.recovered === 'number' ? d.recovered : +d['recovered'].replace(/£|,/g, '');
d.in_recovery = typeof d.in_recovery === 'number' ? d.in_recovery : +d['in_recovery'].replace(/£|,/g, '');
d.total = d.loss + d.in_recovery + d.recovered;
});

现在我们有了正确的数据集,我们应该准备好开始使用 d3 和 stack 布局:

var keys = ['loss', 'recovered', 'in_recovery']; // Declare the keys we will want in our stack
z.domain(keys); // Set them as our z domain so we can retrieve our fill color
var stackLayout = d3.stack().keys(keys)(data); // Create our stack layout

这将创建以下结构:

[
[
[
0,
0
],
[
0,
0
],
[
0,
456324.33
]
// key: loss
],
[
[
0,
0
],
[
0,
457468.31
],
[
456324.33,
2780558.6750000003
]
// key: recovered
],
[
[
0,
0
],
[
457468.31,
2348035.31
],
[
2780558.6750000003,
3113891.6750000003
]
// key: in_recovery
]
]

通过上面的结构,我们现在可以通过键 block 创建条形,如您所见,每个数组都有三个值和一个键。我们需要为每个数组元素创建一个 group 元素:

g.selectAll(".serie")
.data(stackLayout) // Set stack layout as data
.enter()
.append("g") // Creating group for each key
.attr("fill", function(d) { return z(d.key); }) // Fill inner elements with the color provided by our z Scale
.selectAll("rect")
.data(function(d) { // Use the inner array to create our rects
return d;
})
.enter().append("rect")
.attr("x", function(d) { // Position by our x Scale
return x(d.data.year);
})
.attr("y", function(d) { // Position by our y Scale
return y(d[1]);
})
.attr("height", function(d) { // Find the height value by using the values provided in the inner arrays
return y(d[0]) - y(d[1]);
})
.attr("width", x.bandwidth());

我们还必须更改一些标签:

var legend = g.selectAll(".legend")
.data(keys.reverse()) // Use our keys
.enter().append("g")
.attr("class", "legend")
.attr('transform', function(d, i) {
var horz = width - margin.right - (100 * i); // NEW
var vert = 0;
return 'translate(' + horz + ',' + vert + ')'; // NEW
})
.style("font", "10px sans-serif");

legend.append("text")
.attr("x", "-5")
.attr("y", 9)
.attr("dy", ".35em")
.attr("text-anchor", "end")
.text(function(d) {
return d;
});

工作 plnkr:https://plnkr.co/edit/eTKsOz8jlaqm1Mf3Esej?p=preview

关于javascript - D3 中使用内部 JSON 变量的堆叠条形图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42397138/

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