Tips for transforming my JSON format into the necessary column layout for C3.js

The data structure returned by my API is as follows. However, I need to reformat this structure for use in C3.js.

{
   "data":{  
  "test7":[  
     {  
        "Date":"2016-04-26 00:00:00",
        "aId":7,
        "Amount":436464,
        "Piece":37
     },
     {  
        "Date":"2016-04-26 01:00:00",
        "aId":7,
        "Amount":546546,
        "Piece":37
     },
     {  
        "Date":"2016-04-26 02:00:00",
        "aId":7,
        "Amount":5461,
        "Piece":37
     }
  ],
  "test4":[  
     {  
        "Date":"2016-04-26 00:00:00",
        "aId":4,
        "Amount":4564,
        "Piece":60
     },
     {  
        "Date":"2016-04-26 01:00:00",
        "aId":4,
        "Amount":4756,
        "Piece":60
     },
     {  
        "Date":"2016-04-26 02:00:00",
        "aId":4,
        "Amount":2355,
        "Piece":60
     }
  ],
  "test5":[  
     {  
        "Date":"2016-04-26 00:00:00",
        "aId":5,
        "Amount":879,
        "Piece":112
     },
     {  
        "Date":"2016-04-26 01:00:00",
        "aId":5,
        "Amount":1244,
        "Piece":112
     },
     {  
        "Date":"2016-04-26 02:00:00",
        "aId":5,
        "Amount":982,
        "Piece":112
     }
  ]
}

This is the syntax of my C3.js chart. How can I transform the above data into the required column structure for C3.js?

  var chart = c3.generate({
    bindto: '#area-hour',

    data: {
        x: 'Date',
        xFormat: '%Y-%m-%dT%H:%M:%S',
        columns: [
            ['Date', '2016-04-26T00:00:00', '2016-04-26T01:00:00', '2016-04-26T02:00:00'],
            ['test7', 13371, 103871, 103371],
            ['test4', 21654, 2544, 1694],
            ['test5', 6185, 3185, 3785]
        ],
    },
    grid: {
        y: {
            show: true,
        }
    },
    axis: {
        x: {
            type: 'timeseries',
            tick: {
                culling: false,
                format : "%Y-%m-%d " + "\n\r" + "%H:%M:%S"
            }
        }

    }
  });

Answer №1

Below is a handy conversion function tailored for your provided input data. Remember, there's no need to input every date in each dataset or include every attribute for each date.

// Feed your object's "data" attribute value (input.value) into the function
console.log(convert(input.data));

function convert(input) {
    var data = {};
    var listOfAllColumnNames = {};

    // The loop below structures the data & stores all column names for future use
    for(var key in input) {
        if(input.hasOwnProperty(key)) {
            var dataset = input[key];
            listOfAllColumnNames[key] = true;
            for(var i = 0; i < dataset.length; i++) {
                if(!data.hasOwnProperty(dataset[i].Date)) {
                    data[dataset[i].Date] = {};
                }
                data[dataset[i].Date][key] = dataset[i].Amount;
            }
        }
    }

    // Ensures that the required columns are present on every date
    listOfAllColumnNames = Object.keys(listOfAllColumnNames);
    for(var dateKey in data) {
        if(data.hasOwnProperty(dateKey)) {
            for(var m = 0; m < listOfAllColumnNames.length; m++) {
                if(!data[dateKey].hasOwnProperty(listOfAllColumnNames[m])) {
                    data[dateKey][listOfAllColumnNames[m]] = null;
                }
            }
        }
    }

    // Orders dates as C3.js displays columns according to given order
    var temporaryDates = [];
    for(var date in data) {
        if(data.hasOwnProperty(date)) {
            temporaryDates.push(date);
        }
    }
    temporaryDates.sort(function(a, b) {
        return new Date(a) - new Date(b);
    });

    // Builds final nested array structure with dates and attributes
    var columns = [['Date']];
    for(var j = 0; j < temporaryDates.length; j++) {
        columns[0].push(temporaryDates[j]);
        for(var columnName in data[temporaryDates[j]]) {
            var index = -1;
            for(var k = 1; k < columns.length; k++) {
                if(columns[k][0] === columnName) {
                    index = k;
                    break;
                }
            }
            if(index === -1) {
                columns.push([columnName]);
                index = columns.length - 1;
            }
            columns[index].push(data[temporaryDates[j]][columnName]);
        }
    }

    return columns;
}

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

ng-model assigns the value to the select

Below is the angularjs directive I have created: dicApp.directive('listpanel', function ($resource) { return { restrict: 'E', template: '<select ng-model="selectedDictionary" ng-change="listChange()">&apo ...

Retrieve the value of a variable by using either an HTTP GET or POST request

Here's the HTML code snippet that I'm working with: <head> <h1>Sample Page</h1> </head> <body> <form method="POST" action=""> Enter Keyword <input type="text" name="key"> ...

Error: Validation error encountered while validating recipe: _listId field is mandatory and must be provided

As a newcomer to node.js, I am attempting to create a cookbook restful API using nodejs. The goal is to have a list of recipes where each recipe is associated with a specific list selected by its id. However, I am encountering an issue while trying to retr ...

Is It Possible to Use Separate Stylesheets for Different Web Browsers?

I have been trying to implement a JavaScript code that loads a specific stylesheet based on the user's browser. However, it seems like the code is not functioning correctly as none of the stylesheets are being displayed. I have meticulously reviewed t ...

What steps can be taken to effectively build a test suite architecture using Jest?

After exploring all the available resources on the Jest documentation website, including various guides and examples, I have yet to find a solution to my specific question. I am in search of a methodology that would enable me to individually run test case ...

How can I display several custom markers that are constantly updating on a Google map with MySQL and PHP?

Currently, I am using the following code to generate markers on a Google map by retrieving data from a database. However, the issue I am facing is that it only generates one marker instead of all the markers stored in the database. & ...

What is the process for extracting JSON-style information from Yahoo Finance?

I am currently experimenting with HTML and JavaScript to fetch stock quotes from Yahoo and showcase them in a personalized gadget. I am querying the specified URL, using an example symbol: The output is either JSON or similar JSON-like format, depending o ...

Working with varying JSON structures in the same API response when using the Gson library

I've been developing an Android app that makes a web service call and receives a Json Object as the response. However, I've encountered a situation where the structure of the Json Object varies. Let me explain: Case 1: Json Structure The Json in ...

Enhancing Communication Between JavaScript and PHP

Positioned within my form is an input field where users can enter their postcode. The shipping cost for their order will be determined based on this postcode, utilizing PHP to assign different costs depending on the zone. After the user enters their postc ...

Pseudonym fields used for parsing JSON data

On my homepage, users have the ability to upload JSON fields that require parsing. I am specifically looking for certain fields that may have numerous alias names. I am uncertain about the best approach to take in order to identify these aliases. Currentl ...

Creating an Angular loading component using the route parameter

When a user clicks on a link in the home component, I want to load a different component based on the URL parameter. For example, if the user is at "/home" and sees a list of links: Link 1 Link 2 Clicking on Link 1 should load the details component with ...

The scroll bar will be automatically reset once the content inside is updated by using the $selector.html() function

I am looking to create a dynamic scrollable content feature. Initially, I retrieve the data and set the content as follows: $("#sub_menu li").on("click", function () { $("#gallery").html(get_html($(this).attr("id"))); $("#gallery").cs ...

Guide to locating and substituting two integer values within a string using JavaScript

Given a string such as: "Total duration: 5 days and 10 hours", where there are always two integers in the order of days and then hours. If I need to update the old string based on calculations using fields and other values, what is the most efficient meth ...

Animating the opacity of elements using jQuery and CSS

Trying to put together a fading slideshow with five slides that will loop back to the beginning. My code seems like it should do the trick, but there's something not quite right. <script type="text/javascript"> $(document).ready(function( ...

Tips on sending an array to material-ui dataSource props

Currently utilizing material-ui for a component. I am facing an issue with the autocomplete component in material-ui where I intend to display a list of icon names along with the icons. When only passing MenuItem to dataSource, it results in an empty input ...

php code that returns multiple variables after being processed by AJAX

Can someone assist me with handling PHP processing using Ajax for returning values but I'm struggling to handle two variables simultaneously? HTML <html> <head> <title>Sceener Ajax</title> <script src="jquery.js">< ...

Bring the element into view by scrolling horizontally

I am facing a challenge with a list of floated left divs inside another div. This inner block of divs can be hovered over to move it left and right. Each inner div, known as 'events', has class names that include a specific year. Additionally, t ...

Integrate predictive text suggestions in JavaServer Pages for efficient form filling

After some research, I have managed to solve the issue I was facing. On my jsp page, I have three text boxes. When I enter data into the first text box, it triggers a call to get.jsp to fetch data from the database and populate the second text box. However ...

PHP - Detect if there are any nested arrays that are not empty

How do I check for empty dates arrays within a nested array like this one? $myArray = [ '1' => [ 'dates' => []], '2' => [ 'dates' => []], '3' => [ 'dates' => ...

How does ES6 impact the connection between Angular, jQuery, and Vue.js?

Searching for tutorials on implementing ES6 with Vue.js but struggling to find a clear connection between the two. Curious if ES6 can be utilized directly or if it requires integration with libraries such as jQuery, Angular, or Vue.js. If using a script ...