I am using chart.js to create some charts, and I need to make line chart that have multiple entries for the same point in the X axes.
In other words, this:
Whatever I try, i can not create it to look like the image.
Dose anyone know how I can manage this (with plugins or without)?
This can be done with a scatter graph, the data has to be an array of objects with x and y, also you can adjust the tension of the line.
var data = {
datasets: [{
label: "Dataset #1",
backgroundColor: "rgba(255,99,132,0.2)",
borderColor: "rgba(255,99,132,1)",
borderWidth: 2,
hoverBackgroundColor: "rgba(255,99,132,0.4)",
hoverBorderColor: "rgba(255,99,132,1)",
data: [{
x: 0,
y: 5
},
{
x: 1,
y: 10
},
{
x: 1,
y: 5
},
{
x: 3,
y: 10
}]
}]
};
var option = {
scales: {
yAxes: [{
stacked: true,
gridLines: {
display: true,
color: "rgba(255,99,132,0.2)"
}
}],
xAxes: [{
gridLines: {
display: true,
color: "rgba(255,99,132,0.2)"
}
}]
},
elements: {
line: {
tension: .1, // bezier curves
}
}
};
Chart.Scatter('chart_0', {
options: option,
data: data
});
[Codepen]https://codepen.io/devil-geek/pen/KrQWBP
Related
Chart.js translation for plotting on frontend side in Laravel. There is a yield of 3 months dates and their datas. How should I fit charjs that overlap and not all dates are written at the end of x? (texts are overlapping, i dont want it, and I want all the dates to be on the x-axis, I think chartjs skipped it because couldn't fit it.) it is important can you contact with me
var myChart1 = new Chart(ctx1, {
type: 'bar',
data: {
labels: dates,
datasets: [{
label: 'BACKLOG ON HOLD INCIDENTS AVG PERFORMANCE- BURSA',
data: results,
backgroundColor: [
'rgba(76, 196, 23, 0.6)'
],
borderColor: [
'rgba(219, 249, 219, 1)',
],
borderWidth: 1,
}]
},
plugins: [ChartDataLabels],
options: {
plugins:{
legend:{
display:true
},
datalabels:{
color:'blue',
anchor:'end',
font:{
weight:'bold',
size:8
}
}
},
scales: {
y: {
beginAtZero: true
},
x: {
ticks: {
maxRotation: 90,
minRotation: 90,
font: {
size: 8,
}
}
}
},
animation: {
duration: 0
}
}
});
I want to draw a reference line in the time series chart. I tried to use two x axis and two y axis so I have like two graphs in one. the one would show time scale line and the other one would show linear line (reference line).
image example of what I want it to look like :
I tried in fiddle but its like the two X axis are connected and not scaling separately:
var data = {
labels: [],
datasets: [{
fill: 'none',
label: 'signal1',
backgroundColor: 'rgba(75,192,192,0.4)',
pointRadius: 5,
pointHoverRadius: 7,
borderColor: 'rgba(75,192,192,1)',
borderWidth: 1,
lineTension: 0,
xAxisID: 'xAxis1',
yAxisID: 'yAxis1',
data: [{
x: '2016-07-17',
y: 44
},
{
x: '2016-07-19',
y: 50
},
{
x: '2016-07-22',
y: 84
},
],
}, {
fill: 'none',
label: 'signal2',
lineTension: 0,
xAxisID: 'xAxis2',
yAxisID: 'yAxis2',
data: [{
x: 0,
y: 55
},
{
x: 1,
y: 55
},
]
}],
};
var option = {
scales: {
yAxes: [{
id: 'yAxis1',
offset: true,
gridLines: {
color: 'rgba(151, 151, 151, 0.2)',
display: true,
zeroLineColor: '#979797',
zeroLineWidth: 1,
tickMarkLength: 15,
drawBorder: true,
},
ticks: {
beginAtZero: false,
padding: 5,
fontSize: 12,
fontColor: '#222222',
},
}, {
id: 'yAxis2',
gridLines: {
color: 'rgba(151, 151, 151, 0.2)',
display: false,
drawBorder: false,
},
ticks: {
beginAtZero: false,
},
}],
xAxes: [{
id: 'xAxis1',
offset: true,
bounds: 'data',
type: 'time',
distribution: 'linear',
time: {
unit: 'day',
displayFormats: {
day: 'D.M.YYYY',
},
},
gridLines: {
display: true,
color: 'rgba(151, 151, 151, 0.2)',
zeroLineColor: '#979797',
zeroLineWidth: 1,
tickMarkLength: 5,
drawBorder: true,
},
ticks: {
source: 'auto',
autoSkip: true,
autoSkipPadding: 30,
maxRotation: 0,
padding: 2,
fontSize: 12,
fontColor: '#222222',
},
}, {
id: 'xAxis2',
type:"linear",
gridLines: {
display: false,
drawBorder: false,
},
}]
}
};
https://jsfiddle.net/2gyk9v5e/15/
This can be done with the Plugin Core API. The API offers different hooks that may be used for executing custom code. In your case, you can use the afterDraw hook to draw the desired lines directly on the canvas using CanvasRenderingContext2D.
plugins: [{
afterDraw: chart => {
var ctx = chart.chart.ctx;
var xAxis = chart.scales['x-axis-0'];
var yAxis = chart.scales['y-axis-0'];
ctx.save();
chart.data.datasets[0].refLines.forEach(r => {
var y = yAxis.getPixelForValue(r.y);
ctx.strokeStyle = r.color;
ctx.beginPath();
ctx.moveTo(xAxis.left, y);
ctx.lineTo(xAxis.right, y);
ctx.stroke();
});
ctx.restore();
}
}],
Above code assumes that the reference lines are defined inside your dataset through the following definition.
refLines: [
{ y: 45, color: '#0be059' },
{ y: 49, color: '#fc3503' }
]
Please take a look at your amended code and see how it works.
new Chart('canvas', {
type: 'line',
plugins: [{
afterDraw: chart => {
var ctx = chart.chart.ctx;
var xAxis = chart.scales['x-axis-0'];
var yAxis = chart.scales['y-axis-0'];
ctx.save();
chart.data.datasets[0].refLines.forEach(r => {
var y = yAxis.getPixelForValue(r.y);
ctx.strokeStyle = r.color;
ctx.beginPath();
ctx.moveTo(xAxis.left, y);
ctx.lineTo(xAxis.right, y);
ctx.stroke();
});
ctx.restore();
}
}],
data: {
datasets: [{
fill: false,
label: 'signal1',
backgroundColor: 'rgba(75,192,192,0.4)',
pointRadius: 5,
pointHoverRadius: 7,
borderColor: 'rgba(75,192,192,1)',
borderWidth: 1,
lineTension: 0,
data: [
{ x: '2016-07-14', y: 44 },
{ x: '2016-07-15', y: 52 },
{ x: '2016-07-16', y: 45 },
{ x: '2016-07-17', y: 47 },
{ x: '2016-07-18', y: 35 },
{ x: '2016-07-19', y: 46 },
{ x: '2016-07-20', y: 50 },
{ x: '2016-07-21', y: 44 }
],
refLines: [
{ y: 45, color: '#0be059' },
{ y: 49, color: '#fc3503' }
]
}]
},
options: {
scales: {
yAxes: [{
gridLines: {
color: 'rgba(151, 151, 151, 0.2)',
display: false,
drawBorder: false
}
}],
xAxes: [{
offset: true,
bounds: 'data',
type: 'time',
time: {
unit: 'day',
displayFormats: {
day: 'D.M.YYYY',
}
},
gridLines: {
color: 'rgba(151, 151, 151, 0.2)',
zeroLineColor: '#979797',
zeroLineWidth: 1,
tickMarkLength: 5,
drawBorder: true
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.bundle.min.js"></script>
<canvas id="canvas" height="80"></canvas>
What I want to do is to get a position for x axis but I found out I can't get it unless the x axis has the exact same value. But for y axis, I can get position for a value as long as the value is in range of y axis.
Is there a way to get a coordinate for a value in x axis? X axis's labels are numbers and each label has an equal step between the next one.
My current code is like this.
<script>
import { Line } from 'vue-chartjs'
export default {
extends: Line,
data() {
return {
chartdata: {
labels: [
10, 20, 30, 40, 50, 60, 70, 80, 90, 100,
],
datasets: [
{
label: '',
data: [
34, 56, 78, 12, 45, 67, 12, 89, 93, 43,
],
type: 'line',
borderColor: 'red',
fill: false,
lineTension: 0,
}
],
},
options: {
responsive: true,
scales: {
xAxes: [{
scaleLabel: {
display: true,
labelString: 'x',
}
}],
yAxes: [{
ticks: {
beginAtZero: true,
stepSize: 10,
suggestedMax: 100,
},
scaleLabel: {
display: true,
labelString: 'y',
}
}],
}
}
}
},
mounted() {
this.addPlugin({
beforeDraw: (chart) => {
console.log(chart.scales['y-axis-0'].getPixelForValue(23.56)); // Can get a coordinate in canvas
console.log(chart.scales['x-axis-0'].getPixelForValue(36.98)); // The coordinate I get is out of canvas
console.log(chart.scales['x-axis-0'].getPixelForValue(40)); // Can get a coordinate in canvas because label has the same value (40)
}
});
this.renderChart(this.chartdata, this.options);
}
}
</script>
When the data is an array of numbers, the x-axis is generally a category. The points are placed onto the axis using their position in the array, which should also match a value from labels.
Yo need to change the x-axis into linear type in order to obtain correct values from the function getPixelForValue.
Don't define labels
Define the data as an array of points using objects containing x and y properties each.
Add type: 'linear' to the xAxes option
Please take a look at your amended code and see how it works.
new Chart("chart", {
type: 'line',
plugins: [{
beforeDraw: (chart) => {
console.log(chart.scales['y-axis-0'].getPixelForValue(23.56));
console.log(chart.scales['x-axis-0'].getPixelForValue(36.98));
console.log(chart.scales['x-axis-0'].getPixelForValue(40));
}
}],
data: {
datasets: [{
label: '',
data: [
{ x: 10, y:34 },
{ x: 20, y:56 },
{ x: 30, y:78 },
{ x: 40, y:12 },
{ x: 50, y:45 },
{ x: 60, y:67 },
{ x: 70, y:12 },
{ x: 80, y:89 },
{ x: 90, y:93 },
{ x: 100, y:43 }],
type: 'line',
borderColor: 'red',
fill: false,
lineTension: 0,
}],
},
options: {
responsive: true,
scales: {
xAxes: [{
type: 'linear',
scaleLabel: {
display: true,
labelString: 'x',
}
}],
yAxes: [{
ticks: {
beginAtZero: true,
stepSize: 10,
suggestedMax: 100,
},
scaleLabel: {
display: true,
labelString: 'y',
}
}],
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="chart" height="200"></canvas>
I have a bit of a unique chart.js issue here whereas I'm attempting to plot points on a linear chart on a single X axis only. For a visual reference, this chart would look like a vertical line with multiple Y values on a single X value. So far I cannot get the charts.js scipt to not automatically space values across the width of the chart at 100%, even with all X values declared at 0. I've got the sample data set with basic filler with a 0 X Value for each in the following.
<script>
var chart = new Chart(linechart, {
type: 'line',
options: {
scales: {
xAxes: [{
gridLines: {
},
ticks: {
suggestedMin: 0,
},
}],
yAxes: [{
gridLines: {
},
ticks: {
suggestedMin: 0,
suggestedMax: 12,
stepSize: 0.5
},
}]
},
legend: {
}
},
data: {
datasets: [{
data: [{x: 0, y: 12}, {x: 0, y: 11}, {x: 0, y: 10}],
pointBackgroundColor: "rgba(193,46,12,0.5)",
pointBordercolor: "rgba(193,46,12,1)",
pointRadius: 5,
fill: true,
showLine: false
}]
}
});
</script>
The issue here is that the x-axis default type of a line chart is category. To turn this into linear, simply add type: 'linear' to the x-axis as follows:
options: {
scales: {
xAxes: [{
type: 'linear',
...
Please take a look at your amended code below and see how it works.
new Chart('myChart', {
type: 'line',
data: {
datasets: [{
label: 'Dataset',
data: [{ x: 0, y: 12 }, { x: 0, y: 11 }, { x: 0, y: 10 }],
pointBackgroundColor: "rgba(193,46,12,0.5)",
pointBordercolor: "rgba(193,46,12,1)",
pointRadius: 5,
fill: false,
}]
},
options: {
scales: {
xAxes: [{
type: 'linear',
gridLines: {},
ticks: {
suggestedMin: 0,
}
}],
yAxes: [{
gridLines: {},
ticks: {
suggestedMin: 0,
suggestedMax: 12,
stepSize: 0.5
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="myChart" height="200"></canvas>
Hello I writed this code using javascript and Chart.js :
<script>
new Chart(document.getElementById("line-chart"),
{type:'line',
data: {
labels: [18.123,46.8603108462,75.5976216923,104.334932538],
datasets: [{
data: [418872.777267,262233.131655,180687.131758,133676.324505],
label: "Model",
borderColor: "#3e95cd",
fill: false
}]
}
},
{
type: 'scatter',
data: {
datasets: [{
label : 'Data',
fill:false,
showLine: false,
backgroundColor: "#FF0000",
data : [{x: 17.0, y: 454995.091169},
{x: 18.0, y: 457656.874749},
{x: 19.0, y: 444574.49162},
{x: 20.0, y: 432511.514968},
{x: 21.0, y: 421184.776328}],
}]
},
options: {
title:{
display: true,
text:"Test"},
scales: {
xAxes: [{
type: 'logarithmic',
position: 'bottom'
}],
yAxes: [{
type: 'logarithmic'
}]
}
}
}
);
</script>
And the problem is I don't see the scatter plot, I see only the first plot. Actually I would like to plot these two plot on the same graph in logarithmic scale.
Thank you very much !
You need to add one dataset with type "scatter" in the line datasets. You can checkout their mixed chart documentation here http://www.chartjs.org/docs/latest/charts/mixed.html.
You can checkout my running example here https://jsfiddle.net/sherlcode13/m3mfz6jh/5/
var ctx = new Chart(document.getElementById("line-chart"), {
type: 'line',
data: {
labels: [18.123,46.8603108462,75.5976216923,104.334932538],
datasets: [{
data: [418872.777267,262233.131655,180687.131758,133676.324505],
label: "Model",
borderColor: "#3e95cd",
fill: false
}, {
label : 'Data',
fill:false,
showLine: false,
data : [{x: 17.0, y: 454995.091169},
{x: 18.0, y: 457656.874749},
{x: 19.0, y: 444574.49162},
{x: 20.0, y: 432511.514968},
{x: 21.0, y: 421184.776328}],
type: 'scatter'
}
]
},
options: {
title:{
display: true,
text:"Test"
},
scales: {
xAxes: [{
type: 'logarithmic',
position: 'bottom'
}],
yAxes: [{
type: 'logarithmic'
}]
}
}
})
You can use the mixed chart, it is possible to create mixed charts that are a combination of two or more different chart types
http://www.chartjs.org/docs/latest/charts/mixed.html