From b9368f8c596251b6c5b84f1064bdd667947bbc42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20=C3=89vrard?= Date: Fri, 13 Mar 2026 15:14:09 +0100 Subject: [PATCH] Replace d3 by billboard.js Close #14313 --- sao/eslint.config.mjs | 2 +- sao/index.html | 4 ++-- sao/package.json | 3 ++- sao/src/view/graph.js | 42 +++++++++++++++++++++--------------------- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/sao/eslint.config.mjs b/sao/eslint.config.mjs index ac283aeaa7..e2767e922b 100644 --- a/sao/eslint.config.mjs +++ b/sao/eslint.config.mjs @@ -13,7 +13,7 @@ export default [ QUnit: "readonly", Sao: "readonly", Sortable: "readonly", - c3: "readonly", + bb: "readonly", i18n: "readonly", jQuery: "readonly", moment: "readonly", diff --git a/sao/index.html b/sao/index.html index 69bd217b75..e2dd05de2f 100644 --- a/sao/index.html +++ b/sao/index.html @@ -15,7 +15,7 @@ this repository contains the full copyright notices and license terms. --> - + @@ -23,7 +23,7 @@ this repository contains the full copyright notices and license terms. --> - + diff --git a/sao/package.json b/sao/package.json index e6c97d7370..6352cbc3cb 100644 --- a/sao/package.json +++ b/sao/package.json @@ -50,11 +50,12 @@ "tryton" ], "dependencies": { + "billboard.js": "^3.17", + "d3": "^7.9", "jquery": "^3", "bootstrap": "^3.3.7", "moment": "^2.10", "gettext.js": "^2", - "c3": "^0.7", "papaparse": "^5.0", "fullcalendar": "^3.10.2", "mousetrap": "^1.6", diff --git a/sao/src/view/graph.js b/sao/src/view/graph.js index 10fa93282d..b3e2d008bf 100644 --- a/sao/src/view/graph.js +++ b/sao/src/view/graph.js @@ -95,7 +95,7 @@ return () => { record = group[index]; var x = record.field_get_client(this.xfield.name); - // c3 does not support moment + // billboard does not support moment if (x && (x.isDate || x.isDateTime)) { x = x.toString(); } @@ -164,18 +164,18 @@ display: function(group) { var update_prm = this.update_data(group); update_prm.done(data => { - c3.generate(this._c3_config(data)); + bb.generate(this._bb_config(data)); }); return update_prm; }, - _c3_config: function(data) { - var c3_config = {}; + _bb_config: function(data) { + var bb_config = {}; - c3_config.bindto = '#' + this.el.attr('id'); - c3_config.data = data; - c3_config.data.type = this._chart_type; - c3_config.data.x = 'labels'; - c3_config.data.onclick = this.action.bind(this); + bb_config.bindto = '#' + this.el.attr('id'); + bb_config.data = data; + bb_config.data.type = this._chart_type; + bb_config.data.x = 'labels'; + bb_config.data.onclick = this.action.bind(this); var type = this.view.screen.model.fields[this.xfield.name] .description.type; @@ -185,18 +185,18 @@ this.view.screen.context.date_format); time_format = '%X'; if (type == 'datetime') { - c3_config.data.xFormat = '%Y-%m-%d %H:%M:%S'; + bb_config.data.xFormat = '%Y-%m-%d %H:%M:%S'; format_func = function(dt) { return Sao.common.format_datetime( date_format + ' ' + time_format, moment(dt)); }; } else { - c3_config.data.xFormat = '%Y-%m-%d'; + bb_config.data.xFormat = '%Y-%m-%d'; format_func = function(dt) { return Sao.common.format_date(date_format, moment(dt)); }; } - c3_config.axis = { + bb_config.axis = { x: { type: 'timeseries', tick: { @@ -205,7 +205,7 @@ } }; } else { - c3_config.axis = { + bb_config.axis = { x: { type: 'category', } @@ -224,12 +224,12 @@ colors[yfield.key || yfield.name] = yfield.color; } } - c3_config.data.color = function(color, column) { + bb_config.data.color = function(color, column) { // column is an object when called for legend var key = column.id || column; return colors[key] || color; }; - return c3_config; + return bb_config; }, _data_keys: function(data) { let keys = []; @@ -269,8 +269,8 @@ Sao.View.Graph.HorizontalBar = Sao.class_(Sao.View.Graph.Chart, { _chart_type: 'bar', - _c3_config: function(data) { - var config = Sao.View.Graph.HorizontalBar._super._c3_config + _bb_config: function(data) { + var config = Sao.View.Graph.HorizontalBar._super._bb_config .call(this, data); config.axis.rotated = true; return config; @@ -279,8 +279,8 @@ Sao.View.Graph.Line = Sao.class_(Sao.View.Graph.Chart, { _chart_type: 'line', - _c3_config: function(data) { - var config = Sao.View.Graph.Line._super._c3_config + _bb_config: function(data) { + var config = Sao.View.Graph.Line._super._bb_config .call(this, data); config.line = { connectNull: true, @@ -291,8 +291,8 @@ Sao.View.Graph.Pie = Sao.class_(Sao.View.Graph.Chart, { _chart_type: 'pie', - _c3_config: function(data) { - var config = Sao.View.Graph.Pie._super._c3_config.call(this, data); + _bb_config: function(data) { + var config = Sao.View.Graph.Pie._super._bb_config.call(this, data); var pie_columns = [], pie_names = {}; var i, len; var labels, values;