首页 文章

Chart.js 2.0 - 如何更改画布/图表元素的默认外观

提问于
浏览
1

我正在使用新的Chart.js并尝试完成几个自定义 . 在JS中精通但是画布的新手,我有点挣扎 . 我会尽量提供尽可能多的信息 .

相关链接

代码 - JSBin

JavaScript

/**
 * Chart.js Global Config
 */
Chart.defaults.global.pointHitDetectionRadius = 5;
window.count = 0;




/**
 * Chart Data
 * @type {Object}
 */
var lineChartData = {
  labels: ["", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC", ""],
  datasets: [{
    label: "Students",
    data: [ 200, 250,220,180,290,300,370,350,200,280,260,190,210, 200 ],
    backgroundColor: "rgba(247,155,45,1.0)",
    borderColor: "rgba(247,155,45,1.0)",
    borderCapStyle: 'butt',
    borderDash: [],
    borderDashOffset: 0.0,
    pointBorderColor: "rgba(245,245,245,1)",
    pointBackgroundColor: "rgba(80,81,81,1)",
    pointHoverBorderWidth: 5,
    pointBorderWidth: 5,
    pointRadius: 8,
    pointHoverRadius: 9,
    pointHitRadius: 8,
  }]
};



/**
 * Init
 */
window.onload = function() {

  var $chart = $('#chart');

  window.lineChart = new Chart($chart[0], {
    type: 'line',

    data: lineChartData,

    options: {
      showLines: true,

      // Legend
      legend : {
        display: false
      },

      // title
      title:{
        display:false,
        text:'Student Hours'
      },

      // Tooltips
      tooltips: {
        enabled: false,
      },

      // Scales
      scales: {
        yAxes: [{
          id: 'y-axis-0',
          gridLines: {
            display: true,
            lineWidth: 1,
            color: "rgba(255,255,255,0.85)"
          },
          ticks: {
            beginAtZero:true,
            mirror:false,
            suggestedMin: 0,
            suggestedMax: 500,
          },
          afterBuildTicks: function(chart) {

          }
        }],
        xAxes: [{
          id: 'x-axis-0',
          gridLines: {
            display: false
          },
          ticks: {
            beginAtZero: true
          }
        }]
      },
    }
  });

};

HTML

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.3/Chart.bundle.min.js"></script>
  <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>

</head>
<body>
  <div id="chartjs-container" class="chartjs-wrap">
    <canvas id="chart"></canvas>
  </div>
</body>
</html>

CSS

#chartjs-container {
  width:80%;
  margin:20px auto;
  position: relative;
}

.chartjs-wrap {
  background-color: rgba(250, 210, 162, 1.0);
}

  canvas {
    -moz-user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;

    height:100%;
  }

我正在尝试做什么

  • 从y轴上移除网格线

  • 删除符合图表左/右边缘的数据集的第一个和最后一个项目上的点

  • 插入y轴刻度标签

  • 使x轴网格线覆盖在线数据填充的顶部

截图

Current State
current-state-ss

Desired State (近似值)
desired-state-ss

任何帮助我指向正确方向的帮助都会很棒 . 画布上有“Inspect Element”的等价物吗?这些修复在CSS中是微不足道的,但我不确定如何调试 .

干杯

1 回答

  • 9

    1.从y轴上移除网格线

    只需将 display 设置为 options.scales.yAxes 为false . 这也将删除所有标签 - 我们将调用库方法在插件中绘制标签(不绘制y轴)(参见步骤4)


    2.删除符合图表左/右边缘的数据集的第一个和最后一个项上的点

    只需将数组传递给 pointRadiuspointHoverRadius 而不是数字 . 以下数组将隐藏第一个和最后一个点(包含您的数据)

    ...
    pointRadius: [0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0],
    pointHoverRadius: [0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0],
    ...
    

    如果数据长度是动态的,则可能必须使用脚本生成此内容 .


    3.插入y轴刻度标签

    options.scales.yAxes 设为 options.scales.yAxes 为真 . 然后,插件(来自步骤4)将调用库的 draw 方法 .


    4.使x轴网格线覆盖在线数据填充的顶部

    要使gridLines在填充上但在点下方显示(就像它一样),最简单的方法是在填充下绘制它并将填充设置为稍微透明的值 .

    backgroundColor: "rgba(247,155,45,0.4)",
    

    我们必须自己绘制gridLines,因为我们不希望它们从边缘开始 . 因此,为 options.scales.yAxesgridLines.display 设置为false并注册以下插件

    Chart.pluginService.register({
        afterDraw: function (chart, easingDecimal) {
            var yScale = chart.scales['y-axis-0'];
            var helpers = Chart.helpers;
            var chartArea = chart.chartArea;
    
            // draw labels - all we do is turn on display and call scale.draw
            yScale.options.display = true;
            yScale.draw.apply(yScale, [chartArea]);
            yScale.options.display = false;
    
            yScale.ctx.save();
                // draw under the fill
            yScale.ctx.globalCompositeOperation = 'destination-over';
            // draw the grid lines - simplified version of library code
            helpers.each(yScale.ticks, function (label, index) {
                if (label === undefined || label === null) {
                    return;
                }
    
                var yLineValue = this.getPixelForTick(index);
                yLineValue += helpers.aliasPixel(this.ctx.lineWidth);
    
                this.ctx.lineWidth = this.options.gridLines.lineWidth;
                this.ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)';
    
                this.ctx.beginPath();
                this.ctx.moveTo(chartArea.left + 40, yLineValue);
                this.ctx.lineTo(chartArea.right, yLineValue);
                this.ctx.stroke();
    
            }, yScale);
            yScale.ctx.restore();
        },
    })
    

    将为所有图表调用插件 . 如果你想跳过某些图表的上述逻辑,你需要在 options 对象上设置一些属性并在运行逻辑之前检查它(例如 yAxis.options.customyAxis.options.display 处于同一级别


    如果要隐藏0和500标签,可以为 options.scales.yAxes 设置 ticks.callback ,如此

    callback: function(value) {
      if (value !== 0 && value !== 500)
        return '' + value;
    },
    

    请注意,只要您的比例在suggestMin和suggestedMax范围内,它就会起作用 . 如果您的数据超出这些范围,则必须使用比例属性 .


    要使x轴标签背景为白色,只需将以下位添加到插件的 afterDraw 方法的末尾

    yScale.ctx.save();
    yScale.ctx.fillStyle = 'white';
    yScale.ctx.globalCompositeOperation = 'destination-over';
    yScale.ctx.fillRect(0, yScale.bottom, chartArea.right, chartArea.bottom);
    yScale.ctx.restore();
    

    它只是在画布内容下绘制一个白色矩形 . 因为您的背景颜色是通过CSS设置的,所以矩形位于背景颜色之上,一切都是闪亮的 .

    您还必须将背景颜色从.chartjs-wrap移动到画布上(否则底部会出现橙色边框)

    canvas {
        background-color: rgba(250, 210, 162, 1.0);
        ...
    

    您的JSBin的更新版本将应用以上所有 - http://jsbin.com/parucayara/1/edit?output

相关问题