如何遮蔽ChartJS气泡图背景的一部分?

时间:2017-01-25 21:01:07

标签: javascript charts chart.js

我设法弄清楚如何增强我在stackoverflow中找到的解决方案,用于将垂直和水平线添加到ChartJS v2 +中的折线图以应用于气泡图ChartJS Bubble w/Lines(我建议跳过到最后的更新以获得更好的方法)

 var originalBubbleDraw = Chart.controllers.bubble.prototype.draw;
  Chart.helpers.extend(Chart.controllers.bubble.prototype, {
    draw: function() {
      originalBubbleDraw.apply(this, arguments);

      var chart = this.chart;
      var ctx = chart.chart.ctx;
      var xaxis = chart.scales['x-axis-0'];
      var yaxis = chart.scales['y-axis-0'];

      var xvalue = chart.config.data.queryLimits['x'];
      var yvalue = chart.config.data.queryLimits['y'];
      var xcolor = chart.config.data.queryLimits['xcolor'];
      var ycolor = chart.config.data.queryLimits['ycolor'];
      var lineThickness = 3;

      function drawLine(x1,y1,x2,y2,color) {
        console.log("color="+color+", x1="+x1+", x2="+x2+", y1="+y1+", y2="+y2);
        ctx.save();
        ctx.beginPath();
        ctx.moveTo(x1, y1);
        ctx.strokeStyle = color;
        ctx.lineWidth=lineThickness;
        ctx.lineTo(x2, y2);
        ctx.stroke();
        ctx.restore();
      }

      // draw vertical line
      if (xvalue) {
        x1 = xaxis.getPixelForValue(xvalue);
        x2 = xaxis.getPixelForValue(xvalue);
        y1 = yaxis.top;
        y2 = yaxis.bottom;
        drawLine(x1,y1,x2,y2,xcolor);
      }

      // draw horizontal line
      if (yvalue) {
        x1 = xaxis.left;
        x2 = xaxis.right;
        y1 = yaxis.getPixelForValue(yvalue);
        y2 = yaxis.getPixelForValue(yvalue);
        drawLine(x1,y1,x2,y2,ycolor);
      }
    }
  });

var config = {
  type: 'bubble',
  data: {
    queryLimits: {x: 42, y: 21, xcolor: '#00FF00', ycolor: '#0000ff'},
    datasets: [
      {
          label: '',
          data: [
              {x: 20, y: 30, r: 15},
              {x: 40, y: 10, r: 10},
              {x: 100, y: 15, r: 10},
              {x: 50, y: 22, r: 5},
              {x: 80, y: 26, r: 3},
              {x: 63, y: 28, r: 10},
              {x: 71, y: 18, r: 12}
          ],
          backgroundColor:"#FF6384",
          hoverBackgroundColor: "#FF6384",
      }]
  }
};

var ctx = document.getElementById("myChart").getContext("2d");
new Chart(ctx, config);

我需要更进一步,将图表的区域/背景在垂直线的一侧以及水平线的上方或下方涂上不同的颜色(如浅灰色或微妙的颜色)。

我不确定该方法是尝试更改背景的一部分,还是添加尺寸和位置的矩形以模拟背景阴影。

想法?

以下是目标的示例模型:

Bubble/Scatter With Horizontal & Vertical Lines & Shaded Area

更新

对于那些将来观看此内容的人来说,我最终发现了一种更好的方法,通过使用此处https://github.com/chartjs/chartjs-plugin-annotation中的chartjs的注释插件来处理线条和矩形的绘制。使用起来要容易得多,并且没有触发代码来绘制超过必要的线条和矩形的结果。此外,我最终能够使用另一个插件https://github.com/compwright/chartjs-plugin-draggable来拖动从第一个插件创建的注释。我正在离开接受的答案,因为它确实回答了我在原始扩展方法之后如何解决矩形阴影区域的问题,但是我在推荐了更多关于此的内容后推荐插件方法。 / p>

1 个答案:

答案 0 :(得分:2)

正如您对queryLimits属性所做的那样,您可以采用与填充所需部分的属性相同的方式。

将以下属性添加到图表数据集中:

fillBackground: {
    // In this porperty, add the string portion you want to fill
    // Inputs are : "tr" for top-right
    //              "tl" for top-left 
    //              "br" for bottom-right 
    //              "bl" for bottom-left 
    pos: ["tr", "bl", "br"],

    // A single color will be used in all the portions
    // But you can also set an array of colors which must have the same length as the pos
    // i.e color: ["rgba(0, 0, 0, 0.1)", "rgba(30, 30, 30, 0.3)", "rgba(60, 60, 60, 0.5)"]
    color: "rgba(30, 30, 30, 0.15)"
}

然后在draw()函数中添加以下代码:

function drawRect(x1, y1, x2, y2, color) {
    ctx.save();
    ctx.fillStyle = color;
    ctx.fillRect(x1, y1, x2, y2, color);
    ctx.restore();
}

// Checks if you have the attribute in your dataset
if (chart.config.data.fillBackground) {

    // Make sure you have portions in your chart
    if (!xvalue || !yvalue) return;

    var pos = chart.config.data.fillBackground.pos;
    var color = chart.config.data.fillBackground.color;

    // For every position in your array ..
    for (p in pos) {

        // Based on the string code, fills the right portion
        switch (pos[p]) {
            case "tl":
                drawRect(xaxis.left, yaxis.top, xaxis.getPixelForValue(xvalue) - lineThickness / 2 - xaxis.left, yaxis.getPixelForValue(yvalue) - lineThickness / 2 - yaxis.top, (Array.isArray(color)) ? color[p] : color);
                break;
            case "tr":
                drawRect(xaxis.getPixelForValue(xvalue) + lineThickness / 2, yaxis.top, xaxis.right, yaxis.getPixelForValue(yvalue) - lineThickness / 2 - yaxis.top, (Array.isArray(color)) ? color[p] : color);
                break;
            case "bl":
                drawRect(xaxis.left, yaxis.getPixelForValue(yvalue) + lineThickness / 2, xaxis.getPixelForValue(xvalue) - lineThickness / 2 - xaxis.left, yaxis.bottom - (yaxis.getPixelForValue(yvalue) + lineThickness / 2), (Array.isArray(color)) ? color[p] : color);
                break
            case "br":
                drawRect(xaxis.getPixelForValue(xvalue) + lineThickness / 2, yaxis.getPixelForValue(yvalue) + lineThickness / 2, xaxis.right, yaxis.bottom - (yaxis.getPixelForValue(yvalue) + lineThickness / 2), (Array.isArray(color)) ? color[p] : color);
                break;
        }
    }
}

这可以解决您的问题。

您可以在this fiddle中查看使用这些功能的示例,结果如下:

enter image description here