#javascript #chart.js
Вопрос:
Я просто внедрил несколько линейных диаграмм для своих данных, когда столкнулся с проблемой. Я должен показать данные о ежедневных заказах за последний месяц. Могут быть месяцы без каких-либо заказов на конкретный продукт, но могут быть месяцы с большим количеством заказов.
Вот что у меня под options
:
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
callback: function (value) { if (Number.isInteger(value)) {return value; } }
}
}]
}
Я использую эту callback
функцию, чтобы убедиться, что ось y отображает только целые числа. Проблема в том, что теперь, если я оставлю это так, и у меня не будет никаких данных для отображения, он покажет только один шаг (что выглядит странно).:
Я пробовал использовать эту max: 10
опцию, но затем данные сокращаются, если у меня более 10 заказов. Я не мог найти такого варианта minSteps: 10
или что-то в этом роде. Кто-нибудь знает решение этой проблемы?
Ответ №1:
Вы можете просто использовать второй набор данных со всеми значениями 10, а затем сделать его прозрачным, недоступным для просмотра, чтобы не отображалась подсказка, и скрыть его в легенде:
var options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [0, 0, 0, 0, 0, 0],
borderColor: 'blue'
},
{
label: 'filler',
data: [10, 10, 10, 10, 10, 10],
borderWidth: 1,
fill: false,
pointHitRadius: 0,
radius: 0,
hoverRadius: 0,
borderColor: '#00000000'
}
]
},
options: {
legend: {
labels: {
filter: (lEl) => (lEl.text !== 'filler')
}
},
scales: {
yAxes: [{
ticks: {
reverse: false
}
}]
}
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
</body>
Редактировать:
Вы можете использовать эту suggestedMax
опцию, это приведет к тому, что он всегда будет показывать 10 как максимум, если данные не будут превышать его, тогда он автоматически настроит максимальное значение на все, что нужно для данных.
var options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [0, 0, 0, 0, 0, 0],
borderColor: 'blue'
}]
},
options: {
scales: {
yAxes: [{
ticks: {
suggestedMax: 10
}
}]
}
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
</body>
Комментарии:
1. Я надеялся на менее «банальный» способ добиться этого. Тем не менее это работает, и я беру то, что могу получить, спасибо!
2. Просто подумал о лучшем способе, обновил ответ
3. Я пробовал
suggestedMax
раньше (не получилось). Наверное, я неправильно его использовал. Теперь это работает, спасибо за обновление!
Ответ №2:
Добавление к ответу/комментариям, представленным @LeeLenalee, я обновил код до chart.js
v. 3x
Следовательно, я бы рекомендовал:
- обновление до последней версии версии
chart.js
v3.5.1:
в коде у вас есть обе ссылки
улучшенная производительность и новые опции, особенно если данные содержат даты, как в вашем случае. (v3.x не имеет обратной совместимости с v2.x) - используйте Декартову Ось Времени
обратите внимание на разницу между «временем» (равноудаленность) и «временными рядами» (в зависимости от того, есть ли точка данных)
, и вам придется добавитьmomentjs
иchartjs-adapter-moment
(см. Фрагмент кода) или добавитьluxon
и т. Д… как предложил @LeeLenalee (ежедневный просмотр по оси x, еженедельно, ежемесячно, ежегодно —moment.js
обрабатывает фильтрацию). Пригодится вам 😜
Пожалуйста, сообщите, правильна ли следующая среда и структура данных (я угадал вашу структуру данных):
let yourDataJson = [{x: '2021-08-13', y: 20.2},{x: '2021-08-15', y: 16},{x: '2021-08-19', y: 9},{x: '2021-08-23', y: 35},{x: '2021-09-02', y: 2}];
let yourData = {
datasets: [{
label: 'Orders: Product A',
data: yourDataJson,
borderColor: 'rgba(0,0,255,1)',
backgroundColor: 'rgba(0,0,255,0.5)',
fill: true
}
]
};
let yourOptions = {
scales: {
x: { // <-- v3.x now object "{", not array "[{" anymore
type: 'timeseries', // <-- try "time" and "timeseries" to see difference
time: {
unit: 'day', // <-- set 'hour' / 'day' / 'week' / 'month' or 'year'
displayFormats: {
hour: 'h:mm a',
day: 'ddd, MMM DD, YYYY',
week: 'dddd',
month: 'MMM'
},
tooltipFormat: 'dddd, MMM DD, YYYY' // <-- new in v3.x
},
ticks: {
minRotation: 80, // avoiding overlapping of x-Axis ticks
maxRotation: 90
}
},
y: { // <-- v3.x now object "{", not array "[{" anymore
ticks: {
beginAtZero: true,
callback: function (value) {
if (Number.isInteger(value)) return value;
}
},
suggestedMin: 0,
// the data maximum used for determining the ticks is Math.max(dataMax, suggestedMax)
suggestedMax: 10
}
}
};
const ctx = document.getElementById('chartJSContainer').getContext('2d');
const myChart = new Chart(ctx, {
type: 'line',
data: yourData,
options: yourOptions
});
document.querySelector('#btnTime').addEventListener('click', () => {
myChart.options.scales['x'].type = 'time';
myChart.update();
});
document.querySelector('#btnTimeseries').addEventListener('click', () => {
myChart.options.scales['x'].type = 'timeseries';
myChart.update();
});
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script> -->
<!-- get the latest version of Chart.js, now at v3.5.1 -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<!-- for x-Axis type 'time' or 'timeseries' to work, you need additional libraries -->
<!-- (like moment.js and its adapter) -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment"></script>
<button id='btnTime'>time</button>
<button id='btnTimeseries'>timeseries</button>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
Комментарии:
1. Лучше использовать luxon или date-fns, значительно снижающие производительность, влияющие на библиотеки, также это приведет к той же проблеме, что он не отображает полные целые числа, и если вы показываете только полные целые числа, он показывает только 0 и 1, и это то, чего он явно не хотел
2. Также
stepSize: 10
не заставит минимум 10 единиц к показу, она делает так, что между каждой ТИК есть 10, так что, если ваш диапазон оси от 1 до 100 имеется 10 клещей, а если ваш диапазон оси от 1 до 20 у вас есть только 2 галочки, которая по-прежнему дает ту же проблему, имеющих большой разрыв jsfiddle.net/Leelenaleee/w0cxq8r9/1