Display sub-objects within Chart.js

I'm currently tackling a project in Ionic 3 where I am utilizing an API that returns a JSON response with nested objects. My goal is to display certain aspects of these objects within a bar graph using chart.js.

Unfortunately, I lack experience in manipulating JSON objects.

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

It's uncertain how many fruits will be included in the response.

The names of the fruits would serve as the labels for the graph, while the 'good' and 'not good' values would make up the datasets.

Answer №1

const healthyFruits = []; 
const unhealthyFruits = [];
const fruitLabels = [];
for (let index = 0; index < obj.fruits.length; index++) {
    const fruitObj = obj.fruits[index];
    // Iterate through the keys of each fruit object to determine its health status
    for (var property in fruitObj) {
        // Record the fruit name
        fruitLabels.push(property);
        let value = fruitObj[property];
        if(value.good == 1) {
            // If good is 1, add the fruit name to healthyFruits array
            healthyFruits.push(value);
        } else {
            // If bad is 1, add the fruit name to unhealthyFruits array
            unhealthyFruits.push(value);
        }
    }
}

Answer №2

Creating a bar chart using Chart.js entails the following steps:

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>

To adjust the data received from an API to fit the required format for the chart, you can manipulate the data as follows:

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);

Additionally, if the background colors for each bar are not provided by the API, you will need to determine where to source this information.

Here is how everything comes together in the final implementation:

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>

View JSfiddle Example

Reference to getRandomColor Implementation

Answer №3

If you want to transform your object into an array of fruit objects, consider the following approach:

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

 const result = Object.keys(data.fruits[0])
 .map(fruit => ({'name': fruit, 'values': data.fruits[0][fruit] }));

 console.log(result);
 

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Node.js QuickStart guide for authenticating with the Youtube API encounters error

Using node.js for a Discord bot, I encountered an issue with Google's API tutorial being outdated. Here is the link to their tutorial. The tutorial asks to select an "Other" option which no longer exists, now replaced by "desktop app". This was an ea ...

What is the best way to eliminate excess white space on the right side in WordPress for a mobile perspective?

Is there a quick way to identify which element has shifted beyond the border? It seems like there is excess margin. How can I pinpoint the issue? The link to the broken page on mobile is I applied this style * {border: 2px solid red;} and no elements shif ...

Issue with Jquery plugin malfunctioning on dynamically loaded elements via Ajax requests

Description: I'm currently working on a project where I need to load elements with expiration dates pulled from my database. To achieve this, I am using a Jquery plugin that relies on the HTML5 Data Type Attribute for setting the "end date". Everythin ...

Using jQuery sortable with the overflow property set to hidden to sort items between two lists

I need help with a jQuery sortable feature where I have two lists and can move items between them: $( '#productsList, #orderList' ) .sortable({connectWith: '.containerDiv'}) .disableSelection(); My issue arises when I try to implement ...

Having trouble with updating React state? The useEffect hook runs when attempting to change the state, but it seems to have the

Having worked with useEffect and its ability to trigger after a state variable has been updated, I am well-versed in its functionality. I'm currently drafting this post on my phone while away from home. Here's the setup I have: const [dateValue ...

Unusual behavior involving the selection of $stateParams

Seeking a solution for updating angular-ui route parameters based on select field changes. Issue: The route successfully updates with the selected parameter, but the select field does not reflect the change in option selection. Check out the Plunkr. Clic ...

Using JavaScript, HTML, and CSS to select slices of a donut pie chart created with SVG

I have successfully implemented CSS hover effects and can manipulate the HTML to use the .active class. However, I am facing difficulties in making my pie slices switch to the active state upon click. Moreover, once this is resolved, I aim to enable select ...

Error in TypeScript React component due to prop-types ESLint in React

I'm in the process of setting up a typescript-react-eslint project and I've encountered an eslint error with this boilerplate component: import * as React from "react"; interface ButtonProps { children?: React.ReactNode, onClick?: (e: any) ...

Retrieve a Play Scala variable in the $scope of an AngularJS application

After trying various methods recommended on StackOverflow, I am still struggling to retrieve a Play Scala variable within my Javascript $scope. The line of initialization in an HTML file is as follows: @(playVariable: String)(implicit request: play.api.mv ...

Interested in incorporating dynamic calendar entries in ASP C#?

Here is the code snippet I utilized: <script> var count = 1; var limitValue = 3; function addNewInput(sectionName) { if (count == limitValue) { alert("You have reached the limit of adding " + count + " inputs"); ...

Fetching various data from MongoDB using NodeJS and presenting it in Jade(Pug) template

I am working with MongoDB collections and need to showcase them on my website, creating a dynamic page that updates automatically. Specifically, I am dealing with team members' information in the database. Here is an example of how my collections loo ...

Dropdown feature in the side navigation bar

Is it possible to create a drop-down section in a navigation bar using HTML/CSS/JS? For example, clicking on 'products' would reveal a list of products that disappears when clicked again. If this is achievable, how can it be done? I am currently ...

Error message when using Vue Global Filter: Value undefined is not defined

Trying to format currency, I initially attempted to use a global filter in Vue: Vue.filter('formatMoney', (val) => { if (!value) return '' val = val.toString() return val.replace(/\B(?=(\d{3})+(?!\d))/g, ",") ...

The Angular route seems to be unresponsive to a single click, but it starts functioning properly when clicked

I am utilizing a data service to handle all my asynchronous data operations. Whenever I click the ERASE button, a function is triggered to erase all data and return an object indicating the operation status (Success: true/false). If the value returned is ...

Enhance your React application by making two API requests in

Below is the React Component that I am working on: export default function Header () { const { isSessionActive, isMenuOpen, isProfileMenuOpen, setIsMenuOpen, closeMenu, URL } = useContext(AppContext) const [profileData, setProfileData] = useState({}) ...

What is the best way to iterate through an array of objects in React and JavaScript, adding a new property to each object in order to generate a new array

Greetings, I am currently dealing with an array of objects structured as follows: const arr_obj = [ { children: [{}], type: "type1", updated: "somevalue", }, { children: [{}], type: ...

Switching a conditional className to a styled component

Currently, I am in the process of converting my project from plain CSS to styled components using styled-components. So far, I have successfully converted all of my components except for one. I have looked at various examples on Stack Overflow but none of ...

Is it feasible to incorporate a method into a prototype and ensure that 'this' is associated with the appropriate type in TypeScript?

I have a scenario where I need to add a new method to a prototype, specifically to a class created using TypeScript. Here is an example: declare module "./MyClass" { interface MyClass { myNewMethod(); } } MyClass.prototype.myNewM ...

What's the best way to implement asynchronous state updating in React and Redux?

In my React incremental-style game, I have a setInterval function set up in App.ts: useEffect(() => { const loop = setInterval(() => { if (runStatus) { setTime(time + 1); } }, rate); return () => clearInterval(lo ...

Retrieve the thousand separator for numbers using Angular in various languages

When using the English locale, numbers appear as follows: 111,111,222.00, with a comma as the thousand separator and a point as the decimal separator. In languages like German, the same number would be represented as 111.111.222,00, reversing the positions ...