summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/views/graph/graph_view.js
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/web/static/src/js/views/graph/graph_view.js
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/web/static/src/js/views/graph/graph_view.js')
-rw-r--r--addons/web/static/src/js/views/graph/graph_view.js162
1 files changed, 162 insertions, 0 deletions
diff --git a/addons/web/static/src/js/views/graph/graph_view.js b/addons/web/static/src/js/views/graph/graph_view.js
new file mode 100644
index 00000000..759817c8
--- /dev/null
+++ b/addons/web/static/src/js/views/graph/graph_view.js
@@ -0,0 +1,162 @@
+odoo.define('web.GraphView', function (require) {
+"use strict";
+
+/**
+ * The Graph View is responsible to display a graphical (meaning: chart)
+ * representation of the current dataset. As of now, it is currently able to
+ * display data in three types of chart: bar chart, line chart and pie chart.
+ */
+
+var AbstractView = require('web.AbstractView');
+var core = require('web.core');
+var GraphModel = require('web.GraphModel');
+var Controller = require('web.GraphController');
+var GraphRenderer = require('web.GraphRenderer');
+
+var _t = core._t;
+var _lt = core._lt;
+
+var searchUtils = require('web.searchUtils');
+var GROUPABLE_TYPES = searchUtils.GROUPABLE_TYPES;
+
+var GraphView = AbstractView.extend({
+ display_name: _lt('Graph'),
+ icon: 'fa-bar-chart',
+ jsLibs: [
+ '/web/static/lib/Chart/Chart.js',
+ ],
+ config: _.extend({}, AbstractView.prototype.config, {
+ Model: GraphModel,
+ Controller: Controller,
+ Renderer: GraphRenderer,
+ }),
+ viewType: 'graph',
+ searchMenuTypes: ['filter', 'groupBy', 'comparison', 'favorite'],
+
+ /**
+ * @override
+ */
+ init: function (viewInfo, params) {
+ this._super.apply(this, arguments);
+
+ const additionalMeasures = params.additionalMeasures || [];
+ let measure;
+ const measures = {};
+ const measureStrings = {};
+ let groupBys = [];
+ const groupableFields = {};
+ this.fields.__count__ = { string: _t("Count"), type: 'integer' };
+
+ this.arch.children.forEach(field => {
+ let fieldName = field.attrs.name;
+ if (fieldName === "id") {
+ return;
+ }
+ const interval = field.attrs.interval;
+ if (interval) {
+ fieldName = fieldName + ':' + interval;
+ }
+ if (field.attrs.type === 'measure') {
+ const { string } = this.fields[fieldName];
+ measure = fieldName;
+ measures[fieldName] = {
+ description: string,
+ fieldName,
+ groupNumber: 0,
+ isActive: false,
+ itemType: 'measure',
+ };
+ } else {
+ groupBys.push(fieldName);
+ }
+ if (field.attrs.string) {
+ measureStrings[fieldName] = field.attrs.string;
+ }
+ });
+
+ for (const name in this.fields) {
+ const field = this.fields[name];
+ if (name !== 'id' && field.store === true) {
+ if (
+ ['integer', 'float', 'monetary'].includes(field.type) ||
+ additionalMeasures.includes(name)
+ ) {
+ measures[name] = {
+ description: field.string,
+ fieldName: name,
+ groupNumber: 0,
+ isActive: false,
+ itemType: 'measure',
+ };
+ }
+ if (GROUPABLE_TYPES.includes(field.type)) {
+ groupableFields[name] = field;
+ }
+ }
+ }
+ for (const name in measureStrings) {
+ if (measures[name]) {
+ measures[name].description = measureStrings[name];
+ }
+ }
+
+ // Remove invisible fields from the measures
+ this.arch.children.forEach(field => {
+ let fieldName = field.attrs.name;
+ if (field.attrs.invisible && py.eval(field.attrs.invisible)) {
+ groupBys = groupBys.filter(groupBy => groupBy !== fieldName);
+ if (fieldName in groupableFields) {
+ delete groupableFields[fieldName];
+ }
+ if (!additionalMeasures.includes(fieldName)) {
+ delete measures[fieldName];
+ }
+ }
+ });
+
+ const sortedMeasures = Object.values(measures).sort((a, b) => {
+ const descA = a.description.toLowerCase();
+ const descB = b.description.toLowerCase();
+ return descA > descB ? 1 : descA < descB ? -1 : 0;
+ });
+ const countMeasure = {
+ description: _t("Count"),
+ fieldName: '__count__',
+ groupNumber: 1,
+ isActive: false,
+ itemType: 'measure',
+ };
+ this.controllerParams.withButtons = params.withButtons !== false;
+ this.controllerParams.measures = [...sortedMeasures, countMeasure];
+ this.controllerParams.groupableFields = groupableFields;
+ this.controllerParams.title = params.title || this.arch.attrs.string || _t("Untitled");
+ // retrieve form and list view ids from the action to open those views
+ // when the graph is clicked
+ function _findView(views, viewType) {
+ const view = views.find(view => {
+ return view.type === viewType;
+ });
+ return [view ? view.viewID : false, viewType];
+ }
+ this.controllerParams.views = [
+ _findView(params.actionViews, 'list'),
+ _findView(params.actionViews, 'form'),
+ ];
+
+ this.rendererParams.fields = this.fields;
+ this.rendererParams.title = this.arch.attrs.title; // TODO: use attrs.string instead
+ this.rendererParams.disableLinking = !!JSON.parse(this.arch.attrs.disable_linking || '0');
+
+ this.loadParams.mode = this.arch.attrs.type || 'bar';
+ this.loadParams.orderBy = this.arch.attrs.order;
+ this.loadParams.measure = measure || '__count__';
+ this.loadParams.groupBys = groupBys;
+ this.loadParams.fields = this.fields;
+ this.loadParams.comparisonDomain = params.comparisonDomain;
+ this.loadParams.stacked = this.arch.attrs.stacked !== "False";
+ },
+});
+
+return GraphView;
+
+});