[Chartjs]-Prevent y-axis labels from being cut off

2👍

The sampleSize property in your y axis config is the culprit, since you put it to 1 it only looks at the first tick for the length that it can use. But other data in your array is way larger so it wont fit. Removing this property or making it a bigger number so it would sample more ticks will resolve your behaviour (removing will give most consistent results).

const optionsTotali = {
  maintainAspectRatio: false,
  responsive: true,
  plugins: {
    legend: {
      display: false
    },
    tooltip: {
      displayColors: false,
      mode: "index",
      intersect: 0,
      callbacks: {
        label: function(context) {
          return "€" + context.parsed.y.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,').replace(/[,.]/g, m => (m === ',' ? '.' : ','));
        }
      }
    },
  },
  scales: {
    y: {
      grid: {
        display: false
      },
      ticks: {
        min: 0,
        beginAtZero: true,
        callback: function(value, index, values) {
          return "€" + value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
        }
      }
    }
  }
};

const ctx = document.getElementById("chartTotali").getContext('2d');
const chartTotali = new Chart(ctx, {
  type: 'line',
  data: {
    labels: [
      "08:00",
      "09:00",
      "10:00",
      "11:00",
      "12:00",
      "13:00",
      "14:00",
      "15:00",
      "16:00",
      "17:00",
      "18:00",
      "19:00",
      "20:00"
    ],
    datasets: [{
      label: "Totale €",
      fill: true,
      backgroundColor: '#0084ff',
      borderColor: '#0084ff',
      borderWidth: 2,
      pointBackgroundColor: '#0084ff',
      data: [
        "17089.36",
        "394279.52",
        "514863.02",
        "540198.74",
        "379222.06",
        "8793.42",
        "79.58",
        "116379.41",
        "444580.43",
        "506663.36",
        "457947.28",
        "138158.94",
        "398.46"
      ],
    }]
  },
  options: optionsTotali
});
.card-chart {
  overflow: hidden;
}

.card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  word-wrap: break-word;
  background-color: #fff;
  background-clip: border-box;
  border: 0.0625rem solid rgba(34, 42, 66, .05);
  border-radius: 0.2857rem;
}

.card {
  background: #27293d;
  border: 0;
  position: relative;
  width: 100%;
  margin-bottom: 30px;
  box-shadow: 0 1px 20px 0 rgb(0 0 0 / 10%);
}

.card .card-body {
  padding: 15px 15px 15px 15px;
}

.card-body {
  flex: 1 1 auto;
  padding: 1.5rem;
}

.card-chart .chart-area {
  height: 220px;
  width: calc(100% + 30px);
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.7.0/dist/chart.min.js"></script>
<div class="card card-chart">
  <div class="card-header">
    <div class="row">
      <div class="col-sm-6 text-left">
        <h5 class="card-category">Totale vendite</h5>
        <h2 class="card-title">Totali</h2>
      </div>
    </div>
  </div>
  <div class="card-body">
    <div class="chart-area">
      <canvas id="chartTotali" width="1563" height="220" style="display: block; box-sizing: border-box; height: 220px; width: 1563px;"></canvas>
    </div>
  </div>
</div>

2👍

You can handle it with the sampleSize: x, property. You can removed then the y-axis will show correctly. Many thank to @LeeLenalee!

const optionsTotali = {
  maintainAspectRatio: false,
  responsive: true,
  plugins: {
    legend: {
      display: false
    },
    tooltip: {
      displayColors: false,
      mode: "index",
      intersect: 0,
      callbacks: {
        label: function(context) {
          return "€" + context.parsed.y.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,').replace(/[,.]/g, m => (m === ',' ? '.' : ','));
        }
      }
    },
  },
  scales: {
    y: {
      grid: {
        display: false
      },
      ticks: {
        min: 0,
        beginAtZero: true,
        callback: function(value, index, values) {
          return "€" + value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
        }
      }
    }
  }
};

const ctx = document.getElementById("chartTotali").getContext('2d');
const chartTotali = new Chart(ctx, {
  type: 'line',
  data: {
    labels: [
      "08:00",
      "09:00",
      "10:00",
      "11:00",
      "12:00",
      "13:00",
      "14:00",
      "15:00",
      "16:00",
      "17:00",
      "18:00",
      "19:00",
      "20:00"
    ],
    datasets: [{
      label: "Totale €",
      fill: true,
      backgroundColor: '#0084ff',
      borderColor: '#0084ff',
      borderWidth: 2,
      pointBackgroundColor: '#0084ff',
      data: [
        "17089.36",
        "394279.52",
        "514863.02",
        "540198.74",
        "379222.06",
        "8793.42",
        "79.58",
        "116379.41",
        "444580.43",
        "506663.36",
        "457947.28",
        "138158.94",
        "398.46"
      ],
    }]
  },
  options: optionsTotali
});
.card-chart {
  overflow: hidden;
}

.card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  word-wrap: break-word;
  background-color: #fff;
  background-clip: border-box;
  border: 0.0625rem solid rgba(34, 42, 66, .05);
  border-radius: 0.2857rem;
}

.card {
  background: #27293d;
  border: 0;
  position: relative;
  width: 100%;
  margin-bottom: 30px;
  box-shadow: 0 1px 20px 0 rgb(0 0 0 / 10%);
}

.card .card-body {
  padding: 15px 15px 15px 15px;
}

.card-body {
  flex: 1 1 auto;
  padding: 1.5rem;
  background: ;
}

.card-chart .chart-area {
  height: 220px;
  width: calc(100% + 30px);
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.7.0/dist/chart.min.js"></script>
<div class="card card-chart">
  <div class="card-header">
    <div class="row">
      <div class="col-sm-6 text-left">
        <h5 class="card-category">Totale vendite</h5>
        <h2 class="card-title">Totali</h2>
      </div>
    </div>
  </div>
  <div class="card-body">
    <div class="chart-area">
      <canvas id="chartTotali"  style=""></canvas>
    </div>
  </div>
</div>

0👍

After testing your code, the problem seems to come from this part :

    callback: function(value, index, values) {
      return "€" + value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
    }

My guess is : since you change the labels in an async callback, chart.js doesn’t know which width to aply anymore and goes with the width of the first label…

You could resolve this by setting the width like this :

  afterFit: function(scaleInstance) {
    scaleInstance.width = 100; // sets the width to 100px
  }

Source here : How to set fixed width for labels in chartjs

-1👍

You can use the sampleSize property

Leave a comment