I use Chart.js and I need to render a cubic bezier curve which mathematically consists of four data points. I do know the coordinates of all the four points, but I wonder how I could tell my chart that it should connect P1 and P4 by considering P2 and P3 as "control points" in the context of a bezier curve.
UPDATE:
Meanwhile I stumpled upon the property capBezierPoints of the line object having that description:
If true, bezier control points are kept inside the chart. If false, no restriction is enforced.
Documentation about that property is rare, so I can only assume that if I set it to false, the control points (in my case I have two control points and one start and one end point) are not drawn. However, I have no clue how I can tell Chart.js which of my points are the control points.
Recently I do pass the four points to my dataset as follows:
var data = {
datasets: [
{
label: "start point",
data: [
{
x: bezierCurve.getPoint(0).x,
y: bezierCurve.getPoint(0).y
},
{
x: bezierCurve.getPoint(1).x,
y: bezierCurve.getPoint(1).y
},
{
x: bezierCurve.getPoint(2).x,
y: bezierCurve.getPoint(2).y
},
{
x: bezierCurve.getPoint(3).x,
y: bezierCurve.getPoint(3).y
}
],
fill: false,
lineTension: 1,
borderColor: "blue"
}
]
}
var options = {
responsive: true,
scales: {
xAxes: [{
type: 'linear',
position: 'bottom',
ticks: {
beginAtZero: true,
max: Math.round(maxX * 1.1)
}
}],
yAxes: [{
display: true,
ticks: {
beginAtZero: true,
max: Math.round(maxY * 2)
}
}]
},
legend: {
display: false
}
}
Chart.defaults.global.tooltips.enabled = false;
Chart.defaults.global.elements.line.capBezierPoints = false;
Chart.defaults.global.elements.line.tension = 1.0;
this.displayedBezierCurveChart = new Chart(context, {
type: 'line',
data: data,
options: options
});
Using that implementation, a line is drawn connecting all four points.
What I need instead is a line connecting start point and end point considering the two control points in between.
Any ideas?
Related
My requirement is to output 2 y-axis chart with real-time data readings in NodeRED. I have installed ChartJS package in NodeRED and now according to the documentation of the package there should be PATH, Title, X-Axis, Y-Axis, Payload. But I couldn't find the Payload tab anywhere in the Line Chartjs node?
Ref : https://www.npmjs.com/package/node-red-contrib-chartjs
So I assumed that I have to add the code which belonged to Payload inside a function node before the Line Chartjs node.
What I have tried : (my function node)
var left = {payload : msg.payload.readResults[0].v };
var right = {payload : msg.payload.readResults[1].v };
//return [[left,right]];
const labels = [1,2,3,4,5,6,7,8,9,10];
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: left,
borderColor: '#ff0000',
backgroundColor: '#ff0000',
yAxisID: 'leftCamber',
},
{
label: 'Dataset 2',
data: right,
borderColor: '#0000ff',
backgroundColor: '#0000ff',
yAxisID: 'rightCamber',
}
]
};
const config = {
type: 'line',
data: data,
options: {
responsive: true,
interaction: {
mode: 'index',
intersect: false,
},
stacked: false,
plugins: {
title: {
display: true,
text: 'Chart.js Line Chart - Multi Axis'
}
},
scales: {
leftCamber: {
type: 'linear',
display: true,
position: 'left',
},
rightCamber: {
type: 'linear',
display: true,
position: 'right',
// grid line settings
grid: {
drawOnChartArea: false, // only want the grid lines for one axis to show up
},
},
}
},
};
const actions = [
{
name: 'CamberGraph',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = chart.data.labels.length
});
chart.update();
}
},
];
Here I have tried to get the 2 HTTP outputs I've named as left and right as my datasets(2 y-axis) vs hardcoded x-axis(1 through 10) which will be Footage later on.
PS : I have returned the left and right using return statement and it's outputting the values as I expected.
Currently I do not get any output in my debug window as well as in my ChartJS Line Chart when I inject the node. Using what I've tried so far can anybody show where I've done wrong or add/remove anything to make the graph work?
Thank you!
I have the following code to make a chart with chart.js but the main and axis title just does not work. Also I have put the legend to the bottom but does not work. Can anybody tell why it is not working?
let dataSize = 30;
let readings = new Array(dataSize);
const data = {
// X axis labels
labels: new Array(dataSize),
datasets: [{
//label: 'My Input', // chart label
data: readings, // the data to chart
//borderColor: '#272323', // line color (lavender)
backgroundColor: 'rgba(123, 83, 252, 80)',
borderColor: "rgba(255, 0, 0,1)",
borderWidth: 1.2,
pointBorderColor: "rgba(255, 0, 0, 1)",
pointRadius: 0.2 // point size
}]
};
const config = {
type: 'line', // type of chart
data: data, // the data
options: {
animation: false, // remove animation to speed drawing up
responsive: true,
maintainAspectRatio: false,
title: {
display: true,
text: 'Tarrif'
},
legend:{
position: 'bottom'
},
scales: { // axis ranges:
y: {
//type: 'linear',
scaleLabel: {
display: true,
labelString: 'X axis Title'
},
min: 0,
max: 260,
gridLines: {
display: true,
drawBorder: false //hide the chart edge line
}
},
x:[{
gridLines: {
display: false
},
scaleLabel: {
display: true,
labelString: 'X axis Title'
},
min:0
}]
}
}
};
Below is screenshot of my graph:
I followed the advice here:
In Chart.js set chart title, name of x axis and y axis?
thanks
First of all don't use an array for your X scales, all the scales need to be defined as objects. Second you are placing the options in the wrong part, it has to be configured in the title namespace like so:
scales: {
y: {
title: {
display: true,
text: 'yTitle'
}
},
x: {
title: {
display: true,
text: 'xTitle'
}
}
}
I'm currently trying to reproduce the chart you can see on https://discordstatus.com/ for the API Response Time.
However I'm unable to always show the nearest label depending on the mouse position on the X axis. I've tried different configurations for interactions (Chart.js Interactions) but fail to get the desired outcome.
Also it would be nice to show a vertical line dependent on the current active point. As well as always show the tooltip at the top left.
Is this possible with the default chart.js library or do i have to add a plugin or some own modifications?
Here is my current configuration:
const data = {
datasets: [{
label: 'RTT',
backgroundColor: '#C00122',
borderColor: '#C00122',
borderWidth: 2,
}]
};
const config = {
type: 'line',
data: data,
options: {
animation: false,
maintainAspectRatio: false,
pasing: false,
plugins: {
legend: false
},
elements: {
point: {
radius: 1
}
},
scales: {
x: {
type: 'time',
time: {
unit: 'second',
displayFormats: {
'second': 'H:mm:ss',
}
},
ticks: {
minRotation: 0,
maxRotation: 0,
maxTicksLimit: 5
}
},
y: {
min: 0,
ticks: {
stepSize: 10
}
}
},
hover: {
mode: 'index'
}
}
};
EDIT: My datasets are filled dynamically as described here: Updating Charts
I'm using ChartJS to create a line chart with elements. I'm wondering if it possible to set borders on left and right of a element? This is my chart and it gets confusing if you have two elements next to each other and they have the same color.
I've found nothing in the docs that supports it, so I figure that I have to draw it myself using js but I was hoping someone had an solution first :)
In case I have to draw it myself I would run into a problem since every element can have different widths due to the time axis (X). What would be your idea to solve that?
Update
Every element in the chart is a new dataset and gets a gradient object as backgroundColor and fill sets as true. Here is an example of me pushing a new dataset into the chart
chart.data.datasets.push({
fill: true,
backgroundColor: gradient,
data: [
{
x: aIstartX,
y: yAxis_value,
.. Other attributes
},
{
x: newEntryXend,
y: yAxis_value,
..Other attributes
}]
});
xAxes: [
{
stacked: false,
type: 'time',
unit: 'minute',
position: 'bottom',
scaleLabel: {
display: true
},
time: {
displayFormats: {
'minute': 'mm:ss'
}
},
ticks: {
autoSkip: true,
beginAtZero: true,
stepSize: 2,
autoSkipPadding: 5,
padding: 10,
labelOffset: 5,
},
gridLines: {
display: false,
tickMarkLength: 20
},
}
]
Here is a fiddle of my issue
https://jsfiddle.net/fa8hvhtv/1/
Any reason why you can wanted to keep the same background colors for ,
Why cant you try as below
Demo
fill: true,
backgroundColor: 'red',
I've found a solution to my problem. The issue was that I was trying to create some space between my datasets and my datas attribute Y doesnt start and end at 0. Therefor I added two extra datapoints in each dataset with a borderWidth of 3 and borderColor that matches the backgroundColor of the chart. Each extra added datapoint will have a Y with the value of 0. An example of adding a dataset to my chart is below.
chart.data.datasets.push({
fill: true,
backgroundColor: gradient,
borderWidth: 3,
borderColor: '#333',
data: [
{
x: startXvalue,
y: 0
},
{
x: startXvalue,
y: startY,
.. Other attributes
},
{
x: newEntryXend,
y: endY,
.. Other attributes
},
{
x: newEntryXend,
y : 0
}]
});
Suppose I have two Y axes, labeled "foo" and "bar". These axes correspond to points along the same interval, e.g. weekly aggregates of foos and bars in say the last 12 weeks. Ideally you would mouseover one of these points along the line chart and the tooltip would display the data of the week in question for both foo and bar; this is how it works if you don't have more than one Y axes. In practice you have you mouseover the individual point to see only the data for that specific point.
For clarity, this is what my chart options look like:
const CHART_OPTIONS = {
scales:
{
xAxes: [{
ticks: {
display: false,
},
}],
yAxes: [
{
type: 'linear',
id: 'y-axis-0',
display: false,
position: 'left',
},
{
type: 'linear',
id: 'y-axis-1',
display: false,
position: 'right',
},
],
},
};
The chart data specifies a yAxisID of y-axis-0 and y-axis-1 respectively.
For those who haven't seen a chart with two Y axes, I've prepared a simple example.
So my question is if this can be done with Chart.js 2?
References:
Chartjs Docs: Tooltip Configuration - Interaction Modes
mode : index - Finds item at the same index. If the intersect setting is true,
the first intersecting item is used to determine the index in the
data. If intersect false the nearest item is used to determine the
index.
Update the chart options to include the tooltips configurations. Set the mode to index
tooltips : {
mode : 'index'
},
The updated options would look like this.
const CHART_OPTIONS = {
tooltips : {
mode : 'index'
},
scales:
{
xAxes: [{
ticks: {
display: false,
},
}],
yAxes: [
{
type: 'linear',
id: 'y-axis-0',
display: false,
position: 'left',
},
{
type: 'linear',
id: 'y-axis-1',
display: false,
position: 'right',
},
],
},
};
Check updated sample which include tooltips mode set to index