在 d3v4 堆积条形图中使用 JSON

2024-05-08

我找到了一个d3v3堆积条形图示例 http://bl.ocks.org/mstanaland/6100713我想使用它,因为它使用 json 数据。

还有一个d3v4规范条形图示例 https://bl.ocks.org/mbostock/3886208加载并使用 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 堆积条形图中使用此数据?


如果要在升级适合您的数据源类型的 v3 示例和修改 v4 示例以采用 json 而不是 csv 数据之间进行选择,那么转换现有规范 v4 示例的选择应该会获胜。

d3.csv 将 csv 文件转换为 json。 d3.csv 创建的 json 看起来就像来自源 csv 的 json,其标头等于数据项的属性。 因此,这两个示例本质上都使用相同的数据格式和结构。这就是为什么使用 d3v4 示例更加简单。

要在 v4 示例中使用 json 数据而不是 csv 数据,您需要进行两项更改:

  1. 获取正确的列数据:

规范用途中的列var keys = data.columns.slice(1);获取 csv 数据中的哪些列应该用矩形绘制。columns是由 d3.csv 添加到数据数组的属性,用于指定列标题。删除的值不是用矩形绘制的,而是标识堆栈,它可以是堆栈标签并用于 x 轴放置。由于 columns 属性是由 d3.csv 添加的,因此我们需要一种稍微不同的方法。

在您的情况下,我们似乎想要从数据中获取男性、女性、未知,并且每个组的结构如下所示:

{
     "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.
  1. 考虑具有相同名称的多个组/堆栈

由于大多数示例的比例将使用组名称,因此这些将不起作用。相反,我们需要每个组都有独特的东西,索引就可以很好地工作:

x.domain(data.map(function(d,i) { return i; }));

您需要对刻度进行一些格式化,这样您就不会将索引作为标签,比方说:

d3.axisBottom(x).tickFormat(function(d,i) { return data[i].hospitalName })

将类别添加到刻度中应该很容易。

  1. 修改总属性

是的,我说了两个步骤,这太短了,无法保证完整的项目符号,但列表最好包含三个项目。原始规范使用 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.

})
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 d3v4 堆积条形图中使用 JSON 的相关文章

随机推荐