Stack the labels of separate datasets on top of each bar in a bar chart using Chartjs: How can this be achieved?

chart.js 4.4.2 chartjs-plugin-datalabels I am aiming to achieve this effect

 const chartCtr = document.querySelector('#temp-chart1') as HTMLCanvasElement;
  new Chart(chartCtr, {
    type: 'line',
    plugins: [ChartDataLabels],
    options: {
      layout: {
        padding: {
          bottom: 10.15,
        },
      },
      maintainAspectRatio: false,
      animation: false,
      plugins: {
        legend: {
          display: false,
        },
      },
      scales: {
        x: {
          adapters: {
            date: {
              locale: enUS,
            },
          },
          type: 'time',
          ticks: {
            stepSize: 3,
            major: {
              enabled: true,
            },
          },
          time: {
            unit: 'hour',
            tooltipFormat: 'HH:mm',
          },
          position: 'top',
        },
        yTemp: {
          ticks: {
            display: false,
          },
          grid: {
            drawTicks: false,
          },
          border: {
            display: false,
          },
        },
        yPop: {
          display: false,
          max: getMaxValueWithPadding(),
        },
        yLev: {
          display: false,
        },
      },
    },
    data: {
      labels: forecast.map((row) => row.date),
      datasets: [
        {
          label: 'temp every 3 hrs',
          data: forecast.map((row) => row.temp),
          yAxisID: 'yTemp',
          datalabels: {
            display: false,
          },
        },
        {
          label: 'probability of preciptation',
          data: forecast.map((row) => row.pop),
          yAxisID: 'yPop',
          type: 'bar',
          datalabels: {
            anchor: 'end',
            align: 'end',
            font: {
              weight: 'bold',
            },
            formatter: (value) => `${((value as number) * 100).toFixed()}%`,
          },
        },
        {
          label: '3h rain',
          yAxisID: 'yLev',
          data: forecast.map((row) => {
            const sum = (row.rain ?? 0) + (row.snow ?? 0);
            if (sum) return sum;
            else return '';
          }),
          hidden: true,
        },
      ],
    },
  });

I am trying to display the values of the '3h rain' dataset on each bar. I have successfully used the datalabels plugin to display the values of the 'probability of precipitation' dataset on each bar. How can I achieve the same for '3h rain'?

current chart

Answer №1

After some exploration, I have found the solution! I wanted to share my method in case it can assist anyone else facing similar challenges. The formatter option within the datalabels plugin accepts two arguments: value and context. The context object includes a property called dataIndex, which provides the index of the value in your dataset. By utilizing this index, you can easily access and manipulate other data points of interest from your dataset, even when working with multiple datasets simultaneously.

formatter: (value, context) => {
              const bar = forecast[context.dataIndex];
              const sum = (bar.rain ?? 0) + (bar.snow ?? 0);
              if (sum)
                return `${sum} mm/h\n${((value as number) * 100).toFixed()}%`;
              else return `${((value as number) * 100).toFixed()}%`;
            },

Link to more information on the formatter option and context object

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

The React JSON Unhandled Rejection problem requires immediate attention

While working on a form in React 16, I reached out to a tutor for some guidance. However, when trying to mock the componentDidMount, I encountered an error that has left me puzzled. The app still runs fine, but I am curious as to why this error is occurrin ...

Error: Trying to send FormData to ajax results in an Illegal Invocation TypeError being thrown

Successfully sending a file to the server for processing using the code below: var formData = new FormData(); formData.append('file', $('#fileUpload')[0].files[0]); options = JSON.stringify(options); // {"key": "value"} $.ajax({ ...

How to Retrieve Upload Progress via HTTP Request in PHP

Is there a way to monitor the progress of file uploads by accessing the HTTP request in PHP? If so, how can this be achieved when uploading files into a MySQL database? require('../connect_db.php'); //Collect all necessary data $name = $dbc-> ...

Halt execution of routes using backbone.js

Is it feasible to halt route execution within backbone.js solely using the router? I understand there is a callback function for each route where I could verify if routing is permitted, but I am unsure how to prevent execution based on a property (such as ...

How can Vue detect modifications made in the edited field?

I am facing an issue with tracking changes in a specific object. Here is the structure of the object: users: { email: '', password: '' } My goal is to detect any edits made to the keys within the users object and store the key ...

The ElementNotInteractableException was thrown because the element could not be accessed via the keyboard when trying to input text into the FirstName field on Facebook

The issue is as follows: Exception encountered in thread "main" org.openqa.selenium.ElementNotInteractableException: Element is not accessible via keyboard Here is the code snippet: System.setProperty("webdriver.gecko.driver"," ...

The encoding error in the encoding process must adhere to valid encoding standards

I recently developed a basic program that utilizes process.stdin and process.stdout. However, when I executed the program and tried to input a value for stdout, an error message popped up stating "TypeError: 'encoding' must be a valid string enco ...

Error message: Unable to locate module when utilizing my alternative library packaged with Rollup

Currently, I am utilizing rollup to package a UI library for use across various primary applications. However, the bundled ESM file contains imports that are incompatible with webpack in the main applications: import { ArrowDropDownCircleOutlined } from &a ...

Monitor the output of a spawned process that is currently in a state of awaiting user input

In my Swift program, I am logging information to the stdout while waiting for a termination signal of \n. The input is requested immediately upon starting and the info is logged 1~2 seconds later: fetchAndLogDataInBackground(); // will print some dat ...

Issue with React ChartJS rendering – Title not visibleWhen using React Chart

I'm currently using react chart js for displaying a doughnut in my component. "chart.js": "^3.7.1", "react-chartjs-2": "^4.1.0", However, I'm facing an issue where the title is not being displayed: const d ...

Enhancing Website Functionality: How to Swap iFrame for DIV using PHP and AJAX

I am currently working on a website where I need to replace an iframe containing data stored in an invisible form with a div that updates its content using AJAX. If you don't want to read everything, skip to the end for my main question. The chall ...

How can I locate an element within the body of an if statement?

I am working on a simple JavaScript (jQuery library) if statement to check for the presence of a div element with the class 'video' on the page. If it finds the element, the variable 'arrows' is set to true, otherwise it is set to false ...

Using Javascript to change CSS in a Polymer application

Coming from a background in angular and react, I am now delving into the world of polymer. I have a polymer class called myClass with the following template. <div id="[[x]]"> Here, 'x' is a property defined in a property getter. stat ...

What can we achieve using typename and nested types in a Typescript generic function?

I've been exposed to numerous tricks, but I seem to be struggling with this particular puzzle; therefore, any assistance from someone with more experience in TS would be greatly appreciated. My subscribe() function requires: Message type in the form ...

Crockford's method of replacing values with nested objects

/** Custom Supplant Method **/ String.prototype.customSupplant = function(obj) { return this.replace (/{([^{}]*)}/g, function (match, propPath) { var props = propPath.split('.'); var result = obj; f ...

The alert() function in PHP does not function as expected and instead prints to the console

My attempt to display an alert is not working and I'm not sure what I might be missing. Can someone please help me pinpoint the issue? //my.php if(mail($to, $subject, $message, $headers)) { $message = "Mail sent."; echo "<script type=&apo ...

Transform nested JSON objects into a JSON array using JavaScript

Hey there! I've got this JSON structure that I'm trying to convert into an array without having to iterate over each element. Is there a JavaScript function that can help me achieve this? { "ES": { "130": { "code": "A Coruсa", ...

Leveraging TypeScript to sort and extract specific elements from two arrays

Given two arrays, I am looking to identify the elements in array2 that match elements in array1 based on a specific property. The arrays are structured as follows: var array1 = [ {"myId": 1, "text": "a"}, {"myId& ...

Unable to invoke parent method from child component in Vue causing issue

I am facing an issue where I am trying to trigger a method in the parent component from the child component using $emit, but for some reason, it is not working as expected. Can someone please help me troubleshoot this problem? Parent Component <templat ...

Tips for displaying a resolved promise in React js after using the `then` method

While working with promises, I encountered this error: Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous task ...