Chartjs-JS Chart: do not merge duplicate x axis labels

0👍

Such data is typically rendered in a scatter chart. I believe however that x and y values of your data points need to be of number format. Therefore you need to process your data prior to use it in your chart.

Then you must define a xAxes.ticks.callback function and a tooltips.callbacks.label function in order to render the original data.

Please have a look at the runnable code snippet below.

const data = [
  {x: "V", y: 0.72},
  {x: "A", y: 0.59},
  {x: "F", y: 0.59},
  {x: "T", y: 0.65},
  {x: "E", y: 0.59},
  {x: "K", y: 0.63},
  {x: "Q", y: 0.67},
  {x: "D", y: 0.6},
  {x: "A", y: 0.58},
  {x: "L", y: 0.7},
  {x: "V", y: 0.77},
  {x: "S", y: 0.54},
  {x: "S", y: 0.53},
  {x: "S", y: 0.67},
  {x: "F", y: 0.69},
  {x: "E", y: 0.54},
  {x: "A", y: 0.5},
  {x: "F", y: 0.52},
  {x: "K", y: 0.71},
  {x: "A", y: 0.84},
  {x: "N", y: 0.89},
  {x: "I", y: 0.91}
];
const xLabels = data.reduce((acc, v) => acc.includes(v.x) ? acc : acc.concat(v.x), []).sort();

new Chart('myChart', {
  type: 'scatter',
  data: {
    datasets: [{
      label: 'My Dataset',
      borderColor: 'green',
      backgroundColor: 'lightblue',
      data: data.map(o => ({ x: xLabels.indexOf(o.x), y: o.y }))
    }]
  },
  options: {
    responsive: true,
    legend: {
      display: false
    },
    scales: {
      xAxes: [{
        offset: true,
        ticks: {          
          stepSize: 1,
          callback: v => xLabels[v]
        }
      }]
    },
    tooltips: {
      callbacks: {
        label: (tooltipItem, data) => xLabels[tooltipItem.xLabel] + ': ' + tooltipItem.value
      }
    }  
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" height="100"></canvas>

0👍

I realize that it’s been a long time since the question was posted and there’ve been a lot of changes in chart.js in the meanwhile, but this was post I was sent to by google, while having the same issue.

So, with chart.js 4.1.2, a solution to get rid of the merged duplicate labels is to explicitly set the labels properties of the data. I suppose that’s the way it is done by most from the get go. Still, if you don’t set data.labels, but get the labels from the dataset(s) (as x property or through parsing.xAxisKey) option, you’ll get the merging feature.

The OP case without merging (fiddle)

const data = [
    {x: "V", y: 0.72},
    {x: "A", y: 0.59},
    {x: "F", y: 0.59},
    {x: "T", y: 0.65},
    {x: "E", y: 0.59},
    {x: "K", y: 0.63},
    {x: "Q", y: 0.67},
    {x: "D", y: 0.6},
    {x: "A", y: 0.58},
    {x: "L", y: 0.7},
    {x: "V", y: 0.77},
    {x: "S", y: 0.54},
    {x: "S", y: 0.53},
    {x: "S", y: 0.67},
    {x: "F", y: 0.69},
    {x: "E", y: 0.54},
    {x: "A", y: 0.5},
    {x: "F", y: 0.52},
    {x: "K", y: 0.71},
    {x: "A", y: 0.84},
    {x: "N", y: 0.89},
    {x: "I", y: 0.91}
];

const config = {
    type: 'line',
    
    data: {
        labels: data.map(o=>o.x),
        datasets:[{
            data: data.map(o=>o.y)
        }]
    },
    
    options: {
        fill: true,
        plugins:{
            legend:{
                display: false
            }
        }
    }
};

new Chart(document.querySelector('#line-chart'), config);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.1.2/chart.umd.js"
        integrity="sha512-t41WshQCxr9T3SWH3DBZoDnAT9gfVLtQS+NKO60fdAwScoB37rXtdxT/oKe986G0BFnP4mtGzXxuYpHrMoMJLA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>


<div id="line-chart-container" style="height:300px">
<canvas id="line-chart"></canvas>
</div>

And in case that’s just you always did it and are wondering if the merging is still happening, yes it is – just delete data.labels and set data.datasets:[{data}] – see the fiddle. This actually is a very useful and natural feature, if the identical labels are consecutive – it just stacks vertically the different y values that correspond to the same x instead of spreading them horizontally. Still, if there is (or when there will be) a simple option to disable this feature, this is a good place to let us know.

Leave a comment