Javascript 图表js-绘制气泡图中每个气泡的中心

Javascript 图表js-绘制气泡图中每个气泡的中心,javascript,meteor,charts,chart.js,Javascript,Meteor,Charts,Chart.js,我有一张带有大气泡的气泡图。我想在每个泡泡的中心画一个十字或任何东西,但我找不到任何解决方案。下图显示了上下文: 我在meteor上使用Chart.js 2.5.0。我对你的问题很感兴趣,因此,我构建了以下chartjs插件,这将有助于满足你的需求 Chart.plugins.register({ afterDraw: c => { let datasets = c.data.datasets; datasets.forEach((e, i) => {

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


我在meteor上使用Chart.js 2.5.0。

我对你的问题很感兴趣,因此,我构建了以下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();
            });
         }
      });
   }
});
ᴅᴇᴍᴏ

Chart.plugins.register({
后置绘图:c=>{
设dataset=c.data.dataset;
数据集.forEach((e,i)=>{
设isHidden=e._meta[0]。隐藏;
如果(!isHidden){
设data=c.getDatasetMeta(i).data;
data.forEach(e=>{
设ctx=c.chart.ctx;
设x=e._模型x;
设y=e._模型y;
设r=e.\u模型半径;
//画十字
//或者,您可以使用常规画布方法绘制任何内容
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=‘白色’;
ctx.lineWidth=2;
ctx.stroke();
ctx.restore();
});
}
});
}
});
设ctx=document.querySelector('#c').getContext('2d');
让图表=新图表(ctx{
类型:'气泡',
数据:{
标签:['一月','二月','三月'],
数据集:[{
标签:“约翰”,
数据:[
{x:5,y:5,r:10},
{x:10,y:10,r:15},
{x:16,y:15,r:18}
],
背景颜色:“#76d1bf”
}, {
标签:“史密斯”,
数据:[
{x:3,y:10,r:10},
{x:7,y:11,r:15},
{x:12,y:6,r:18}
],
背景颜色:“#827ada”
}]
},
选项:{
回答:错,
比例:{
xAxes:[{
滴答声:{
民:2,,
最高:18,
步长:4
}
}],
雅克斯:[{
滴答声:{
分:0,,
最高:20,
步长:4
}
}]
}
}
});

Chart.js一直是一个非常直接和简单的库。它的优点之一是易于定制。这也是JavaScript的优点之一,无论您使用什么库,源代码总是可用的

有一个是如何与定制撤退。一旦对库进行了更改,就必须使用那个特定的版本,因为定制不是作者在修改时会考虑的事情。 因此,要使用下面的代码,您应该转到并下载该项目,并在您的站点上使用该版本的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();   
然后添加自定义代码以呈现所需内容。保存当前二维上下文非常重要,因为您不必担心将某个内容进一步分解

        // 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.defaultDrawPoint=Chart.canvasHelpers.drawPoint;
Chart.canvasHelpers.drawPoint=函数(ctx、pointStyle、半径、x、y){
//默认为未定义的PointStyle
//PointStyle==“圆形”是默认命名样式
如果(点样式===未定义| |点样式===“圆”){
ctx.beginPath();
ctx.弧(x,y,半径,0,数学PI*2);
ctx.closePath();
ctx.fill();
//这里是自定义代码
保存();//保存状态
ctx.strokeStyle=“白色”;
ctx.strokeWidth=4;
ctx.beginPath();
ctx.moveTo(x-半径*0.3,y-半径*0.3);
ctx.lineTo(x+半径*0.3,y+半径*0.3);
ctx.moveTo(x+半径*0.3,y-半径*0.3);
ctx.lineTo(x-半径*0.3,y+半径*0.3);
ctx.stroke();
还原();//还原状态
}else{//所有其他样式将传递给默认处理程序
canvasHelpers.defaultDrawPoint(ctx,pointStyle,radius,x,y);
}
}
//添加数据的一些util
//返回一个随机整数
常数rand=(最小值,最大值=min+(最小值=0))=>Math.floor(Math.random()*(max-min)+min);
//返回一个随机数据点{x,y,r}
常数randData=()=>({x:rand(0,50),y:rand(5,50),r:rand(4,20)});
//创建一个图表。
const ctx=canvas.getContext(“2d”);
常量图表=新图表(ctx{
类型:“气泡”,
数据:{
数据集:[{
标签:“随机数据”,
背景色:“7AF”,
数据:(()=>{
var-dat=[];
对于(var i=0;i<10;i++){dat.push(randData())}
返回数据;
})(),
}]
},
选项:{responsive:false}//这是工作所必需的,否则会引发
//不知道为什么不是因为
//变化
});