chartjs / Chart.js

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

Dataset colors: option for different colors for negative values? #1493

Closed ghost closed 8 years ago

ghost commented 9 years ago

If I'm charting an account balance in a line/bar chart, it'd be nice to show positive values in, say, black and negative values in, say, red. Right now that doesn't seem to be an option. The thresholds/ranges should eventually be configurable so that 0 isn't the only threshold and that there could be multiple ranges/bands of fills. This might only be for fills. Fill color boundaries could be abrupt or possibly a gradient mesh effect?

matfrog commented 8 years ago

+1 This is exactly what I need, I found a script to extend the line chart for v1.x but it's not working anymore for v2.x It could be nice to have fillPositive: and fillNegative option, and of course backgroundColorPositive, backgroundColorNegative.

etimberg commented 8 years ago

@matfrog you can do this manually in v2.

When you set the backgroundColor property of the dataset, set it as an array of colors. The first color in the array will be used for the first bar, the second color for the second bar, etc

matfrog commented 8 years ago

ok thank you, I use the Line Chart to make a balance, Positive must be green and negative red. To make it, I've separated my data and I've putted it into 2 different Chart. One for the positive values, and an another one for the negative values. That do the job.

etimberg commented 8 years ago

Closing since this is doable manually. At this point, I don't think we'll build this into core directly. It could certainly live in user space though as a plugin.

PTruscott commented 7 years ago

etimberg's suggesting as an array of colours straight up doesn't work, as only the first colour in the array is used for all of it.

etimberg commented 7 years ago

@PTruscott this works fine. See https://jsfiddle.net/c1w5Laee/

PTruscott commented 7 years ago

@etimberg On a bar chart, unless I'm missing something (which is a possibility) , it doesn't for line graphs. Editing the fiddle and my own code couldn't get it to work.

etimberg commented 7 years ago

@PTruscott for a line the pointBorderColor and pointBackgroundColor properties support arrays: https://jsfiddle.net/9psxbz4c/1/

PTruscott commented 7 years ago

Ok, apologies if I misunderstood. I was talking about plain background colour, as I understand it the fill under the line, not the colour of the point itself which I assumed (perhaps wrongly) was what this thread was about as well.

etimberg commented 7 years ago

ohhh, sorry about that I thought you meant the fill of the points. Your best bet for that is to construct a CanvasGradient object that does the filling you desire. There is a library that automates creating the gradient objects to change the line colour, maybe you can adapt it to your needs: https://github.com/bbc/Chart.Bands.js/

AllanAndrade commented 6 years ago

@etimberg if all values gone positive, will give error: Works fine with at least one value negative: See https://jsfiddle.net/c1w5Laee/78/ But has any thing wrong if all values are positives (with no value negative): See https://jsfiddle.net/c1w5Laee/80/

am-awais commented 5 years ago

Can we achieve this in Angular along with chart.js and ng2-charts

frazras commented 5 years ago

@AllanAndrade You can fix the issue of the missing datapoints by using this configuration options: { scales: { yAxes: [{ ticks: { beginAtZero: true } }] } }

helderhernandez commented 4 years ago

@matfrog puedes hacer esto manualmente en v2.

Cuando establezca la backgroundColorpropiedad del conjunto de datos, configúrelo como una matriz de colores. El primer color de la matriz se usará para la primera barra, el segundo color para la segunda barra, etc.

Efectivamente, funciona... un ejemplo

{
    //prev config...
    scales: {
        yAxes: [{
            gridLines: {
                display: true,
                color: ['red', 'orange', "transparent", "yellow"],
                zeroLineColor: 'black',
                lineWidth: 1,
            },
            ticks: {
                beginAtZero: true,
                stepSize: 2, 
                max: 20,
                min: -10,
            }
        }],
    //next config...
}
andig commented 4 years ago

This would still be desirable, not only for bar charts. Also line charts would profit, including differently-colored fill-to-zero option.

benmccann commented 4 years ago

You should be able to do this with scriptable options

andig commented 4 years ago

You should be able to do this with scriptable options

Wasn't aware of those, much appreciated. I gave it a quick test but couldn't get this to apply to line charts in any meaningful way (and maybe I can't expect it should):

label: 'Netz',
borderColor: function(context) {
    var index = context.dataIndex;
    var value = context.dataset.data[index];
    return value < 1000 ? '#FF4136' : '#00ff00';
},

Is there an example that applies to line charts?

benmccann commented 4 years ago

Here's an example for line charts: https://www.chartjs.org/samples/latest/scriptable/line.html

The sample is with point style and not borderColor, but borderColor should work. Scriptable options have been gradually being introduced and are supported on more properties and chart types in later versions. I checked the latest version (2.9.3) and it looks like borderColor is supported there, but it might not be in older versions, so make sure you're using the latest.

andig commented 4 years ago

The sample is with point style and not borderColor, but borderColor should work.

Unfortunately that doesn't seem to work running 3.0 alpha (https://codepen.io/andig2/pen/LYVgqgG):

Screenshot 2020-03-25 at 09 15 45

While the points are colored, lines and fill are handled globally. I'm not even sure if anything else could be expected (a fill is a fill and not done per point?).

Closing since this is doable manually. At this point, I don't think we'll build this into core directly. It could certainly live in user space though as a plugin.

Should I open a separate issue for this? I don't currently see how this could be achieved.

benmccann commented 4 years ago

Oh yeah, scriptable options would work for the points, but not the line or fill. (borderColor is a property of the line and the points, so it wasn't quite clear to me which one you were targeting)

Here's a few examples of people doing the line/fill on StackOverflow: https://stackoverflow.com/questions/36916867/chart-js-line-different-fill-color-for-negative-point https://stackoverflow.com/questions/34161616/chart-js-line-graphs-fill-area-above-line-as-opposed-to-below-and-to-the-right https://stackoverflow.com/questions/52636353/chartjs-different-background-gradient-depending-on-data-line-graph

DjovDev commented 3 years ago

Is there an active solution for this? I can't seem to find a way to color the line of a chart (I don't need fill)

I have tried scriptable options but as stated above, it does not work for the lines and only the points.

Has anybody else been able to achieve this?

Edit: typo

kurkle commented 3 years ago

@DjovDev https://www.chartjs.org/docs/latest/samples/line/line.html

Edit: Sorry, was supposed to link this: https://www.chartjs.org/docs/latest/samples/line/segments.html

Kylekoh commented 3 years ago

This could be the solution for this.

https://www.chartjs.org/docs/master/charts/area.html

qharlie commented 1 year ago

I've been searching for two days now on how to accomplish this with no results. I'm trying to fill the background color with red if the value is negative, green otherwise. The array of background colors is not working, I can change the point color but thats not what Im wanting.

Is there anyway in 2023 to fill below or above a point on a line graph using chart.js 4.2 ?

ConradLetelier commented 1 year ago

@charlie-sanders Was not able to do it with background color, but had some minor success with border color. Try this: ` datasets: [

 {
    label: "Sales",
    borderWidth: 5,
    segment: {
      borderColor: (purchasesData) => {
        var value = purchasesData.p1.raw;
        return value < 0 ? "red" : "green";
      },
    },
    //backgroundColor: colours,
    fill: false,
    tension: 0.3,
    data: purchasesData,
  },
]`

If you change borderColor to backgroundColor and fill: true, the colors do change but not in the way we want because of how segments work. Maybe there is a better attribute.

SergeyMell commented 4 months ago

For now there is an easier way to implement this. According to the documentation you can separately set colors for positive and negative parts when setting the fill property

new Chart(ctx, {
    data: {
        datasets: [
            {
              fill: {
                target: 'origin',
                above: 'rgb(255, 0, 0)',   // Area will be red above the origin
                below: 'rgb(0, 0, 255)'    // And blue below the origin
              }
            }
        ]
    }
});