Find intersection between the chart lines in chartjs - javascript

I am trying to create a line chart that presents score level from 1-100.
Line is static and needs to be curved
but the dot on the chart is dynamic value and by that it changes its location along the existing line.
First I was thinking to add additional data that represents only the dot itself, but Y(height) is unknown.
Second attempt led me to create a second line that crosses / intersects the first one in hope of finding intersection point and making it a dot.
Unfortunately, I couldn't find a way to locate intersection.
This is expected result.
new Chart(
document.getElementById('lineChart'), {
type: 'line',
data: {
datasets: [
{
data: [
{
x: 70, y: 0,
},
{
x: 70, y: 100,
}],
fill: false,
borderColor: 'red',
showLine:true,
},
{
data: [
{
x: 0, y: 2,
},
{
x: 25, y: 10,
},
{
x: 50, y: 50,
},
{
x: 80, y: 90,
},
{
x: 100, y: 98,
}],
startWithZero: true,
fill: false,
lineTension: 0.3,
borderColor: 'blue',
}
]
},
options: {
bezierCurve : true,
lineTension: 0.3,
tooltips: {
mode: 'intersect'
},
scales: {
xAxes: [{
type: 'linear',
ticks: {
min: 0, //minimum tick
max: 100, //maximum tick
},
}],
yAxes: [{
ticks: {
bezierCurve : true,
min: 0, //minimum tick
max: 100, //maximum tick
},
bezierCurve : true,
type: 'linear',
lineTension: 0.3,
scaleLabel: {
lineTension: 0.1,
display: true,
}
}]
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<body>
<div style="width: 750px; height: 250px; margin: 0 auto;">
<canvas style="width: 750px; height: 250px" id="lineChart"></canvas>
</div>
</body>
You can check snippet in order to see example and how far I got.

Can you try to create dynamic values
const lineData = [
{ x: 0, y: 2 },
{ x: 10, y: 3 },
{ x: 20, y: 10 },
{ x: 30, y: 20 },
{ x: 40, y: 35 },
{ x: 50, y: 50 },
{ x: 60, y: 65 },
{ x: 70, y: 80 },
{ x: 80, y: 90 },
{ x: 90, y: 97 },
{ x: 100, y: 98 },
];
const xValue = 70;
let key = Math.floor(xValue / 10);
let diff = (lineData[key + 1].y - lineData[key].y) / 10;
let toAdd = (xValue - lineData[key].x) * diff;
const yValue = lineData[key].y + toAdd;
And include dynamic values in chartJs code
new Chart(
document.getElementById('lineChart'), {
type: 'line',
data: {
datasets: [
{
data: lineData,
startWithZero: true,
fill: false,
lineTension: 0.3,
borderColor: 'blue',
}
]
},
options: {
bezierCurve : true,
lineTension: 0.3,
tooltips: {
mode: 'intersect'
},
scales: {
xAxes: [{
type: 'linear',
ticks: {
min: 0, //minimum tick
max: 100, //maximum tick
},
}],
yAxes: [{
ticks: {
bezierCurve : true,
min: 0, //minimum tick
max: 100, //maximum tick
},
bezierCurve : true,
type: 'linear',
lineTension: 0.3,
scaleLabel: {
lineTension: 0.1,
display: true,
}
}]
}
}
})
const lineData = [
{ x: 0, y: 2 },
{ x: 10, y: 3 },
{ x: 20, y: 10 },
{ x: 30, y: 20 },
{ x: 40, y: 35 },
{ x: 50, y: 50 },
{ x: 60, y: 65 },
{ x: 70, y: 80 },
{ x: 80, y: 90 },
{ x: 90, y: 97 },
{ x: 100, y: 98 },
];
const xValue = 70;
let key = Math.floor(xValue / 10);
let diff = (lineData[key + 1].y - lineData[key].y) / 10;
let toAdd = (xValue - lineData[key].x) * diff;
const yValue = lineData[key].y + toAdd;
new Chart(
document.getElementById('lineChart'), {
type: 'line',
data: {
datasets: [
{
data: lineData,
startWithZero: true,
fill: false,
lineTension: 0.3,
borderColor: 'blue',
}
]
},
options: {
bezierCurve : true,
lineTension: 0.3,
tooltips: {
mode: 'intersect'
},
scales: {
xAxes: [{
type: 'linear',
ticks: {
min: 0, //minimum tick
max: 100, //maximum tick
},
}],
yAxes: [{
ticks: {
bezierCurve : true,
min: 0, //minimum tick
max: 100, //maximum tick
},
bezierCurve : true,
type: 'linear',
lineTension: 0.3,
scaleLabel: {
lineTension: 0.1,
display: true,
}
}]
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<body>
<div style="width: 750px; height: 250px; margin: 0 auto;">
<canvas style="width: 750px; height: 250px" id="lineChart"></canvas>
</div>
</body>

Related

Chart.js - Multiple JSON data object array [{x: Date, y: count}....] representing each dataset of the chart

I've been trying to implement a Stacked Area Line Chart using Chart.js, which in turn uses multiple datasets as an input for each line graph.
Although I'am able to view the final stacked chart with the associated dataset, I can clearly notice that y-axis data is falsely represented(hover on data-point) w.r.t x-axis for each dataset, which is a major issue.
Major issues are:
x-axis and y-axis mapping issue for 2nd dataset chart onwards
x-axis values (dates) are repetitive and not in order - causes an abrupt display of chart
To be more clear, I need dataset1[ {x: "2030*08-03", y: 8},{}...] to precisely map keys x and y to the respective x-axis and y-axis of chart1, similary, dataset2[ {x: "2030*08-10", y: 8},{}...] mapping to the 2nd chart respectively and so on.
This is the sample codepen implementation replicating the issue.
Also, I'm adding the complete code snippet for a clear understanding.
var ctx = document.getElementById("myChart").getContext("2d");
const colors = {
green: {
fill: 'rgb(0,128,0,0.2)',
stroke: 'green',
},
grey: {
fill: 'rgb(128,128,128, 0.2)',
stroke: 'grey',
},
red: {
fill: 'rgba(255, 0, 0, 0.2)',
stroke: 'red',
}
};
const data1 = [
{x: "2030*08-03", y: 8},
{x: "2030-08-04", y: 1},
{x: "2030-08-08", y: 2},
{x: "2030-08-09", y: 10},
{x: "2030-08-10", y: 2},
{x: "2030-08-12", y: 34} ];
const data2 = [
{x: "2030-08-09", y: 1},
{x: "2030-08-12", y: 12},
{x: "2030-08-13", y: 3},
{x: "2030-08-15", y: 3}
];
const data3 = [
{x: "2030-08-06", y: 1},
{x: "2030-08-09", y: 12},
{x: "2030-08-10", y: 3},
{x: "2030-08-12", y: 3} , ];
const myChart = new Chart(ctx, {
type: 'line',
data: {
datasets: [
{
label: "Data1",
fill: true,
backgroundColor: colors.green.fill,
pointBackgroundColor: colors.green.stroke,
borderColor: colors.green.stroke,
pointHighlightStroke: colors.green.stroke,
borderCapStyle: 'butt',
data: data1,
},
{
label: "Data2",
fill: true,
backgroundColor: colors.grey.fill,
pointBackgroundColor: colors.grey.stroke,
borderColor: colors.grey.stroke,
pointHighlightStroke: colors.grey.stroke,
data: data2,
},
{
label: "Data3",
fill: true,
backgroundColor: colors.red.fill,
pointBackgroundColor: colors.red.stroke,
borderColor: colors.red.stroke,
pointHighlightStroke: colors.red.stroke,
data: data3,
}
]
},
options: {
plugins: {
responsive: true,
legend: {
display: true,
position: 'bottom',
},
title: {
display: true,
text: 'Status',
padding: {
top: 20,
bottom: 15
},
font: {
weight: "bold",
size: 25
}
}
},
layout: {
padding: {
left: 20,
right: 0,
top: 0,
bottom: 25
}
},
scales: {
x: {
ticks: {
align: "center"
}
},
y: {
stacked: true,
title: {
display: true,
text: "Count",
font: {
weight: "bold",
size: 20
}
}
},
},
parsing: {
xAxisKey: 'x',
yAxisKey: 'y'
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.0/chart.min.js"></script>
<canvas id="myChart" width="400" height="200"></canvas>
Any help will be greatly appreciated. Thanks in advance.
This behaviour is happening because chart.js automatically adds the labels if they are not there and doesnt care about ordering, you have 2 ways of fixing it, providing a labels array with all the labels in correct order already:
var ctx = document.getElementById("myChart").getContext("2d");
const colors = {
green: {
fill: 'rgb(0,128,0,0.2)',
stroke: 'green',
},
grey: {
fill: 'rgb(128,128,128, 0.2)',
stroke: 'grey',
},
red: {
fill: 'rgba(255, 0, 0, 0.2)',
stroke: 'red',
}
};
const data1 = [{
x: "2030-08-03",
y: 8
},
{
x: "2030-08-04",
y: 1
},
{
x: "2030-08-08",
y: 2
},
{
x: "2030-08-09",
y: 10
},
{
x: "2030-08-10",
y: 2
},
{
x: "2030-08-12",
y: 34
}
];
const data2 = [{
x: "2030-08-09",
y: 1
},
{
x: "2030-08-12",
y: 12
},
{
x: "2030-08-13",
y: 3
},
{
x: "2030-08-15",
y: 3
}
];
const data3 = [{
x: "2030-08-06",
y: 1
},
{
x: "2030-08-09",
y: 12
},
{
x: "2030-08-10",
y: 3
},
{
x: "2030-08-12",
y: 3
},
];
const myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["2030-08-03", "2030-08-04", "2030-08-06", "2030-08-08", "2030-08-09", "2030-08-10", "2030-08-12", "2030-08-13", "2030-08-15"],
datasets: [{
label: "Data1",
fill: true,
backgroundColor: colors.green.fill,
pointBackgroundColor: colors.green.stroke,
borderColor: colors.green.stroke,
pointHighlightStroke: colors.green.stroke,
borderCapStyle: 'butt',
data: data1,
},
{
label: "Data2",
fill: true,
backgroundColor: colors.grey.fill,
pointBackgroundColor: colors.grey.stroke,
borderColor: colors.grey.stroke,
pointHighlightStroke: colors.grey.stroke,
data: data2,
},
{
label: "Data3",
fill: true,
backgroundColor: colors.red.fill,
pointBackgroundColor: colors.red.stroke,
borderColor: colors.red.stroke,
pointHighlightStroke: colors.red.stroke,
data: data3,
}
]
},
options: {
plugins: {
responsive: true,
legend: {
display: true,
position: 'bottom',
},
title: {
display: true,
text: 'Status',
padding: {
top: 20,
bottom: 15
},
font: {
weight: "bold",
size: 25
}
}
},
layout: {
padding: {
left: 20,
right: 0,
top: 0,
bottom: 25
}
},
scales: {
x: {
ticks: {
align: "center"
}
},
y: {
stacked: true,
title: {
display: true,
text: "Count",
font: {
weight: "bold",
size: 20
}
}
},
},
parsing: {
xAxisKey: 'x',
yAxisKey: 'y'
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.0/chart.min.js"></script>
<canvas id="myChart" width="400" height="100"></canvas>
Codepen: https://codepen.io/leelenaleee/pen/gOWNXKm?editors=1010
Or you can use a time axis:
var ctx = document.getElementById("myChart").getContext("2d");
const colors = {
green: {
fill: 'rgb(0,128,0,0.2)',
stroke: 'green',
},
grey: {
fill: 'rgb(128,128,128, 0.2)',
stroke: 'grey',
},
red: {
fill: 'rgba(255, 0, 0, 0.2)',
stroke: 'red',
}
};
const data1 = [{
x: "2030-08-03",
y: 8
},
{
x: "2030-08-04",
y: 1
},
{
x: "2030-08-08",
y: 2
},
{
x: "2030-08-09",
y: 10
},
{
x: "2030-08-10",
y: 2
},
{
x: "2030-08-12",
y: 34
}
];
const data2 = [{
x: "2030-08-09",
y: 1
},
{
x: "2030-08-12",
y: 12
},
{
x: "2030-08-13",
y: 3
},
{
x: "2030-08-15",
y: 3
}
];
const data3 = [{
x: "2030-08-06",
y: 1
},
{
x: "2030-08-09",
y: 12
},
{
x: "2030-08-10",
y: 3
},
{
x: "2030-08-12",
y: 3
},
];
const myChart = new Chart(ctx, {
type: 'line',
data: {
datasets: [{
label: "Data1",
fill: true,
backgroundColor: colors.green.fill,
pointBackgroundColor: colors.green.stroke,
borderColor: colors.green.stroke,
pointHighlightStroke: colors.green.stroke,
borderCapStyle: 'butt',
data: data1,
},
{
label: "Data2",
fill: true,
backgroundColor: colors.grey.fill,
pointBackgroundColor: colors.grey.stroke,
borderColor: colors.grey.stroke,
pointHighlightStroke: colors.grey.stroke,
data: data2,
},
{
label: "Data3",
fill: true,
backgroundColor: colors.red.fill,
pointBackgroundColor: colors.red.stroke,
borderColor: colors.red.stroke,
pointHighlightStroke: colors.red.stroke,
data: data3,
}
]
},
options: {
plugins: {
responsive: true,
legend: {
display: true,
position: 'bottom',
},
title: {
display: true,
text: 'Status',
padding: {
top: 20,
bottom: 15
},
font: {
weight: "bold",
size: 25
}
}
},
layout: {
padding: {
left: 20,
right: 0,
top: 0,
bottom: 25
}
},
scales: {
x: {
type: 'time',
ticks: {
align: "center"
}
},
y: {
stacked: true,
title: {
display: true,
text: "Count",
font: {
weight: "bold",
size: 20
}
}
},
},
parsing: {
xAxisKey: 'x',
yAxisKey: 'y'
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.0/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
<canvas id="myChart" width="400" height="100"></canvas>
Codepen: https://codepen.io/leelenaleee/pen/GRmbOxN?editors=1010

how can i use chart.js to create a chart that has one time series line and one linear line on it at the same time?

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>

Chart.js: Can't get a coordinate for value for x axis unless x axis has the exact same value

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>

Draw Circle on EChart

I have the following Apache EChart:
var option = {
series: [
{
name: 'RollPitch',
type: 'gauge',
data: [
{
value: 0,
name: '',
itemStyle: { color: '#CF4437' },
},
],
min: 0,
max: 360,
splitNumber: 4,
splitLine: {
show: false,
},
startAngle: 0,
endAngle: 359.9999999,
axisLine: {
lineStyle: {
color: [[100, '#D8D8D8']],
width: 50,
},
},
axisTick: {
show: false,
},
pointer: {
show: true,
length: '110%',
width: 8,
},
detail: {
show: false,
},
},
],
};
https://echarts.apache.org/examples/en/editor.html?
What I want to achieve is to draw a circle given with x and y coordinates.
Can somebody give me a hint how a possible solution would be achieved?
Shall I draw on the canvas that is created by ECharts? How to map the position?
To draw a shape you can with the two ways:
The custom series (too expensive and complex for this case)
With the graphic component (more suitable option)
In general you need to add the component then setup predefined shape circle and you will have small circle.
var option = {
graphic: [{
elements: [{
id: 'small_circle',
type: 'circle',
z: 100,
shape: {
cx: 350,
cy: 200,
r: 20,
},
style: {
fill: 'rgba(0, 140, 250, 0.5)',
stroke: 'rgba(0, 50, 150, 0.5)',
lineWidth: 2,
}
}]
}]
// series: [...]
}
Bonus: how to update circle coordinates:
var myChart = echarts.init(document.getElementById('main'));
var option = {
graphic: [{
elements: [{
id: 'small_circle',
type: 'circle',
z: 100,
shape: {
// "... draw a circle given with x and y coordinates." — it's here
cx: 350,
cy: 200,
r: 20,
},
style: {
fill: 'rgba(0, 140, 250, 0.5)',
stroke: 'rgba(0, 50, 150, 0.5)',
lineWidth: 2,
}
}]
}],
series: [{
name: 'RollPitch',
type: 'gauge',
data: [{
value: 0,
name: '',
itemStyle: {
color: '#CF4437'
},
}, ],
min: 0,
max: 360,
splitNumber: 4,
splitLine: {
show: false,
},
startAngle: 0,
endAngle: 359.9999999,
axisLine: {
lineStyle: {
color: [
[100, '#D8D8D8']
],
width: 50,
},
},
axisTick: {
show: false,
},
pointer: {
show: true,
length: '110%',
width: 8,
},
detail: {
show: false,
},
}, ],
};
myChart.setOption(option);
/* Taken from https://stackoverflow.com/a/35455786/1597964 */
function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
var angleInRadians = (angleInDegrees - 90) * Math.PI / 180.0;
return [
centerX + (radius * Math.cos(angleInRadians)),
centerY + (radius * Math.sin(angleInRadians))
]
}
var angle = 90;
setInterval(function() {
var [cx, cy] = polarToCartesian(300, 200, 50, angle);
myChart.setOption({
graphic: [{
id: 'small_circle',
shape: {
cx: cx,
cy: cy,
}
}]
});
angle = angle + 1;
}, 20);
<script src="https://cdn.jsdelivr.net/npm/echarts#4.8.0/dist/echarts.min.js"></script>
<div id="main" style="width: 600px;height:400px;"></div>

Chart.js - how to make proportional intervals on X axis on line chart

I'm using Chart.js to draw the line chart with 6 points. That points are:
x: 140, y: null,
x: 150.5, y: 3500,
x: 886.35, y: 3500,
x: 1617.2, y: 0,
x: 2348.05, y: 0
x: 2583, y: null
As one can see, the intervals between x0 and x1 (and also x4-x5) are much smaller than x1-x2-x3-x4. But on the chart they are being drawn like they are equal:
I would rather expect, that the gap between x0 and x1 will be much shorter than between x1 and x2. Can it be done some way?
Code snippet:
var chart = new Chart(document.getElementById("myChart1"), {
type: 'line',
data: {
labels: [140, 155.5, 886.35, 1617.2, 2348.05, 2583],
datasets: [{
label: 'My chart',
spanGaps: true,
lineTension: 0,
data: [{
x: 140,
y: null
},
{
x: 155.5,
y: 3500
},
{
x: 886.35,
y: 3500
},
{
x: 1617.2,
y: 0
},
{
x: 2348.05,
y: 0
},
{
x: 2583,
y: null
}
],
fill: false,
borderColor: '#4bc0c0'
}]
},
options: {
showXLabels: 30,
legend: {
display: false
},
tooltips: {
enabled: true,
},
scales: {
yAxes: [{
scaleLabel: {
display: true
},
ticks: {
suggestedMin: 0,
suggestedMax: 3700
}
}],
xAxes: [{
scaleLabel: {
display: true,
},
ticks: {
autoSkip: true,
maxTicksLimit: 10
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="myChart1"></canvas>
Just add type: 'linear' to the xAxes object, like this:
xAxes: [{
type: 'linear',
scaleLabel: { ...
Your first point has y:null and it won't be included on the chart. I changed it to x:140,y:0.
try{
var chart = new Chart(document.getElementById("my_chart"), {
type: 'line',
data: {
labels: [140, 155.5, 886.35, 1617.2, 2348.05, 2583],
datasets: [{
label: 'My chart',
spanGaps: false,
lineTension: 0,
data: [{
x: 140,
y: 0
},
{
x: 155.5,
y: 3500
},
{
x: 886.35,
y: 3500
},
{
x: 1617.2,
y: 0
},
{
x: 2348.05,
y: 0
},
{
x: 2583,
y: null
}
],
fill: false,
borderColor: '#4bc0c0'
}]
},
options: {
showXLabels: 30,
legend: {
display: false
},
tooltips: {
enabled: true,
},
scales: {
yAxes: [{
scaleLabel: {
display: true
},
ticks: {
suggestedMin: 0,
suggestedMax: 3700
}
}],
xAxes: [{
type: 'linear', /* <--- this */
scaleLabel: {
display: true,
},
ticks: {
autoSkip: true,
maxTicksLimit: 10
}
}]
}
}
});
}catch(e){}
body { m1argin-bottom: -30px }
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="my_chart"></canvas>

Categories