How to plot a single value with line in line chart graph using charts.js?

雨燕双飞 提交于 2021-02-04 08:39:05

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!