chart.js – Failed to display data correctly for charts of more than one item in Chartjs

/*-------------- Color --------------*/
const ColorBac = ["rgba(255, 0, 50, 0.2)", "rgba(27, 68, 128, 0.2)", "rgba(246, 162, 30, 0.2)", "rgba(1, 49, 32, 0.2)"];
const Colorborder = ["rgba(255, 0, 50, 0.6)", "rgba(27, 68, 128, 0.6)", "rgba(246, 162, 30, 0.6)", "rgba(1, 49, 32, 0.6)"];


let getColor = function getColor(i) {
  var obj = {
    background: ColorBac[i],
    border: Colorborder[i],
  };
  return obj;
}
/*-------------- Labels And Date --------------*/
function Get_Labels_Date(apiData, type="line") {
  /*console.log('show apiData: ' + apiData);*/
  var fields = Object.keys(apiData[0]).sort().reverse();
  /*console.log('show fields: ' + fields);*/
  var serieslabels = fields.slice(1, fields.length);
  /*console.log('show serieslabels: ' + serieslabels);*/

  let series = [];
  let labels = [];

  serieslabels.forEach((item, index) => {
    series.push({
      label: item,
      data: [],
      backgroundColor: getColor(index).background,
      borderColor: getColor(index).border,
      borderWidth: 2,
      pointStyle: 'rectRot',
      fill: false,
    });
  })

  apiData.reduce((acc, value) => {
    serieslabels.forEach(item => {
      var seri = series.find(element => element.label == item);
      seri.data.push(value[item]);
    })
    labels.push(value[fields[0]]);

    return acc
  }, []);

  // Define desired object
  var obj = {
    series: series.sort().reverse(),
    labels: labels.sort(),
  };
  /*console.log('series: ' + series.sort().reverse());
 console.log('Sort labels: ' + labels.sort());*/
 
  // Return it
  return obj;
}

/*-------------- Labels And Date --------------*/
var ctx = 'lineChart';

function GetChart() {
  Api = api('ChartDashbord');
  var Labels_Date = Get_Labels_Date(Api.ExData);

  if (typeof(myChart) != "undefined")
    myChart.destroy();

  var myChart = new Chart(ctx, {
    type: 'line',
    data: {
      labels: Labels_Date.labels,
      datasets: Labels_Date.series
    },
    options: {
      maintainAspectRatio: false,
      responsive: true,
      interaction: {
        mode: 'index',
        intersect: false,
      },
      stacked: false,
      plugins: {
        legend: {
          labels: {
            usePointStyle: true,
          },
          position: 'bottom',
        },
        animation: {
          onComplete: () => {
            delayed = true;
          },
          delay: (context) => {
            let delay = 0;
            if (context.type === 'data' && context.mode === 'default' && !delayed) {
              delay = context.dataIndex * 30 + context.datasetIndex * 10;
            }
            return delay;
          },
        },
        title: {
          display: true,
        }
      },
      scales: {
        y: {
          type: 'linear',
          display: true,
          position: 'left',
          stacked: true,
          ticks: {
            font: {
              family: 'iransansx', // Your font family
              size: 10,
            },
          },

        },
        x: {
          ticks: {
            font: {
              family: 'iransansx', // Your font family
              size: 10,
            },
          },
        },
      },
    },
  });
}

GetChart();

/*------- defaults Chart ---------*/
Chart.defaults.font.size = 11;
Chart.defaults.font.family = 'iransansx';


const getOrCreateLegendList = (chart, id) => {
  const legendContainer = document.getElementById(id);
  let listContainer = legendContainer.querySelector('ul');

  if (!listContainer) {
    listContainer = document.createElement('ul');
    listContainer.style.display = 'flex';
    listContainer.style.flexDirection = 'row';
    listContainer.style.margin = 0;
    listContainer.style.padding = 0;
    legendContainer.appendChild(listContainer);
  }

  return listContainer;
};

const htmlLegendPlugin = {
  id: 'htmlLegend',
  afterUpdate(chart, args, options) {
    const ul = getOrCreateLegendList(chart, options.containerID);

    // Remove old legend items
    while (ul.firstChild) {
      ul.firstChild.remove();
    }

    // Reuse the built-in legendItems generator
    const items = chart.options.plugins.legend.labels.generateLabels(chart);

    items.forEach(item => {
      const li = document.createElement('li');
      li.style.alignItems="center";
      li.style.cursor="pointer";
      li.style.display = 'flex';
      li.style.flexDirection = 'row';
      li.style.marginLeft="10px";

      li.onclick = () => {
        const {
          type
        } = chart.config;
        if (type === 'pie' || type === 'doughnut') {
          // Pie and doughnut charts only have a single dataset and visibility is per item
          chart.toggleDataVisibility(item.index);
        } else {
          chart.setDatasetVisibility(item.datasetIndex, !chart.isDatasetVisible(item.datasetIndex));
        }
        chart.update();
      };

      // Color box
      const boxSpan = document.createElement('span');
      boxSpan.style.background = item.fillStyle;
      boxSpan.style.borderColor = item.strokeStyle;
      boxSpan.style.borderWidth = item.lineWidth + 'px';
      boxSpan.style.display = 'inline-block';
      boxSpan.style.height="20px";
      boxSpan.style.marginRight="10px";
      boxSpan.style.width="20px";

      // Text
      const textContainer = document.createElement('p');
      textContainer.style.color = item.fontColor;
      textContainer.style.margin = 0;
      textContainer.style.padding = 0;
      textContainer.style.textDecoration = item.hidden ? 'line-through' : '';

      const text = document.createTextNode(item.text);
      textContainer.appendChild(text);

      li.appendChild(boxSpan);
      li.appendChild(textContainer);
      ul.appendChild(li);
    });
  }
};

/*-------- sum for data ---------*/
function SumData(tooltipItems) {
  let sum = 0;
  tooltipItems.forEach(function(tooltipItem) {
    sum += tooltipItem.parsed.y;
  });
  return 'جمع : ' + sum;
}

/*-------Randomize---------*/
const actions = [{
  name: 'Randomize',
  handler(chart) {
    chart.data.datasets.forEach(dataset => {
      dataset.data = Utils.numbers({
        count: chart.data.labels.length,
      });
    });
    chart.update();
  }
}, ];

/*-------resize---------*/
window.addEventListener('beforeprint', () => {
  myChart.resize(100, 100);
});

window.addEventListener('afterprint', () => {
  myChart.resize();
});
.tile {
  width: 100%;
  height: 100%;
}

#lineChart {
  max-height: 12vw;
  width: 100%;
}

@media screen  {
  #lineChart {
    max-width: 100%;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<div class="tile">
  <canvas id="lineChart"></canvas>
</div>

Leave a Comment