2017-06-20 105 views
0

我的目標是創建自定義工具提示並始終顯示它們。稍後會有更多花哨的東西,但現在我正在努力實現這兩件事。Charts.js v2:始終在圖表上顯示自定義(html)工具提示

爲了創建自定義工具提示,我使用了charts.js docs的教程;這裏在stackoverflow我發現solution for always showing the tooltips

所以現在我有兩個工具提示:標準的工具提示,出現在Draw後並保持可見狀態,以及自定義工具提示,這些提示工作到目前爲止,但只出現在懸停點/數據點。

jsFiddlehttps://jsfiddle.net/2c4261wj/1/以下圖片顯示問題。紅色容器顯示自定義工具提示,只出現在懸停點上。

enter image description here

而不是標準的提示,我想總是顯示自定義的afterDraw,但我不能設法做到這一點。

原料codebits在提示選項

自定義工具提示:

custom: function(tooltipModel) { 
// Tooltip Element 
var tooltipEl = document.getElementById('chartjs-tooltip'); 
// Create element on first render 
if (!tooltipEl) { 
    tooltipEl = document.createElement('div'); 
    tooltipEl.id = 'chartjs-tooltip'; 
    tooltipEl.innerHTML = "<table></table>"; 
    document.body.appendChild(tooltipEl); 
} 
// Hide if no tooltip 
if (tooltipModel.opacity === 0) { 
    tooltipEl.style.opacity = 1; 
    return; 
} 
// Set caret Position 
tooltipEl.classList.remove('above', 'below', 'no-transform'); 
if (tooltipModel.yAlign) { 
    tooltipEl.classList.add(tooltipModel.yAlign); 
} else { 
    tooltipEl.classList.add('no-transform'); 
} 

function getBody(bodyItem) { 
    return bodyItem.lines; 
} 
// Set Text 
if (tooltipModel.body) { 
    var titleLines = tooltipModel.title || []; 
    var bodyLines = tooltipModel.body.map(getBody); 
    var innerHtml = '<div>'; 
    titleLines.forEach(function(title) { 
     innerHtml += '<span>' + title + '</span>'; 
    }); 
    innerHtml += '</div>'; 
    bodyLines.forEach(function(body, i) { 
     var colors = tooltipModel.labelColors[i]; 
     var style = 'background:' + colors.backgroundColor; 
     style += '; border-color:' + colors.borderColor; 
     style += '; border-width: 2px'; 
     var span = '<span class="chartjs-tooltip-key" style="' + style + '"></span>'; 
     innerHtml += '<div class="inner">' + span + body + '</div>'; 
    }); 
    innerHtml += 'last'; 
    var tableRoot = tooltipEl; 
    tableRoot.innerHTML = innerHtml; 
} 
// `this` will be the overall tooltip 
var position = this._chart.canvas.getBoundingClientRect(); 
// Display, position, and set styles for font 
tooltipEl.style.opacity = 1; 
tooltipEl.style.left = position.left + tooltipModel.caretX - 100 + 'px'; 
tooltipEl.style.top = position.top + tooltipModel.caretY - 100 + 'px'; 
tooltipEl.style.fontFamily = tooltipModel._fontFamily; 
tooltipEl.style.fontSize = tooltipModel.fontSize; 
tooltipEl.style.fontStyle = tooltipModel._fontStyle; 
tooltipEl.style.padding = tooltipModel.yPadding + 'px ' + tooltipModel.xPadding + 'px'; 
} 

始終顯示工具提示:

Chart.pluginService.register({ 
     beforeRender: function (chart) { 
      if (chart.config.options.showAllTooltips) { 
       // create an array of tooltips 
       // we can't use the chart tooltip because there is only one tooltip per chart 
       chart.pluginTooltips = []; 
       chart.config.data.datasets.forEach(function (dataset, i) { 
        chart.getDatasetMeta(i).data.forEach(function (sector, j) { 
         chart.pluginTooltips.push(new Chart.Tooltip({ 
          _chart: chart.chart, 
          _chartInstance: chart, 
          _data: chart.data, 
          _options: chart.options.tooltips, 
          _active: [sector] 
         }, chart)); 
        }); 
       }); 

       // turn off normal tooltips 
       chart.options.tooltips.enabled = false; 
      } 
     }, 
     afterDraw: function (chart, easing) { 
      if (chart.config.options.showAllTooltips) { 
       // we don't want the permanent tooltips to animate, so don't do anything till the animation runs atleast once 
       if (!chart.allTooltipsOnce) { 
        if (easing !== 1) 
         return; 
        chart.allTooltipsOnce = true; 
       } 

       // turn on tooltips 
       chart.options.tooltips.enabled = true; 
       Chart.helpers.each(chart.pluginTooltips, function (tooltip) { 
        tooltip.initialize(); 
        tooltip.update(); 
        // we don't actually need this since we are not animating tooltips 
        tooltip.pivot(); 
        tooltip.transition(easing).draw(); 
       }); 
       chart.options.tooltips.enabled = false; 
      } 
     } 
    }); 

我試圖用自定義提示右側的第一個插件內,但沒有結果,也許我在插件中引用它是錯誤的。 任何想法?

+0

是的,我添加了鏈接。謝謝 – Tonsenson

+0

好的,那你到底想要什麼?根據你的問題,你目前的圖表狀態對我來說似乎很好。 –

+0

對不起,如果我沒有解釋確切的問題:現在我有2種工具提示:自定義HTML和「標準」。我設法在Draw之後使標準顯示器正確顯示,但是我需要對它們進行很多定製,所以我想使用已經創建的定製顯示器。而不是標準的工具提示,我想在Draw之後始終顯示自定義的工具提示,但我無法做到這一點。(會試着更新這個新增的問題) – Tonsenson

回答

1

所以,我找到了一個解決方案。之前,我嘗試使用自定義工具提示並創建了一個插件,這會使自定義工具提示在加載時顯示並保持可見。

我現在所做的是:

  • 刪除自定義工具提示
  • 創建一個新的插件來處理我所有的需求和願望關於顏色和任何

第一:working fiddle of the current state

其實它很簡單;該插件獲取所有數據集,循環遍歷它們並在畫布上繪製東西。多虧了插件,你可以通過將數據保存到數組來訪問所有的數據,然後是...抓住他們,做你想做的任何事情。

神奇的是發生在這裏:

Chart.plugins.register({ 
afterDraw: function(chart, easing) { 
    // To only draw at the end of animation, check for easing === 1 
    var debug = false; 
    var ctx = chart.chart.ctx; 
    var numbers = [], 
     position = [], 
     dataString = [], 
     safetyCounter = 0; 
    var datasetAmount = chart.data.datasets.length; 
    var datasetLength = chart.getDatasetMeta(0).data.length; 
    var amountLength = (datasetAmount * datasetLength); 
    chart.data.datasets.forEach(function(dataset, i) { 
     var meta = chart.getDatasetMeta(i); 
     if (!meta.hidden) { 
      meta.data.forEach(function(element, index) { 
       if (numbers.indexOf(dataset.data[index]) < 0) { 
        numbers.push(dataset.data[index]); 
       } 
       position.push(element.tooltipPosition()); 
       var fontSize = 20; 
       var fontStyle = 'bold'; 
       var fontFamily = 'Helvetica Neue'; 
       ctx.font = Chart.helpers.fontString(fontSize, fontStyle, fontFamily); 
       ctx.textAlign = 'center'; 
       ctx.textBaseline = 'middle'; 
       ctx.lineWidth = 2; 
       dataString.push(dataset.data[index].toString() + '%'); 
       var padding = 5; 
       if (numbers.length === amountLength) { 
        if (safetyCounter === 0) { 
         safetyCounter++ 
        } 
        for (var k = 0; k < numbers.length; k++) { 
         if (k < datasetLength) { 
          ctx.strokeStyle = "#c7d85e"; 
          ctx.fillStyle = "#c7d85e"; 
          if (numbers[k] >= numbers[k + datasetLength]) { 
           ctx.beginPath(); 
           ctx.moveTo(position[k].x, position[k].y - 50); 
           ctx.lineTo(position[k].x, position[k].y); 
           ctx.stroke(); 
           ctx.fillText(dataString[k], position[k].x, position[k].y - 50 - (fontSize/2) - padding); 
          } else { 
           ctx.beginPath(); 
           ctx.moveTo(position[k].x, position[k].y + 50); 
           ctx.lineTo(position[k].x, position[k].y); 
           ctx.stroke(); 
           ctx.fillText(dataString[k], position[k].x, position[k].y + 80 - (fontSize/2) - padding); 
          } 
         } else { 
          ctx.strokeStyle = "#4f708b"; 
          ctx.fillStyle = "#4f708b"; 
          if (numbers[k] >= numbers[k - datasetLength]) { 
           ctx.beginPath(); 
           ctx.moveTo(position[k].x, position[k].y - 50); 
           ctx.lineTo(position[k].x, position[k].y); 
           ctx.stroke(); 
           ctx.fillText(dataString[k], position[k].x, position[k].y - 50 - (fontSize/2) - padding); 
          } else { 
           ctx.beginPath(); 
           ctx.moveTo(position[k].x, position[k].y + 50); 
           ctx.lineTo(position[k].x, position[k].y); 
           ctx.stroke(); 
           ctx.fillText(dataString[k], position[k].x, position[k].y + 80 - (fontSize/2) - padding); 
          } 
         } 
        } 
       } else { 
        // nothing yet here 
       } 
      }); 
     } 
    }); 
    si++; 
    // necessary for prevent standard tooltips from showing 
    // but I also use css pointer events for preventing canvas to respond to mouseevents 
    if (chart.config.options.showAllTooltips) { 
     if (!chart.allTooltipsOnce) { 
      if (easing !== 1) return; 
      chart.allTooltipsOnce = true; 
     } 
     chart.options.tooltips.enabled = true; 
     Chart.helpers.each(chart.pluginTooltips, function(tooltip) { 
      tooltip.initialize(); 
      tooltip.update(); 
      tooltip.pivot(); 
      tooltip.transition(easing).draw(); 
     }); 
     chart.options.tooltips.enabled = false; 
    } 
} 
}); 
+1

Ya,I已經知道這種方法,但後來認爲,對你來說會很複雜*(考慮到事實,你有多少關於畫布的知識)*。那麼,如果你使用ChartJS v1 –

+0

,那麼使用一般的HTML DOM元素和CSS就可以達到相同的效果!是的,我對畫布很新,但在這裏學習:) – Tonsenson

相關問題