[Chartjs]-Controlling x-axis ticks on time series chart with chart.js

1👍

TLDR – use stepSize: 15; time axes use the concept of unit, that can be specified by the user as options.time.unit, see the docs. If not specified, the unit is computed from the data; in your case it’s "second", but it’s better to set it explicitly if you’re using it – and you are, since the stepSize is computed in units not milliseconds.

const config = {
  type: "line",
  data: {
    datasets: [{
      label: "20070480",
      borderColor: "#36A2EB",
      backgroundColor: "#9BD0F5",
      data: [
        [1681792679186, 1096],
        [1681792680186, 1147],
        [1681792681187, 1056],
        [1681792682187, 1100],
        [1681792683188, 1104],
        [1681792684188, 1158],
        [1681792685188, "1124.6319921491659"],
        [1681792686189, "1111.2244897959183"],
        [1681792687189, 1055.937193326791],
        [1681792688189, 1126.530612244898],
        [1681792689190, 1083.415112855741],
        [1681792690190, 1160],
        [1681792691190, "1068.3673469387754"],
        [1681792692191, "1094.2100098135427"],
        [1681792693191, 1159],
        [1681792694191, 1092],
        [1681792695192, 1115],
        [1681792696192, 1083],
        [1681792697192, 1146],
        [1681792698193, 1105],
        [1681792699193, 1085],
        [1681792700193, 1133],
        [1681792701194, 1101],
        [1681792702194, 1107],
        [1681792703195, 1074],
        [1681792704195, 1094],
        [1681792705195, 1126],
        [1681792706196, 1101],
        [1681792707196, 1065],
        [1681792708196, 1108],
        [1681792709197, 1125],
        [1681792710197, 1059],
        [1681792711198, 1186],
        [1681792712198, 1087],
        [1681792713198, 1117],
        [1681792714199, 1062],
        [1681792715199, 1118],
        [1681792716199, 1172],
        [1681792717200, 1148],
        [1681792718200, 1106],
        [1681792719201, 1061],
        [1681792720201, 1139],
        [1681792721201, 1114],
        [1681792722202, 1117],
        [1681792723202, 1123],
        [1681792724202, 1119],
        [1681792725203, 1119],
        [1681792726203, 1175],
        [1681792727204, 1089],
        [1681792728204, 1132],
        [1681792729204, "1130.5201177625124"],
        [1681792730205, "1161.2244897959183"],
        [1681792731205, 1085],
        [1681792732205, "1133.4641805691856"],
        [1681792733206, 1139],
        [1681792734206, 1147],
        [1681792735207, 1109],
        [1681792736207, "1152.0408163265306"],
        [1681792737207, "1087.3405299313054"],
        [1681792738208, 1145],
        [1681792739208, 1163],
        [1681792740208, 1061],
        [1681792741209, "1151.0204081632653"],
        [1681792742209, "1076.5456329735036"],
        [1681792743209, 1048],
        [1681792744210, 1117],
        [1681792745210, 1105],
        [1681792746210, 1103],
        [1681792747211, 1122],
        [1681792748211, 1105],
        [1681792749212, 1095],
        [1681792750212, 1141],
        [1681792751212, 1138],
        [1681792752212, 1160],
        [1681792753213, 1106],
        [1681792754213, 1077],
        [1681792755213, 1087],
        [1681792756214, 1138],
        [1681792757214, 1103],
        [1681792758215, 1114],
        [1681792759215, 1130],
        [1681792760215, 1128],
        [1681792761216, 1100],
        [1681792762216, 1068],
        [1681792763216, 1143],
        [1681792764217, 1142],
        [1681792765217, 1118],
        [1681792766218, 1089],
        [1681792767218, 1122],
        [1681792768218, 1122],
        [1681792769218, 1080],
        [1681792770219, 1182],
        [1681792771219, 1162],
        [1681792772220, 1100],
        [1681792773220, 1181],
        [1681792774220, 1103],
        [1681792775221, 1116],
        [1681792776221, 1095],
        [1681792777221, "1047.0588235294117"],
        [1681792778222, "1166.4964249233913"],
        [1681792779222, "1087.2549019607843"],
        [1681792780223, 1125],
        [1681792781223, 1060],
        [1681792782223, 1111],
        [1681792783224, 1057],
        [1681792784224, 1074],
        [1681792785224, "1141.9816138917263"],
        [1681792786225, 1104],
        [1681792787225, "1112.7450980392157"],
        [1681792788226, 1148],
        [1681792789226, 1146],
        [1681792790226, 1098],
        [1681792791227, 1164],
        [1681792792227, 1120],
        [1681792793227, 1144],
        [1681792794228, 1133],
        [1681792795228, 1163],
        [1681792796229, 1101],
        [1681792797229, 1108],
        [1681792798229, 1105]
      ]
    }]
  },

  options: {
    animation: false,
    scales: {
      x: {
        title: {
          display: true,
          text: "Time (UTC)",
          font: {
            //size: 30,
            weight: "bold"
          }
        },
        type: "time",
        time: {
          //unit: "millisecond", // try this with stepsize 15000
          unit: "second" // that's the computed unit for this data
        },
        //beforeBuildTicks: function(ax){
        //   console.log(ax._unit);
        //},
        ticks: {
          font: {
            //size: 20,
            weight: "bold"
          },

          minRotation: 45,
          //count: 3,
          stepSize: 15,
          // autoSkip: false
        },
        min: 1681792710000,
        max: 1681792740000
      },
      y: {
        title: {
          display: true,
          text: "Count Rate",
          font: {
            //size: 30,
            weight: "bold"
          }
        },
        ticks: {
          font: {
           // size: 15
          }
        }
      }
    }
  }
};

new Chart(document.querySelector('#myChart'), config);
<div class="chart-container" style="width: 90vw">
    <canvas id="myChart"></canvas>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.3.0/chart.umd.min.js" integrity="sha512-TJ7U6JRJx5IpyvvO9atNnBzwJIoZDaQnQhb0Wmw32Rj5BQHAmJG16WzaJbDns2Wk5VG6gMt4MytZApZG47rCdg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns@3.0.0/dist/chartjs-adapter-date-fns.bundle.min.js"></script>

The same in this fiddle

Now, the unit is relevant in the way the tick marks are rounded. In the code above I put under comments the variant unit: "millisecond"; you may use that and then you have to set stepSize: 15000 to get the three ticks, but then the text will be 7:38:30.000.

So, I guess that’s the solution the authors of chart.js found to give a consistent approach to all things time-related, by replacing the hard javascript time unit of 1ms, with the more abstract unit that gives more control to the user. Note: don’t experiment with unit: "minute" and stepSize: 0.25 – it gets into a nasty infinite loop 🙂

The variant where you set different tick formats for different units can be seen as "preventive": don’t explicitly set the unit, let the code choose the optimal one from the data, and if it happens to be second use this format, and if it happens to be minute, use the other one, etc. It also makes sense with dynamic data, that comes from an external source, so the programmer might not know a priori what the appropriate unit will be.

Leave a comment