#javascript #chart.js
#javascript #chart.js
Вопрос:
У меня есть Chart.js гистограмма, отображающая два набора данных: полные SQL-запросы и медленные SQL-запросы. У меня есть метки по оси Y для каждого соответствующего набора данных. График можно увидеть ниже:
Когда я переключаю один из наборов данных так, чтобы он не отображался, соответствующие метки по оси Y по-прежнему отображаются. При интерпретации графика это немного сбивает с толку. Как показано ниже:
Мой вопрос: как я могу скрыть метки по оси Y любого набора данных, которые в данный момент не отображаются?
Вот как я в настоящее время настраиваю свою диаграмму:
<canvas id="SQLPerformanceChart" minHeight="400"></canvas>
<script type="text/javascript">
...
var data = {
labels: labelArray,
datasets: [{
label: "Total SQL Queries",
fill: false,
borderWidth: 1,
borderColor: "green",
backgroundColor: "rgba(0, 255, 0, 0.3)",
yAxisID: "y-axis-0",
data: totalQueriesArray
}, {
label: "Slow SQL Queries",
fill: false,
borderWidth: 1,
borderColor: "orange",
backgroundColor: "rgba(255, 255, 0, 0.3)",
yAxisID: "y-axis-1",
data: slowQueriesArray,
}]
};
var options = {
animation: false,
scales: {
yAxes: [{
position: "left",
ticks: {
beginAtZero: true
},
scaleLabel: {
display: true,
labelString: 'Total SQL Queries'
},
id: "y-axis-0"
}, {
position: "right",
ticks: {
beginAtZero: true
},
scaleLabel: {
display: true,
labelString: 'Slow SQL Queries'
},
id: "y-axis-1"
}]
},
tooltips: {
enabled: true,
mode: 'single',
callbacks: {
title: function(tooltipItem, data) {
return data.label;
},
beforeLabel: function(tooltipItem, data) {
if (tooltipItem.index == 24) {
return data.labels[tooltipItem.index] " - Now";
} else {
return data.labels[tooltipItem.index] " - " data.labels[(tooltipItem.index) 1];
}
}
}
}
}
var ctx = document.getElementById("SQLPerformanceChart");
var SQLPerformanceChart = new Chart(ctx, {
type: 'bar',
data: data,
options: options
});
</script>
Ответ №1:
Вы можете добавить функцию обратного вызова в легенды onClick:
var options = {
animation: false,
scales: {
yAxes: [{
position: "left",
ticks: {
beginAtZero: true
},
scaleLabel: {
display: true,
labelString: 'Total SQL Queries'
},
id: "y-axis-0"
}, {
position: "right",
ticks: {
beginAtZero: true
},
scaleLabel: {
display: true,
labelString: 'Slow SQL Queries'
},
id: "y-axis-1"
}]
},
legend: {
onClick: function(event, legendItem) {
//get the index of the clicked legend
var index = legendItem.datasetIndex;
//toggle chosen dataset's visibility
SQLPerformanceChart.data.datasets[index].hidden =
!SQLPerformanceChart.data.datasets[index].hidden;
//toggle the related labels' visibility
SQLPerformanceChart.options.scales.yAxes[index].display =
!SQLPerformanceChart.options.scales.yAxes[index].display;
SQLPerformanceChart.update();
}
}
}
Комментарии:
1. Спасибо, но это навсегда скрывает метки. Я пытаюсь скрыть метки только тогда, когда данные переключены на не отображение. Если данные переключаются обратно на отображение, метки должны появиться снова.
2. Спасибо, это улучшение! Но теперь нажатие на элемент легенды приводит только к исчезновению меток. При переопределении функции onClick поведение функции onClick по умолчанию больше не выполняется (например, данные больше не исчезают, в элементе легенды нет зачеркивания и т. Д.). В настоящее время я пытаюсь решить эту проблему.
3. Я добавил еще две строки для решения упомянутых проблем
4. Спасибо за ваш умный способ включения / выключения с помощью «!»
Ответ №2:
Это решение применимо, если вы используете angular-chartjs, и если вы хотите применить это поведение ко всем отображаемым диаграммам.
Если вы хотите перейти к коду, проверьте этот fiddlejs .
Вы также можете проверить этот другой fiddlejs, чтобы проверить поведение Angular-Chartjs по умолчанию.
Шаг за шагом:
Я использую первый пример диаграммы в angular-chart.js , так что это будет конечный результат после нажатия кнопки:
<div ng-app="app" ng-controller="MainController as mainCtrl">
<canvas id="line" class="chart chart-line" chart-data="data"
chart-labels="labels" chart-series="series" chart-options="options"
chart-dataset-override="datasetOverride" chart-click="onClick">
</canvas>
</div>
- Замените обработчик глобальной диаграммы:
Chart.defaults.global.legend.onClick = function (e, legendItem) {
var idx = legendItem.datasetIndex;
// IMPORTANT charts will be created in the second and third step
var chart = charts[e.srcElement.id];
chart.options.scales.yAxes[idx].display = !chart.options.scales.yAxes[idx].display;
var meta = chart.getDatasetMeta(idx);
// See controller.isDatasetVisible comment
meta.hidden = meta.hidden === null ? !chart.data.datasets[idx].hidden : null;
chart.update();
};
- Создайте глобальную переменную
charts
, чтобы мы могли получить доступ к каждой из диаграмм с идентификатором canvas:
var charts = {};
- Заполните переменные диаграммы с помощью
chart-create
события:
angular.module("app", ["chart.js"]).controller("MainController", function ($scope) {
$scope.$on('chart-create', function (event, chart) {
charts[chart.chart.canvas.id] = chart;
});
$scope.labels = ["January", "February", "March", "April", "May", "June", "July"];
$scope.series = ['Series A', 'Series B'];
$scope.data = [...
Хотелось бы, чтобы был лучший способ получения диаграммы из идентификатора canvas, но, насколько я знаю, это предложенный разработчиками способ.
Ответ №3:
Это решение применимо, если вы используете ng2-диаграммы с chart.js и Angular 7 ^ и если вы хотите применить это поведение ко всем отображаемым диаграммам.
import Chart from chart.js
Chart.defaults.global.legend.onClick = function (e: MouseEvent, chartLegendLabelItem: ChartLegendLabelItem) {
const idx: number = chartLegendLabelItem.datasetIndex;
const chart = this.chart;
chart.options.scales.yAxes[idx].display = !chart.options.scales.yAxes[idx].display;
const meta = chart.getDatasetMeta(idx);
meta.hidden = meta.hidden === null ? !chart.data.datasets[idx].hidden : null;
chart.update();
};
или для локальной конфигурации
legend: <ChartLegendOptions>{
onClick: function (e: MouseEvent, chartLegendLabelItem:ChartLegendLabelItem) {
const idx: number = chartLegendLabelItem.datasetIndex;
const chart = this.chart;
chart.options.scales.yAxes[idx].display =
!chart.options.scales.yAxes[idx].display;
const meta = chart.getDatasetMeta(idx);
meta.hidden = meta.hidden === null ?
!chart.data.datasets[idx].hidden : null;
chart.update();
}
}
Комментарии:
1. Отлично сработало, спасибо, сэр 🙂
Ответ №4:
Я столкнулся с этой проблемой, используя версию v3.8.0, ни один из вариантов не сработал для меня. Этот код работает для меня. Обратите внимание, что я сохраняю все свои экземпляры диаграмм на карте, потому что у меня есть несколько диаграмм на одной странице.
var instances = new Map();
При создании заклинаний я помещаю их туда.
и теперь скрытие метки оси y и данных в легенде щелкает:
onClick: function (event, legendItem) {
var instance = instances.get(event.chart.id);
var meta = instance.getDatasetMeta(legendItem.datasetIndex);
var newValue = !meta.yScale.options.display;
meta.hidden = meta.yScale.options.display;
meta.yScale.options.display = newValue;
instance.update();
}