iwonz
iwonz

Reputation: 421

How to make inner paddings from canvas in chart.js?

I use https://chartjs-plugin-datalabels.netlify.com/ for drawing datalabels. I tried to find issue and found (https://github.com/chartjs/chartjs-plugin-datalabels/issues/88) but this solution doesn't suit me. As you can see, if i add layout paddings it affects height of gridlines. I need something like inner paddings.

const ITEMS_COUNT = 25;
const MIN = -8000;
const MAX = 8000;

const defaultDatasetOptions = {
  pointRadius: 0,
  pointHoverRadius: 0,
  pointBorderWidth: 0,
  pointHoverBorderWidth: 0,
  pointHitRadius: 10,
  borderWidth: 0
};

const datalabels = {
    color: 'black',
    anchor: context => {
      const index = context.dataIndex;
      const value = context.dataset.data[index];

      return value < 0 ? 'start' : 'end';
    },
    align: context => {
      const index = context.dataIndex;
      const value = context.dataset.data[index];

      return value < 0 ? 'end' : 'start';
    },
    display: getDataLabelDisplay,
    formatter: value => value.toLocaleString(),
    offset: -20
};

const data = {
  labels: _.range(1, ITEMS_COUNT),
  datasets: [
    {
      ...defaultDatasetOptions,
      label: 'Series 1',
      data: Array.from(Array(ITEMS_COUNT), () => _.random(MIN, MAX)),
      backgroundColor: 'rgba(255, 0, 0, .3)'
    },
    {
      ...defaultDatasetOptions,
      label: 'Series 2',
      data: Array.from(Array(ITEMS_COUNT), () => _.random(MIN, MAX)),
      backgroundColor: 'rgba(0, 255, 0, .3)'
    },
    {
      ...defaultDatasetOptions,
      label: 'Series 3',
      data: Array.from(Array(ITEMS_COUNT), () => _.random(MIN, MAX)),
      backgroundColor: 'rgba(0, 0, 255, .3)'
    }
  ]
};

const options = {
  legend: {
    display: false
  },
  scales: {
    xAxes: [
      {
        type: 'category',
        gridLines: {
          offsetGridLines: true,
          color: 'orange',
          tickMarkLength: 0,
          drawBorder: false
        },
        ticks: {
          display: false,
          maxRotation: 0,
          beginAtZero: true,
          autoSkip: false,
          stepSize: 1
        },
        offset: true
      }
    ],
    yAxes: [{ display: false }]
  },
  tooltips: {
    mode: 'index',
    intersect: false
  },
  hover: {
    mode: 'index',
    intersect: false
  },
  layout: {
    padding: {
      top: 20,
      bottom: 20
    }
  },
  plugins: {
    datalabels
  }
};

new Chart(document.querySelector('canvas'), {
  type: 'line',
  data,
  options
});

// You can skip this function
function getDataLabelDisplay(context) {
    const index = context.dataIndex;
    const value = context.dataset.data[index];

    if (value === 0) {
      return false;
    }

    const minVisibleIndex = 0;
    const maxVisibleIndex = _.size(context.chart.data.labels) - 1;

    const dataInViewport = _.flatten(
      _.map(context.chart.data.datasets, dataset => {
        const dataInViewPort = _.slice(dataset.data, minVisibleIndex, maxVisibleIndex + 1);

        return _.map(dataInViewPort, (value, index) => {
          return {
            index: minVisibleIndex + index,
            value
          };
        });
      })
    );

    const minData = _.minBy(dataInViewport, 'value');
    const minDataValue = _.get(minData, 'value');

    const maxData = _.maxBy(dataInViewport, 'value');
    const maxDataValue = _.get(maxData, 'value');

    const allMinData = _.filter(dataInViewport, data => data.value === minDataValue);
    const allMaxData = _.filter(dataInViewport, data => data.value === maxDataValue);

    const isFoundedInMinValues = Boolean(_.find(allMinData, ['index', index]));
    const isFoundedInMaxValues = Boolean(_.find(allMaxData, ['index', index]));

    return value < 0 ? isFoundedInMinValues && value === minDataValue : isFoundedInMaxValues && value === maxDataValue;
  }
canvas { border: 1px solid black; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels"></script>

<canvas></canvas>

Upvotes: 3

Views: 124

Answers (1)

rogerct
rogerct

Reputation: 29

I can't prove it right now but sometimes the problem is on the version of chart.js that you are using. Try to use the 2.7.0

Upvotes: 1

Related Questions