How to add gradient background to Line Chart [vue-chart.js] - javascript

how can I add a gradient backgroundColor to a line chart, I pass the data as props.
this is my LineChart.vue component:
import { Line, mixins } from 'vue-chartjs'
const { reactiveProp } = mixins
export default {
extends: Line,
mixins: [reactiveProp],
data: () => ({
gradient: null,
options: {
layout: {
padding: {
bottom: -20,
left: -20,
}
},
maintainAspectRatio: false,
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
min: 0,
display: false,
},
gridLines: {
drawBorder: false,
showBorder: false,
display: false,
},
}],
xAxes: [{
gridLines: {
drawBorder: false,
showBorder: false,
display: false,
},
ticks: {
display: false
}
}]
}
}
}),
mounted () {
// this.chartData is created in the mixin.
// If you want to pass options please create a local options object.
this.renderChart(this.chartData, this.options)
}
}
and this is the chartdata initialization in Home.vue:
this.chartdata3 = {
labels: ['bla', 'bla', 'bla', 'bla'],
datasets: [
{
backgroundColor: "rgba(42, 115, 237, 0.9)",
data: ['200', '400', '100', '700'],
}
]
};
How can I have a gradient instead of solid color in the background of the line chart?

You should be able to add ref="chart" to your canvas. After that you can declare the new variable that will store the background color.
Like this:
var gradientFill = this.$refs.chart.createLinearGradient(500, 0, 100, 0);
gradientFill.addColorStop(0, "rgba(128, 182, 244, 0.6)");
gradientFill.addColorStop(1, "rgba(244, 144, 128, 0.6)");
Then you should be able to use backgroundColor: gradientFill in your chart options.
Please put this code in created or mounted methods in Vue lifecycle as needed to make sure it renders properly when component displays.
That should be it.
Yo can try and play with it here: https://codepen.io/plavookac/pen/RKjNEV
I hope this helps.
Let me know if you have any questions.

Related

Chart js axes padding

I would like to use mirror option in order to show y-axis value "inside" the graph:
now the problem is the x-axis should start after those values but I can't move them.
The chart is build with following code:
this.chart = new Chart(this.canvas.nativeElement, {
type: 'bar',
data: data,
options: {
scales: {
x: {
stacked: true,
grid: {
display: false,
drawBorder: false
},
ticks: {
color: '#333',
font: {
weight: 'bold'
},
maxRotation: 0,
maxTicksLimit: this.loadLabels()?.length / 2
},
bounds: 'ticks'
},
y: {
type: 'linear',
beginAtZero: true,
stacked: true,
title: {
display: false,
},
display: true,
grid: {
display: true,
drawBorder: false,
lineWidth: 1,
borderColor: 'rgb(244, 244, 244, 0.7)',
color: 'rgb(244, 244, 244, 0.7)'
},
ticks: {
display: true,
maxTicksLimit: 5,
mirror: true,
callback: (val) => formatCurrency(+val, 'it', getCurrencySymbol(this.currency, 'narrow'), this.currency)
}
}
}
},
});
I tried both padding and grace options without success.. Anyone knows how to do it?
You can define y.ticks.padding as follows:
y: {
ticks: {
...
padding: -50
}
}
Together with this, you also need to define layout.padding.left to make sure, the tick labels still appear on the canvas.
options: {
layout: {
padding: {
left: 100
}
}
...
Obviously you need to adapt the numbers to your needs.
For further information, please consult Tick Configuration and Padding from the Chart.js documentation.

How can I display different values on xAxes than on tooltip Chart.js V3

I am not really familiar with the Chart.js V3.7.0(This is the version I am currently using) So I tried in different ways to display different values on xAxes and different values on the tooltip.
What's important here to note, is that I am using Php to echo the values inside the dataset.
For example (the data variable I use):
const data = {
datasets: [{
backgroundColor: 'black',
borderColor: '#2d84b4',
borderWidth: 2,
fill: false,
pointBorderColor: 'rgba(0, 0, 0, 0)',
pointBackgroundColor: 'rgba(0, 0, 0, 0)',
pointHoverBackgroundColor: 'rgba(0,0,0,0)',
pointHoverBackgroundWidth: 5,
pointHoverBorderColor: 'rgba(45, 132, 180, 0.5)',
pointHoverBorderWidth: 4,
pointStyle: 'circle',
pointHoverRadius: 5.5,
data: [ <? echo $values; ?> ],
}],
labels: [ <? echo $labels; ?> ],
};
So my php echoes the $values variable with values in this form:
{0.504, 0.675, 0.305, etc...}
Same applies for the $labels variable but because labels are data related to time I display them as strings:
example: {'Dec 28', '01:00', '02:00', etc...}
Here is the config variable which includes the data variable inside of it, and then the config variable is being called inside the initialization of the chart.
Config:
const config = {
type: 'line',
data: data,
options: {
onHover: (event, activeElements) => {
if (activeElements?.length > 0) {
event.native.target.style.cursor = 'pointer';
} else {
event.native.target.style.cursor = 'auto';
}
},
animation: {
duration: 0
},
responsive: true,
maintainAspectRatio: false,
scales: {
x: {
stacked : true,
ticks: {
autoSkip: true,
maxTicksLimit: <? echo $ticks_val; ?>,
maxRotation: 0
},
grid: {
display: true,
drawBorder: false,
drawOnChartArea: false,
drawTicks: true,
tickLength: 3,
},
},
yAxes: {
min: '0.0',
ticks: {
autoSkip: true,
maxTicksLimit: 6,
},
grid: {
drawBorder: false,
drawTicks: false
}
},
},
elements: {
point: {
radius: 5
}
},
locale: 'en-EN',
plugins: {
tooltip: {
displayColors: false,
backgroundColor: 'rgba(45,132,180,0.8)',
bodyFontColor: 'rgb(255,255,255)',
callbacks: {
title: () => {
return
},
label: (ttItem) => ( `${ttItem.parsed.y} ppm` ),
afterBody: (ttItems) => (ttItems[0].label)
}
},
legend: {
display: false
}
}
}
};
Goal:
I want to echo a different php variable inside the tooltip, but I dont want to change what I am currently displaying on xAxes. Problem is that If I just echo another php variable in the tooltip, I end up with the wrong Date date being displayed simply because the index values are not connected with the chart and so on with the tooltip popup.
Notes:
1): Chart.js version: 3.7.0
Picture of the chart:
This is achievable. One solution would be to reformat the values stored at $labels so that they are consistent. For example, store each value in the format that you want to render, i.e. {'Dec 28 00:00', 'Dec 28 01:00', 'Dec 02:00'}. You can then use a callback to create a custom tick format.
options: {
scales: {
x: {
stacked : true,
ticks: {
autoSkip: true,
maxTicksLimit: 12,
maxRotation: 0,
callback: function(value) {
let labelValue = this.getLabelForValue(value);
if(labelValue.slice(-5, -3) == '00') {
return labelValue.slice(0, -6);
} else {
return labelValue.slice(-5);
}
}
}
}
}
}
JSFiddle showing this working

chartjs-plugin-streaming: onRefresh() callback isn't working

Hello I'm new in javascript world; I'm trying to display random numbers in real time with Chart.js and chartjs-plugin-streaming starting from a tutorial code which I started to modify for my scope.
const Chart= require ("chart.js");
const chartStreaming = require('chartjs-plugin-streaming');
const boxWhiteColor = "#2043CE";
const pressure_graph = document.getElementById('pressureGraph').getContext('2d');
Chart.register(chartStreaming);
let pressure_graph_config = {
type: 'line',
data: {
datasets: [{
label: 'Pressure',
data: [],
borderColor: boxWhiteColor,
fill: false
}]
},
options: {
title: {
display: true,
text: 'PRESSURE',
fontColor: boxWhiteColor,
fontSize: 30
},
scales: {
xAxes: [{
gridLines: {
display: true,
drawBorder: true,
color: boxWhiteColor,
lineWidth: 5},
ticks: {
fontColor: boxWhiteColor,
display: false
},
type: 'realtime',
realtime: {
duration: 10000,
refresh: 100, // plot at 10 Hz
delay:200,
pause: false, // chart is not paused
ttl: undefined, // data will be automatically deleted as it disappears off the chart
frameRate: 100, // data points are drawn 100 times every second
onRefresh: chart => {
console.log(trocarP.data.datasets.data);
chart.config.data.datasets.forEach(function(dataset) {
chart.data.dataset[0].data.push({
x: Date.now(),
y: Math.random() //pressure16bits[pressure16bits.length-1]
});
});
}
}
}],
yAxes: [{
scaleLabel: {
display: true,
labelString: '[mmHg]', fontColor: boxWhiteColor, fontSize: 30, fontStyle: 900,
},
ticks: {
fontColor: boxWhiteColor,
fontSize: 25,
fontStyle: 700,
maxTicksLimit: 5,
min: 0,
max: 40,
},
gridLines: {display: true, drawBorder: true, color: boxWhiteColor, lineWidth: 5},
}]
},
elements: {
point: {radius: 0},
},
legend: { display: false}
}
}
trocarP = new Chart (pressure_graph, pressure_graph_config);
The problem is the graph is being created on a canvas via the .html file, but then it doesn't display anything; trying to debug the code I found out that the console.log() I placed inside the onRefresh callback is not printing anything, so I'm assuming the callback isn't working. Any clue on what's happening?
Screenshot of the graph
Edit: I noticed that also Y axis label has not been displayed. I don't get what's wrong with this code.
You are using v2 syntax while using v3 of the lib this wont work as there are several breaking changes, see migration guide for all of them.
For example, way of defining scales has changed, you need an adapter for dates and more.
working basic v3 example:
var options = {
type: 'line',
data: {
datasets: [{
label: '# of Votes',
data: [],
borderColor: 'pink'
}]
},
options: {
scales: {
x: {
type: 'realtime',
realtime: {
duration: 20000,
refresh: 100,
delay: 200,
onRefresh: chart => {
const now = Date.now();
chart.data.datasets.forEach(dataset => {
dataset.data.push({
x: now,
y: Math.random()
});
});
}
}
}
}
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-streaming/2.0.0/chartjs-plugin-streaming.js"></script>
</body>

Change tool-tip direction in react-chartjs2

I have implemented the react-chartjs2 https://www.npmjs.com/package/react-chartjs-2
in my react app. I have implemented it successfully but i need to change the direction of the tooltip when hovering the chart. Currently it looks like this
But i want my tooltip to look like this
How can i achieve this
My code for chart and chart options
const barChartOptions = {
tooltips: {
custom: function(tooltip) {
if (!tooltip) return;
// disable displaying the color box;
tooltip.displayColors = false;
},
callbacks: {
// use label callback to return the desired label
label: function(tooltipItem, data) {
return tooltipItem.yLabel + " kWh";
},
// remove title
title: function(tooltipItem, data) {
return;
}
}
},
responsive: true,
maintainAspectRatio: false,
legend: {
display: false
},
scales: {
xAxes: [
{
barPercentage: 1,
barThickness: 10,
gridLines: {
display: false,
color: "rgba(0, 0, 0, 0.1)"
}
}
],
yAxes: [
{
gridLines: {
display: true,
categorySpacing: 90,
drawBorder: false,
color: "rgba(0, 0, 0, 0.1)"
},
ticks: {
beginAtZero: true,
min: 0,
max: 100,
stepSize: 20,
padding: 20
}
}
]
}
};
inside render
<Bar
data={data}
width={100}
height={400}
options={barChartOptions}
/>
options: {
tooltips: {
yAlign: "bottom"
}
}
The problem is I don't know a way that the caret is in the middle of your box.
I think you need to add more configuration for your tooltip
Check what you can use for position and alignment of your Tooltip

How to make points in chartjs draggable?

Question
I'm looking to make 3 points on a graph draggable between 0 and 100. I'm looking to do this in React with ChartJS via react-chartjs-2.
Here is a fiddle with everything setup (js also below).
Extra Info
The fiddle uses some random version of react-chartjs-2 because I couldn't figure out how to import. On my local setup I use import { Line } from 'react-chartjs-2'; but I'm not sure how to do that in jsfiddle. Webdev is super new to me.
What have I tried so far?
I tried using a few chartjs plugins (like this one) that claimed
to do draggable points, but I couldn't figure out how to get them
working in React. This might be the easiest solutin.
I tried adding my own event listeners for mouseDown/Up/Enter/Leave,
but I was unable to attach these to the actual points. If I just have
access to <Line /> is there a way in React for me to attach to the
points themselves? If I could get the coordinates and have these
events, I could kludge together a solution.
I tried searching on the chartjs and react-chartjs-2 docs, but I
couldn't find anything that would let me drag, or attach the right
listeners.
Code
var Line = reactChartjs2.Line;
const options = {
tooltips: {enabled: true},
scales: {
xAxes: [{
gridLines: {display: false, color: 'grey',},
ticks: {fontColor: '#3C3C3C', fontSize: 14,},
}],
yAxes: [{
scaleLabel: {display: true, labelString: 'Color Strength', fontSize: 14,},
ticks: {
display: true,
min: -5,
max: 100,
scaleSteps: 50,
scaleStartValue: -50,
maxTicksLimit: 4,
fontColor: '#9B9B9B',
padding: 30,
callback: point => (point < 0 ? '' : point),
},
gridLines: {
display: false,
offsetGridLines: true,
color: '3C3C3C',
tickMarkLength: 4,
},
}],
},
};
class DraggableGraph extends React.Component {
state = {
dataSet: [0, 0, 0],
labels: ['red', 'green', 'blue'],
};
render() {
const data = {
labels: this.state.labels,
datasets: [{
data: this.state.dataSet,
borderColor: '9B9B9B',
borderWidth: 1,
pointRadius: 10,
pointHoverRadius: 10,
pointBackgroundColor: '#609ACF',
pointBorderWidth: 0,
spanGaps: false,
}],
};
return (
<div>
<Line
data={data}
options={options}
legend={{display: false}}
plugins={{}}
/>
</div>
);
}
}
ReactDOM.render(<DraggableGraph />, document.getElementById('app'));
You can do this by using chartjs-plugin-dragData. You have to set dragData: true within options object to use this plugin in chart js. Here I have provided updated code.
var Line = reactChartjs2.Line;
const options = {
tooltips: {enabled: true},
scales: {
xAxes: [{
gridLines: {display: false, color: 'grey',},
ticks: {fontColor: '#3C3C3C', fontSize: 14,},
}],
yAxes: [{
scaleLabel: {display: true, labelString: 'Color Strength', fontSize: 14,},
ticks: {
display: true,
min: -5,
max: 100,
scaleSteps: 50,
scaleStartValue: -50,
maxTicksLimit: 4,
fontColor: '#9B9B9B',
padding: 30,
callback: point => (point < 0 ? '' : point),
},
gridLines: {
display: false,
offsetGridLines: true,
color: '3C3C3C',
tickMarkLength: 4,
},
}],
},
legend:{
display: false
},
dragData: true,
onDragStart: function (e) {
console.log(e)
},
onDrag: function (e, datasetIndex, index, value) {
console.log(datasetIndex, index, value)
},
onDragEnd: function (e, datasetIndex, index, value) {
console.log(datasetIndex, index, value)
}
};
class DraggableGraph extends React.Component {
state = {
dataSet: [0, 0, 0],
labels: ['red', 'green', 'blue'],
};
render() {
const data = {
labels: this.state.labels,
datasets: [{
data: this.state.dataSet,
borderColor: '9B9B9B',
borderWidth: 1,
pointRadius: 10,
pointHoverRadius: 10,
pointBackgroundColor: '#609ACF',
pointBorderWidth: 0,
spanGaps: false,
}],
};
return (
<div>
<Line
data={data}
options={options}
/>
</div>
);
}
}
ReactDOM.render(<DraggableGraph />, document.getElementById('app'));
https://jsfiddle.net/4mdenzjx/

Categories