Skip to content

Commit

Permalink
EZEE-3479: As a developer I want to have reusable componenet for char…
Browse files Browse the repository at this point in the history
…ts (#1705)

* EZEE-3479: As a developer I want to have reusable componenet for charts

* After CR
  • Loading branch information
lucasOsti authored Feb 17, 2021
1 parent 02665a3 commit 35eda25
Show file tree
Hide file tree
Showing 8 changed files with 461 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/bundle/Resources/encore/ez.js.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ const layout = [
path.resolve(__dirname, '../public/js/scripts/helpers/table.helper.js'),
path.resolve(__dirname, '../public/js/scripts/admin.format.date.js'),
path.resolve(__dirname, '../public/js/scripts/core/draggable.js'),
path.resolve(__dirname, '../public/js/scripts/core/base.chart.js'),
path.resolve(__dirname, '../public/js/scripts/core/line.chart.js'),
path.resolve(__dirname, '../public/js/scripts/core/pie.chart.js'),
path.resolve(__dirname, '../public/js/scripts/core/custom.dropdown.js'),
path.resolve(__dirname, '../public/js/scripts/core/custom.tooltip.js'),
path.resolve(__dirname, '../public/js/scripts/admin.notifications.js'),
Expand Down
144 changes: 144 additions & 0 deletions src/bundle/Resources/public/js/scripts/core/base.chart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
(function(global, doc, eZ, Chart) {
const IBEXA_WHITE = '#fff';
const IBEXA_COLOR_BASE = '#e0e0e8';
const IBEXA_COLOR_BASE_DARK = '#878b90';

class BaseChart {
constructor(data) {
this.setData(data);
this.lang = document.documentElement.lang.replace('_', '-'); // TO DO: Get this config from settings
}

setData(data) {
this.datasets = data.datasets;
this.labels = data.labels;

if (data.summary) {
this.summary = data.summary;
}
}

setCheckboxBackground(checkbox) {
const { checkedColor } = checkbox.dataset;
const { checked } = checkbox;

if (checked) {
checkbox.style.backgroundColor = checkedColor;
checkbox.style.borderColor = checkedColor;
} else {
checkbox.style.backgroundColor = IBEXA_WHITE;
checkbox.style.borderColor = IBEXA_COLOR_BASE_DARK;
}
}

setLegendCheckboxes() {}

getType() {}

getSummaryValue() {}

getSummaryName(value) {
return value.name;
}

getLayoutOptions() {}

getScaleOptions() {}

getLegendOptions(chart) {}

updateSummary() {}

updateChartMessageDisplay() {
const chartBody = this.chart.canvas.closest('.ez-chart__body');
const chartMessagesNode = chartBody.querySelector('.ez-chart__message');
const chartMessageMethod = this.chart.config.data.datasets.length ? 'add' : 'remove';

chartMessagesNode.classList[chartMessageMethod]('d-none');
}

updateChart() {
this.chart.data.labels = this.labels;
this.chart.data.datasets = this.datasets;

this.chart.update();

this.updateChartMessageDisplay();

if (this.legendContainer) {
this.setLegendCheckboxes();
}

if (this.summaryContainer) {
this.updateSummary();
}
}

render() {
this.chart = new Chart(this.canvas.getContext('2d'), {
type: this.getType(),
data: {
labels: this.labels,
datasets: this.datasets,
},
options: {
responsive: true,
maintainAspectRatio: false,
layout: this.getLayoutOptions(),
elements: {
point: {
radius: 2,
},
line: {
tension: 0,
},
},
legendCallback: (chart) => this.getLegendOptions(chart),
legend: {
display: false,
},
tooltips: {
enabled: true,
mode: 'nearest',
cornerRadius: 4,
borderWidth: 1,
borderColor: IBEXA_COLOR_BASE,
titleFontStyle: 'light',
titleFontColor: IBEXA_COLOR_BASE_DARK,
xPadding: 12,
yPadding: 12,
backgroundColor: IBEXA_WHITE,
callbacks: {
labelTextColor: (tooltipItem, chart) => {
return IBEXA_COLOR_BASE_DARK;
},
},
},
animation: {
onComplete: (animation) => {
const chart = animation.chart;
const chartMethod = chart.config.data.datasets.length ? 'remove' : 'add';
const chartNode = chart.canvas.closest('.ez-chart');

chartNode.dispatchEvent(new CustomEvent('ez-chart-animation-complete'));
chartNode.classList[chartMethod]('ez-chart--no-data');
},
},
scales: this.getScaleOptions(),
},
});

this.updateChartMessageDisplay();

if (this.legendContainer) {
this.setLegendCheckboxes();
}

if (this.summaryContainer) {
this.updateSummary();
}
}
}

eZ.addConfig('core.BaseChart', BaseChart);
})(window, window.document, window.eZ, window.Chart);
106 changes: 106 additions & 0 deletions src/bundle/Resources/public/js/scripts/core/line.chart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
(function(global, doc, eZ) {
const MAX_NUMBER_OF_LABELS = 16;

class LineChart extends eZ.core.BaseChart {
constructor(data) {
super(data);

this.type = 'line';
}

getType() {
return this.type;
}

setData(data) {
super.setData(data);

if (this.labels.length) {
this.labelsInterval = Math.ceil(this.labels.length / MAX_NUMBER_OF_LABELS);
} else {
this.labelsInterval = 1;
}
}

getScaleOptions() {
return {
xAxes: [
{
display: true,
gridLines: {
display: false,
},
ticks: {
maxRotation: 0,
autoSkip: false,
callback: (value, index, values) => {
return index % this.labelsInterval ? null : value;
},
},
},
],
yAxes: [
{
display: true,
type: 'logarithmic',
ticks: {
callback: (...args) => {
const value = Chart.Ticks.formatters.logarithmic.call(this, ...args);

if (value.length) {
return Number(value).toLocaleString();
}

return value;
},
},
},
],
};
}

getLegendOptions(chart) {
const { legendCheckboxTemplate } = this.legendContainer.dataset;
const fragment = doc.createDocumentFragment();

chart.data.datasets.forEach((dataset, index) => {
const container = doc.createElement('div');
const rendredTempalte = legendCheckboxTemplate
.replace('{{ checked_color }}', dataset.backgroundColor)
.replace('{{ dataset_index }}', index)
.replace('{{ label }}', dataset.label);

dataset.hidden = false;
container.insertAdjacentHTML('beforeend', rendredTempalte);

const checkboxNode = container.querySelector('.ez-chart__legend-checkbox-label');

checkboxNode.querySelector('input').checked = !dataset.hidden;
fragment.append(checkboxNode);
});

return fragment;
}

setLegendCheckboxes() {
this.legendContainer.innerHTML = '';
this.legendContainer.appendChild(this.chart.generateLegend());

this.legendContainer.querySelectorAll('.ez-input--legend-checkbox').forEach((legendCheckbox) => {
this.setCheckboxBackground(legendCheckbox);

legendCheckbox.addEventListener('change', (event) => {
const { datasetIndex } = event.currentTarget.dataset;
const dataset = this.chart.data.datasets[datasetIndex];

dataset.hidden = !dataset.hidden;

this.setCheckboxBackground(event.currentTarget);
this.chart.update();
});
});
}
}

eZ.addConfig('core.chart.LineChart', LineChart);
})(window, window.document, window.eZ, window.Chart);
62 changes: 62 additions & 0 deletions src/bundle/Resources/public/js/scripts/core/pie.chart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
(function(global, doc, eZ) {
class PieChart extends eZ.core.BaseChart {
constructor(data) {
super(data);

this.type = 'pie';
}

getType() {
return this.type;
}

getLegendOptions(chart) {
const { backgroundColor } = chart.data.datasets[0];
const { legendCheckboxTemplate } = this.legendContainer.dataset;
const fragment = doc.createDocumentFragment();

chart.data.labels.forEach((label, index) => {
const container = doc.createElement('div');
const rendredTempalte = legendCheckboxTemplate
.replace('{{ checked_color }}', backgroundColor[index])
.replace('{{ dataset_index }}', index)
.replace('{{ label }}', label);

container.insertAdjacentHTML('beforeend', rendredTempalte);

const checkboxNode = container.querySelector('.ez-chart__legend-checkbox-label');
checkboxNode.querySelector('input').checked = true;

fragment.append(checkboxNode);
});

return fragment;
}

setLegendCheckboxes() {
this.legendContainer.innerHTML = '';
this.legendContainer.appendChild(this.chart.generateLegend());
this.legendContainer.querySelectorAll('.ez-input--legend-checkbox').forEach((legendCheckbox) => {
this.setCheckboxBackground(legendCheckbox);
legendCheckbox.addEventListener('change', (event) => {
const dateValues = [];
const backgroundColorValues = [];
this.chart.data.datasets[0].data = [];
this.chart.data.datasets[0].backgroundColor = [];
this.legendContainer.querySelectorAll('.ez-input--legend-checkbox').forEach((legendCheckbox, index) => {
if (legendCheckbox.checked) {
dateValues.push(this.initValues.datasets[0].data[index]);
backgroundColorValues.push(this.initValues.datasets[0].backgroundColor[index]);
}
});
this.chart.data.datasets[0].data = dateValues;
this.chart.data.datasets[0].backgroundColor = backgroundColorValues;
this.setCheckboxBackground(event.currentTarget);
this.chart.update();
});
});
}
}

eZ.addConfig('core.chart.PieChart', PieChart);
})(window, window.document, window.eZ, window.Chart);
Loading

0 comments on commit 35eda25

Please sign in to comment.