ChartJS 绘制气泡图中每个气泡的中心

eoxn13cs  于 2022-11-06  发布在  Chart.js
关注(0)|答案(3)|浏览(149)

我有一个气泡图,上面有很多大气泡。我想在每个气泡的中心画一个十字或其他东西,但是我找不到任何解决方案。下面的图片显示了上下文:

我使用Chart.js 2.5.0对流星。

zhte4eai

zhte4eai1#

你的问题似乎对我很感兴趣,因此,我构建了下面的chartjs插件,这将有助于满足您的要求.

Chart.plugins.register({
   afterDraw: c => {
      let datasets = c.data.datasets;
      datasets.forEach((e, i) => {
         let isHidden = e._meta[0].hidden;
         if (!isHidden) {
            let data = c.getDatasetMeta(i).data;
            data.forEach(e => {
               let ctx = c.chart.ctx;
               let x = e._model.x;
               let y = e._model.y;
               let r = e._model.radius;

               // draw a cross
               // or you can draw anything using general canvas methods
               ctx.save();
               ctx.beginPath();
               ctx.moveTo(x - r / 4, y - r / 4);
               ctx.lineTo(x + r / 4, y + r / 4);
               ctx.moveTo(x + r / 4, y - r / 4);
               ctx.lineTo(x - r / 4, y + r / 4);
               ctx.strokeStyle = 'white';
               ctx.lineWidth = 2;
               ctx.stroke();
               ctx.restore();
            });
         }
      });
   }
});

第一个

qlfbtfca

qlfbtfca2#

Chart.js一直是一个非常直接和简单的库。它的优点之一是很容易定制。这也是JavaScript的优点之一,源代码总是可以为你使用的任何库。
有一个如何以往任何时候都与定制后退。一旦你已经作出了改变的库,你将不得不使用该特定的版本,因为定制是不是一些作者会考虑时,作出改变。
所以要使用下面的代码,你应该去github page并下载项目,并使用该版本的chart.js为您的网站。我不改变原来的,大多数时候,每个定制是特定的一个特定的情况下,代码是在客户端定制。
修改很简单,先备份绘制点的函数

Chart.canvasHelpers.defaultDrawPoint = Chart.canvasHelpers.drawPoint;

这样做是为了让您可以将所有不感兴趣的调用传递回标准处理程序。
接下来,通过替换刚才备份的函数来编写截取代码。

Chart.canvasHelpers.drawPoint = function(ctx, pointStyle, radius, x, y){

通过查看原始源代码,您可以了解它是如何绘制圆圈的,并且只需捕获将所有其他参数变量传递给原始代码的行为。
如果pointStyle未定义或===“circle”,则您自行处理

// pointStyle undefined is default 
    // pointStyle === "circle" is the default named style
    if(pointStyle === undefined || pointStyle === "circle"){

        // next 4 lines copied from the source
        ctx.beginPath();
        ctx.arc(x, y, radius, 0, Math.PI * 2);
        ctx.closePath();
        ctx.fill();

然后添加您的自定义代码来渲染您喜欢的任何东西。保存当前的2D上下文是很重要的,因为您不想担心您会进一步破坏一些东西。

// draw a cross

        ctx.save();  // save the state
        ctx.strokeStyle = "white";
        ctx.strokeWidth = 4;
        ctx.beginPath();
        ctx.moveTo(x - radius *0.3, y - radius *0.3);
        ctx.lineTo(x + radius *0.3, y + radius *0.3);
        ctx.moveTo(x + radius *0.3, y - radius *0.3);
        ctx.lineTo(x - radius *0.3, y + radius *0.3);
        ctx.stroke();

然后恢复2D上下文的状态

ctx.restore(); // restore the state

else处理您不感兴趣的标准调用

}else{  // all other styles pass on to default handler
        Chart.canvasHelpers.defaultDrawPoint(ctx, pointStyle, radius, x, y);
    }

对于Chart.js,这一点特别有用,因为它提供了一种定制和获取动画的方法。
第一个
要回滚更改,只需将函数设置回原始值。

Chart.canvasHelpers.drawPoint = Chart.canvasHelpers.defualtDrawPoint;

并删除多余的引用

Chart.canvasHelpers.defualtDrawPoint = undefined;
nfeuvbwi

nfeuvbwi3#

grunt's answer对我不起作用。我不知道是否有不同的格式或者它是否是用过时的版本写的,但是我已经修改了他的解决方案,使它能在我的项目中工作。基本上我有

  • 删除了register,因为它与background-color的示例不一致,
  • 我发现数据点的信息不再是嵌套的,所以我也改变了访问属性的方式
plugins: [
          {
              id: 'background-colour',
              beforeDraw: (chart) => {
                  const ctx = chart.ctx;
                  ctx.save();
                  ctx.fillStyle = 'white';
                  ctx.fillRect(0, 0, width, height);
                  ctx.restore();
              }
          },
          {
              id: 'abc',
              afterDraw: (c) => {
                  let datasets = c.data.datasets;

                  datasets.forEach((e, i) => {

                      let isHidden = e.hidden;
                      if (!isHidden) {
                          let data = c.getDatasetMeta(i).data;
                          data.forEach(e => {
                              let ctx = c.ctx;
                              let x = e.x;
                              let y = e.y;
                              let r = e.options.radius as number;

                              ctx.save();
                              ctx.beginPath();
                              ctx.moveTo(x - r / 4, y - r / 4);
                              ctx.lineTo(x + r / 4, y + r / 4);
                              ctx.moveTo(x + r / 4, y - r / 4);
                              ctx.lineTo(x - r / 4, y + r / 4);
                              ctx.strokeStyle = 'white';
                              ctx.lineWidth = 2;
                              ctx.stroke();
                              ctx.restore();
                          });
                      }
                  });
              }
          }
      ]

相关问题