我需要使用带有reactjs的chartjs格式化来自json的数据,以显示带有2个x轴的数据

问题描述 投票:0回答:1

我不明白我做错了什么,我需要像这个例子: 以正确的图形为例

这是我收到的json数据:

[
  {
    "label": "Others",
    "type": "bar",
    "stack": "Person 1",
    "data": [
      22,
      0,
      80
    ]
  },
  {
    "label": "AWS",
    "type": "bar",
    "stack": "Person 1",
    "data": [
      2,
      0,
      21
    ]
  },
  {
    "label": "Github Enterprise Cloud - Organization",
    "type": "bar",
    "stack": "Person 1",
    "data": [
      1,
      0,
      8
    ]
  },
  {
    "label": "Okta Admin Console",
    "type": "bar",
    "stack": "Person 1",
    "data": [
      2,
      0,
      10
    ]
  },
  {
    "label": "PacificTimeSheet",
    "type": "bar",
    "stack": "Person 1",
    "data": [
      0,
      0,
      12
    ]
  },
  {
    "label": "ArgoCD - Dev",
    "type": "bar",
    "stack": "Person 1",
    "data": [
      0,
      0,
      0
    ]
  },
  {
    "label": "kubero",
    "type": "bar",
    "stack": "Person 1",
    "data": [
      0,
      0,
      0
    ]
  },
  {
    "label": "Okta Dashboard",
    "type": "bar",
    "stack": "Person 1",
    "data": [
      0,
      0,
      0
    ]
  },
  {
    "label": "ArgoCD - Production IPV6",
    "type": "bar",
    "stack": "Person 1",
    "data": [
      0,
      0,
      0
    ]
  },
  {
    "label": "Okta Browser Plugin",
    "type": "bar",
    "stack": "Person 1",
    "data": [
      0,
      0,
      0
    ]
  },
  {
    "label": "Vercel",
    "type": "bar",
    "stack": "Person 1",
    "data": [
      0,
      0,
      0
    ]
  },
  {
    "label": "ONEDigital Portal Prod",
    "type": "bar",
    "stack": "Person 1",
    "data": [
      0,
      0,
      6
    ]
  },
  {
    "label": "Others",
    "type": "bar",
    "stack": "Person 2",
    "data": [
      8,
      0,
      16
    ]
  },
  {
    "label": "AWS",
    "type": "bar",
    "stack": "Person 2",
    "data": [
      2,
      0,
      1
    ]
  },
  {
    "label": "Github Enterprise Cloud - Organization",
    "type": "bar",
    "stack": "Person 2",
    "data": [
      0,
      0,
      2
    ]
  },
  {
    "label": "Okta Admin Console",
    "type": "bar",
    "stack": "Person 2",
    "data": [
      0,
      0,
      0
    ]
  },
  {
    "label": "PacificTimeSheet",
    "type": "bar",
    "stack": "Person 2",
    "data": [
      0,
      0,
      1
    ]
  },
  {
    "label": "ArgoCD - Dev",
    "type": "bar",
    "stack": "Person 2",
    "data": [
      0,
      0,
      0
    ]
  },
  {
    "label": "kubero",
    "type": "bar",
    "stack": "Person 2",
    "data": [
      0,
      0,
      0
    ]
  },
  {
    "label": "Okta Dashboard",
    "type": "bar",
    "stack": "Person 2",
    "data": [
      0,
      0,
      0
    ]
  },
  {
    "label": "ArgoCD - Production IPV6",
    "type": "bar",
    "stack": "Person 2",
    "data": [
      0,
      0,
      0
    ]
  },
  {
    "label": "Okta Browser Plugin",
    "type": "bar",
    "stack": "Person 2",
    "data": [
      0,
      0,
      0
    ]
  },
  {
    "label": "Vercel",
    "type": "bar",
    "stack": "Person 2",
    "data": [
      0,
      0,
      0
    ]
  },
  {
    "label": "ONEDigital Portal Prod",
    "type": "bar",
    "stack": "Person 2",
    "data": [
      0,
      0,
      0
    ]
  },
  {
    "label": "Others",
    "type": "bar",
    "stack": "Person 3",
    "data": [
      18,
      0,
      217
    ]
  },
  {
    "label": "AWS",
    "type": "bar",
    "stack": "Person 3",
    "data": [
      3,
      0,
      17
    ]
  },
  {
    "label": "Github Enterprise Cloud - Organization",
    "type": "bar",
    "stack": "Person 3",
    "data": [
      1,
      0,
      7
    ]
  },
  {
    "label": "Okta Admin Console",
    "type": "bar",
    "stack": "Person 3",
    "data": [
      0,
      0,
      11
    ]
  },
  {
    "label": "PacificTimeSheet",
    "type": "bar",
    "stack": "Person 3",
    "data": [
      0,
      0,
      2
    ]
  },
  {
    "label": "ArgoCD - Dev",
    "type": "bar",
    "stack": "Person 3",
    "data": [
      0,
      0,
      0
    ]
  },
  {
    "label": "kubero",
    "type": "bar",
    "stack": "Person 3",
    "data": [
      4,
      0,
      0
    ]
  },
  {
    "label": "Okta Dashboard",
    "type": "bar",
    "stack": "Person 3",
    "data": [
      2,
      0,
      4
    ]
  },
  {
    "label": "ArgoCD - Production IPV6",
    "type": "bar",
    "stack": "Person 3",
    "data": [
      0,
      0,
      0
    ]
  },
  {
    "label": "Okta Browser Plugin",
    "type": "bar",
    "stack": "Person 3",
    "data": [
      3,
      0,
      3
    ]
  },
  {
    "label": "Vercel",
    "type": "bar",
    "stack": "Person 3",
    "data": [
      0,
      0,
      0
    ]
  },
  {
    "label": "ONEDigital Portal Prod",
    "type": "bar",
    "stack": "Person 3",
    "data": [
      0,
      0,
      0
    ]
  }
]

这是我的初始代码:

const parsed = {
        labelsX2: ["May", "June", "July"],
        labelsX: ["Person 1", "Person 2", "Person 3", "Person 1", "Person 2", "Person 3", "Person 1", "Person 2", "Person 3"], // example names but should be according json stacks
        datasets: json.map((item) => {
            console.info("item: ", item);

            const { label, data, stack } = item;
            return {
                ...item,
                label,
                data,
                stack
            };
        }),
    };

    const [chartData, setChartData] = React.useState(parsed);

    const options = {
        plugins: {
            tooltip: {
                title: "Total",
            },
            subtitle: {
                display: true,
                text: "Number of events",
                position: 'left'
            },
            legend: {
                display: true,
                position: 'right',
            },
        },
        scales:{
            x: {
                type: 'category',
                stacked: true,
                labels: parsed.labelsX,
            },
            x2: {
                type: 'category',
                stacked: true,
                labels: parsed.labelsX2,
            },
            y: {
                stacked: true,
            },
        }
    };


// ...

<div className="chart-container">
    <h2 style={{textAlign: "center"}}>Bar Chart</h2>
    <Bar
        data={chartData}
        options={options}
    />
</div>

它总是像这样坏掉,我不明白我处理错了什么。 如果有人可以帮助我,我将不胜感激。我查了很久的文档和论坛都没有找到解决办法。

使用我的代码的图形错误

如前所述,我需要图形与第一张图片中的示例类似: 以正确的图形为例

但它返回不正确,我不明白我做错了什么以及如何修复它。也许这不仅仅是我的问题,我已经认为这种类型的图很复杂。

reactjs graphics chart.js stacked
1个回答
0
投票

问题的根源似乎是对条形数据

stack
如何工作的错误认识(可能没有足够的材料 在这些的官方文档中)。首先 - 堆栈名称和 x 轴类别名称之间没有任何联系。 您链接到的正确图形显示每个类别(人名)在其空间中只有一个栏。 这意味着整个图表只有一个堆栈。使用多个(
n
)堆栈对数据进行分组 在
n
中每个类别

数据按主要 x 轴类别分组。主 x 轴上有 9 个类别。 (图表.js 类别名称之间没有任何联系 - 因为您明确给出了标签名称, 它不会验证某些类别是否具有相同的名称。)

因此,系统期望每个数据集是一个 9 值数组。如果小于9,则对应的值为

undefined
并在内部替换为
null
。由于您的所有数据集都有 3 个数据点,因此您将没有数据之外的数据 前三类。如果您希望数据从 4 开始,您必须用
null
填充前 3 个位置。

这为我们提供了一种对“json”数据进行分组的方法:

 const labelsX2 = ["May", "June", "July"],
    labelsX = ["Person 1", "Person 2", "Person 3", "Person 1", "Person 2", "Person 3", "Person 1", "Person 2", "Person 3"],
    labelsXWithIdx = labelsX.map((x, i) => [x, i]);
    datasets = [];

json.forEach(({ label, data, stack }) => {
    const indices = labelsXWithIdx.filter(([name]) => name === stack).map(([_, i]) => i);
    // will be [0, 3, 6], or [1, 4, 7], or [2, 5, 8]

    let dataset = datasets.find(({label: existingLabel}) => (existingLabel === label));
    if(!dataset){
        dataset  = {label, data: Array(labelsX.length).fill(null)};
        datasets.push(dataset);
    }

    data.forEach((value, i) => {
        dataset.data[indices[i]] = value;
    });
});

片段:

const json = [
    {
        "label": "Others",
        "type": "bar",
        "stack": "Person 1",
        "data": [
            22,
            0,
            80
        ]
    },
    {
        "label": "AWS",
        "type": "bar",
        "stack": "Person 1",
        "data": [
            2,
            0,
            21
        ]
    },
    {
        "label": "Github Enterprise Cloud - Organization",
        "type": "bar",
        "stack": "Person 1",
        "data": [
            1,
            0,
            8
        ]
    },
    {
        "label": "Okta Admin Console",
        "type": "bar",
        "stack": "Person 1",
        "data": [
            2,
            0,
            10
        ]
    },
    {
        "label": "PacificTimeSheet",
        "type": "bar",
        "stack": "Person 1",
        "data": [
            0,
            0,
            12
        ]
    },
    {
        "label": "ArgoCD - Dev",
        "type": "bar",
        "stack": "Person 1",
        "data": [
            0,
            0,
            0
        ]
    },
    {
        "label": "kubero",
        "type": "bar",
        "stack": "Person 1",
        "data": [
            0,
            0,
            0
        ]
    },
    {
        "label": "Okta Dashboard",
        "type": "bar",
        "stack": "Person 1",
        "data": [
            0,
            0,
            0
        ]
    },
    {
        "label": "ArgoCD - Production IPV6",
        "type": "bar",
        "stack": "Person 1",
        "data": [
            0,
            0,
            0
        ]
    },
    {
        "label": "Okta Browser Plugin",
        "type": "bar",
        "stack": "Person 1",
        "data": [
            0,
            0,
            0
        ]
    },
    {
        "label": "Vercel",
        "type": "bar",
        "stack": "Person 1",
        "data": [
            0,
            0,
            0
        ]
    },
    {
        "label": "ONEDigital Portal Prod",
        "type": "bar",
        "stack": "Person 1",
        "data": [
            0,
            0,
            6
        ]
    },
    {
        "label": "Others",
        "type": "bar",
        "stack": "Person 2",
        "data": [
            8,
            0,
            16
        ]
    },
    {
        "label": "AWS",
        "type": "bar",
        "stack": "Person 2",
        "data": [
            2,
            0,
            1
        ]
    },
    {
        "label": "Github Enterprise Cloud - Organization",
        "type": "bar",
        "stack": "Person 2",
        "data": [
            0,
            0,
            2
        ]
    },
    {
        "label": "Okta Admin Console",
        "type": "bar",
        "stack": "Person 2",
        "data": [
            0,
            0,
            0
        ]
    },
    {
        "label": "PacificTimeSheet",
        "type": "bar",
        "stack": "Person 2",
        "data": [
            0,
            0,
            1
        ]
    },
    {
        "label": "ArgoCD - Dev",
        "type": "bar",
        "stack": "Person 2",
        "data": [
            0,
            0,
            0
        ]
    },
    {
        "label": "kubero",
        "type": "bar",
        "stack": "Person 2",
        "data": [
            0,
            0,
            0
        ]
    },
    {
        "label": "Okta Dashboard",
        "type": "bar",
        "stack": "Person 2",
        "data": [
            0,
            0,
            0
        ]
    },
    {
        "label": "ArgoCD - Production IPV6",
        "type": "bar",
        "stack": "Person 2",
        "data": [
            0,
            0,
            0
        ]
    },
    {
        "label": "Okta Browser Plugin",
        "type": "bar",
        "stack": "Person 2",
        "data": [
            0,
            0,
            0
        ]
    },
    {
        "label": "Vercel",
        "type": "bar",
        "stack": "Person 2",
        "data": [
            0,
            0,
            0
        ]
    },
    {
        "label": "ONEDigital Portal Prod",
        "type": "bar",
        "stack": "Person 2",
        "data": [
            0,
            0,
            0
        ]
    },
    {
        "label": "Others",
        "type": "bar",
        "stack": "Person 3",
        "data": [
            18,
            0,
            217
        ]
    },
    {
        "label": "AWS",
        "type": "bar",
        "stack": "Person 3",
        "data": [
            3,
            0,
            17
        ]
    },
    {
        "label": "Github Enterprise Cloud - Organization",
        "type": "bar",
        "stack": "Person 3",
        "data": [
            1,
            0,
            7
        ]
    },
    {
        "label": "Okta Admin Console",
        "type": "bar",
        "stack": "Person 3",
        "data": [
            0,
            0,
            11
        ]
    },
    {
        "label": "PacificTimeSheet",
        "type": "bar",
        "stack": "Person 3",
        "data": [
            0,
            0,
            2
        ]
    },
    {
        "label": "ArgoCD - Dev",
        "type": "bar",
        "stack": "Person 3",
        "data": [
            0,
            0,
            0
        ]
    },
    {
        "label": "kubero",
        "type": "bar",
        "stack": "Person 3",
        "data": [
            4,
            0,
            0
        ]
    },
    {
        "label": "Okta Dashboard",
        "type": "bar",
        "stack": "Person 3",
        "data": [
            2,
            0,
            4
        ]
    },
    {
        "label": "ArgoCD - Production IPV6",
        "type": "bar",
        "stack": "Person 3",
        "data": [
            0,
            0,
            0
        ]
    },
    {
        "label": "Okta Browser Plugin",
        "type": "bar",
        "stack": "Person 3",
        "data": [
            3,
            0,
            3
        ]
    },
    {
        "label": "Vercel",
        "type": "bar",
        "stack": "Person 3",
        "data": [
            0,
            0,
            0
        ]
    },
    {
        "label": "ONEDigital Portal Prod",
        "type": "bar",
        "stack": "Person 3",
        "data": [
            0,
            0,
            0
        ]
    }
];

const labelsX2 = ["May", "June", "July"],
    labelsX = ["Person 1", "Person 2", "Person 3", "Person 1", "Person 2", "Person 3", "Person 1", "Person 2", "Person 3"],
    labelsXWithIdx = labelsX.map((x, i) => [x, i]);
    datasets = [];

json.forEach(({ label, data, stack }) => {
    const indices = labelsXWithIdx.filter(([name])=>name === stack).map(([_, i]) => i);
    // will be [0, 3, 6], or [1, 4, 7], or [2, 5, 8]

    let dataset = datasets.find(({label: existingLabel}) => (existingLabel === label));
    if(!dataset){
        dataset  = {label, data: Array(labelsX.length).fill(null)};
        datasets.push(dataset);
    }

    data.forEach((value, i) => {
        dataset.data[indices[i]] = value;
    });
});

const parsed = {
    labelsX2,
    labelsX,
    datasets,
};

const options = {
    plugins: {
        tooltip: {
            title: "Total",
        },
        subtitle: {
            display: true,
            text: "Number of events",
            position: 'left'
        },
        legend: {
            display: true,
            position: 'right',
        },
    },
    scales:{
        x: {
            type: 'category',
            stacked: true,
            labels: parsed.labelsX,
        },
        x2: {
            type: 'category',
            //stacked: true,
            labels: parsed.labelsX2,
        },
        y: {
            stacked: true,
        },
    }
};

new Chart('myChart', {type: "bar", data: parsed, options});
<div style="height: 300px">
    <canvas id="myChart">
    </canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

© www.soinside.com 2019 - 2024. All rights reserved.