Chartjs-Dynamically create dataset objects for multi-line graphing, using pre-defined dataset object arrays (JavaScript / Chart.js)

0๐Ÿ‘

โœ…

A multi-line chart will have three important object arrays that need to be created, assigned to:

  1. chart.data.labels โ€“ for x-axis labeling (ex. an independent variable like time)
  2. chart.data.datasets โ€“ for y-axis labeling (including multiple lines)
  3. chart.options.scales.yAxes โ€“ for the properties of the line(s)

If you have a pre-existing set of data (in this particular case objectArray) that contains pre-existing data associated with particular line names, you can create a constant array that contains strings of the same names (in this case NAME_ARRAY), as well as temporary arrays for each dataset (name1 = []; name2 = []; etcโ€ฆ) acquired by iterating through a for loop.

This can be seen with:

// 'N' PRE-DEFINED CONSTANTS

// Names of the lines you are graphing
const NAME_ARRAY = [
  'name1',
  'name2',
  'name3'
];
// Colors of lines in same order as aforementioned names
const HEX_ARRAY = [
  '#3CBA9F',
  '#51b7ed',
  '#FF0000'
];

// GRAPHING LINE PROPERTIES SHARED BY 'N' LINES

// Doesn't require arguments so can utilize .map() effectively
const datasetLineArray = NAME_ARRAY.map((value,index,array) => {
  return {
    id: value,
    display: false,
    ticks: {
      // INSERT YOUR PROPERTIES HERE (although none required)
      // max: 1000,
      // min: 100000,
      // reverse: true,
      // stepSize: 10000,
      // suggestedMax: 500,
      // etc...
    },
  };
});
// Utilizes two arguments so needs object creation upon call rather than pre-defined array mapping (as in .map())
function addDataToDataset(dataArray, index) {
  const tempObject = {
    data: dataArray,
    label: NAME_ARRAY[index],
    yAxisID: NAME_ARRAY[index],
    borderColor: HEX_ARRAY[index],
    fill: false,
    scaleOverride: true,
  };
  return tempObject;
}

// CHART.JS GRAPH CREATION

export class AppComponent implements OnInit {
    // Store dataset objects
    Dataset_Object_Array = [];

    // Store data with same name as incoming objects
    name1 = [];
    name2 = [];
    name3 = [];

    // Essentially main()
    ngOnInit() { 
        for (const categoryArray in objectArray) {
            const categoryObject = objectArray[categoryArray];
            // these names are arbitrary, just note that categoryObject is an object that contains 
            // the property 'category' which is the equivalent of the name from the constant array 
            // 'NAME_ARRAY'; however, this object may contain data that we need to parse

            // IMPORTANT BIT
            this.Dataset_Object_Array.push(addDataToDataset(this[categoryObject.category], categoryArray));
        }

        // The actual graph formatting
        this.chart = new Chart('canvas', {
            type: 'line',
            data: {
                // **IMPORTANT BIT**
                labels: this.one, // x-axis labeling

                // **IMPORTANT BIT**
                datasets: this.Dataset_Object_Array // multi-line y-axis labeling as well as data
            },
            options: {
                responsive: true,
                maintainAspectRatio: true,
                legend: {
                  display: true
                },
                scales: {
                  xAxes: [{
                    display: true,
                    ticks: {
                        callback: function(value, index, values) {
                          return parseFloat(value).toFixed(3);
                        },
                    }
                 }],

                 // **IMPORTANT BIT**
                 yAxes: datasetLineArray, // property meta-data for the lines
               }
            }
        });
    }
}

Leave a comment