Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Axis scaling: Time ignores bound option and max option. #6464

Closed
joeyhub opened this issue Aug 13, 2019 · 11 comments
Closed

Axis scaling: Time ignores bound option and max option. #6464

joeyhub opened this issue Aug 13, 2019 · 11 comments

Comments

@joeyhub
Copy link

joeyhub commented Aug 13, 2019

When I set bound to fit to the data, it still draws with extra padding to the right of the data.

When I force it with max to fit the data, it still adds padding to the right to draw the label rather than not drawing the label or culling it.

@benmccann
Copy link
Contributor

@joeyhub can you add an interactive example on plukr, codepen (e.g. https://codepen.io/pen?template=JXVYzq), or a similar site?

@joeyhub
Copy link
Author

joeyhub commented Aug 14, 2019

I'm seeing a lot of things that are a bit off.

The fiddle doesn't have moment.

var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
    type: 'line',
    data: {
        datasets: [{
            data: [{x: new Date(0), y: 123}, {x: new Date((86400 - 3600) * 1000), y: 321}]
        }, {
            data: [{x: new Date(0), y: 12}, {x: new Date((86400 - 3600) * 1000), y: 32}]
        }]
    },
    options: {
        scales: {
            xAxes: [{
                display: true,
                type: 'time',
                time: {unitStepSize: 1, unit: 'day'},
                ticks: {
                    display: true
                }
            }]
        }
    }
});

There's also some mess up with the timezones. Ticks are drawn to UTC but points to GMT / DST. The documentation doesn't mention TZ but in any event if not specified it should be the same everywhere! I'm guessing you're using toLocaleString but just pulling the MS for the points without applying the offset. I'd hazard a guess you can get localstring to work as though UTC by subtracting the offset (test what happens with new Date(-3600000)). What this means is that by default it appears to be erroneous (mismatched, phase shifted).

In my graph in the legacy code, it's not drawing the label at an angle, I have no idea why as maxRotation is left to default. Maybe it's some weirdness competing with the yAxes for height? It seems like the kind of thing that is undefined behaviour and you have to fiddle until it works. Though it makes no sense that it jumps around when the yAxes is constant.

In the fiddle, changing source to data causes rotation! It appears to be arbitrary. It also seems to snap it to UTC? Or not, it's just snapping to points then flooring? This produces double printed points of the same day that overlap if you shift them an hour apart!

When it orients horizontally in my legacy case, it prints extra padding at the end.

Angular chart 1.1.1 -> Chart.js 2.3.0.

@joeyhub
Copy link
Author

joeyhub commented Aug 14, 2019

image

For me in my legacy example, the grid lines are drawing all the way up to the bounding box defined by labels where as in the fiddle about they truncate / are cropped to the date bounds rather than the label overflow.

In my legacy case they also protrude ever so slightly because of the TZ error. There's another oddity that when replicated in the fiddle the protrusion doesn't result in grid lines being drawn, I'm guessing someone has mucked around with the global defaults in my case such the gridlines snap to the parent box though I don't see any obvious settings that would do that being changed.

For me gridlines extend all the way to the top of 350's bounding box and the right of Jan 11's bounding box.

That looks like a problem with settings, I hope, and not an arbitrary thing like the label orientation. Though I see nothing obvious in the legacy touching any explicit settings directly specifying where to draw gridlines to.

The TZ drift however is a problem under the hood. The only way to fix it would be using custom handling instead making time potentially useless. I don't think it's just superficial, the method of iterating ticks / stepping would need to be addressed as well.

@joeyhub
Copy link
Author

joeyhub commented Aug 14, 2019

https://jtblin.github.io/angular-chart.js/

A lot of the examples here overshoot. Though I don't see anything in their lib that would obviously cause that.

@joeyhub
Copy link
Author

joeyhub commented Aug 14, 2019

This is weird. I copy the chart data from the angular-chart.js example page of one with over draw....

Chart.defaults.global.multiTooltipTemplate = '<%if (datasetLabel){%><%=datasetLabel%>: <%}%><%= value %>';
Chart.defaults.global.tooltips.mode = 'label';
Chart.defaults.global.elements.line.borderWidth = 2;
Chart.defaults.global.elements.rectangle.borderWidth = 2;
Chart.defaults.global.legend.display = false;
Chart.defaults.global.colors = [
    '#97BBCD', // blue
    '#DCDCDC', // light grey
    '#F7464A', // red
    '#46BFBD', // green
    '#FDB45C', // yellow
    '#949FB1', // grey
    '#4D5360'  // dark grey
  ];

var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
  "type": "line",
  "data": {
    "labels": [
      "Monday",
      "Tuesday",
      "Wednesday",
      "Thursday",
      "Friday",
      "Saturday",
      "Sunday"
    ],
    "datasets": [
      {
        "backgroundColor": "rgba(151,187,205,0.2)",
        "pointBackgroundColor": "rgba(151,187,205,1)",
        "pointHoverBackgroundColor": "rgba(151,187,205,0.8)",
        "borderColor": "rgba(151,187,205,1)",
        "pointBorderColor": "#fff",
        "pointHoverBorderColor": "rgba(151,187,205,1)",
        "label": "Series A",
        "data": [
          65,
          59,
          80,
          81,
          56,
          55,
          40
        ],
        "yAxisID": "y-axis-1"
      },
      {
        "backgroundColor": "rgba(220,220,220,0.2)",
        "pointBackgroundColor": "rgba(220,220,220,1)",
        "pointHoverBackgroundColor": "rgba(220,220,220,0.8)",
        "borderColor": "rgba(220,220,220,1)",
        "pointBorderColor": "#fff",
        "pointHoverBorderColor": "rgba(220,220,220,1)",
        "label": "Series B",
        "data": [
          28,
          48,
          40,
          19,
          86,
          27,
          90
        ],
        "yAxisID": "y-axis-2"
      }
    ]
  },
  "options": {
    "responsive": true,
    "colors": [
      "#97BBCD",
      "#DCDCDC",
      "#F7464A",
      "#46BFBD",
      "#FDB45C",
      "#949FB1",
      "#4D5360"
    ],
    "doughnut": {
      "cutoutPercentage": 60
    },
    "bubble": {
      "tooltips": {
        "enabled": false
      }
    },
    "scales": {
      "yAxes": [
        {
          "id": "y-axis-1",
          "type": "linear",
          "display": true,
          "position": "left"
        },
        {
          "id": "y-axis-2",
          "type": "linear",
          "display": true,
          "position": "right"
        }
      ]
    }
  }
});

This is actually the wrong one, I intended to copy the reactive one.

In the fiddle it doesn't show the overdraw at the top.

On the demo page though it does.

@joeyhub
Copy link
Author

joeyhub commented Aug 14, 2019

Half the issue is that angular-chart.js is unmaintained abandonware (that falsely gives the impression of using 2.x latest). I've raised an issue with them to either transfer it or shut it down via a great big notification in their readme, possibly with a redirect to something else that's the same (or back down to bare chart.js).

I'm guessing in some version after 2.3.0 you changed how grid lines are drawn?

benmccann added a commit to chartjs/awesome that referenced this issue Aug 14, 2019
It looks like this plugin is very outdated and causing problems for users. See jtblin/angular-chart.js#712 and chartjs/Chart.js#6464
@benmccann
Copy link
Contributor

I'd highly recommend using 2.8.0. There's too much different that's changed since 2.3.0 to really be able to effectively offer much guidance

@joeyhub
Copy link
Author

joeyhub commented Aug 14, 2019

I have managed to swap out 2.3 for 2.8 which fixes the grid over draw issue now that I know the version bundled with the angular lib wasn't actually the latest.

The only thing remaining is that even with 2.8 there appears to potentially be a discrepancy when using Date with points versus ticks and timezones. I'm not sure if it's the case for use with moment though.

@benmccann
Copy link
Contributor

You could try the luxon adapter. It has timezone support, which moment doesn't by default

@joeyhub
Copy link
Author

joeyhub commented Aug 23, 2019

It seems the issue is here:

#4334

It should be possible to implement UTC versus local, in JS you should normally always have support for both locale and UTC using either native (albeit hacksome) or moment. For others that's an additional feature.

const
  start = new Date(0),
  middle = new Date((86400 + start.getTimezoneOffset() * 60) * 1000),
  end = new Date(86400 * 1000),
  datasets = {
    a: [
      {data: [{x: start, y: 123}, {x: middle, y: 132}, {x: end, y: 321}]},
      {data: [{x: start, y: 12}, {x: middle, y: 13}, {x: end, y: 32}]}
    ],
    b: [
      {data: [{x: moment(+start), y: 123}, {x: moment(+middle), y: 132}, {x: moment(+end), y: 321}]},
      {data: [{x: moment(+start), y: 12}, {x: moment(+middle), y: 13}, {x: moment(+end), y: 32}]}
    ]
  };

for(let k in datasets)
  new Chart(document.getElementById(`chart_${k}`), {
    type: 'line',
    data: {datasets: datasets[k]},
    options: {
      legend: {display: false},
      scales: {
        xAxes: [{
          display: true,
          type: 'time',
          time: {unitStepSize: 1, unit: 'day'},
          ticks: {display: true}
        }]
      }
    }
  });
.chart_holder {
  max-width: 600px;
  max-height: 400px;
  display: inline-block;
}
<html>
  <body>
    <div class="chart_holder">
      <canvas id="chart_a" width="600" height="400"></canvas>
    </div>
    <div class="chart_holder">
      <canvas id="chart_b" width="600" height="400"></canvas>
    </div>
  </body>
</html>

@etimberg
Copy link
Member

etimberg commented Mar 7, 2021

This is due to how moment formats dates. Using another date adapter such as luxon solves the problem https://jsfiddle.net/joLp0fw5/

@etimberg etimberg closed this as completed Mar 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants