0

I have these objects below:

 const data1 = {
    Tragedy: "25.00",
    Romance: "50.00",
    Comedy: "50.00",
    others: "25.00"
  };
  const data2 = {
    "Chick Flick": "50.00",
    Tragedy: "25.00",
    Comedy: "25.00",
    others: "25.00"
  };

I have recreated this in my codesandbox: https://codesandbox.io/s/heuristic-snow-5j3ys?file=/src/App.js:63-2076

I have this sample problem I have encountered.

const data1 = {
    Tragedy: "25.00",
    Romance: "50.00",
    Comedy: "50.00",
    others: "25.00"
  };
  1. I have the first value as 25.00 from the "Tragedy", but then since I'm using Object.values(data1) it will display in the graph that Comedy is the one that has a value of 25 which is wrong. How can I match the datasets and the labels?
  2. Also, in data1, romance exists. But in data2 it does not exist. It does cause a problem if presented in the graph.

Below are the codes:

   export default function App() {
      const data1 = {
        Tragedy: "25.00",
        Romance: "50.00",
        Comedy: "50.00",
        others: "25.00"
      };
      const data2 = {
        "Chick Flick": "50.00",
        Tragedy: "25.00",
        Comedy: "25.00",
        others: "25.00"
      };

  return (
    <div className="App">
      <Bar
        data={{
          labels: ["Comedy", "Romance", "Tragedy", "Chick Flick", "Others"],
          datasets: [
            {
              label: "Part1",
              data: Object.values(data1),
              backgroundColor: ["rgba(255, 99, 132, 0.2)"],
              borderColor: ["rgba(255, 99, 132, 1)"],
              borderWidth: 1
            },
            {
              label: "Part2",
              data: Object.values(data2),
              backgroundColor: ["rgba(75, 192, 192, 0.2)"],
              borderColor: ["rgba(255, 159, 64, 1)"],
              borderWidth: 1
            }
          ]
        }}
        height={400}
        width={600}
        options={{
          maintainAspectRatio: false,
          title: {
            display: true,
            text: "hello",
            fontSize: 20
          },
          scales: {
            y: {
              min: 0,
              max: 100,
              ticks: {
                stepSize: 20,
                callback: function (value) {
                  return ((value / this.max) * 100).toFixed(0) + "%"; // convert it to percentage
                }
              }
            }
          },
          plugins: {
            tooltip: {
              callbacks: {
                label: function (context) {
                  var label = context.dataset.label || "";
                  if (context.parsed.y !== null) {
                    label += " " + context.parsed.y + "%";
                  }
                  return label;
                }
              }
            }
          },
          legend: {
            labels: {
              fontSize: 25
            }
          }
        }}
      />
    </div>
  );
}
JS3
  • 1,623
  • 3
  • 23
  • 52

1 Answers1

2

Here is the updated code that you can use:

I have added a function which will create the data based on the label value getData.

import "./styles.css";
import { Bar } from "react-chartjs-2";

export default function App() {
  const data1 = {
    Tragedy: "25.00",
    Romance: "50.00",
    Comedy: "50.00",
    Others: "25.00"
  };
  const data2 = {
    "Chick Flick": "50.00",
    Tragedy: "25.00",
    Comedy: "25.00",
    Others: "25.00"
  };

  const labels = ["Comedy", "Romance", "Tragedy", "Chick Flick", "Others"];

  const getData = (data) => {
    return labels.map((label) => data[label]);
  };

  return (
    <div className="App">
      <Bar
        data={{
          labels,
          datasets: [
            {
              label: "Part1",
              data: getData(data1),
              backgroundColor: ["rgba(255, 99, 132, 0.2)"],
              borderColor: ["rgba(255, 99, 132, 1)"],
              borderWidth: 1
            },
            {
              label: "Part2",
              data: getData(data2),
              backgroundColor: ["rgba(75, 192, 192, 0.2)"],
              borderColor: ["rgba(255, 159, 64, 1)"],
              borderWidth: 1
            }
          ]
        }}
        height={400}
        width={600}
        options={{
          maintainAspectRatio: false,
          title: {
            display: true,
            text: "hello",
            fontSize: 20
          },
          scales: {
            y: {
              min: 0,
              max: 100,
              ticks: {
                stepSize: 20,
                callback: function (value) {
                  return ((value / this.max) * 100).toFixed(0) + "%"; // convert it to percentage
                }
              }
            }
          },
          plugins: {
            tooltip: {
              callbacks: {
                label: function (context) {
                  var label = context.dataset.label || "";
                  if (context.parsed.y !== null) {
                    label += " " + context.parsed.y + "%";
                  }
                  return label;
                }
              }
            }
          },
          legend: {
            labels: {
              fontSize: 25
            }
          }
        }}
      />
    </div>
  );
}

Link to codesandbox https://codesandbox.io/s/gracious-wilbur-jbw6v?file=/src/App.js

Akshay Dhiman
  • 123
  • 1
  • 10
  • 1
    Nice clean solution. You might want to make the `labels` array based on the data objects. `const labels = [...new Set([...Object.keys(data1), ...Object.keys(data2)])];` – pilchard Sep 20 '21 at 08:18