首页 > 解决方案 > 如何从 JSON 数据制作 SVG 中的堆栈条形图?

问题描述

我正在回答@markb个人资料提出的这个问题,但该问题已被删除。我在这里分享我的解决方案。

目标是将 JSON 数据转换为如下图条:

目标结果

JSON 数据的格式如下:

// dummy data
const json = `{ "data": [ 
    { "value": [1, 2, 3, 4] }, 
    { "value": [5, 6, 7, 8] },
    { "value": [9, 0, 1, 2] },
    { "value": [3, 4, 5, 6] } 
] }`,
  dataJSON = JSON.parse(json).data;

标签: javascripthtmlsvg

解决方案


我可以提出这个解决方案。

// dummy data
const json = `{ "data": [ 
{ "value": [1, 2, 3, 4] }, 
{ "value": [5, 6, 7, 8] },
{ "value": [9, 0, 1, 2] },
{ "value": [3, 4, 5, 6] } 
] }`,
dataJSON = JSON.parse(json).data;

const graphDOM = document.getElementById("graphDOM");

const imageHeight = 100;
const colWidth = 10;
const spaceBetweenCols = 20;

// this will contain the sum for each column
const totalColumns = [];

// this is the highest a column will go
maxValueAllColumns = 0;

// this is the number of columns that will be displayed
nbColumns = 0;


for (line=0; line<dataJSON.length; line++) {
  for (col=0; col<dataJSON[line]["value"].length; col++) {
    if (typeof totalColumns[col] == "undefined") {
      totalColumns[col] = 0;
    }
    totalColumns[col]+=dataJSON[line]["value"][col];
    maxValueAllColumns=Math.max(maxValueAllColumns,totalColumns[col]);
    nbColumns = Math.max(nbColumns, col+1);
  }
}

// ratio
ratioDisplayed = imageHeight / maxValueAllColumns;

// variables
dataContainer = document.getElementById('data-container');
dataItem = document.createElementNS('http://www.w3.org/2000/svg', 'g');

html="";
for (col=0; col<nbColumns; col++) {
  stackTo = 0;
  for (line=0; line<dataJSON.length; line++) {
    if (typeof dataJSON[line]["value"][col] != "undefined") {
      rectHeight = Math.round(dataJSON[line]["value"][col] * ratioDisplayed);
      rect_x0 = (spaceBetweenCols+colWidth)*col;
      rect_y0 = 0 + imageHeight - stackTo - rectHeight;
      stackTo += rectHeight;
      
      html += '<rect x="' + rect_x0 + '"y="' + rect_y0 + '"width="' + colWidth + '" height="' + rectHeight + '" fill="rgb(' + (50*line) + ', ' + (50*line) + ', ' + (50*line) + ')"></rect>"';
    }
  }
}

graphDOM.innerHTML = "<svg>" + html + "</svg>";
svg {
  max-width: 25em;
  margin: 2em 5em;
  overflow: visible !important;
}
<div id="graphDOM"><svg viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet">
    <g id="data-container"></g>
</svg>
</div>


推荐阅读