summaryrefslogtreecommitdiff
path: root/addons/website/static/src/snippets/s_chart/000.js
blob: 2c67bd036124c58d1a1023c80d8dff8af2000cd9 (plain)
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;
});