chartjs / Chart.js

Simple HTML5 Charts using the <canvas> tag
https://www.chartjs.org/
MIT License
64.32k stars 11.88k forks source link

Filler plugin fill wrong region when target has negative value #8583

Closed zeitlinger closed 3 years ago

zeitlinger commented 3 years ago

Expected Behavior

image

Current Behavior

image

Steps to Reproduce

Changed order.js on master

module.exports = {
  config: {
    type: 'line',
    data: {
      labels: [0, 1, 2],
      datasets: [
        {
          fill: "-1",
          data: [0, -1, -1],
          // data: [1, 0, 0], //this produced the expected
          backgroundColor: '#ff0000',
        },
        {
          fill: "-1",
          data: [0, 2, 2],
          backgroundColor: '#00ff00',
        },
        {
          fill: "-1",
          data: [0, 0, 1],
          backgroundColor: '#0000ff',
        }
      ]
    },
    options: {
      elements: {
        line: {
          fill: true
        },
        point: {
          radius: 0
        }
      },
      layout: {
        padding: 32
      },
      scales: {
        x: {display: false},
        y: {display: false, stacked: true}
      },
      plugins: {
        legend: false,
        title: false,
        tooltip: false,
        filler: true
      }
    }
  },
  options: {
    canvas: {
      height: 256,
      width: 512
    }
  }
};

Context

Trying to get charts correct for Gaia Project

image

Environment

Git: 7ccf9e2d4d2e052de0fb71da52d9d41f8eeda85c Used Karma Debug Runner

zeitlinger commented 3 years ago

I tried to debug the issues - but the filler plugin is quite complicated. With some hints, I might be able to create a PR.

kurkle commented 3 years ago

Looks more like a stacking issue.

image

image

https://codepen.io/kurkle/pen/NWbLLXy

kurkle commented 3 years ago

So the 0 is stacked on top of -1, and you'd expect it not to stack. I'm not sure which one is correct behavior.

kurkle commented 3 years ago

You could use the stack option to specify what stacks where:

    datasets: [
      {
        stack: "neg",
        data: [0, -1, -1],
        backgroundColor: "#ff000050",
      },
      {
        stack: "pos",
        data: [0, 2, 2],
        backgroundColor: "#00ff0050",
      },
      {
        stack: "pos",
        data: [0, 0, 1],
        backgroundColor: "#0000ff50",
      }
    ]
zeitlinger commented 3 years ago

Not sure I understand correctly:

I always want to fill/srack to the previous line.

The difference between both examples is only that the first line has all values subtracted by 1 - which should not make a difference.

kurkle commented 3 years ago

This behavior comes from the bar charts, where negative and positive values are put on a different stack. So for the 2nd point, the mid line 2 is not stacked on top of the -1, but goes in its own stack. The third one 0, is then stacked on top of -1, and I'm not sure if that is the correct behavior or not (for bar charts).

I think your use case would need a new mode/option for stacking, putting everything on the same stack.

This behavior is there, on the applyStack function: https://github.com/chartjs/Chart.js/blob/7ccf9e2d4d2e052de0fb71da52d9d41f8eeda85c/src/core/core.datasetController.js#L86

zeitlinger commented 3 years ago

Thanks a lot - this explanation makes sense - I and think I want a new mode - or another value for stacked, e.g. y: {display: false, stacked: single}.

Does that make sense & how would I do that?

kurkle commented 3 years ago

@etimberg @simonbrunel @benmccann any thoughts?

etimberg commented 3 years ago

We could add a new mode for this, or if specifying the stacks manually works, we could document it

kurkle commented 3 years ago

It still does not stack positive and negative to same stack, when stack is specified manually, so I guess a new mode (could be default for line datasets) is required.