1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
odoo.define('website.s_chart', function (require) {
'use strict';
const publicWidget = require('web.public.widget');
const weUtils = require('web_editor.utils');
const ChartWidget = publicWidget.Widget.extend({
selector: '.s_chart',
disabledInEditableMode: false,
jsLibs: [
'/web/static/lib/Chart/Chart.js',
],
/**
* @override
* @param {Object} parent
* @param {Object} options The default value of the chartbar.
*/
init: function (parent, options) {
this._super.apply(this, arguments);
this.style = window.getComputedStyle(document.documentElement);
},
/**
* @override
*/
start: function () {
// Convert Theme colors to css color
const data = JSON.parse(this.el.dataset.data);
data.datasets.forEach(el => {
if (Array.isArray(el.backgroundColor)) {
el.backgroundColor = el.backgroundColor.map(el => this._convertToCssColor(el));
el.borderColor = el.borderColor.map(el => this._convertToCssColor(el));
} else {
el.backgroundColor = this._convertToCssColor(el.backgroundColor);
el.borderColor = this._convertToCssColor(el.borderColor);
}
el.borderWidth = this.el.dataset.borderWidth;
});
// Make chart data
const chartData = {
type: this.el.dataset.type,
data: data,
options: {
legend: {
display: this.el.dataset.legendPosition !== 'none',
position: this.el.dataset.legendPosition,
},
tooltips: {
enabled: this.el.dataset.tooltipDisplay === 'true',
},
title: {
display: !!this.el.dataset.title,
text: this.el.dataset.title,
},
},
};
// Add type specific options
if (this.el.dataset.type === 'radar') {
chartData.options.scale = {
ticks: {
beginAtZero: true,
}
};
} else if (['pie', 'doughnut'].includes(this.el.dataset.type)) {
chartData.options.tooltips.callbacks = {
label: (tooltipItem, data) => {
const label = data.datasets[tooltipItem.datasetIndex].label;
const secondLabel = data.labels[tooltipItem.index];
let final = label;
if (label) {
if (secondLabel) {
final = label + ' - ' + secondLabel;
}
} else if (secondLabel) {
final = secondLabel;
}
return final + ':' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
},
};
} else {
chartData.options.scales = {
xAxes: [{
stacked: this.el.dataset.stacked === 'true',
ticks: {
beginAtZero: true
},
}],
yAxes: [{
stacked: this.el.dataset.stacked === 'true',
ticks: {
beginAtZero: true
},
}],
};
}
// Disable animation in edit mode
if (this.editableMode) {
chartData.options.animation = {
duration: 0,
};
}
const canvas = this.el.querySelector('canvas');
this.chart = new window.Chart(canvas, chartData);
return this._super.apply(this, arguments);
},
/**
* @override
* Discard all library changes to reset the state of the Html.
*/
destroy: function () {
if (this.chart) { // The widget can be destroyed before start has completed
this.chart.destroy();
this.el.querySelectorAll('.chartjs-size-monitor').forEach(el => el.remove());
}
this._super.apply(this, arguments);
},
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* @private
* @param {string} color A css color or theme color string
* @returns {string} Css color
*/
_convertToCssColor: function (color) {
if (!color) {
return 'transparent';
}
return weUtils.getCSSVariableValue(color, this.style) || color;
},
});
publicWidget.registry.chart = ChartWidget;
return ChartWidget;
});
|