我找到了我想使用的d3v3 stacked bar chart example,因为它使用json数据。
还有一个d3v4 canonical bar chart example可以加载和使用csv。
我想制作一个d3v4堆叠的条形图,但我想使用json数据创建它,而不是从csv加载。我不确定如何升级v3版本或修改v4版本来实现此目的。
这是我的数据结构:
[{
"hospitalName": "hospital1",
"category": "Injury & Poisoning",
"Females": "0",
"Males": "4",
"Unknown": "0",
"count": "4"
},
{
"hospitalName": "hospital1",
"category": "Symptoms, Signs, & Ill-Defined Conditions",
"Females": "1",
"Males": "1",
"Unknown": "0",
"count": "2"
},
{
"hospitalName": "hospital2",
"category": "Mental Disorders",
"Females": "0",
"Males": "1",
"Unknown": "0",
"count": "1"
}]
在给出两个示例的情况下,如何在d3v4堆叠条形图中使用此数据?
答案 0 :(得分:2)
考虑到在升级适合您的数据源类型的v3示例和修改v4示例以使用json而不是csv数据之间的选择,应该选择转换现有的规范v4示例。
d3.csv将csv文件转换为json。 d3.csv从源csv创建的头文件看起来与您的json一样,其头文件等于您的数据项的属性。 因此,两个示例实质上都使用相同的数据格式和结构。这就是为什么使用d3v4示例更直接的原因。
要使用json数据而不是v4示例中的csv数据,您需要进行两项更改:
规范中的列使用var keys = data.columns.slice(1);
来获取csv数据中应使用矩形绘制的列。 columns
是d3.csv添加到数据数组的属性,用于指定列标题。删除的值不是用矩形绘制的,而是标识堆栈,它可以是堆栈标签,并用于x轴放置。由于d3.csv添加了columns属性,因此我们需要一种略有不同的方法。
在您的情况下,看起来我们想从数据中获取男性,女性,未知人物,并且每个组的结构如下:
{
"hospitalName": "hospital1",
"category": "Injury & Poisoning",
"Females": "0",
"Males": "4",
"Unknown": "0",
"count": "4"
}
因此,我们可以对键/属性(将用矩形绘制)进行一些修改:
var columns = d3.keys(data[0]); // get the properties of the first item in the data array
var keys = columns.slice(2,5); // extract keys with index 2,3,4. These will be the properties that are represented by rectangles in the chart.
由于大多数示例的比例尺将使用组名,因此这些将不起作用。取而代之的是,我们每个组都需要唯一的东西,索引可以正常工作:
x.domain(data.map(function(d,i) { return i; }));
您需要对刻度线进行一些格式化,以免将索引作为标签,让我们说:
d3.axisBottom(x).tickFormat(function(d,i) { return data[i].hospitalName })
使用该类别将价格添加到刻度线应该足够容易。
是的,我说了两个步骤,这太短了,不足以保证整个项目符号,但是列出三个项目会更好。原始规范使用d.total,您的数据使用d.count,这用于确定y标度的域。
一起:
<!DOCTYPE html>
<style>
.axis .domain {
display: none;
}
</style>
<svg width="600" height="200"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
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,
g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var x = d3.scaleBand()
.rangeRound([0, width])
.paddingInner(0.05)
.align(0.1);
var y = d3.scaleLinear()
.rangeRound([height, 0]);
var z = d3.scaleOrdinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var data = [{
"hospitalName": "hospital1",
"category": "Injury & Poisoning",
"Females": "0",
"Males": "4",
"Unknown": "0",
"count": "4"
},
{
"hospitalName": "hospital1",
"category": "Symptoms, Signs, & Ill-Defined Conditions",
"Females": "1",
"Males": "1",
"Unknown": "0",
"count": "2"
},
{
"hospitalName": "hospital2",
"category": "Mental Disorders",
"Females": "0",
"Males": "1",
"Unknown": "0",
"count": "1"
}]
var columns = d3.keys(data[0]);
var keys = columns.slice(2,5);
data.sort(function(a, b) { return b.total - a.total; });
x.domain(data.map(function(d,i) { return i; }));
y.domain([0, d3.max(data, function(d) { return d.count; })]).nice();
z.domain(keys);
g.append("g")
.selectAll("g")
.data(d3.stack().keys(keys)(data))
.enter().append("g")
.attr("fill", function(d) { return z(d.key); })
.selectAll("rect")
.data(function(d) { return d; })
.enter().append("rect")
.attr("x", function(d,i) { return x(i); })
.attr("y", function(d) { return y(d[1]); })
.attr("height", function(d) { return y(d[0]) - y(d[1]); })
.attr("width", x.bandwidth());
g.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).tickFormat(function(d,i) { return data[i].hospitalName}));
g.append("g")
.attr("class", "axis")
.call(d3.axisLeft(y).ticks(null, "s"))
.append("text")
.attr("x", 2)
.attr("y", y(y.ticks().pop()) + 0.5)
.attr("dy", "0.32em")
.attr("fill", "#000")
.attr("font-weight", "bold")
.attr("text-anchor", "start")
.text("Population");
var legend = g.append("g")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.attr("text-anchor", "end")
.selectAll("g")
.data(keys.slice().reverse())
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("x", width - 19)
.attr("width", 19)
.attr("height", 19)
.attr("fill", z);
legend.append("text")
.attr("x", width - 24)
.attr("y", 9.5)
.attr("dy", "0.32em")
.text(function(d) { return d; });
</script>
如果要使用d3.json,则可以使用:
d3.json("json.json", function(error,data) {
if(error) throw error;
// Parts that use the data here.
})