Show nested objects in Chart.js

-2๐Ÿ‘

โœ…

You can try converting your object into an array of fruits objects:

const input = {
"fruits": [
    {
    "oranges": {
      "good": 1,
      "not_good": 0
    },
    "apples": {
      "good": 1,
      "not_good": 0
    },
    "grapes": {
      "good": 2,
      "not_good": 0
    }
  }]
  };

const output = Object.keys(input.fruits[0])
.map(fruit => ({'name' : fruit, 'dataset' : input.fruits[0][fruit] })  ); 

console.log(output);
 

๐Ÿ‘:0

let goods = []; 
let bads = [];
let labels = [];
for (let i = 0; i < obj.fruits.length; i++) {
    const fruit = obj.fruits[i];
    // Since we don't know the fruit name, we iterate through its keys
    for (var key in fruit) {
        // Push the fruit name
        labels.push(key);
        let val = fruit[key];
        if(val.good == 1) {
            // If good is 1, push the fruit name to goods array
            goods.push(val);
        } else {
            // If not_good is 1, push to bads array
            bads.push(val);
        }
    }
}

๐Ÿ‘:0

Drawing this kind of bar chart with chart.js could be done like this.

var ctx = document.getElementById("myChart").getContext("2d");

var data = {
  labels: ["Good", "Not good"],
  datasets: [{
    label: "Oranges",
    backgroundColor: "orange",
    data: [2, 1]
  }, {
    label: "Apples",
    backgroundColor: "green",
    data: [4, 2]
  }, {
    label: "Grapes",
    backgroundColor: "purple",
    data: [3, 1]
  }]
};

var myBarChart = new Chart(ctx, {
  type: 'bar',
  data: data,
  options: {
    barValueSpacing: 20,
    scales: {
      yAxes: [{
        ticks: {
          min: 0,
        }
      }]
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.bundle.min.js"></script>
<canvas id="myChart" width="400" height="400"></canvas>

However, the data provided by your api is not ideal. So you would have to manipulate the data from your response like this.

const res = {
  fruits: [
    {
      oranges: {
        good: 1,
        not_good: 0
      },
      apples: {
        good: 1,
        not_good: 0
      },
      grapes: {
        good: 2,
        not_good: 0
      }
    }
  ]
};
const dataset = Object.entries(res.fruits[0]).map(fruit => {
  return {
    label: fruit[0],
    data: Object.values(fruit[1])
  };
});

console.log(dataset);

Given that the backgroundColor for each bar is not included in the data from your api, you would also have to figure out where to get this from.

Here is how it could all look together.

const res = {
  fruits: [
    {
      oranges: {
        good: 10,
        not_good: 5
      },
      apples: {
        good: 6,
        not_good: 1
      },
      grapes: {
        good: 9,
        not_good: 5
      },
      pears: {
        good: 15,
        not_good: 6
      }
    }
  ]
};

const datasets = Object.entries(res.fruits[0]).map(fruit => {
  return {
    label: fruit[0], 
    data: Object.values(fruit[1]),
    backgroundColor: getRandomColor()
  };
});


const ctx = document.getElementById("myChart").getContext("2d");

const data = {
  labels: ["Good", "Not good"],
  datasets
};

const myBarChart = new Chart(ctx, {
  type: 'bar',
  data: data,
  options: {
    barValueSpacing: 20,
    scales: {
      yAxes: [{
        ticks: {
          min: 0,
        }
      }]
    }
  }
});

function getRandomColor() {
  const letters = '0123456789ABCDEF';
  let color = '#';
  for (let i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.bundle.min.js"></script>
<canvas id="myChart" width="400" height="400"></canvas>

JSfiddle

getRandomColor from this answer

Leave a comment