Plotting datapoints with a slight deviation on multiple charts using chart.js

As I navigate my way through the world of Javascript, I may stumble upon some questions that seem trivial.

My current challenge involves creating a chart with 4 datasets where the 3rd dataset is stacked with the 1st, and the 4th is stacked with the 2nd. Despite my attempts to utilize grouped stacked bar charts, I find that it only stacks the 3rd and 4th datasets on top of the 2nd.

I've experimented with standard inputs following the link provided below.

While the approach in the link works perfectly for a single chart, it fails when implementing multiple charts on the same page. The plugin runs simultaneously on both charts causing rendering issues.

How to add an offset to a dataset in Chart js

Even after trying the inline plugin method from the chart.js documentation, the issue persists as it affects both charts altogether. Is there a way to target a specific chart instance or perhaps another workaround?

var ctx = document.getElementById("myChartTEC").getContext("2d");
    var myChart = new Chart.Line(ctx, {
        type: 'line',
        data: {
            labels: ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC", ""],
            datasets: [{
                data: [5, 10.5, 18.2, 33.9, 121.2, 184.9, 179.9, 196.1, 158.3, 166.3, 66.4, 20.6, null],
                pointLabelFontSize: 4,
                borderWidth: 2,
                fill: false,
                lineTension: .3,
                borderColor: "#f37029",
                borderCapStyle: 'round',
                borderDash: [],
                borderDashOffset: 0.0,
                borderJoinStyle: 'bevel',
                pointBorderColor: "#f37029",
                pointBackgroundColor: "#f37029",
                pointBorderWidth: 1,
                pointHoverRadius: 4,
                pointHoverBackgroundColor: "rgba(220,220,220,1)",
                pointHoverBorderColor: "rgba(220,220,220,1)",
                pointHoverBorderWidth: 2,
                pointRadius: 4,
                pointHitRadius: 10,
                spanGaps: false,
            },
                {
                    data: [10, 20, 5.2, 35.9, 121.2, 184.9, 179.9, 196.1, 158.3, 166.3, 66.4, 20.6, null],
                    pointLabelFontSize: 4,
                    borderWidth: 2,
                    fill: false,
                    lineTension: .3,
                    borderColor: "#f37029",
                    borderCapStyle: 'round',
                    borderDash: [],
                    borderDashOffset: 0.0,
                    borderJoinStyle: 'bevel',
                    pointBorderColor: "#f37029",
                    pointBackgroundColor: "#f37029",
                    pointBorderWidth: 1,
                    pointHoverRadius: 4,
                    pointHoverBackgroundColor: "rgba(220,220,220,1)",
                    pointHoverBorderColor: "rgba(220,220,220,1)",
                    pointHoverBorderWidth: 2,
                    pointRadius: 4,
                    pointHitRadius: 10,
                    spanGaps: false,
                }
            ]
        },
        plugins: [{
            afterUpdate: function (chart) {
                var dataset = chart.config.data.datasets[0];
                var offset = -20;

                for (var i = 0; i < dataset._meta[0].data.length; i++) {
                    var model = dataset._meta[0].data[i]._model;
                    model.x += offset;
                    model.controlPointNextX += offset;
                    model.controlPointPreviousX += offset;
                }

                var dataset2 = chart.config.data.datasets[1];
                var offset2 = 20;

                for (var o = 0; o < dataset2._meta[0].data.length; o++) {
                    var model2 = dataset2._meta[0].data[o]._model;
                    model2.x += offset2;
                    model2.controlPointNextX += offset2;
                    model2.controlPointPreviousX += offset2;
                }
            }
        }],
        options: {
            scales: {
                xAxes: [{
                    gridLines: {
                        offsetGridLines: true,
                        display: false,
                        borderDash: [6, 2],
                        tickMarkLength: 5
                    },
                    ticks: {
                        fontSize: 8,
                        labelOffset: 10,
                        maxRotation: 0
                    }
                }],
                yAxes: [{
                    gridLines: {
                        display: false
                    },
                    ticks: {
                        beginAtZero: true,
                        max: 200,
                        min: 0,
                        stepSize: 20,
                        fontSize: 8
                    }
                }]
            },
            legend: {
                display: false
            },
            responsive: false,
            maintainAspectRatio: true
        }
    });
    var ctx = document.getElementById("myChart").getContext("2d");
    var myChart = new Chart.Line(ctx, {
        type: 'line',
        data: {
            labels: ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC", ""],
            datasets: [{
                data: [5, 10.5, 18.2, 33.9, 121.2, 184.9, 179.9, 196.1, 158.3, 166.3, 66.4, 20.6, null],
                pointLabelFontSize: 4,
                borderWidth: 2,
                fill: false,
                lineTension: .3,
                borderColor: "#f37029",
                borderCapStyle: 'round',
                borderDash: [],
                borderDashOffset: 0.0,
                borderJoinStyle: 'bevel',
                pointBorderColor: "#f37029",
                pointBackgroundColor: "#f37029",
                pointBorderWidth: 1,
                pointHoverRadius: 4,
                pointHoverBackgroundColor: "rgba(220,220,220,1)",
                pointHoverBorderColor: "rgba(220,220,220,1)",
                pointHoverBorderWidth: 2,
                pointRadius: 4,
                pointHitRadius: 10,
                spanGaps: false,
            },
                {
                    data: [10, 20, 5.2, 35.9, 121.2, 184.9, 179.9, 196.1, 158.3, 166.3, 66.4, 20.6, null],
                    pointLabelFontSize: 4,
                    borderWidth: 2,
                    fill: false,
                    lineTension: .3,
                    borderColor: "#f37029",
                    borderCapStyle: 'round',
                    borderDash: [],
                    borderDashOffset: 0.0,
                    borderJoinStyle: 'bevel',
                    pointBorderColor: "#f37029",
                    pointBackgroundColor: "#f37029",
                    pointBorderWidth: 1,
                    pointHoverRadius: 4,
                    pointHoverBackgroundColor: "rgba(220,220,220,1)",
                    pointHoverBorderColor: "rgba(220,220,220,1)",
                    pointHoverBorderWidth: 2,
                    pointRadius: 4,
                    pointHitRadius: 10,
                    spanGaps: false,
                }]
        },
// This part is not working. Uncaught TypeError: Cannot read property 'data' of undefined
        plugins: [{
            afterUpdate: function (chart) {
                var dataset = chart.config.data.datasets[0];
                var offset = -20;

                for (var i = 0; i < dataset._meta[0].data.length; i++) {
                    var model = dataset._meta[0].data[i]._model;
                    model.x += offset;
                    model.controlPointNextX += offset;
                    model.controlPointPreviousX += offset;
                }

                var dataset2 = chart.config.data.datasets[1];
                var offset2 = 20;

                for (var o = 0; o < dataset2._meta[0].data.length; o++) {
                    var model2 = dataset2._meta[0].data[o]._model;
                    model2.x += offset2;
                    model2.controlPointNextX += offset2;
                    model2.controlPointPreviousX += offset2;
                }
            }
        }],
        options: {
            scales: {
                xAxes: [{
                    gridLines: {
                        offsetGridLines: true,
                        display: false,
                        borderDash: [6, 2],
                        tickMarkLength: 5
                    },
                    ticks: {
                        fontSize: 8,
                        labelOffset: 10,
                        maxRotation: 0
                    }
                }],
                yAxes: [{
                    gridLines: {
                        display: false
                    },
                    ticks: {
                        beginAtZero: true,
                        max: 200,
                        min: 0,
                        stepSize: 20,
                        fontSize: 8
                    }
                }]
            },
            legend: {
                display: false
            },
            responsive: false,
            maintainAspectRatio: true
        }
    });

Answer №1

One issue that arises when creating an inline-plugin for a new chart instance is the need to increment the index number of _meta[index] in both for loops. For example, for the first chart it will be _meta[0], for the second chart _meta[1], and so on.

Below is a revised version of your code with the necessary adjustments:

var ctx = document.getElementById("myChartTEC").getContext("2d");
var myChart = new Chart.Line(ctx, {
  type: 'line',
  data: {
    labels: ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC", ""]
    // Additional dataset configurations here...
  },
  plugins: [{
    // Plugin function with updated index numbers
  }],
  options: {
    // Additional chart options here...
  }
});

var ctx = document.getElementById("myChart").getContext("2d");
var myChart = new Chart.Line(ctx, {
  type: 'line',
  data: {
    labels: ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC", ""]
    // Additional dataset configurations here...
  },
  plugins: [{
    // Plugin function with updated index numbers
  }],
  options: {
    // Additional chart options here...
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="myChartTEC"></canvas>
<canvas id="myChart"></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

Adding animation to the initial loading process of a Vue application

I want to include an animation when the application's modules are loading for the first time. I have attempted to use an image, but I am unable to add an animation to it. Adding a CSS file did not always work as expected. I then tried utilizi ...

Center the div vertically aligned with the following element

Seeking guidance on aligning an element to the vertical center of another element. https://i.sstatic.net/Hk8UE.png In the provided scenario, the goal is to align the top of text with the vertical center of the adjacent image. https://i.sstatic.net/hxmm9 ...

Express API developed with the use of Node.js

In the process of creating a weather application API using Express in Node.js, I have decided not to utilize a database since no data needs to be saved. The application enables users to input a city name, and the weather information is fetched directly fro ...

What is the method for combining two box geometries together?

I am looking to connect two Box Geometries together (shown in the image below) so that they can be dragged and rotated as one object. The code provided is for a drag-rotatable boxgeometry (var geometry1). What additional code do I need to include to join t ...

A method for setting a value from an HTML textbox to a variable and displaying it on the same page

How can I retrieve the value from a textbox and display it on the same page? The purpose behind this is that when the user enters their BTC wallet into the textbox, I want to store this value in a variable on the same page and then output the value. I at ...

Highlight the active page or section dynamically using HTML and jQuery - How can it be achieved?

What am I trying to achieve? I am attempting to use jQuery to dynamically highlight the current page from the navigation bar. Am I new to jQuery/HTML? Yes, please excuse my lack of experience in this area. Have I exhausted all resources looking for a sol ...

Generate random floating numbers at intervals and calculate their sum

I've been given a task to complete. Upon page load, there should be 10 fields labeled as A, B, C, D ... each with the initial value of 3. After the page has loaded, every 2 seconds all field values should change randomly. The change will be a rand ...

issue encountered while passing a callback in a res.render() function

Currently, I am working on a small application where I am fetching data from remote JSON files to generate statistics that will be displayed in an EJS file later. My objective is to pass separate values for rendering and then utilize them within the EJS d ...

Angular II slash avoiding Pipe

I am working on developing a customized pipe in Angular 2 that will handle the replacement of the backslash ('\') character in a given string. This backslash is commonly used to escape special characters. What I have accomplished so far: T ...

Is it possible to connect ng-model with a style tag?

Is it feasible to create a basic template editor using angularjs where an input field with an ng-model can be connected to a style tag to control the css on an entire page rather than applying it to a specific element with inline styling? Could something ...

Implementing promises in my MEAN stack application

I have developed a controller that performs a Bing search based on the user's input in the URL. After testing the controller with console.log, it seems to be functioning correctly and I have set the variable to return the results. However, when trying ...

Odd behavior in Google Chrome when PHP includes JavaScript code

When working with my application built on Zend Framework, I have a layout.phtml file that contains the <head> section with some javascripts included using the following method: <head> // Some code <?php include('template/javascript ...

Discover the method for storing multiple values in local storage using a dictionary with JavaScript

I have a scenario in my code where I need to update a value without storing a new one. Let's say I need to input values in the following format: { firstname:'kuldeep', lastname:- 'patel' } After entering the values, they g ...

I have a task to create a program that can extract unique elements from an existing array and add them to a new array

I am in the process of creating a code snippet that will extract unique elements from an array and store them in a new array. My approach involves developing two custom functions, similar to .includes and .push. The arrIncludesTest function is designed to ...

Navigating an HTML table with the precision of a battleship commander: A guide

I have a simple HTML table that I want to parse line by line using JavaScript without any specific identifiers like class names. My goal is to create a mapping system similar to the following: AC000(red)(green) => cell match. As illustrated in the scr ...

Issue with receiving output from tessearct.js in PDF format

I am currently working on a basic javaScript OCR (Optical Character Recognition) application using tesseract.js. I have included {tess_create_pdf: "1"} in the .recognize() method to receive the result in PDF format, but it seems to be malfunctioning. Can ...

Utilize the functions.php script in the footer, rather than in the head section

Encountered an issue in my JS file where a hover event listener was causing a 'Cannot read property 'addEventListener' of null' error. The code snippet I used for the listener came from W3 schools and targeted elements with the class "c ...

Experiencing an excessive amount of re-renders in React due to useState

In this scenario, the user is expected to press the correct letter on the keyboard (which is the first letter of the bird's name) in order to delete the first bird's name from the birds array. This process repeats until the array is empty. Howeve ...

Tips for displaying errors in React applications

Having trouble troubleshooting React (16.13.0) as I am not receiving any useful errors, just this message: Error: Minified React error #321; visit https://reactjs.org/docs/error-decoder.html?invariant=321 for more info or switch to the non-minified dev en ...

Mastering the art of scrolling to a specific element with angular-scroll

Currently implementing Angular Scroll and when reaching a specific page, I trigger a function to scroll to an ID. Encountering the following error in the code snippet below: TypeError: $document.scrollToElement is not a function initHelp(); function ...