ChartJS 向网格和自定义 x 轴标签添加阴影颜色

时间:2021-05-27 17:45:09

标签: chart.js

我正在使用带有散点图的 chartJS 2.6.0。我使用的代码如下:

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta name="description" content="">
        <meta name="author" content="">
        <link rel="stylesheet" href="css/960.css" />
        <title>OCA-Test</title>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
    </head>
    <body>
        <div class="container_12">
            <canvas id="linechart"></canvas>
        <script>
var linedata = {
   datasets: [{
      fill: false,
      lineTension: 0,
      borderColor: "black",
      borderWidth: [2,2,2,2,2,2,2,2,2,2],
      pointBackgroundColor: ["blue", "blue","blue", "blue","blue", "blue","blue", "blue","blue", "blue"],
      pointRadius: [5,5,5,5,5,5,5,5,5,5],
      pointStyle: ["rect","rect","rect","rect","rect","rect","rect","rect","rect","rect"],
      data: [
      {x: 0.25, y: 80},
      {x: 0.75, y: -14},
      {x: 1.25, y: -46},
    {x: 1.75, y: 30},
    {x: 2.25, y: 14},
    {x: 2.75, y: -20},
    {x: 3.25, y: -72},
    {x: 3.75, y: -56},
    {x: 4.25, y: -24},
    {x: 4.75, y: -52}
      ]
   }]
};
var chartOptions = {
   responsive: true,
   maintainAspectRatio: true,
   legend: {display: false},
   gridLines :{
       
   },
   scales: {
      yAxes: [{
         ticks: {
            beginAtZero: false,
            max: 100,
            min: -100
         }
      }],
    xAxes: [{
        ticks: {
            display: false
        }
    }]
   }
};
var lineID = document.getElementById("linechart").getContext("2d");
var lineChart = new Chart(lineID, {
   type: "scatter",
   data: linedata,
   options: chartOptions
});
        </script>
    </body>
</html>

我想要做的是在每个网格列中间的 x 轴上显示一些文本,就像条形图看到的图像Bar graph image

此外,我想在 y 轴 -30 和 20 之间的网格中添加一种颜色,如下面的截图所示 HTML workaround

我所能做的就是在 HTML 中通过在图表下方显示

标签并使用边距以及在背景中放置一个图像来获取图像 2 中显示的内容,但这是一个丑陋的解决方案.

如有任何帮助,将不胜感激。

1 个答案:

答案 0 :(得分:0)

对于这两个要求,您可以编写自定义内联插件。

示例:

var options = {
  type: 'scatter',
  data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [{
      label: '# of Votes',
      data: [{
          x: 0.25,
          y: 80
        },
        {
          x: 0.75,
          y: -14
        },
        {
          x: 1.25,
          y: -46
        },
        {
          x: 1.75,
          y: 30
        },
        {
          x: 2.25,
          y: 14
        },
        {
          x: 2.75,
          y: -20
        },
        {
          x: 3.25,
          y: -72
        },
        {
          x: 3.75,
          y: -56
        },
        {
          x: 4.25,
          y: -24
        },
        {
          x: 4.75,
          y: -52
        }
      ],
      borderWidth: 1
    }]
  },
  options: {
    plugins: {
        customText: {
        text: ['hi', 'this', 'is', 'text', 'in', 'Mid', '!', ':)'],
        size: '20px',
        color: 'red',
        font: 'Arial black'
      },
      backgrounds: {
        hbars: [{
            from: -28,
            to: -80,
            color: "rgb(195, 230, 195)"
          },
          {
            from: 20,
            to: 28,
            color: "rgb(230, 220, 195)"
          },
          {
            from: 0,
            to: 20,
            color: "rgb(230, 195, 195)"
          }
        ]
      }
    }
  },
  plugins: [{
    id: 'backgrounds',
    beforeDraw: (chart, args, options) => {
      const {
        ctx,
        chartArea,
        scales
      } = chart;
      const y = scales['y-axis-1'];
      const x = scales['y-axis-1'];

      options.hbars.forEach((hBar) => {
        ctx.save();
        ctx.fillStyle = hBar.color;
        ctx.fillRect(chartArea.left, y.getPixelForValue(hBar.from), chartArea.right - chartArea.left, y.getPixelForValue(hBar.to) - y.getPixelForValue(hBar.from));
        ctx.restore();
      })
    }
  },
  {
    id: 'customText',
    afterDraw: (chart, args, options) => {
        const {
        ctx,
        chartArea,
        scales
      } = chart;
      const y = scales['y-axis-1'];
      const x = scales['x-axis-1'];
    
        options.text.forEach((text, i) => {
        ctx.save();
        ctx.textAlign = 'center';
        ctx.font = `${options.size || '20px'} ${options.font || 'Arial'}`;
        ctx.fillStyle = options.color || 'black'
        ctx.fillText(text, x.getPixelForValue((Number(x.ticks[0]) + Number(x.ticks[1])) / 2), y.getPixelForValue((Number(y.ticks[i]) + Number(y.ticks[i + 1])) / 2))

        ctx.restore();
      })
    }
  }]
}

var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
    <canvas id="chartJSContainer" width="600" height="400"></canvas>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
</body>