关于D3堆叠条形图结构

Regarding D3 stacked bar chart structure

当数据为正常格式时,我可以轻松创建 d3 堆积条形图(垂直)。但是这种格式,我发现很难绘制图表。如果有人能指出一个示例,其中数据采用我在下面给出的格式,将不胜感激。我尝试了很多例子。都使用了不同的结构。至少让我知道这种结构是否可以堆叠条形图。我的格式。

[
  {
    "key": "AK",
    "values": [
      {
        "state": "AK",
        "zip": "99546",
        "sum(quantity)": "623.95"
      }
    ]
  },
  {
    "key": "AL",
    "values": [
      {
        "state": "AL",
        "zip": "35440",
        "sum(quantity)": "265.40"
      }
    ]
  },
  {
    "key": "CA",
    "values": [
      {
        "state": "CA",
        "zip": "93510",
        "sum(quantity)": "682.81"
      },
      {
        "state": "CA",
        "zip": "95220",
        "sum(quantity)": "367.14"
      }
    ]
  },
  {
    "key": "GA",
    "values": [
      {
        "state": "GA",
        "zip": "30102",
        "sum(quantity)": "609.85"
      },
      {
        "state": "GA",
        "zip": "30103",
        "sum(quantity)": "691.53"
      }
    ]
  },
  {
    "key": "IA",
    "values": [
      {
        "state": "IA",
        "zip": "50001",
        "sum(quantity)": "597.52"
      },
      {
        "state": "IA",
        "zip": "50601",
        "sum(quantity)": "741.38"
      }
    ]
  },
  {
    "key": "IL",
    "values": [
      {
        "state": "IL",
        "zip": "62214",
        "sum(quantity)": "564.20"
      }
    ]
  },
  {
    "key": "LA",
    "values": [
      {
        "state": "LA",
        "zip": "70420",
        "sum(quantity)": "576.45"
      },
      {
        "state": "LA",
        "zip": "70511",
        "sum(quantity)": "377.81"
      },
      {
        "state": "LA",
        "zip": "70710",
        "sum(quantity)": "398.69"
      }
    ]
  },
  {
    "key": "MD",
    "values": [
      {
        "state": "MD",
        "zip": "20606",
        "sum(quantity)": "423.71"
      },
      {
        "state": "MD",
        "zip": "20607",
        "sum(quantity)": "544.17"
      },
      {
        "state": "MD",
        "zip": "21005",
        "sum(quantity)": "233.74"
      },
      {
        "state": "MD",
        "zip": "21520",
        "sum(quantity)": "601.30"
      }
    ]
  },
  {
    "key": "ME",
    "values": [
      {
        "state": "ME",
        "zip": "4406",
        "sum(quantity)": "238.58"
      },
      {
        "state": "ME",
        "zip": "4606",
        "sum(quantity)": "412.01"
      }
    ]
  },
  {
    "key": "MS",
    "values": [
      {
        "state": "MS",
        "zip": "39735",
        "sum(quantity)": "486.00"
      }
    ]
  },
  {
    "key": "MT",
    "values": [
      {
        "state": "MT",
        "zip": "59001",
        "sum(quantity)": "434.12"
      }
    ]
  },
  {
    "key": "ND",
    "values": [
      {
        "state": "ND",
        "zip": "58001",
        "sum(quantity)": "122.81"
      },
      {
        "state": "ND",
        "zip": "58002",
        "sum(quantity)": "883.31"
      }
    ]
  },
  {
    "key": "NE",
    "values": [
      {
        "state": "NE",
        "zip": "68001",
        "sum(quantity)": "605.27"
      }
    ]
  },
  {
    "key": "NJ",
    "values": [
      {
        "state": "NJ",
        "zip": "8205",
        "sum(quantity)": "630.63"
      }
    ]
  },
  {
    "key": "NM",
    "values": [
      {
        "state": "NM",
        "zip": "87510",
        "sum(quantity)": "1059.78"
      }
    ]
  },
  {
    "key": "NY",
    "values": [
      {
        "state": "NY",
        "zip": "12404",
        "sum(quantity)": "573.52"
      },
      {
        "state": "NY",
        "zip": "12405",
        "sum(quantity)": "911.70"
      },
      {
        "state": "NY",
        "zip": "13606",
        "sum(quantity)": "295.05"
      },
      {
        "state": "NY",
        "zip": "14410",
        "sum(quantity)": "91.27"
      }
    ]
  },
  {
    "key": "OH",
    "values": [
      {
        "state": "OH",
        "zip": "43802",
        "sum(quantity)": "234.60"
      }
    ]
  },
  {
    "key": "OK",
    "values": [
      {
        "state": "OK",
        "zip": "73520",
        "sum(quantity)": "331.16"
      },
      {
        "state": "OK",
        "zip": "74330",
        "sum(quantity)": "679.95"
      },
      {
        "state": "OK",
        "zip": "74720",
        "sum(quantity)": "723.63"
      },
      {
        "state": "OK",
        "zip": "74821",
        "sum(quantity)": "624.22"
      }
    ]
  },
  {
    "key": "OR",
    "values": [
      {
        "state": "OR",
        "zip": "97810",
        "sum(quantity)": "229.12"
      }
    ]
  },
  {
    "key": "PA",
    "values": [
      {
        "state": "PA",
        "zip": "15410",
        "sum(quantity)": "558.51"
      },
      {
        "state": "PA",
        "zip": "15520",
        "sum(quantity)": "859.19"
      },
      {
        "state": "PA",
        "zip": "15610",
        "sum(quantity)": "656.57"
      },
      {
        "state": "PA",
        "zip": "15611",
        "sum(quantity)": "303.19"
      },
      {
        "state": "PA",
        "zip": "16820",
        "sum(quantity)": "763.54"
      },
      {
        "state": "PA",
        "zip": "17301",
        "sum(quantity)": "314.21"
      },
      {
        "state": "PA",
        "zip": "18010",
        "sum(quantity)": "522.25"
      },
      {
        "state": "PA",
        "zip": "19001",
        "sum(quantity)": "541.86"
      },
      {
        "state": "PA",
        "zip": "19501",
        "sum(quantity)": "314.65"
      }
    ]
  },
  {
    "key": "SC",
    "values": [
      {
        "state": "SC",
        "zip": "29426",
        "sum(quantity)": "387.74"
      }
    ]
  },
  {
    "key": "TX",
    "values": [
      {
        "state": "TX",
        "zip": "77326",
        "sum(quantity)": "497.49"
      },
      {
        "state": "TX",
        "zip": "79311",
        "sum(quantity)": "619.80"
      },
      {
        "state": "TX",
        "zip": "79699",
        "sum(quantity)": "546.51"
      },
      {
        "state": "TX",
        "zip": "79713",
        "sum(quantity)": "424.77"
      }
    ]
  },
  {
    "key": "VA",
    "values": [
      {
        "state": "VA",
        "zip": "23001",
        "sum(quantity)": "340.39"
      },
      {
        "state": "VA",
        "zip": "23301",
        "sum(quantity)": "446.56"
      }
    ]
  },
  {
    "key": "VT",
    "values": [
      {
        "state": "VT",
        "zip": "5640",
        "sum(quantity)": "548.90"
      }
    ]
  },
  {
    "key": "WA",
    "values": [
      {
        "state": "WA",
        "zip": "98520",
        "sum(quantity)": "223.90"
      }
    ]
  },
  {
    "key": "WI",
    "values": [
      {
        "state": "WI",
        "zip": "54101",
        "sum(quantity)": "680.80"
      },
      {
        "state": "WI",
        "zip": "54405",
        "sum(quantity)": "485.17"
      }
    ]
  },
  {
    "key": "WV",
    "values": [
      {
        "state": "WV",
        "zip": "25606",
        "sum(quantity)": "404.94"
      }
    ]
  }
]

此处 key 应作为 x 轴。 values 应作为 y 轴 (sum(quantity))。值内的对象应形成堆积条。

例如:CA 密钥在其 values 密钥中有两个对象,应该形成一个有两个堆栈的条。希望你能明白。

我不是故意回避代码。我没有这种结构。我什至不知道如何使用这些数据。我用 d3 的 nest 得到了这个。

请帮忙

我不得不自己做,因为我别无选择(感谢我的同事一如既往地帮助我)。发布下面的代码片段。这里还有一个link到codepen。谁知道,这可能会在将来节省某人的时间和精力。这是代码。

var WIDTH = 1250,
  HEIGHT = 500,
  MARGINS = {
    top: 20,
    right: 20,
    bottom: 20,
    left: 50
  },
  xoffset = 22,
  svg = [],
  tooltip = [];

function appendResponsiveSvg() {
  svg = d3.select("svg")
    .attr("width", 100 + "%")
    .attr("height", 100 + "%")
    .attr("preserveAspectRatio", "xMinYMin meet")
    .attr("viewBox", "-80 -10 " + (WIDTH + 200) + " " + (HEIGHT + 100))
    .classed("svg-content-responsive", true);

  return svg;
}

var verticalStackedData = multiLineData;
console.log(verticalStackedData);

function plotVerticallyStacked(data) {

  var x = d3.scale.ordinal()
    .rangeRoundBands([0, WIDTH], .1);

  var y = d3.scale.linear()
    .rangeRound([HEIGHT, 0]);

  // Color range - add your favorites here
  var color = d3.scale.ordinal()
    .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

  var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

  var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .tickFormat(d3.format(".2s"));

  appendResponsiveSvg();

  svg.append("g")
    .attr("transform", "translate(" + MARGINS.left + "," + MARGINS.top + ")");

  var domain = ["sum(quantity)"];

  data.forEach(function(_data) {
    var y0 = 0;
    _data.groupedItem = [];
    _data.values.map(function(d, index) {
      _data.groupedItem.push(domain.map(function(name) {
        return {
          label: "quantity" + (index + 1),
          name: name,
          y0: y0,
          y1: y0 += +d[name]
        };
      })[0]);
      _data.total = _data.groupedItem[_data.groupedItem.length - 1].y1;
    });

  });

  data.sort(function(a, b) {
    return b.total - a.total;
  });

  x.domain(data.map(function(d) {
    return d.values[0]["sum(quantity)"];
  }));
  y.domain([0, d3.max(data, function(d) {
    return d.total;
  })]);

  svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + HEIGHT + ")")
    .call(xAxis);

  svg.append("g")
    .attr("class", "y axis")
    .call(yAxis);

  var state = svg.selectAll(".state")
    .data(data)
    .enter().append("g")
    .attr("class", "g")
    .attr("transform", function(d) {
      return "translate(" + x((d.values[0])["sum(quantity)"]) + ",0)";
    });

  state.selectAll("rect")
    .data(function(d) {
      return d.groupedItem;
    })
    .enter().append("rect")
    .attr("width", x.rangeBand())
    .attr("y", function(d) {
      return y(d.y1);
    })
    .attr("height", function(d) {
      return y(d.y0) - y(d.y1);
    })
    .style("fill", function(d) {
      return color(d.label);
    });
}
plotVerticallyStacked(verticalStackedData);