问题
I need to plot a single value in line chart. Currently i am using charts.JS library for line graph purpose.
The data will be varied some times i'll get the single data inside the data set at that time i need to plot the single value with line in the line chart.
I tried with the charts.js annotation plugin but it wasn't met my requirements. which is like it wis overlapping the plotted point in the graph area.
CODE WHICH I HAD TRIED
createLineChart() {
this.lineChart = new Chart(this.lineCanvas.nativeElement, {
type: "line",
data: {
labels:[],
datasets: [
{
fill: false,
backgroundColor: "#0168FF",
borderColor: "#0168FF",
pointBackgroundColor: "white", // wite point fill
pointBorderWidth: 1, // point border width
lineTension: 0,
pointBorderColor: "blue",
pointRadius: 4,
},
],
},
options: {
scales: {
yAxes: [
{
ticks: {
padding: 20,
beginAtZero: true,
min: 0,
stepSize: 100,
},
gridLines: {
drawBorder: false,
},
},
],
xAxes: [
{
// offset: true,
ticks: {
display: false,
//beginAtZero: true,
min: 0,
},
gridLines: {
zeroLineColor: "transparent",
drawBorder: false,
display: false,
},
//offset:true,
},
],
legend: {
display: false,
},
tooltips: {
enabled: false,
},
},
drawTime: "afterDraw", // (default)
} as ChartOptions,
// plugins: [ChartAnnotation]
},
});
}
To generate dynamic data and plot in the graph area.
generateRandomDataSet(size) {
let yaxisArr = [];
let xaxisArr = [];
let random_data:any = this.getRandomData(size)
let maxYTickVal = Math.max.apply(Math, random_data.map((val) => {return val.yaxis}));
let maxVal = Math.ceil((maxYTickVal+1) / 10) * 10
for(let data of random_data) {
yaxisArr.push(data.yaxis)
xaxisArr.push(data.xaxis)
}
console.log("X-Axis array values : "+xaxisArr)
console.log("Y-Axis array values : "+yaxisArr)
this.lineChart.data.datasets[0].data = yaxisArr
this.lineChart.config.data.labels = []
this.lineChart.config.data.labels = xaxisArr
this.lineChart.config.options.scales.yAxes[0].ticks.max =maxVal
this.lineChart.config.options.scales.yAxes[0].ticks.stepSize = maxVal/2
this.lineChart.update()
}
getRandomData(arraySize) {
let data = []
for(var i=1; i<=arraySize; i++) {
let number = Math.floor(Math.random() * 200) + 1
data.push({'xaxis':i,'yaxis':number})
}
return data
}
with the above code i am getting like
what i need to have
回答1:
You can define an animation.onComplete function as follows to draw the line in case a single data value is present.
animation: {
onComplete: e => {
var ctx = chart.chart.ctx;
var data = chart.config.data.datasets[0].data;
if (data[0] == null) {
var xAxis = chart.scales['x-axis-0'];
var yAxis = chart.scales['y-axis-0'];
var y = yAxis.getPixelForValue(data[1]);
ctx.save();
ctx.globalCompositeOperation='destination-over';
ctx.strokeStyle = 'blue'
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(xAxis.left, y);
ctx.lineTo(xAxis.right, y);
ctx.stroke();
ctx.restore();
}
}
},
This function expects the data
array to be of format [null, <value>, null]
in case a single value is present, otherwise it will be hard to horizontally center the data point (see this answer). It's up to you to change the generateRandomDataSet()
function in a way that it provides such data.
Please have a look at your changed code below.
const chart = new Chart('line-chart', {
type: "line",
data: {
labels: ['', 'A', ''],
datasets: [{
data: [null, 120, null],
fill: false,
backgroundColor: "#0168FF",
borderColor: "#0168FF",
pointBackgroundColor: "white",
pointBorderWidth: 1,
lineTension: 0,
pointBorderColor: "blue",
pointRadius: 4,
}],
},
options: {
legend: {
display: false
},
tooltips: {
enabled: false
},
animation: {
onComplete: e => {
var ctx = chart.chart.ctx;
var data = chart.config.data.datasets[0].data;
if (data[0] == null) {
var xAxis = chart.scales['x-axis-0'];
var yAxis = chart.scales['y-axis-0'];
var y = yAxis.getPixelForValue(data[1]);
ctx.save();
ctx.globalCompositeOperation='destination-over';
ctx.strokeStyle = 'blue'
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(xAxis.left, y);
ctx.lineTo(xAxis.right, y);
ctx.stroke();
ctx.restore();
}
}
},
scales: {
yAxes: [{
ticks: {
padding: 20,
min: 0,
stepSize: 100
},
gridLines: {
drawBorder: false
}
}],
xAxes: [{
ticks: {
display: false
},
gridLines: {
zeroLineColor: "transparent",
drawBorder: false,
display: false
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="line-chart" height="80"></canvas>
来源:https://stackoverflow.com/questions/62131154/how-to-plot-a-single-value-with-line-in-line-chart-graph-using-charts-js