13

I have a chartjs linechart diagram to show the sales of different products on a range of dates. The user can select a date range (for example from 2015-12-01 to 2015-12-10) to view the sales per day and thats fine and its working.

But if the user selects only one day (range from for example 2015-12-01 to 2015-12-01), he gets the correct diagram, but it doesn't look good:

enter image description here

As you can see, the points are stick to the y-axis. Is there a possibility, to center the points on the diagram?

Thats how it should look like:

enter image description here

bernhardh
  • 3,137
  • 10
  • 42
  • 77

4 Answers4

28

Instead of hardcoding the labels and values with blank parameters, use the offset property.

const options = {
  scales: {
    x: {
      offset: true
    }
  }
}

Documentation: https://www.chartjs.org/docs/latest/axes/cartesian/linear.html#common-options-to-all-cartesian-axes

ndequeker
  • 7,932
  • 7
  • 61
  • 93
Manhar Sapra
  • 659
  • 1
  • 11
  • 21
9

You can check the length of your labels (or data) arrays and add dummy non-renderable points to the left and right by using empty string labels and null value, like so

var chartData = {
  labels: ['', "A", ''],
  datasets: [
    {
      fillColor: "rgba(255, 52, 21, 0.2)",
      pointColor: "#da3e2f",
      strokeColor: "#da3e2f",
      data: [null, 20, null]
    },
    {
      fillColor: "rgba(52, 21, 255, 0.2)",
      strokeColor: "#1C57A8",
      pointColor: "#1C57A8",
      data: [null, 30, null]
    },
  ]
}

Fiddle - https://jsfiddle.net/pf24vg16/

potatopeelings
  • 40,709
  • 7
  • 95
  • 119
  • I don't think you need the nulls and blanks. you just need to make sure the labels and data are arrays i.e. [value] – AGDM May 02 '18 at 18:21
0

Wanted to add to the above answer and say that I got a similar effect on a time series scatter plot using this:

if (values.length === 1) {
        const arrCopy = Object.assign({}, values);
        values.unshift({x: arrCopy[0].x - 86400000, y: null});
        values.push({x: arrCopy[0].x + 2 * 86400000, y: null});
}

That only handles for a single point, however. To add in functionality for multiple points, I did the following:

const whether = (array) => {
    const len = array.length;
    let isSame = false;
    for (let i = 1; i < len; i++) {
        if (array[0].x - array[i].x >= 43200000) {
            isSame = false;
            break;
        } else {
            isSame = true;
        }
    }
    return isSame;
}
if (values.length === 1 || whether(arr[0])) {
        const arrCopy = Object.assign({}, values);
        values.unshift({x: arrCopy[0].x - 86400000, y: null});
        values.push({x: arrCopy[0].x + 2 * 86400000, y: null});
}

You might notice I'm just subtracting/adding a day in milliseconds into the x values. To be honest, I was just having the worst of times with moment.js and gave up haha. Hope this helps someone else!

Note: my code has a tolerance of 43200000, or 12 hours, on the time. You could use moment.js to compare days if you have better luck with it than I did tonight :)

Benny Hinrichs
  • 1,393
  • 9
  • 17
0

For your specific problem, try to modify the options->scales->xAxes option like so:

options: {
      title: {
         display: true,
         text: 'mytitle1'
      },
      scales: {
         xAxes: [{
            type: 'linear',
            ticks: {
               suggestedMin: 0,
               suggestedMax: (11.12*2),
               stepSize: 1 //interval between ticks
            }
         }],

More info at: Chart JS: Ignoring x values and putting point data on first available labels

TomoMiha
  • 1,218
  • 1
  • 14
  • 12