2016-05-16 77 views
6

我使用Chart.js版本2.1.3製作了折線圖。Chart.js:使用maxTicksLimit時均勻分佈刻度

 var canvas = $('#gold_chart').get(0); 
     var ctx = canvas.getContext('2d'); 
     var fillPatternGold = ctx.createLinearGradient(0, 0, 0, canvas.height); 
     fillPatternGold.addColorStop(0, '#fdca55'); 
     fillPatternGold.addColorStop(1, '#ffffff'); 

     var goldChart = new Chart(ctx, { 
      type: 'line', 
      animation: false, 
      data: { 
       labels: dates, 
       datasets: [{ 
        label: '', 
        data: prices, 
        pointRadius: 0, 
        borderWidth: 1, 
        borderColor: '#a97f35', 
        backgroundColor: fillPatternGold 
       }] 
      }, 
      title: { 
       position: 'bottom', 
       text: '\u7F8E\u5143/\u76CE\u53F8' 
      }, 
      options: { 
       legend: { 
        display: false 
       }, 
       tooltips: { 
        callback: function(tooltipItem) { 
         return tooltipItem.yLabel; 
        } 
       }, 
       scales: { 
        xAxes: [{ 
         ticks: { 
          maxTicksLimit: 8 
         } 
        }] 
       } 
      } 
     }); 

輸出結果如下:

Screenshot

正如你所看到的,我通過maxTicksLimit限制蜱的最大數爲8。但是,分配不均。我怎樣才能使蜱分佈均勻?

p.s.數據集中總是有289條記錄,並且每5分鐘記錄一次數據。 prices變量的樣本值是:

[ 
    {"14:10", 1280.3}, 
    {"14:15", 1280.25}, 
    {"14:20", 1282.85} 
] 

我嘗試了不同maxTicksLimit值,結果仍然沒有均勻分佈。

回答

12

Chart.js使用積分skipRatio(計算出要跳過多少個標籤)。隨着chart.js之v2.1.x,您可以編寫自己的插件使用分數skipRatio


預覽

enter image description here


腳本

Chart.pluginService.register({ 
    afterUpdate: function (chart) { 
     var xScale = chart.scales['x-axis-0']; 
     if (xScale.options.ticks.maxTicksLimit) { 
      // store the original maxTicksLimit 
      xScale.options.ticks._maxTicksLimit = xScale.options.ticks.maxTicksLimit; 
      // let chart.js draw the first and last label 
      xScale.options.ticks.maxTicksLimit = (xScale.ticks.length % xScale.options.ticks._maxTicksLimit === 0) ? 1 : 2; 

      var originalXScaleDraw = xScale.draw 
      xScale.draw = function() { 
       originalXScaleDraw.apply(this, arguments); 

       var xScale = chart.scales['x-axis-0']; 
       if (xScale.options.ticks.maxTicksLimit) { 
        var helpers = Chart.helpers; 

        var tickFontColor = helpers.getValueOrDefault(xScale.options.ticks.fontColor, Chart.defaults.global.defaultFontColor); 
        var tickFontSize = helpers.getValueOrDefault(xScale.options.ticks.fontSize, Chart.defaults.global.defaultFontSize); 
        var tickFontStyle = helpers.getValueOrDefault(xScale.options.ticks.fontStyle, Chart.defaults.global.defaultFontStyle); 
        var tickFontFamily = helpers.getValueOrDefault(xScale.options.ticks.fontFamily, Chart.defaults.global.defaultFontFamily); 
        var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily); 
        var tl = xScale.options.gridLines.tickMarkLength; 

        var isRotated = xScale.labelRotation !== 0; 
        var yTickStart = xScale.top; 
        var yTickEnd = xScale.top + tl; 
        var chartArea = chart.chartArea; 

        // use the saved ticks 
        var maxTicks = xScale.options.ticks._maxTicksLimit - 1; 
        var ticksPerVisibleTick = xScale.ticks.length/maxTicks; 

        // chart.js uses an integral skipRatio - this causes all the fractional ticks to be accounted for between the last 2 labels 
        // we use a fractional skipRatio 
        var ticksCovered = 0; 
        helpers.each(xScale.ticks, function (label, index) { 
         if (index < ticksCovered) 
          return; 

         ticksCovered += ticksPerVisibleTick; 

         // chart.js has already drawn these 2 
         if (index === 0 || index === (xScale.ticks.length - 1)) 
          return; 

         // copy of chart.js code 
         var xLineValue = this.getPixelForTick(index); 
         var xLabelValue = this.getPixelForTick(index, this.options.gridLines.offsetGridLines); 

         if (this.options.gridLines.display) { 
          this.ctx.lineWidth = this.options.gridLines.lineWidth; 
          this.ctx.strokeStyle = this.options.gridLines.color; 

          xLineValue += helpers.aliasPixel(this.ctx.lineWidth); 

          // Draw the label area 
          this.ctx.beginPath(); 

          if (this.options.gridLines.drawTicks) { 
           this.ctx.moveTo(xLineValue, yTickStart); 
           this.ctx.lineTo(xLineValue, yTickEnd); 
          } 

          // Draw the chart area 
          if (this.options.gridLines.drawOnChartArea) { 
           this.ctx.moveTo(xLineValue, chartArea.top); 
           this.ctx.lineTo(xLineValue, chartArea.bottom); 
          } 

          // Need to stroke in the loop because we are potentially changing line widths & colours 
          this.ctx.stroke(); 
         } 

         if (this.options.ticks.display) { 
          this.ctx.save(); 
          this.ctx.translate(xLabelValue + this.options.ticks.labelOffset, (isRotated) ? this.top + 12 : this.options.position === "top" ? this.bottom - tl : this.top + tl); 
          this.ctx.rotate(helpers.toRadians(this.labelRotation) * -1); 
          this.ctx.font = tickLabelFont; 
          this.ctx.textAlign = (isRotated) ? "right" : "center"; 
          this.ctx.textBaseline = (isRotated) ? "middle" : this.options.position === "top" ? "bottom" : "top"; 
          this.ctx.fillText(label, 0, 0); 
          this.ctx.restore(); 
         } 
        }, xScale); 
       } 
      }; 
     } 
    }, 
}); 

小提琴 - http://jsfiddle.net/bh63pe1v/

+2

哇,這個作品完美!我認爲Chart.js應該整合你的代碼來使'maxTicksLimit'更好地工作。 – Raptor

+0

經過進一步測試後,當畫布變小時,無法正確顯示滴答**隨機**(僅顯示第一個和最後一個滴答);有時會在刷新後正確顯示。看到這個:http://imgur.com/RtgYWZc – Raptor

+0

你可以更新我的答案與你的HTML和數據的小提琴嗎?此顯示問題是否出現相同數據或數據更改時出現問題?發生問題時出現任何控制檯錯誤? – potatopeelings