Chciałbym zapytać, czy jest to możliwe przy użyciu Chart.js. wyświetlić wartości danych? Chcę wydrukować wykres.
Dzięki za każdą radę.
Chciałbym zapytać, czy jest to możliwe przy użyciu Chart.js. wyświetlić wartości danych? Chcę wydrukować wykres.
Dzięki za każdą radę.
Odpowiedzi:
Późna edycja: istnieje oficjalna wtyczka do Chart.js, 2.7.0+
aby to zrobić: https://github.com/chartjs/chartjs-plugin-datalabels
Oryginalna odpowiedź:
Możesz przechodzić przez punkty / słupki onAnimationComplete i wyświetlać wartości
Zapowiedź
HTML
<canvas id="myChart1" height="300" width="500"></canvas>
<canvas id="myChart2" height="300" width="500"></canvas>
Scenariusz
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
tutaj wywołania zwrotnego, ale jest ono również uruchamiane, gdy najechanie kursorem myszy znajduje się na słupku wykresu, powodując migotanie numeru z powodu przerysowania. Czy to samo, jeśli onAnimationComplete
? Nie mogę użyć tego wywołania zwrotnego z moim istniejącym kodem wykresu (patrz var chartBar
na dole pastebin.com/tT7yTkGh )
Oto zaktualizowana wersja Chart.js 2.3
23 września 2016: Zmodyfikowałem mój kod, aby działał z wersją 2.3 dla obu typów linii / słupków.
Ważne: Nawet jeśli nie potrzebujesz animacji, nie zmieniaj opcji czasu trwania na 0, w przeciwnym razie otrzymasz chartInstance.controller jest niezdefiniowanym błędem.
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>
Ta opcja animacji działa w wersji 2.1.3 na wykresie słupkowym.
Nieznacznie zmodyfikowana odpowiedź @ 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}
aby zatrzymać
.filter(dataset => !dataset._meta[0].hidden)
Myślę, że najładniejszą opcją do zrobienia tego w chartJS v2.x jest użycie wtyczki, więc nie masz dużego bloku kodu w opcjach. Ponadto zapobiega znikaniu danych po najechaniu kursorem na słupek.
To znaczy po prostu użyj tego kodu, który rejestruje wtyczkę, która dodaje tekst po narysowaniu wykresu.
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;
. Problem z tym rozwiązaniem polega na tym, że afterDraw
funkcja jest wywoływana setki razy, prawdopodobnie generując obciążenie procesora. Mimo wszystko jest to na razie jedyna odpowiedź bez mrugnięcia okiem. Jeśli potrzebujesz lepszego renderowania horizontalBar
wykresów, użyj ctx.textAlign = 'left'; ctx.textBaseline = 'middle';
i ctx.fillText(dataset.data[i], model.x+5, model.y);
.
Opierając się na odpowiedzi @ Rossa dla Chart.js 2.0 i nowszych, musiałem wprowadzić niewielkie poprawki, aby zabezpieczyć się przed przypadkiem, gdy wysokość słupka jest zbyt wybrana do granicy skali.
animation
Atrybut opcji wykresie słupkowym za:
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()
na koniec, ale to nie pomogło
onComplete
powrotem połączenie jest wykonywane, kiedy unosiła się na bar, który powoduje, że pojawi się przerysować & tekstowe do blink.Would być to samo onAnimationComplete
jak dobrze? Jestem w stanie używać onAnimationComplete
plecy rozmowę z moim istniejącego kodu (patrz var chartBar
na dole pastebin. com / tT7yTkGh
Jeśli używasz wtyczki chartjs-plugin-datalabels, pomocny będzie następujący obiekt opcji kodu
Upewnij się, że importujesz import 'chartjs-plugin-datalabels';
w pliku maszynopisu lub dodajesz odniesienie do <script src="chartjs-plugin-datalabels.js"></script>
w pliku javascript.
options: {
maintainAspectRatio: false,
responsive: true,
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
}
}]
},
plugins: {
datalabels: {
anchor: 'end',
align: 'top',
formatter: Math.round,
font: {
weight: 'bold'
}
}
}
}
Po tej dobrej odpowiedzi użyłbym następujących opcji dla wykresu słupkowego:
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);
To nadal wykorzystuje system podpowiedzi i jego zalety (automatyczne pozycjonowanie, szablony, ...), ale ukrywa dekoracje (kolor tła, daszek, ...)
this.datasets[0].points
zamiast .bars
. Wolę to rozwiązanie, ponieważ korzysta z systemu podpowiedzi.
onComplete
wywołaniu zwrotnym animacji, ale jest ono uruchamiane nawet po najechaniu kursorem na słupki wykresu, co powoduje, że tekst przerysowuje się i daje niepożądany efekt mrugnięcia. Także próbowałem afterDraw
i wszystko jest takie samo. nie dzieje się na skrzypcach dostarczonych przez potatopeelings.Any Ideas plz?
Z próbek chart.js (plik Chart.js-2.4.0 / samples / data_labelling.html):
`` `` // Zdefiniuj wtyczkę do dostarczania etykiet danych
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);
});
}
});
}
});
`` ''
Polecam użycie tej wtyczki: https://github.com/chartjs/chartjs-plugin-datalabels
Etykiety można dodawać do wykresów po prostu importując wtyczkę do pliku js, np .:
import 'chartjs-plugin-datalabels'
Można je precyzyjnie dostroić, korzystając z tych dokumentów: https://chartjs-plugin-datalabels.netlify.com/options.html
Trochę zredagowano odpowiedź @ ajhuddy. Tylko dla wykresów słupkowych . Moja wersja dodaje:
Wada: po najechaniu kursorem na słupek, który ma wartość w środku, wartość może wyglądać na nieco poszarpaną. Nie znalazłem rozwiązania wyłączającego efekty najechania kursorem. Może również wymagać dostosowania w zależności od własnych ustawień.
Konfiguracja:
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);
}
}
}
Pomocnicy:
// 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
, wiersz 7075. , znajduje się w funkcji Scale. Przeanalizuję to.
Z mojego doświadczenia wynika , że po dołączeniu wtyczki chartjs-plugin-datalabels (pamiętaj, aby umieścić <script>
tag po tagu chart.js na stronie), wykresy zaczną wyświetlać wartości.
Jeśli wybierzesz, możesz dostosować go do swoich potrzeb. Dostosowanie jest wyraźnie udokumentowane tutaj, ale zasadniczo format jest podobny do tego hipotetycznego przykładu:
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);
}
}
}
}
});