D3 - 使用JSON数据创建多个条形图

时间:2017-08-07 17:58:51

标签: d3.js

我正在学习D3并拥有JSON数据。我想从这个JSON数据构建多个条形图来绘制已经在excel中构建的图形。我可以在SVG上绘制一行Pax_Rev,但我不确定如何从数据中添加其他行。当我执行console.log(dataset.length)时,它显示0表示数据集中只有一个项目是预期的。

enter image description here

<script>
    var dataset = [{"Pax_Rev": 1000, "Crg_Rev": 500, 
                    "Fixed_Costs": 800, "Variable_Costs": 200}];

    var width = 500;
    var height = 1000;
    var barPadding = 1;

    var svg = d3.select("body")
                .append("svg")
                .append("g")
                .attr("width", width)
                .attr("height", height)
                .attr("class", "svg")

               svg3.selectAll("rect")
                    .data(dataset)
                    .enter()
                    .append("rect")
                    .attr("x", 0)
                    .attr("y", function(d){
                    return height - d.Pax_Rev // How to add other items like Crg_Rev etc?
                    })
                    .attr("width", 20)
                    .attr("height", function(d){
                    return d.Pax_Rev
                    });
</script>

1 个答案:

答案 0 :(得分:1)

正如我在previous question中解释的那样,这是预期的行为。由于数据数组中只有一个对象,因此D3“输入”选择将只创建一个元素。

如果查看API,您会看到selection.data()

  

使用所选元素[...]连接指定的数组数据指定的数据是任意值(例如,数字或对象)的数组。 (强调我的)

因此,我们必须在多个对象中转换该巨大的对象。这是几种可能的方法之一:

var dataset = [{
  "Pax_Rev": 1000,
  "Crg_Rev": 500,
  "Fixed_Costs": 800,
  "Variable_Costs": 200
}];

var data = [];

for (var key in dataset[0]) {
  data.push({
    category: key,
    value: dataset[0][key]
  })
}

console.log(data)

现在,我们有一个data数组,有几个对象,每个条形一个,我们可以创建条形图。

这是一个演示:

var dataset = [{
  "Pax_Rev": 1000,
  "Crg_Rev": 500,
  "Fixed_Costs": 800,
  "Variable_Costs": 200
}];

var data = [];

for (var key in dataset[0]) {
  data.push({
    category: key,
    value: dataset[0][key]
  })
}

var svg = d3.select("svg");
var yScale = d3.scaleLinear()
  .domain([0, d3.max(data, function(d) {
    return d.value
  })])
  .range([120, 10]);
var xScale = d3.scaleBand()
  .domain(data.map(function(d) {
    return d.category
  }))
  .range([40, 280])
  .padding(0.2);

var rects = svg.selectAll(null)
  .data(data)
  .enter()
  .append("rect")
  .attr("fill", "steelblue")
  .attr("x", function(d) {
    return xScale(d.category)
  })
  .attr("width", xScale.bandwidth())
  .attr("y", function(d) {
    return yScale(d.value)
  })
  .attr("height", function(d) {
    return 120 - yScale(d.value)
  });

var yAxis = d3.axisLeft(yScale);
var xAxis = d3.axisBottom(xScale);

svg.append("g").attr("transform", "translate(40,0)").call(yAxis);
svg.append("g").attr("transform", "translate(0,120)").call(xAxis);
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>