diff --git a/addons/website/static/src/snippets/s_chart/000.js b/addons/website/static/src/snippets/s_chart/000.js index 2c67bd03612..eb32dbc119e 100644 --- a/addons/website/static/src/snippets/s_chart/000.js +++ b/addons/website/static/src/snippets/s_chart/000.js @@ -48,6 +48,7 @@ const ChartWidget = publicWidget.Widget.extend({ }, tooltips: { enabled: this.el.dataset.tooltipDisplay === 'true', + position: 'custom', }, title: { display: !!this.el.dataset.title, @@ -80,18 +81,30 @@ const ChartWidget = publicWidget.Widget.extend({ }, }; } else { + // For extending the range of the axis while maintaining the auto + // fit behavior + const beforeBuildTicks = (scale) => { + scale.min = parseInt(this.el.dataset.ticksMin) || scale.min; + scale.max = parseInt(this.el.dataset.ticksMax) || scale.max; + }; chartData.options.scales = { xAxes: [{ stacked: this.el.dataset.stacked === 'true', ticks: { beginAtZero: true }, + // Maintaining the gap between two values on + // vertical/horizontally axis + beforeBuildTicks: beforeBuildTicks, }], yAxes: [{ stacked: this.el.dataset.stacked === 'true', ticks: { beginAtZero: true }, + // Maintaining the gap between two values on + // vertical/horizontally axis + beforeBuildTicks: beforeBuildTicks, }], }; } @@ -104,6 +117,7 @@ const ChartWidget = publicWidget.Widget.extend({ } const canvas = this.el.querySelector('canvas'); + window.Chart.Tooltip.positioners.custom = (elements, eventPosition) => eventPosition; this.chart = new window.Chart(canvas, chartData); return this._super.apply(this, arguments); }, diff --git a/addons/website/static/src/snippets/s_chart/options.js b/addons/website/static/src/snippets/s_chart/options.js index 49f4789861b..bcce637a661 100644 --- a/addons/website/static/src/snippets/s_chart/options.js +++ b/addons/website/static/src/snippets/s_chart/options.js @@ -118,6 +118,9 @@ options.registry.InnerChart = options.Class.extend({ this._setDefaultSelectedInput(); await this._reloadGraph(); } + if (params.attributeName === 'minValue' || params.attributeName === 'maxValue') { + this._computeTicksMinMaxValue(); + } }, //-------------------------------------------------------------------------- @@ -148,6 +151,44 @@ options.registry.InnerChart = options.Class.extend({ } return this._super(...arguments); }, + /** + * Maintains the gap between the scale axis for the auto fit behavior if we + * used min/max config. + * + * @private + */ + _computeTicksMinMaxValue() { + const dataset = this.$target[0].dataset; + let minValue = parseInt(dataset.minValue); + let maxValue = parseInt(dataset.maxValue); + if (!isNaN(maxValue)) { + // Reverse min max values when min value is greater than max value + if (maxValue < minValue) { + maxValue = minValue; + minValue = parseInt(dataset.maxValue); + } else if (maxValue === minValue) { + // If min value and max value are same for positive and negative + // number + minValue < 0 ? (maxValue = 0, minValue = 2 * minValue) : (minValue = 0, maxValue = 2 * maxValue); + } + } else { + // Find max value from each row/column data + const datasets = JSON.parse(dataset.data).datasets || []; + const dataValue = _.flatten(datasets.map(el => el.data.map(data => { + return !isNaN(parseInt(data)) ? parseInt(data) : 0; + }))); + // When max value is not given and min value is greater than chart + // data values + if (minValue >= Math.max(...dataValue)) { + maxValue = minValue; + minValue = 0; + } + } + this.$target.attr({ + 'data-ticks-min': minValue, + 'data-ticks-max': maxValue, + }); + }, /** * Sets and reloads the data on the canvas if it has changed. * Used in matrix related method. diff --git a/addons/website/views/snippets/s_chart.xml b/addons/website/views/snippets/s_chart.xml index 42852be1466..379d8552587 100644 --- a/addons/website/views/snippets/s_chart.xml +++ b/addons/website/views/snippets/s_chart.xml @@ -28,7 +28,7 @@ Bar Vertical Bar Horizontal - Line + Line Pie Doughnut Radar @@ -53,6 +53,8 @@ + +