score:16
You can extend the line chart to do this.
Preview
Script
Chart.defaults.NegativeTransparentLine = Chart.helpers.clone(Chart.defaults.line);
Chart.controllers.NegativeTransparentLine = Chart.controllers.line.extend({
update: function () {
// get the min and max values
var min = Math.min.apply(null, this.chart.data.datasets[0].data);
var max = Math.max.apply(null, this.chart.data.datasets[0].data);
var yScale = this.getScaleForId(this.getDataset().yAxisID);
// figure out the pixels for these and the value 0
var top = yScale.getPixelForValue(max);
var zero = yScale.getPixelForValue(0);
var bottom = yScale.getPixelForValue(min);
// build a gradient that switches color at the 0 point
var ctx = this.chart.chart.ctx;
var gradient = ctx.createLinearGradient(0, top, 0, bottom);
var ratio = Math.min((zero - top) / (bottom - top), 1);
gradient.addColorStop(0, 'rgba(75,192,192,0.4)');
gradient.addColorStop(ratio, 'rgba(75,192,192,0.4)');
gradient.addColorStop(ratio, 'rgba(0,0,0,0)');
gradient.addColorStop(1, 'rgba(0,0,0,0)');
this.chart.data.datasets[0].backgroundColor = gradient;
return Chart.controllers.line.prototype.update.apply(this, arguments);
}
});
and then
...
var myLineChart = new Chart(ctx, {
type: 'NegativeTransparentLine',
data: {
...
Fiddle - http://jsfiddle.net/g2r2q5Lu/
score:0
@potatopeelings code will work if your dataset data format is in [1,2,3,...]
form
If your data format is in [{x: 1 , y: 1},...]
form, you need to change var min
and var max
to:
var min = this.chart.data.datasets[0].data.reduce((min, p) => p.y < min ? p.y : min, this.chart.data.datasets[0].data[0].y);
var max = this.chart.data.datasets[0].data.reduce((max, p) => p.y > max ? p.y : max, this.chart.data.datasets[0].data[0].y);
Tested on ChartJS 2.7.3
score:0
@potatopeelings The gradient messed up if all data was negative or positive, here's how I fixed it. (Changed the gradient colours but the fix is still there)
Chart.defaults.NegativeTransparentLine = Chart.helpers.clone(Chart.defaults.line);
Chart.controllers.NegativeTransparentLine = Chart.controllers.line.extend({
update: function () {
// get the min and max values
var min = Math.min.apply(null, this.chart.data.datasets[0].data);
var max = Math.max.apply(null, this.chart.data.datasets[0].data);
var yScale = this.getScaleForId(this.getDataset().yAxisID);
// figure out the pixels for these and the value 0
var top = yScale.getPixelForValue(max);
var zero = yScale.getPixelForValue(0);
var bottom = yScale.getPixelForValue(min);
// build a gradient that switches color at the 0 point
var ctx = this.chart.chart.ctx;
var gradient = ctx.createLinearGradient(0, top, 0, bottom);
var ratio = Math.min((zero - top) / (bottom - top), 1);
if(ratio < 0){
ratio = 0;
gradient.addColorStop(1, 'rgba(0,255,0,1)');
}else if(ratio == 1){
gradient.addColorStop(1, 'rgba(255,0,0,1)');
}else{
gradient.addColorStop(0, 'rgba(255,0,0,1)');
gradient.addColorStop(ratio, 'rgba(255,0,0,1)');
gradient.addColorStop(ratio, 'rgba(0,255,0,1)');
gradient.addColorStop(1, 'rgba(0,255,0,1)');
}
console.log(ratio)
this.chart.data.datasets[0].backgroundColor = gradient;
return Chart.controllers.line.prototype.update.apply(this, arguments);
}
});
score:0
This is derived from this post. It works for Chart.js v2.9.4 and doesn't require any external code or creating a custom chart type. Simply add this plugins object to your chart options. (note that the plugins object is separate from the options object. If you put the plugins object inside of the options object, it won't work.)
new Chart(document.querySelector(`canvas`), {
type: 'line',
data: {
labels: your_labels,
datasets: [{
data: your_data
}]
},
options: {
maintainAspectRatio: false, //allow the graph to resize to its container
scales: {
yAxes: [{
ticks: {
beginAtZero: true //make sure zero line exists on the graph
}
}]
}
}, //<-make sure plugins is outside of the options object
plugins: [{
beforeRender: function(graph) {
let gradient = graph.ctx.createLinearGradient(0, 0, 0, graph.height), //create a gradient for the background
zero_line = graph.scales[`y-axis-0`].getPixelForValue(0) / graph.height; //calculate where the zero line is plotted on the graph
gradient.addColorStop(0, `rgba(0,200,0,.2)`); //good color faded out
gradient.addColorStop(zero_line, `rgba(0,200,0,.8)`); //good color at zero line
gradient.addColorStop(zero_line, `rgba(200,0,0,.8)`); //bad color at zero line
gradient.addColorStop(1, `rgba(200,0,0,.2)`); //bad color faded out
graph.data.datasets[0]._meta[0].$filler.el._model.backgroundColor = gradient; //set the graphs background to the gradient we just made
}
}]
});
Obviously for more complex graphs you'll need to update dataset indexes and axis names, but for simple graphs, it's this simple.
score:1
i update the method to work with multiple datasets.
Chart.defaults.NegativeTransparentLine = Chart.helpers.clone(Chart.defaults.line);
Chart.controllers.NegativeTransparentLine = Chart.controllers.line.extend({
update: function () {
for(let i=0; i< this.chart.data.datasets.length; i++) {
// get the min and max values
var min = Math.min.apply(null, this.chart.data.datasets[i].data);
var max = Math.max.apply(null, this.chart.data.datasets[i].data);
var yScale = this.getScaleForId(this.chart.data.datasets[i].yAxisID);
// figure out the pixels for these and the value 0
var top = yScale.getPixelForValue(max);
var zero = yScale.getPixelForValue(0);
var bottom = yScale.getPixelForValue(min);
// build a gradient that switches color at the 0 point
var ctx = this.chart.chart.ctx;
var gradient = ctx.createLinearGradient(0, top, 0, bottom);
var ratio = Math.min((zero - top) / (bottom - top), 1);
gradient.addColorStop(0, 'rgba(55,210,99,0.4)');
gradient.addColorStop(ratio, 'rgba(55,210,99,0.4)');
gradient.addColorStop(ratio, 'rgba(247,100,120,0.4)');
gradient.addColorStop(1, 'rgba(247,100,120,0.4)');
this.chart.data.datasets[i].backgroundColor = gradient;
}
return Chart.controllers.line.prototype.update.apply(this, arguments);
}
});
Tested on chart.js 2.8.0 on Angular 8
import { Component, OnInit, ViewChild } from '@angular/core';
import { Chart, ChartDataSets, ChartOptions } from 'chart.js';
import { Color, Label } from 'ng2-charts';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
public lineChartData: ChartDataSets[] = [
{ data: [89, 0, -80, 81, 56, -55, 40], label: 'Series A', yAxisID: 'y-axis-0' },
{ data: [-890, 0, 800, -810, -560, 550, -400], label: 'Series B', yAxisID: 'y-axis-0' },
];
public lineChartLabels: Label[] = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
public lineChartOptions: (ChartOptions & { annotation: any }) = {
responsive: true,
};
public lineChartColors: Color[] = [
{
backgroundColor: 'rgba(255,0,0,0.3)',
},
{
backgroundColor: 'rgba(0,255,0,0.3)',
},
];
public lineChartLegend = true;
public lineChartType = 'line';
public lineChartPlugins = [];
constructor() {
Chart.defaults.NegativeTransparentLine = Chart.helpers.clone(Chart.defaults.line);
Chart.controllers.NegativeTransparentLine = Chart.controllers.line.extend({
update: function () {
for(let i=0; i< this.chart.data.datasets.length; i++) {
// get the min and max values
var min = Math.min.apply(null, this.chart.data.datasets[i].data);
var max = Math.max.apply(null, this.chart.data.datasets[i].data);
var yScale = this.getScaleForId(this.chart.data.datasets[i].yAxisID);
// figure out the pixels for these and the value 0
var top = yScale.getPixelForValue(max);
var zero = yScale.getPixelForValue(0);
var bottom = yScale.getPixelForValue(min);
// build a gradient that switches color at the 0 point
var ctx = this.chart.chart.ctx;
var gradient = ctx.createLinearGradient(0, top, 0, bottom);
var ratio = Math.min((zero - top) / (bottom - top), 1);
gradient.addColorStop(0, 'rgba(55,210,99,0.4)');
gradient.addColorStop(ratio, 'rgba(55,210,99,0.4)');
gradient.addColorStop(ratio, 'rgba(247,100,120,0.4)');
gradient.addColorStop(1, 'rgba(247,100,120,0.4)');
this.chart.data.datasets[i].backgroundColor = gradient;
}
return Chart.controllers.line.prototype.update.apply(this, arguments);
}
});
this.lineChartType = 'NegativeTransparentLine';
}
ngOnInit() {
}
}
<div style="display: block;">
<canvas baseChart width="400" height="400"
[datasets]="lineChartData"
[labels]="lineChartLabels"
[options]="lineChartOptions"
[colors]="lineChartColors"
[legend]="lineChartLegend"
[chartType]="lineChartType"
[plugins]="lineChartPlugins">
</canvas>
</div>
score:10
To get @potatopeelings code above to work with chart.js 2.5.x you need to add yAxisID : 'y-axis-0' into your datasets, as below.
var myLineChart = new Chart(ctx, {
type: 'NegativeTransparentLine',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
yAxisID : 'y-axis-0',
....
Source: stackoverflow.com
Related Query
- Chart.js Line, different fill color for negative point
- chart.js Line chart with different background colors for each section
- Different color for each column in angular-chartjs bar chart
- how to set chart.js grid color for line chart
- chart js - Apply different color for each x-axes label
- Different color for line segments in ChartJS
- Add a text as tooltip for each point on a line chart
- How to add area with break on line chart with fill color
- Empty circle - only point strok in line chart for ChartJS
- chart.JS i want to put different color for each Y axis value grid line color
- Chartjs Different Fill Color For Overlap Area
- Angular-Chart-JS - Line chart with different fill colors according to points' range
- How to start Y Axis Line at 0 from right for negative values in chart js 2?
- Show label for every data point in line chart
- Trouble with setting background color for Line chart at Chartjs version 3.5.1
- Angular 4: Different color for bar in bar chart dynamically using ChartJS
- Different labels needed for second line graph, chart js
- Different color for each bar in a bar chart; ChartJS
- Chart Js Change Label orientation on x-Axis for Line Charts
- ChartJS - Different color per data point
- line chart with {x, y} point data displays only 2 values
- Chart.js how to show cursor pointer for labels & legends in line chart
- Chart.js line chart set background color
- How to display Line Chart dataset point labels with Chart.js?
- show label in tooltip but not in x axis for chartjs line chart
- chartjs show dot point on hover over line chart
- How to add second Y-axis for Bar and Line chart in Chart.js?
- Can I set different fill color based on a given threshold in Chart.js?
- Chart.js Mixed Bar and Line chart with different scales
- Unable to parse color in line chart (angular-chart.js)
More Query from same tag
- Use transparent stroke color with chartjs pie chart
- ChartJS GridLine Dynamically
- Split JSON into two arrays gives undefined keys-values
- I want to multiply chart data according as array length
- ChartJS show value in legend (Chart.js V3.5)
- Y axis limit in Chart JS Bar chart?
- How to load an array of external data in QuickChart?
- How to integrate basic ChartJs customizations when using react-chartjs-2?
- Chart.js use font awesome in labels
- Pass data from array to function vue
- Display API data in line charts dynamically
- How to add an end line to my graph using Chart.js?
- Text inside Doughnut chart using Chart.js and Angular2, Ionic2
- How do you revert xAxes with Chart.js?
- Chart.js set global point size not working
- how to use chartJS to show breakdown of selected data
- Trouble getting Axis Labels to show up in Chart.js
- ChartJS: Get individual values minus another value in the custom legend
- Print chart using chart js
- Get value of min/lowest label from y-axis chart
- Different color for each bar in a bar chart; ChartJS
- How to display grid lines (without showing label) between each ticks?
- Chart.js is it possible to fire javascript when clicking on point on the graph?
- Chartjs is not rendering
- Change Chartjs financial chart yaxis from left to right
- Dates not displaying on X Axis using Chart.Js on MVC 5
- Chartjs Polar Area Chart - Data labels shown don't rotate with startAngle
- LinearGradient doesnt't work on chartJs canvas for Angular
- Prevent y-axis labels from being cut off
- Data with x and y data, missing data are not taken into account