Creating bar charts with Chartjs using dynamic and variable JSON data sources

I am currently working on developing a dynamic bar graph using JSON data that changes based on the applied filter.

The objective is to display the TYPE associated with the PERIOD in the graph, but only if it exists. If not, then nothing should be shown.

Although I managed to create the graph as per this helpful discussion on Stack Overflow, it requires all data options to be available, which is not always the case.

One issue I encountered is that if a certain TYPE is missing for a particular PERIOD, it shifts that TYPE back into the previous PERIOD, which is not the desired behavior.

Two examples are provided below:

  1. Two months featuring two types, but only 3 values (appears correct)
 [
    {
        "Period": "2023-12",
        "Total": 2238.86,
        "Type": "Drinks"
    },
    {
        "Period": "2023-12",
        "Total": 4672.35,
        "Type": "Food"
    },
    {
        "Period": "2024-01",
        "Total": 1166.5,
        "Type": "Drinks"
    }
]

View image here

  1. Three months with three types and 4 values (data from second period shifted to the first period)
[
    {
        "Period": "2023-11",
        "Total": 2782.13,
        "Type": "Other"
    },
    {
        "Period": "2023-12",
        "Total": 2238.86,
        "Type": "Drinks"
    },
    {
        "Period": "2023-12",
        "Total": 4672.35,
        "Type": "Food"
    },
    {
        "Period": "2024-01",
        "Total": 1166.5,
        "Type": "Drinks"
    }
]

Data from second period shifted to the first period

Despite spending days researching and experimenting with various approaches, no solution seems to work.

Below is the code snippet used based on the aforementioned topic:

jQuery.ajax({
    url: "../../ajax/barGraph.php?period=<?= $period; ?>",
    type: "GET",
    dataType: 'json',
    success: function(soldeInfo) {

          let labels = [...new Set(soldeInfo.map((x) => x.Period))];
          let datasets = soldeInfo.reduce(function (acc, cur) {
            let Type = acc.find((x) => x.label == cur.Type);
            if (Type == null) {
              let color = '';

              switch (cur.Type) {
                case 'Food':
                  color = 'red';
                  break;
                case 'Drinks':
                  color = 'green';
                  break;
                default:
                  color ='gray';
              }

              Type = {
                label: cur.Type,
                data: [cur.Total],
                backgroundColor: color,
                borderColor: color,
                borderWidth: 1,
              };

              acc.push(Type);
            } else {
              Type.data.push(cur.Total);
            }

            return acc;
          }, []);

          var soldeInfo = {
            type: 'bar',
            data: {
              labels: labels,
              datasets: datasets,
            },
          };

            const soldeChart = document.getElementById('chartSolde');
            new Chart(soldeChart, soldeInfo);

    }
});

Thank you!

Answer №1

Values from each dataset are selected at random positions from left to right. Thus, every data array should have empty values where no actual data exists.

Please review your updated code to see how this can be achieved.

const soldeInfo = [
    { "Period": "2023-11", "Total": 2782.13, "Type": "Other" },
    { "Period": "2023-12", "Total": 2238.86, "Type": "Drinks" },
    { "Period": "2023-12", "Total": 4672.35, "Type": "Food" },
    { "Period": "2024-01", "Total": 1166.5, "Type": "Drinks" }
];

const colorOf = (type) => {
  switch (type) {
    case 'Food':
      return 'red';
    case 'Drinks':
      return 'green';
    default:
      return 'gray';
  }
}

let labels = [...new Set(soldeInfo.map((x) => x.Period))];
let datasets = soldeInfo.reduce(function(acc, cur) {
  let type = acc.find((x) => x.label == cur.Type);
  if (type == null) {
    let color = colorOf(cur.Type);
    type = {
      label: cur.Type,
      data: new Array(labels.length).fill(0),
      backgroundColor: color,
      borderColor: color,
      borderWidth: 1,
    };
    acc.push(type);
  }
  type.data[labels.indexOf(cur.Period)] = cur.Total;  
  return acc;
}, []);

new Chart('chartSolde', {
  type: 'bar',
  data: {
    labels: labels,
    datasets: datasets,
  },
});
<script src="https://cdn.jsdelivr.net/npm/chart.js@^4"></script>
<canvas id="chartSolde" height="90"></canvas>

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

Tips for manipulating observableArray information retrieved through the $.getJSON method

Recently, I've started using knockout.js and I'm really enjoying it so far! While working in MVC4, I encountered a small issue. I had successfully implemented kojs with static data, but now I need to work with data passed from a controller via JS ...

Unable to convert the string into a Go struct field Article.article_type with the specified models.ArticleType type

I'm having trouble unmarshalling the JSON field article_type into a Golang struct called Article. The error I'm encountering is: json: cannot unmarshal string into Go struct field Article.article_type of type models.ArticleType str := []byte(` ...

Unraveling intricate JSON structures without field names using Golang

I am currently on a mission to decode the given JSON structure: [ { "2015-08-14 19:29:48-04:00": { "value": "0.1", "measurement_tag_id": "0.1.1a", "UTC_time": "2015-08-14 23:29:48", "error": "0" ...

The filtering feature for array and model selection in Angular's UI-Select appears to be malfunctioning

Below is a Json structure: $scope.people = [ { name: 'Niraj'}, { name: 'Shivam'}, { name: 'Arun'}, { name: 'Mohit'}] There's also a variable, var array = "Niraj,Shivam";. My goal is to filter out the names fro ...

Angular JavaScript Object Notation structure

I am a beginner in AngularJS and I'm attempting to create formatted JSON based on the values of table rows (tr) and cells (td). The table rows are generated automatically. When the form is submitted, I try to create the JSON values. Once the form is ...

Tips for including an object in a JSON array based on the value of another key within the file using JoltTransformationJson in NiFi

I am new to using JoltTransformationJson, so my understanding and experience with it are limited. I would greatly appreciate assistance with this complex project. Request: when the payment.code <> "paid", I need to perform the following tw ...

Building a table using jQuery and adding elements using JavaScript's append method

Greetings! I've been attempting to add new records from a form that registers or updates student information, but unfortunately it doesn't seem to be functioning correctly. Can anyone point me in the right direction as to why this may be happenin ...

Combining two JSON objects into a single JSON object using Python Flask

I currently have a Python Flask 3.4 web service running. In addition, I am using a MySQL database that consists of two tables - Table 1 and Table 2. For Table 1, I am able to fetch data in JSON format and display it on the browser. As for Table 2, I hav ...

What is the best way to encode images for inclusion in a JSON array?

I have a task that involves the following: Connecting to Amazon S3 to retrieve an image (.jpg) or sound file (.m4a). Storing these files in an array of objects. Sending the array to a client. The files exist on S3 and can be accessed through a browser. ...

updating a d3js line graph in real-time using JSON information

Trying to wrap my head around dynamically updating a line graph with new data, shifting the graph to the left and adding fresh data from the right - you following me? Want it to behave just like the examples on I'm fairly new to d3 (javascript) and l ...

Utilizing Laravel's Array and JSON casting feature for seamless integration with Algolia

I am encountering an issue while attempting to send data to Algolia using the toSearchableArray method. The strings from my database are transferring correctly, but I'm facing a challenge with nested JSON data—it's being sent as an escaped stri ...

Unresponsive jQuery Autocomplete function failing to trigger

There seems to be an issue with the unobtrusive autocomplete feature not working on the Sales/Accounts page of my application. I have followed advice from different sources, including a blog post linked here, on how to set up the autocomplete functionality ...

Utilizing Spring's Rest Service in Version 4.x

Despite encountering numerous inquiries on the subject, none have proven helpful to me. I'm attempting to launch a basic REST service, but no matter what I try, it just won't work. My initial approach was to set up a REST controller like this: ...

Obtaining only the updated objects from a web API in C#

When fetching data from a c# web api to my angular app, I notice that all the data is being polled every time, even if most of it remains unchanged. What I really want is to only retrieve and update the objects that have been modified in some way. Here&ap ...

Presenting quiz questions using javascript

Currently, I am following the learning path on javascriptissexy.com and facing a challenge with displaying quiz questions in the best way possible. As a beginner student of JavaScript, my question is about how to approach developing the behavior of a quiz ...

Exploring JSON as a tree structure within the Jersey framework

Personally, I find managing multiple POJOs for an API quite tedious. Instead, I believe it would be more efficient in certain situations to handle incoming JSON data as a tree structure. For example, consider a scenario where you could access data like th ...

The selection of activities is made dynamically while the splash screen is being

Today, as I was working on a small project, we decided to add conditional validation in the splash screen. The project was almost complete when this decision was made. I made some modifications to my class and everything seemed fine until I added a timeou ...

Struggling to transform JSON data into a dataframe

I am currently developing a recommendation engine and have encountered an issue with converting event data from a JSON file into a dataframe. I attempted to use the read_json method, but unfortunately, it resulted in an error. UnicodeDecodeError:'ch ...

Having trouble displaying the name and pricing

Can someone help me troubleshoot an issue with fetching data from this website? Here is the link . When I hit request to fetch the data, no data is being printed. import requests import time url = "https://www.adidas.com/api/metadata/pdp?" # ...

How can I display only the y-axis values and hide the default y-axis line in react-chartjs-2?

Although I have some experience with chartjs, I am struggling to figure out how to hide the default line. To clarify, I have attached an image that illustrates the issue. I would like to achieve a result similar to this example: . My goal is to make it loo ...