Chart.js – 如何创建分组堆叠柱状图

huangapple go评论70阅读模式
英文:

Chart.js - How to create group stacked chart bars

问题

以下是您要翻译的内容:

"I have a few device names in my original data set. And there are also how many points a user has on each device. Now how do I want to show the number of users and points associated with each device in the bar/column of that device? I'm totally stacked and new in Chart.js, any help would be greatly appreciated.

Original data in console:


(2) [{…}, {…}] 0: device: "Laptop" values: Array(2) 0: {amckinlay: '30'} 1: {cvu: '150'} 1: device: "Phone" values: Array(1) 0: {amckinlay: '100'} ```

Dataset for chart:

``` js d1 = [ { label: 'amckinlay', data: [30], backgroundColor: 'rgba(75, 192, 192, 0.6)', }, { label: 'cvu', data: [150], backgroundColor: 'rgba(255, 99, 132, 0.6)', } ] d2 =[ { label: 'amckinlay', data: [30], backgroundColor: 'rgba(75, 192, 192, 0.6)', } ]

var dataset = { labels: ['Laptop', 'Phone'], datasets: [d1,d2] }; ```

The chart looks like [this][1]

``` js var alldata = data.data var datasets = []; var labels = [];

for (var i = 0; i < alldata.length; i++) { labels.push(alldata[i].device) for (var group in labels) { if (labels[group] === alldata[i].device) { console.log(alldata[i].values) // var val =alldata[i].values } }

datasets.push({ label: [], data: alldata[i].values, backgroundColor: 'rgba(54, 162, 235, 0.5)', }); } ``` [1]: https://photos.app.goo.gl/3aDAvdFqFE1J9jSx7"

<details>
<summary>英文:</summary>

I have a few device names in my original data set. And there are also how many points a user has on each device. Now how do I want to show the number of users and points associated with each device in the bar/column of that device? I&#39;m totally stacked and new in Chart.js, any help would be greatly appreciated.

Original data in console:

console.log(alldata)

(2) [{…}, {…}]
0:
device: "Laptop"
values: Array(2)
0: {amckinlay: '30'}
1: {cvu: '150'}
1: device: "Phone"
values: Array(1)
0: {amckinlay: '100'}


Dataset for chart:

```js
d1 = [
        {
            label: &#39;amckinlay&#39;,
            data: [30],
            backgroundColor: &#39;rgba(75, 192, 192, 0.6)&#39;,
        },
        {
            label: &#39;cvu&#39;,
            data: [150],
            backgroundColor: &#39;rgba(255, 99, 132, 0.6)&#39;,
        }
    ]
d2 =[
        {
            label: &#39;amckinlay&#39;,
            data: [30],
            backgroundColor: &#39;rgba(75, 192, 192, 0.6)&#39;,
        }
    ]

var dataset = {
    labels: [&#39;Laptop&#39;, &#39;Phone&#39;],
    datasets: [d1,d2]
};

The chart looks like this

var alldata = data.data
var datasets = [];
var labels = [];

for (var i = 0; i &lt; alldata.length; i++) {
    labels.push(alldata[i].device)
    for (var group in labels) {
        if (labels[group] === alldata[i].device) {
            console.log(alldata[i].values)
            // var val =alldata[i].values
        }
    }

datasets.push({
    label: [],
    data: alldata[i].values,
    backgroundColor: &#39;rgba(54, 162, 235, 0.5)&#39;,
    });
}

答案1

得分: 1

  1. x轴标签应为“device”。

  2. 数据集中,每个项目的标签应为类别,如“amckinlay”、“cvu”等。每个项目的数据包含与“device”相对应的值。

问题在于你的数据 values 来自 alldata,它是键值对,提取键值变得困难。建议将其转换为以下形式:

{ "category": "amckinlay", "value": 100 }
var colorSettings = [
  {
    category: 'amckinlay',
    backgroundColor: 'rgba(75, 192, 192, 0.6)',
  },
  {
    category: 'cvu',
    backgroundColor: 'rgba(255, 99, 132, 0.6)',
  },
];

var labels = alldata.map((x) => x.device);
alldata = alldata
  .map((x) =>
    x.values.reduce((acc, cur) => {
      for (let k in cur) {
        acc.push({
          device: x.device,
          category: k,
          value: cur[k],
        });
      }

      return acc;
    }, [])
  )
  .flat();

var subLabels = [...new Set(alldata.map((x) => x.category))];

var datasets = subLabels.reduce((acc, cur) => {
  for (let device of labels) {
    var value =
      alldata.find((x) => x.device == device && x.category == cur)?.value ?? 0;

    var category = acc.find((x) => x.label == cur);
    if (category == null) {
      acc.push({
        label: cur,
        data: [value],
        backgroundColor: colorSettings.find((x) => x.category == cur)
          .backgroundColor,
      });
    } else {
      category.data.push(value);
    }
  }

  return acc;
}, []);

请注意,你的图表配置 options 应该具有如堆叠条形图文档中所述的堆叠设置。

const ctx = document.getElementById('myChart').getContext('2d');
const myChart = new Chart(ctx, {
  type: 'bar',
  data: {
    labels: labels,
    datasets: datasets,
  },
  options: {
    responsive: true,
    scales: {
      x: {
        stacked: true,
      },
      y: {
        stacked: true,
      },
    },
  },
});

在 .NET Fiddle 上的演示

英文:

To summarize:

  1. x-axis label should be the device.

  2. The dataset in which each item's label should be the category such as "amckinlay", "cvu" etc. And each item's data contains the value according to the device.

The problem is your data values from alldata which is key-value pair makes it difficult to extract the key. Would recommend converting it into the form:

{ &quot;category&quot;: &quot;amckinlay&quot;, &quot;value&quot;: 100 }
var colorSettings = [
  {
    category: &#39;amckinlay&#39;,
    backgroundColor: &#39;rgba(75, 192, 192, 0.6)&#39;,
  },
  {
    category: &#39;cvu&#39;,
    backgroundColor: &#39;rgba(255, 99, 132, 0.6)&#39;,
  },
];

var labels = alldata.map((x) =&gt; x.device);
alldata = alldata
  .map((x) =&gt;
    x.values.reduce((acc, cur) =&gt; {
      for (let k in cur) {
        acc.push({
          device: x.device,
          category: k,
          value: cur[k],
        });
      }

      return acc;
    }, [])
  )
  .flat();

var subLabels = [...new Set(alldata.map((x) =&gt; x.category))];

var datasets = subLabels.reduce((acc, cur) =&gt; {
  for (let device of labels) {
    var value =
      alldata.find((x) =&gt; x.device == device &amp;&amp; x.category == cur)?.value ??
      0;

    var category = acc.find((x) =&gt; x.label == cur);
    if (category == null) {
      acc.push({
        label: cur,
        data: [value],
        backgroundColor: colorSettings.find((x) =&gt; x.category == cur)
          .backgroundColor,
      });
    } else {
      category.data.push(value);
    }
  }

  return acc;
}, []);

Note that, your chart configuration options should have the stacked setting as mentioned in the Stacked bar chart documentation.

const ctx = document.getElementById(&#39;myChart&#39;).getContext(&#39;2d&#39;);
const myChart = new Chart(ctx, {
  type: &#39;bar&#39;,
  data: {
    labels: labels,
    datasets: datasets,
  },
  options: {
    responsive: true,
    scales: {
      x: {
        stacked: true,
      },
      y: {
        stacked: true,
      },
    },
  },
});

Demo @ .NET Fiddle

huangapple
  • 本文由 发表于 2023年6月12日 01:48:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76451747.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定