簡體   English   中英

如何在 chart.js 中制作沒有 ticks.min/max 的固定寬度?

[英]How to make fixed width of column without ticks.min/max in chart.js?

我需要能夠設置固定的列寬。 例如,如果我指定 50 像素並且 canvas 寬度為 500 像素,Chart.JS 渲染 10 列並自動將 ticks.min/max 設置為 0 和 9。

我知道條形圖中的 barThickness 和 barPercentage。 但我有折線圖。 我知道 maxTicksLimit 但它僅適用於“線性”比例類型(我有“類別”比例類型)。 我找到了解決方案。 我使用 onResize 回調並做了一些技巧(選擇 canvas 寬度並將其除以所需的列寬度,然后設置 ticks.min/max)。 它有效但效果不佳,因為結果未接近預期寬度。 如果您有 500px canvas 和 5 個數據項並且您需要 50px 的列寬,則會出現更多問題。 在這種情況下,Chart.JS 將按 canvas 寬度拉伸列。

沒有我的技巧的清晰示例。

 const ITEMS_COUNT = 50; const MIN = -5000; const MAX = 8000; const defaultDatasetOptions = { pointRadius: 0, pointHoverRadius: 0, pointBorderWidth: 0, pointHoverBorderWidth: 0, pointHitRadius: 10, borderWidth: 0 }; const data = { labels: _.range(1, ITEMS_COUNT), datasets: [ {...defaultDatasetOptions, label: 'Series 1', data: Array.from(Array(ITEMS_COUNT), () => _.random(MIN, MAX)), backgroundColor: 'rgba(255, 0, 0, .3)' }, {...defaultDatasetOptions, label: 'Series 2', data: Array.from(Array(ITEMS_COUNT), () => _.random(MIN, MAX)), backgroundColor: 'rgba(0, 255, 0, .3)' }, {...defaultDatasetOptions, label: 'Series 3', data: Array.from(Array(ITEMS_COUNT), () => _.random(MIN, MAX)), backgroundColor: 'rgba(0, 0, 255, .3)' } ] }; const options = { legend: { display: false }, scales: { xAxes: [ { type: 'category', gridLines: { offsetGridLines: true, color: 'orange', tickMarkLength: 0, drawBorder: false }, ticks: { display: false, maxRotation: 0, beginAtZero: true, autoSkip: false, stepSize: 1 }, offset: true } ], yAxes: [{ display: false }] }, tooltips: { mode: 'index', intersect: false }, hover: { mode: 'index', intersect: false } }; new Chart(document.querySelector('canvas'), { type: 'line', data, options });
 canvas { border: 1px solid black; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script> <canvas></canvas>

以我的解決方案為例。

 const ITEMS_COUNT = 50; const MIN = -5000; const MAX = 8000; const COLUMN_WIDTH = 50; const defaultDatasetOptions = { pointRadius: 0, pointHoverRadius: 0, pointBorderWidth: 0, pointHoverBorderWidth: 0, pointHitRadius: 10, borderWidth: 0 }; const data = { labels: _.range(1, ITEMS_COUNT + 1), datasets: [ {...defaultDatasetOptions, label: 'Series 1', data: Array.from(Array(ITEMS_COUNT), () => _.random(MIN, MAX)), backgroundColor: 'rgba(255, 0, 0, .3)' }, {...defaultDatasetOptions, label: 'Series 2', data: Array.from(Array(ITEMS_COUNT), () => _.random(MIN, MAX)), backgroundColor: 'rgba(0, 255, 0, .3)' }, {...defaultDatasetOptions, label: 'Series 3', data: Array.from(Array(ITEMS_COUNT), () => _.random(MIN, MAX)), backgroundColor: 'rgba(0, 0, 255, .3)' } ] }; const options = { onResize: setupTicksMinMax, legend: { display: false }, scales: { xAxes: [ { type: 'category', gridLines: { offsetGridLines: true, color: 'orange', tickMarkLength: 0, drawBorder: false }, ticks: { display: false, maxRotation: 0, beginAtZero: true, autoSkip: false, stepSize: 1 }, offset: true } ], yAxes: [{ display: false }] }, tooltips: { mode: 'index', intersect: false }, hover: { mode: 'index', intersect: false } }; const setupTicksMinMax = (chartInstance) => { const xScale = chartInstance.scales['x-axis-0']; xScale.options.ticks.min = chartInstance.data.labels[0]; xScale.options.ticks.max = chartInstance.data.labels[Math.ceil(chartInstance.canvas.width / COLUMN_WIDTH)]; chartInstance.update(0); }; const chartInstance = new Chart(document.querySelector('canvas'), { type: 'line', data, options }); setupTicksMinMax(chartInstance);
 canvas { border: 1px solid black; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script> <canvas></canvas>

如果我正確理解了您的問題,那么下面的代碼片段可以達到您想要的結果。

它從兩個輸入參數(寬度和點數)調整圖表的右側填充以將點保持在指定的寬度,無論是太多還是太少的點都無法填充 canvas 的寬度。

出於演示目的,您可以更改輸入值並按“更新”按鈕查看結果。

 let chart = new Chart(document.getElementById("chart"), { type: "line", data: { datasets: [{ data: [] }] }, options: { maintainAspectRatio: false, legend: { display: false }, scales: { xAxes: [{ type: 'category', gridLines: { offsetGridLines: true, color: 'orange', tickMarkLength: 0, drawBorder: false }, ticks: { display: false, maxRotation: 0, beginAtZero: true, autoSkip: false, stepSize: 1 }, offset: true }], yAxes: [{ display: false }] } }, plugins: [{ resize: function(chart) { update(chart); } }] }); function update(chart) { let pointWidth = parseInt(document.getElementById("pw").value), pointCount = parseInt(document.getElementById("pc").value), width = chart.width - chart.chartArea.left, points = Math.floor(width / pointWidth); if (points > pointCount) { points = pointCount; } chart.config.data.labels = _.range(1, points + 1); chart.config.data.datasets[0].data = Array.from(Array(points), () => _.random(-5000, 8000)); chart.options.layout.padding.right = width - (pointWidth * points); chart.update(); } document.getElementById("update").addEventListener("click", function() { update(chart); });
 canvas { background-color: #f5f5f5 }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script> <p> Width: <input id="pw" type="text" value="50">px Count: <input id="pc" type="text" value="5"><button id="update">Update</button> </p> <canvas id="chart"></canvas>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM