skip to Main Content

Given the following chart how can I show a custom HTML label for the Y ticks?

  const yAxisLabelsLookup = {
    0: {
      label: '2024-01-01',
      color: 'red',
    },
    1: {
      label: '2024-01-02',
      color: 'blue',
    },
    2: {
      label: '2024-01-03',
      color: 'green',
    },
    3: {
      label: '2024-01-04',
      color: 'yellow',
    },
  }
  const ctx = document.getElementById('chart-container');

  const data = {
    datasets: [{
      label: 'First Dataset',
      data: [
        {
          x: 20,
          y: 0,
          r: 15
        }, {
          x: 40,
          y: 0,
          r: 10
        },
        {
          x: 20,
          y: 1,
          r: 10
        },
        {
          x: 40,
          y: 1,
          r: 10
        },
        {
          x: 25,
          y: 2,
          r: 10
        },
        {
          x: 35,
          y: 2,
          r: 10
        },
      ],
      backgroundColor: 'rgb(255, 99, 132)'
    }]
  };

  const chart = new Chart(ctx, {
    type: 'bubble',
    data: data,
    options: {
      // So we can set the height with css.
      // maintainAspectRatio: false,
      responsive: true,
      scales: {
        x: {
          type: 'time',
          // time: {
          //   displayFormats: {
          //     quarter: 'MMM YYYY'
          //   }
          // }
          position: 'top',
          ticks: {
            padding: 15,
          },
        },
        y: {
          // display: false,
          ticks: {
            padding: 25,
            callback: function (value) {
              if (value in yAxisLabelsLookup) {
                const label = yAxisLabelsLookup[value].label;
                const color = yAxisLabelsLookup[value].color;
                return `<span style="color: ${color};">${label}</span>`;
              } else {
                // Return the default numeric value if no custom label is found
                return value;
              }
              // if (value in dateLookupMap) {
              //   return dateLookupMap[value]
              // } else {
              //   return ''
              // }
            }
          }
        },
      }
    }
  });

2

Answers


  1. chart.js uses canvas to render charts; you can’t return html to format stuff inside the chart.
    All available options
    are to be set through the configuration object.

    Some options are scriptable,
    which means that the value can be a function, that will be called only when the option is needed and
    should return the actual value of the option based on the context, in a similar way to what callback does for
    tick labels text.

    The tick label color can be set through options.scales.y.ticks.color, programmatically if needed since it is
    scriptable. Similarly, you may use options.scales.y.ticks.font to set other visual properties of labels like size or weight.

    Your code could thus be changed to:

       options: {
           // .... other options
           scales: {
             // x ....
              y: {
                  ticks: {
                     callback: function (value) {
                        if (value in yAxisLabelsLookup) {
                           return yAxisLabelsLookup[value].label;
                        } else {
                           return value;
                        }
                     },
                     color: function({tick: {value}}){
                        if (value in yAxisLabelsLookup){
                           return yAxisLabelsLookup[value].color;
                        }
                     }
                  }
              }
           }
       }
    

    Snippet:

    const yAxisLabelsLookup = {
        0: {
            label: '2024-01-01',
            color: 'red',
        },
        1: {
            label: '2024-01-02',
            color: 'blue',
        },
        2: {
            label: '2024-01-03',
            color: 'green',
        },
        3: {
            label: '2024-01-04',
            color: 'yellow',
        },
    }
    
    const data = {
        datasets: [{
            label: 'First Dataset',
            data: [
                {
                    x: 20,
                    y: 0,
                    r: 15
                }, {
                    x: 40,
                    y: 0,
                    r: 10
                },
                {
                    x: 20,
                    y: 1,
                    r: 10
                },
                {
                    x: 40,
                    y: 1,
                    r: 10
                },
                {
                    x: 25,
                    y: 2,
                    r: 10
                },
                {
                    x: 35,
                    y: 2,
                    r: 10
                },
            ],
            backgroundColor: 'rgb(255, 99, 132)'
        }]
    };
    const chart = new Chart('chart-container', {
        type: 'bubble',
        data: data,
        options: {
            // So we can set the height with css.
            // maintainAspectRatio: false,
            responsive: true,
            scales: {
                x: {
                    type: 'time',
                    // time: {
                    //   displayFormats: {
                    //     quarter: 'MMM YYYY'
                    //   }
                    // }
                    position: 'top',
                    ticks: {
                        padding: 15,
                    },
                },
                y: {
                    ticks: {
                        padding: 25,
                        callback: function (value) {
                            if (value in yAxisLabelsLookup) {
                                return yAxisLabelsLookup[value].label;
                            } else {
                                return value;
                            }
                        },
                        color: function({tick: {value}}){
                            if (value in yAxisLabelsLookup){
                                return yAxisLabelsLookup[value].color
                            }
                        }
                    }
                },
            }
        }
    });
    <div style="max-height: 400px">
        <canvas id="chart-container"></canvas>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.umd.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
    Login or Signup to reply.
  2. I added just one example about the customizing label of the chart. I added one link, you can follow.
    https://www.chartjs.org/docs/latest/samples/scale-options/ticks.html

    const DATA_COUNT = 12;
    const NUMBER_CFG = {count: DATA_COUNT, min: 0, max: 100};
    const data = {
      labels: [['June', '2015'], 'July', 'August', 'September', 'October', 'November', 'December', ['January', '2016'], 'February', 'March', 'April', 'May'],
      datasets: [
        {
          label: 'Dataset 1',
          data: Utils.numbers(NUMBER_CFG),
          fill: false,
          borderColor: Utils.CHART_COLORS.red,
          backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
        },
        {
          label: 'Dataset 2',
          data: Utils.numbers(NUMBER_CFG),
          fill: false,
          borderColor: Utils.CHART_COLORS.blue,
          backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
        }
      ]
    };
        const config = {
          type: 'line',
          data: data,
          options: {
            responsive: true,
            plugins: {
              title: {
                display: true,
                text: 'Chart with Tick Configuration'
              }
            },
            scales: {
              x: {
                ticks: {
                  // For a category axis, the val is the index so the lookup via getLabelForValue is needed
                  callback: function(val, index) {
                    // Hide every 2nd tick label
                    return index % 2 === 0 ? this.getLabelForValue(val) : '';
                  },
                  color: 'red',
                }
              }
            }
          },
        };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search