Я хотел бы спросить, можно ли использовать Chart.js отображать значения данных? Я хочу распечатать график.
Спасибо за любой совет.
Я хотел бы спросить, можно ли использовать Chart.js отображать значения данных? Я хочу распечатать график.
Спасибо за любой совет.
Ответы:
Позднее редактирование: для этого есть официальный плагин для Chart.js 2.7.0+
: https://github.com/chartjs/chartjs-plugin-datalabels
Оригинальный ответ:
Вы можете перемещаться по точкам / полосам на AnimationComplete и отображать значения
Предварительный просмотр
HTML
<canvas id="myChart1" height="300" width="500"></canvas>
<canvas id="myChart2" height="300" width="500"></canvas>
Сценарий
var chartData = {
labels: ["January", "February", "March", "April", "May", "June"],
datasets: [
{
fillColor: "#79D1CF",
strokeColor: "#79D1CF",
data: [60, 80, 81, 56, 55, 40]
}
]
};
var ctx = document.getElementById("myChart1").getContext("2d");
var myLine = new Chart(ctx).Line(chartData, {
showTooltips: false,
onAnimationComplete: function () {
var ctx = this.chart.ctx;
ctx.font = this.scale.font;
ctx.fillStyle = this.scale.textColor
ctx.textAlign = "center";
ctx.textBaseline = "bottom";
this.datasets.forEach(function (dataset) {
dataset.points.forEach(function (points) {
ctx.fillText(points.value, points.x, points.y - 10);
});
})
}
});
var ctx = document.getElementById("myChart2").getContext("2d");
var myBar = new Chart(ctx).Bar(chartData, {
showTooltips: false,
onAnimationComplete: function () {
var ctx = this.chart.ctx;
ctx.font = this.scale.font;
ctx.fillStyle = this.scale.textColor
ctx.textAlign = "center";
ctx.textBaseline = "bottom";
this.datasets.forEach(function (dataset) {
dataset.bars.forEach(function (bar) {
ctx.fillText(bar.value, bar.x, bar.y - 5);
});
})
}
});
Fiddle - http://jsfiddle.net/uh9vw0ao/
onComplete
здесь обратный вызов, но он также срабатывает при наведении курсора мыши на полосу диаграммы, в результате чего число мигает из-за перерисовки. Было бы так, если бы onAnimationComplete
? Я не могу использовать этот обратный вызов с моим существующим кодом диаграммы (см. var chartBar
Внизу pastebin.com/tT7yTkGh )
Вот обновленная версия Chart.js 2.3
23 сентября 2016 г .: Отредактировал мой код для работы с версией 2.3 для типов линий и полос.
Важно: даже если вам не нужна анимация, не меняйте параметр продолжительности на 0, иначе вы получите ошибку chartInstance.controller is undefined .
var chartData = {
labels: ["January", "February", "March", "April", "May", "June"],
datasets: [
{
fillColor: "#79D1CF",
strokeColor: "#79D1CF",
data: [60, 80, 81, 56, 55, 40]
}
]
};
var opt = {
events: false,
tooltips: {
enabled: false
},
hover: {
animationDuration: 0
},
animation: {
duration: 1,
onComplete: function () {
var chartInstance = this.chart,
ctx = chartInstance.ctx;
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, Chart.defaults.global.defaultFontStyle, Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
this.data.datasets.forEach(function (dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
meta.data.forEach(function (bar, index) {
var data = dataset.data[index];
ctx.fillText(data, bar._model.x, bar._model.y - 5);
});
});
}
}
};
var ctx = document.getElementById("Chart1"),
myLineChart = new Chart(ctx, {
type: 'bar',
data: chartData,
options: opt
});
<canvas id="myChart1" height="300" width="500"></canvas>
Этот вариант анимации работает в версии 2.1.3 на гистограмме.
Слегка измененный ответ @Ross
animation: {
duration: 0,
onComplete: function () {
// render the value of the chart above the bar
var ctx = this.chart.ctx;
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, 'normal', Chart.defaults.global.defaultFontFamily);
ctx.fillStyle = this.chart.config.options.defaultFontColor;
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
this.data.datasets.forEach(function (dataset) {
for (var i = 0; i < dataset.data.length; i++) {
var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model;
ctx.fillText(dataset.data[i], model.x, model.y - 5);
}
});
}}
hover: {animationDuration: 0}
чтобы метки не
.filter(dataset => !dataset._meta[0].hidden)
Я думаю, что лучший вариант сделать это в chartJS v2.x - использовать плагин, поэтому у вас нет большого блока кода в параметрах. Кроме того, он предотвращает исчезновение данных при наведении курсора на полосу.
Т.е. просто используйте этот код, который регистрирует плагин, который добавляет текст после рисования диаграммы.
Chart.pluginService.register({
afterDraw: function(chartInstance) {
var ctx = chartInstance.chart.ctx;
// render the value of the chart above the bar
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, 'normal', Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
chartInstance.data.datasets.forEach(function (dataset) {
for (var i = 0; i < dataset.data.length; i++) {
var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model;
ctx.fillText(dataset.data[i], model.x, model.y - 2);
}
});
}
});
Chart.defaults.global.tooltips.enabled = false;
. Проблема с этим решением заключается в том, что afterDraw
функция вызывается сотни раз, что, вероятно, вызывает накладные расходы ЦП. Тем не менее, это пока единственный ответ без моргания. Если вам нужен лучший рендеринг для horizontalBar
диаграмм, используйте ctx.textAlign = 'left'; ctx.textBaseline = 'middle';
и ctx.fillText(dataset.data[i], model.x+5, model.y);
.
Основываясь на ответе @ Ross для Chart.js 2.0 и выше, мне пришлось включить небольшую настройку, чтобы не допустить случая, когда высота столбца слишком велика к границе шкалы.
animation
Атрибут опции Гистограмма в:
animation: {
duration: 500,
easing: "easeOutQuart",
onComplete: function () {
var ctx = this.chart.ctx;
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontFamily, 'normal', Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
this.data.datasets.forEach(function (dataset) {
for (var i = 0; i < dataset.data.length; i++) {
var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model,
scale_max = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._yScale.maxHeight;
ctx.fillStyle = '#444';
var y_pos = model.y - 5;
// Make sure data value does not get overflown and hidden
// when the bar's value is too close to max value of scale
// Note: The y value is reverse, it counts from top down
if ((scale_max - model.y) / scale_max >= 0.93)
y_pos = model.y + 20;
ctx.fillText(dataset.data[i], model.x, y_pos);
}
});
}
}
ctx.save()
onComplete
обратный вызов выполняется , когда я парил на баре, который вызывает перерисовки и текст отображается в blink.Would это то же самое с onAnimationComplete
, а? Я не могу использовать onAnimationComplete
вызов обратно с моего существующего кода (см var chartBar
в нижней части Pastebin. com / tT7yTkGh
Если вы используете плагин chartjs-plugin-datalabels, следующий объект параметров кода поможет
Убедитесь, что вы импортируете import 'chartjs-plugin-datalabels';
файл машинописного текста или добавляете ссылку на него <script src="chartjs-plugin-datalabels.js"></script>
в свой файл javascript.
options: {
maintainAspectRatio: false,
responsive: true,
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
}
}]
},
plugins: {
datalabels: {
anchor: 'end',
align: 'top',
formatter: Math.round,
font: {
weight: 'bold'
}
}
}
}
После этого хорошего ответа я бы использовал эти параметры для гистограммы:
var chartOptions = {
animation: false,
responsive : true,
tooltipTemplate: "<%= value %>",
tooltipFillColor: "rgba(0,0,0,0)",
tooltipFontColor: "#444",
tooltipEvents: [],
tooltipCaretSize: 0,
onAnimationComplete: function()
{
this.showTooltip(this.datasets[0].bars, true);
}
};
window.myBar = new Chart(ctx1).Bar(chartData, chartOptions);
Он по-прежнему использует систему всплывающих подсказок и его преимущества (автоматическое позиционирование, создание шаблонов, ...), но скрывает украшения (цвет фона, курсор, ...)
this.datasets[0].points
вместо .bars
. Я предпочитаю это решение, потому что оно использует систему всплывающих подсказок.
onComplete
но он срабатывает даже при наведении курсора мыши на столбцы диаграммы, что приводит к перерисовке текста и возникновению нежелательного эффекта мигания. Я также пробовал, afterDraw
и это все то же самое. не происходит в скрипке, предоставленной картофелечистками. Любые идеи, пожалуйста?
Из примеров chart.js (файл Chart.js-2.4.0 / samples / data_labelling.html):
`` `// Определяем плагин для предоставления меток данных
Chart.plugins.register({
afterDatasetsDraw: function(chartInstance, easing) {
// To only draw at the end of animation, check for easing === 1
var ctx = chartInstance.chart.ctx;
chartInstance.data.datasets.forEach(function (dataset, i) {
var meta = chartInstance.getDatasetMeta(i);
if (!meta.hidden) {
meta.data.forEach(function(element, index) {
// Draw the text in black, with the specified font
ctx.fillStyle = 'rgb(0, 0, 0)';
var fontSize = 16;
var fontStyle = 'normal';
var fontFamily = 'Helvetica Neue';
ctx.font = Chart.helpers.fontString(fontSize, fontStyle, fontFamily);
// Just naively convert to string for now
var dataString = dataset.data[index].toString();
// Make sure alignment settings are correct
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
var padding = 5;
var position = element.tooltipPosition();
ctx.fillText(dataString, position.x, position.y - (fontSize / 2) - padding);
});
}
});
}
});
`` `
Я бы рекомендовал использовать этот плагин: https://github.com/chartjs/chartjs-plugin-datalabels
Ярлыки можно добавлять в ваши диаграммы, просто импортировав плагин в файл js, например:
import 'chartjs-plugin-datalabels'
И его можно точно настроить с помощью этих документов: https://chartjs-plugin-datalabels.netlify.com/options.html
Немного отредактировал ответ @ajhuddy. Только для гистограмм . Моя версия добавляет:
Оборотная сторона: при наведении курсора на полосу, внутри которой есть значение, значение может выглядеть немного неровным. Я не нашел решения отключить эффекты наведения. Это также может потребовать настройки в зависимости от ваших собственных настроек.
Конфигурация:
bar: {
tooltips: {
enabled: false
},
hover: {
animationDuration: 0
},
animation: {
onComplete: function() {
this.chart.controller.draw();
drawValue(this, 1);
},
onProgress: function(state) {
var animation = state.animationObject;
drawValue(this, animation.currentStep / animation.numSteps);
}
}
}
Помощники:
// Font color for values inside the bar
var insideFontColor = '255,255,255';
// Font color for values above the bar
var outsideFontColor = '0,0,0';
// How close to the top edge bar can be before the value is put inside it
var topThreshold = 20;
var modifyCtx = function(ctx) {
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, 'normal', Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
return ctx;
};
var fadeIn = function(ctx, obj, x, y, black, step) {
var ctx = modifyCtx(ctx);
var alpha = 0;
ctx.fillStyle = black ? 'rgba(' + outsideFontColor + ',' + step + ')' : 'rgba(' + insideFontColor + ',' + step + ')';
ctx.fillText(obj, x, y);
};
var drawValue = function(context, step) {
var ctx = context.chart.ctx;
context.data.datasets.forEach(function (dataset) {
for (var i = 0; i < dataset.data.length; i++) {
var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model;
var textY = (model.y > topThreshold) ? model.y - 3 : model.y + 20;
fadeIn(ctx, dataset.data[i], model.x, textY, model.y > topThreshold, step);
}
});
};
calculateTickRotation
, это внутри функции Scale. Я это проанализирую.
По моему опыту, после того, как вы включите плагин chartjs-plugin-datalabels (обязательно разместите <script>
тег после тега chart.js на своей странице), ваши диаграммы начинают отображать значения.
Если вы затем выберете, вы можете настроить его в соответствии со своими потребностями. Настройка четко задокументирована здесь, но в основном формат похож на этот гипотетический пример:
var myBarChart = new Chart(ctx, {
type: 'bar',
data: yourDataObject,
options: {
// other options
plugins: {
datalabels: {
anchor :'end',
align :'top',
// and if you need to format how the value is displayed...
formatter: function(value, context) {
return GetValueFormatted(value);
}
}
}
}
});