Skip to content
Extraits de code Groupes Projets
Sélectionner une révision Git
  • 58a384c85b60e220fcfbd9087ccaffdba7956cc2
  • 16.0 par défaut protégée
  • 16.0-admin-menu-refactoring
3 résultats

canvas.js

Blame
  • canvas.js 30,40 Kio
    odoo.define("oacc_portal_overview_cdc.canvas", function (require) {
        "use strict";
    
        var publicWidget = require("web.public.widget");
    
        publicWidget.registry.oaccPortalOverviewCdc = publicWidget.Widget.extend({
            jsLibs: [
                "/web/static/lib/Chart/Chart.js",
                "/oacc_portal_overview_cdc/static/src/js/lib/chartjs-plugin-datalabels.min.js",
            ],
            selector: ".oe_website_canvas",
            events: {
                "click .btn-period": "_onBtnPeriodClick",
                "click #previous-period": "_onPreviousPeriod",
                "click #next-period": "_onNextPeriod",
                "change select[name='endpoint']": "_onChangePrm",
            },
    
            /**
             * @class
             */
            init: function () {
                this._super.apply(this, arguments);
    
                this.operation = $(".oe_website_canvas").data("id");
    
                this.scale = null;
                this.minDate = null;
                this.maxDate = null;
    
                this.partner_id = null;
                this.title_name = null;
                this.prm_id = null;
                this.data_type = null;
    
                //            Init chart
                this.chart_line_conso = null;
                this.chart_pie_conso = null;
                this.chart_histo_conso = null;
                this.chart_line_prod = null;
                this.chart_pie_prod = null;
                this.chart_histo_prod = null;
    
                this.date_range_picker = null;
    
                this.chartData = null;
            },
    
            /**
             * @override
             */
            willStart: function () {
                var self = this;
                var def = this._rpc({
                    model: "acc.operation",
                    method: "get_date_min_max",
                    args: [self.operation],
                }).then(function (data) {
                    self.minDate = data.date_min;
                    self.maxDate = data.date_max;
                });
                return Promise.all([this._super.apply(this, arguments), def]);
            },
            /**
             * @override
             */
            start: function () {
                var self = this;
                $('select[name="endpoint"]').select2({
                    placeholder: "Sélectionner",
                });
                $('button[id="next-period"]').prop("disabled", true);
    
                return this._super().then(function () {
                    // Récupération des dates de début et fin
                    var $btnWeekVal = $('button[name="month"]').val();
                    var objquote = $btnWeekVal.replaceAll("'", '"');
                    const obj = JSON.parse(objquote);
                    self.first_day = obj.first_day;
                    self.last_day = obj.last_day;
    
                    self.data_type = self.$el.data("name");
                    if (self.data_type == "cons") {
                        self.title_name = "Consommation globale";
                    }
                    if (self.data_type == "prod") {
                        self.title_name = "Production globale";
                    }
                    self.render_daterangepicker();
                    self.render_data();
                });
            },
    
            render_data: function () {
                var self = this;
                self.render_graph();
            },
    
            render_graph: function () {
                var self = this;
    
                var ctx_line_conso = self.$(".line_chart_conso");
                var ctx_line_prod = self.$(".line_chart_prod");
                var ctx_pie_conso = self.$(".pie_chart_conso");
                var ctx_pie_prod = self.$(".pie_chart_prod");
                var ctx_histo_conso = self.$(".histo_chart_conso");
                var ctx_histo_prod = self.$(".histo_chart_prod");
    
                this._rpc({
                    model: "acc.operation",
                    method: "graph_view_global",
                    args: [
                        self.operation,
                        self.first_day,
                        self.last_day,
                        self.partner_id,
                        self.prm_id,
                        self.data_type,
                    ],
                }).then(function (data) {
                    self.scale = data.scale;
                    self.chartData = data.chart_data;
    
                    if (ctx_line_conso.length > 0) {
                        self.chart_line_conso = new Chart(
                            ctx_line_conso,
                            self._getLineChartConfig("cons")
                        );
                    }
    
                    if (ctx_pie_conso.length > 0) {
                        self.chart_pie_conso = new Chart(
                            ctx_pie_conso,
                            self._getPieChartConfig("cons")
                        );
                    }
    
                    if (ctx_histo_conso.length > 0) {
                        self.chart_histo_conso = new Chart(
                            ctx_histo_conso,
                            self._getBarChartConfig("cons")
                        );
                    }
    
                    if (ctx_line_prod.length > 0) {
                        self.chart_line_prod = new Chart(
                            ctx_line_prod,
                            self._getLineChartConfig("prod")
                        );
                    }
    
                    if (ctx_pie_prod.length > 0) {
                        self.chart_pie_prod = new Chart(
                            ctx_pie_prod,
                            self._getPieChartConfig("prod")
                        );
                    }
    
                    if (ctx_histo_prod.length > 0) {
                        self.chart_histo_prod = new Chart(
                            ctx_histo_prod,
                            self._getBarChartConfig("prod")
                        );
                    }
                });
            },
    
            render_daterangepicker: function () {
                var self = this;
    
                this.date_range_picker = this.$(
                    'input[name="daterange"]'
                ).daterangepicker(
                    {
                        showDropdowns: true,
                        startDate: self.first_day,
                        endDate: self.last_day,
                        minDate: self.minDate,
                        maxDate: self.maxDate,
                        autoApply: true,
                        alwaysShowCalendars: true,
                        autoUpdateInput: true,
                        linkedCalendars: true,
                    },
                    function (start, end, label) {
                        self.first_day = start.format("DD/MM/YYYY");
                        self.last_day = end.format("DD/MM/YYYY");
                        self._rpc({
                            route: "/chart/update_json",
                            params: {
                                operation_id: self.operation,
                                date_start: self.first_day,
                                date_end: self.last_day,
                                partner_id: self.partner_id,
                                prm_id: self.prm_id,
                                data_type: self.data_type,
                            },
                        }).then(function (data) {
                            self._updateDataTemplate(data);
                        });
                    }
                );
            },
    
            /**
             * Returns a bar chart configuration.
             *
             * @private
             */
            _getBarChartData: function (typeData) {
                var data, data_autocons, data_allocons, data_label, data_surplus;
    
                if (typeData === "cons") {
                    if (this.scale === "day") {
                        data_autocons = this.chartData.autocons_histo;
                        data_allocons = this.chartData.allocons_histo;
                        data_label = this.chartData.label_histo;
                    } else {
                        data_autocons = this.chartData.autocons;
                        data_allocons = this.chartData.allocons;
                        data_label = this.chartData.label;
                    }
                    data = {
                        labels: data_label,
                        datasets: [
                            {
                                label: "AutoConso",
                                data: data_autocons,
                                backgroundColor: "rgba(91, 154, 81, 0.4)",
                                hoverBackgroundColor: "rgba(91, 154, 81, 0.7)",
                            },
                            {
                                label: "AlloConso",
                                data: data_allocons,
                                backgroundColor: "rgba(57, 120, 187, 0.4)",
                                hoverBackgroundColor: "rgba(57, 120, 187, 0.7)",
                            },
                        ],
                    };
                } else {
                    if (this.scale === "day") {
                        data_autocons = this.chartData.autocons_prod_histo;
                        data_surplus = this.chartData.surplus_histo;
                        data_label = this.chartData.label_histo;
                    } else {
                        data_autocons = this.chartData.autocons_prod;
                        data_surplus = this.chartData.surplus;
                        data_label = this.chartData.label;
                    }
                    data = {
                        labels: data_label,
                        datasets: [
                            {
                                label: "AutoConso",
                                data: data_autocons,
                                backgroundColor: "rgba(91, 154, 81, 0.4)",
                                hoverBackgroundColor: "rgba(91, 154, 81, 0.7)",
                                borderColor: "rgba(91, 154, 81, 1)",
                            },
                            {
                                label: "Surplus",
                                data: data_surplus,
                                backgroundColor: "rgba(225, 80, 96, 0.4)",
                                hoverBackgroundColor: "rgba(225, 80, 96, 0.7)",
                                borderColor: "rgba(225, 80, 96, 1)",
                            },
                        ],
                    };
                }
                return data;
            },
    
            _getBarChartConfig: function (typeData) {
                var data = this._getBarChartData(typeData);
    
                return {
                    type: "bar",
                    data: data,
                    options: {
                        legend: {
                            onHover: (event, chartElement) => {},
                        },
                        interaction: {
                            intersect: false,
                        },
                        scales: {
                            xAxes: [
                                {
                                    type: "time",
                                    time: {
                                        unit: this.scale,
                                        displayFormats: {
                                            hour: "HH:mm",
                                            day: "DD MMM",
                                            quarter: "D MMM",
                                        },
                                    },
                                    stacked: true,
                                    offset: true,
                                    gridLines: {
                                        offsetGridLines: true,
                                    },
                                },
                            ],
                            yAxes: [
                                {
                                    stacked: true,
                                    ticks: {
                                        beginAtZero: true,
                                    },
                                    scaleLabel: {
                                        display: true,
                                        labelString: "kWh",
                                    },
                                },
                            ],
                        },
                        tooltips: {
                            mode: "x",
                            callbacks: {
                                title: function (tooltipItems) {
                                    return moment(tooltipItems[0].xLabel)
                                        .locale("fr-FR")
                                        .format("DD/MM/YYYY HH:ss");
                                },
                                label: function (context, data) {
                                    return (
                                        data.datasets[context.datasetIndex].label +
                                        " : " +
                                        context.yLabel.toLocaleString("fr", {
                                            maximumFractionDigits: 1,
                                        }) +
                                        " kWh"
                                    );
                                },
                            },
                        },
                    },
                };
            },
    
            /**
             * Returns a Pie chart configuration.
             *
             * @private
             */
            _getPieChartData: function (typeData) {
                var data, res;
                var sum_res1 = 0;
                var sum_res2 = 0;
                if (typeData === "cons") {
                    this.chartData.autocons.forEach((item) => {
                        if ("y" in item) {
                            sum_res1 += item.y;
                        } else {
                            sum_res1 += item;
                        }
                    });
                    this.chartData.allocons.forEach((item) => {
                        if ("y" in item) {
                            sum_res2 += item.y;
                        } else {
                            sum_res2 += item;
                        }
                    });
                    res = [Math.floor(sum_res1), Math.floor(sum_res2)];
                    data = {
                        labels: ["AutoConso", "AlloConso"],
                        datasets: [
                            {
                                label: "Inférieur à 3",
                                data: res,
                                backgroundColor: [
                                    "rgba(91, 154, 81, 0.4)",
                                    "rgba(57, 120, 187, 0.4)",
                                ],
                                hoverBackgroundColor: [
                                    "rgba(91, 154, 81, 0.7)",
                                    "rgba(57, 120, 187, 0.7)",
                                ],
                                borderWidth: 1,
                            },
                        ],
                    };
                } else {
                    this.chartData.autocons_prod.forEach((item) => {
                        if ("y" in item) {
                            sum_res1 += item.y;
                        } else {
                            sum_res1 += item;
                        }
                    });
                    this.chartData.surplus.forEach((item) => {
                        if ("y" in item) {
                            sum_res2 += item.y;
                        } else {
                            sum_res2 += item;
                        }
                    });
                    res = [Math.floor(sum_res1), Math.floor(sum_res2)];
                    data = {
                        labels: ["AutoConso", "Surplus"],
                        datasets: [
                            {
                                label: "Inférieur à 3",
                                data: res,
                                backgroundColor: [
                                    "rgba(91, 154, 81, 0.4)",
                                    "rgba(225, 80, 96, 0.4)",
                                ],
                                hoverBackgroundColor: [
                                    "rgba(91, 154, 81, 0.7)",
                                    "rgba(225, 80, 96, 0.7)",
                                ],
                                borderWidth: 1,
                            },
                        ],
                    };
                }
                return data;
            },
    
            _getPieChartConfig: function (typeData) {
                var data = this._getPieChartData(typeData);
                return {
                    type: "pie",
                    data: data,
                    plugins: [ChartDataLabels],
                    options: {
                        animation: {
                            animateScale: true,
                        },
                        plugins: {
                            datalabels: {
                                textAlign: "center",
                                font: {
                                    size: 18,
                                    weight: "bold",
                                },
                                formatter: (value, data) => {
                                    var total = 0;
                                    data.dataset.data.forEach((num) => {
                                        total += num;
                                    });
                                    var labelPercentage = Math.round(
                                        (value / total) * 100
                                    );
                                    return (
                                        value + " kWh\n" + labelPercentage + " %"
                                    );
                                },
                            },
                        },
                        tooltips: {
                            callbacks: {
                                label: function (tooltipItem, data) {
                                    var allData =
                                        data.datasets[tooltipItem.datasetIndex]
                                            .data;
                                    var tooltipLabel =
                                        data.labels[tooltipItem.index];
                                    var tooltipData = allData[tooltipItem.index];
                                    var total = 0;
                                    for (var i in allData) {
                                        total += allData[i];
                                    }
                                    var tooltipPercentage = Math.round(
                                        (tooltipData / total) * 100
                                    );
                                    return (
                                        tooltipLabel +
                                        ": " +
                                        tooltipData +
                                        " kWh (" +
                                        tooltipPercentage +
                                        "%)"
                                    );
                                },
                            },
                        },
                    },
                };
            },
    
            /**
             * Returns a line chart configuration.
             *
             * @private
             */
            _getLineChartData: function (typeData) {
                var data;
                if (typeData === "cons") {
                    data = {
                        labels: this.chartData.label,
                        datasets: [
                            {
                                label: "Conso",
                                data: this.chartData.cons,
                                backgroundColor: "rgba(57, 120, 187, 0.2)",
                                borderColor: "rgba(57, 120, 187, 1)",
                                borderWidth: 1,
                                hoverRadius: 1,
                                radius: 0,
                            },
                            {
                                label: "Production solaire",
                                data: this.chartData.prod,
                                backgroundColor: "rgba(244, 165, 25, 0)",
                                borderColor: "rgba(244, 165, 25, 1)",
                                borderWidth: 2,
                                hoverRadius: 1,
                                radius: 0,
                                hidden: true,
                            },
                            {
                                label: "AutoConso",
                                data: this.chartData.autocons,
                                backgroundColor: "rgba(91, 154, 81, 0.4)",
                                borderColor: "rgba(91, 154, 81, 1)",
                                borderWidth: 2,
                                hoverRadius: 1,
                                radius: 0,
                            },
                        ],
                    };
                } else {
                    data = {
                        labels: this.chartData.label,
                        datasets: [
                            {
                                label: "AutoConso",
                                data: this.chartData.autocons_prod,
                                backgroundColor: "rgba(91, 154, 81, 0.4)",
                                borderColor: "rgba(91, 154, 81, 1)",
                                borderWidth: 2,
                                hoverRadius: 1,
                                radius: 0,
                                fill: "origin",
                            },
                            {
                                label: "Surplus",
                                data: this.chartData.surplus,
                                backgroundColor: "rgba(225, 80, 96, 0.4)",
                                borderColor: "rgba(225, 80, 96, 1)",
                                borderWidth: 2,
                                hoverRadius: 1,
                                radius: 0,
                                fill: "-1",
                            },
                        ],
                    };
                }
                return data;
            },
    
            _getLineChartConfig: function (typeData) {
                var data = this._getLineChartData(typeData);
                var stacked;
                if (typeData === "cons") {
                    stacked = false;
                } else {
                    stacked = true;
                }
                return {
                    type: "line",
                    data: data,
                    options: {
                        scales: {
                            xAxes: [
                                {
                                    type: "time",
                                    time: {
                                        unit: this.scale,
                                        displayFormats: {
                                            hour: "HH:mm",
                                            day: "DD MMM",
                                            quarter: "D MMM",
                                        },
                                    },
                                    gridLines: {
                                        offsetGridLines: true,
                                    },
                                },
                            ],
                            yAxes: [
                                {
                                    stacked: stacked,
                                    scaleLabel: {
                                        display: true,
                                        labelString: "kW",
                                    },
                                },
                            ],
                        },
                        tooltips: {
                            backgroundColor: "#f5f5f5",
                            titleFontColor: "#333",
                            bodyFontColor: "#666",
                            bodySpacing: 4,
                            xPadding: 12,
                            mode: "x",
                            intersect: false,
                            callbacks: {
                                title: function (tooltipItems) {
                                    return moment(tooltipItems[0].xLabel)
                                        .locale("fr-FR")
                                        .format("DD/MM/YYYY HH:ss");
                                },
                                label: function (context, data) {
                                    return (
                                        data.datasets[context.datasetIndex].label +
                                        " : " +
                                        context.yLabel.toLocaleString("fr", {
                                            maximumFractionDigits: 1,
                                        }) +
                                        " kW"
                                    );
                                },
                            },
                        },
                        elements: {
                            point: {
                                radius: 0,
                            },
                        },
                    },
                };
            },
    
            // --------------------------------------------------------------------------
            // Private
            // --------------------------------------------------------------------------
            _updateChartData: function (title_name) {
                var self = this;
                this._rpc({
                    route: "/chart/update_json",
                    params: {
                        operation_id: self.operation,
                        date_start: self.first_day,
                        date_end: self.last_day,
                        partner_id: self.partner_id,
                        prm_id: self.prm_id,
                        data_type: self.data_type,
                    },
                }).then(function (data) {
                    if (title_name) {
                        var title_cdc = $(".title_cdc");
                        var title_upd =
                            '<h3 class="title_cdc text-center mt-2">' +
                            title_name +
                            "</h3>";
                        title_cdc.replaceWith(title_upd);
                    }
                    self._updateDataTemplate(data);
                });
            },
    
            _updateDataTemplate: function (data) {
                self = this;
    
                self.chartData = data.chart_data;
    
                self.scale = data.scale;
    
                if (data.is_curve_line) {
                    $(".js_curv_line").removeClass("d-none");
                } else {
                    $(".js_curv_line").addClass("d-none");
                }
    
                // Disable buttons if first or last date
                if (moment(this.last_day, "dd/mm/yyyy") >= moment(this.maxDate, "dd/mm/yyyy")) {
                    $('button[id="next-period"]').prop("disabled", true);
                } else {
                    $('button[id="next-period"]').prop("disabled", false);
                }
                if (moment(this.first_day, "dd/mm/yyyy") <= moment(this.minDate, "dd/mm/yyyy")) {
                    $('button[id="previous-period"]').prop("disabled", true);
                } else {
                    $('button[id="previous-period"]').prop("disabled", false);
                }
    
                if (self.chart_line_conso !== null) {
                    self.chart_line_conso.data = self._getLineChartData("cons");
                    self.chart_line_conso.options.scales.xAxes[0].time.unit =
                        self.scale;
                    self.chart_line_conso.update();
                }
    
                if (self.chart_pie_conso !== null) {
                    self.chart_pie_conso.data = self._getPieChartData("cons");
                    self.chart_pie_conso.update();
                }
                if (self.chart_histo_conso !== null) {
                    self.chart_histo_conso.data = self._getBarChartData("cons");
                    self.chart_histo_conso.options.scales.xAxes[0].time.unit =
                        self.scale;
                    self.chart_histo_conso.update();
                }
    
                if (self.chart_line_prod !== null) {
                    self.chart_line_prod.data = self._getLineChartData("prod");
                    self.chart_line_prod.options.scales.xAxes[0].time.unit =
                        self.scale;
                    self.chart_line_prod.update();
                }
    
                if (self.chart_pie_prod !== null) {
                    self.chart_pie_prod.data = self._getPieChartData("prod");
                    self.chart_pie_prod.update();
                }
    
                if (self.chart_histo_prod !== null) {
                    self.chart_histo_prod.data = self._getBarChartData("prod");
                    self.chart_histo_prod.options.scales.xAxes[0].time.unit =
                        self.scale;
                    self.chart_histo_prod.update();
                }
            },
    
            _onBtnPeriodClick: function (ev) {
                var $iframe = $(ev.currentTarget).val();
                var objquote = $iframe.replaceAll("'", '"');
                const obj = JSON.parse(objquote);
                this.first_day = obj.first_day;
                this.last_day = obj.last_day;
                this.date_range_picker
                    .data("daterangepicker")
                    .setStartDate(this.first_day);
                this.date_range_picker
                    .data("daterangepicker")
                    .setEndDate(this.last_day);
                this._updateChartData(this.title_name);
            },
    
            _onChangePrm: function (ev) {
                var selected = $(ev.currentTarget).find("option:selected");
                this.title_name = selected.data("name");
                this.partner_id = parseInt(selected.data("partner-id"));
                this.prm_id = parseInt(selected.data("prm-id"));
                this._updateChartData(this.title_name);
            },
    
            _onPreviousPeriod: function (ev) {
                this._onChangePeriod("previous");
            },
            _onNextPeriod: function (ev) {
                this._onChangePeriod("next");
            },
            _onChangePeriod: function (type) {
                const first_day = moment(this.first_day, "DD/MM/YYYY");
                const last_day = moment(this.last_day, "DD/MM/YYYY");
                const delta_days = last_day - first_day;
                let delta_month = 0;
    
                if (
                    first_day.isSame(first_day.clone().startOf("month"), "day") &&
                    last_day.isSame(last_day.clone().endOf("month"), "day")
                ) {
                    delta_month = last_day.month() - first_day.month() + 1;
                }
    
                if (type == "previous") {
                    // Compare for first day
                    let next_first = first_day
                        .clone()
                        .subtract(delta_days)
                        .subtract(1, "d");
                    const moment_min = moment(this.minDate, "DD/MM/YYYY");
                    this.last_day = moment(this.first_day, "DD/MM/YYYY")
                        .subtract(1, "d")
                        .format("DD/MM/YYYY");
    
                    if (delta_month > 0) {
                        next_first = first_day
                            .clone()
                            .subtract(delta_month, "months");
                    }
    
                    this.first_day = moment
                        .max([next_first, moment_min])
                        .format("DD/MM/YYYY");
                }
                if (type == "next") {
                    // Compare for last day
                    let next_last = last_day.clone().add(delta_days).add(1, "d");
                    const moment_max = moment(this.maxDate, "DD/MM/YYYY");
                    this.first_day = moment(this.last_day, "DD/MM/YYYY")
                        .add(1, "d")
                        .format("DD/MM/YYYY");
    
                    if (delta_month > 0) {
                        next_last = last_day
                            .clone()
                            .add(delta_month, "months")
                            .endOf("month");
                    }
    
                    this.last_day = moment
                        .min([next_last, moment_max])
                        .format("DD/MM/YYYY");
                }
                this.date_range_picker
                    .data("daterangepicker")
                    .setStartDate(this.first_day);
                this.date_range_picker
                    .data("daterangepicker")
                    .setEndDate(this.last_day);
                this._updateChartData(this.title_name);
            },
        });
    });