This is an automated email from the ASF dual-hosted git repository. sushuang pushed a commit to branch fix/bar-width-on-value-axis in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git
commit 7f7e0131ac2a9efddbc04b3f308e83c6f7d12226 Author: SHUANG SU <sushuang0...@gmail.com> AuthorDate: Thu Nov 7 05:14:19 2019 +0800 fix: fix bar width strategy. (1) On value axis, the auto-calculated bar width might be near 0, which make the bar invisible. So we add option `barMinWidth` (default 1 in category and default null in other coord sys). (2) In #5316 (commit 2823ab502bf1af27c33de6d09729bc287ef0a185) the fix seems not correct. check the "main3" case in `echarts/test/bar-width.html`. That fix would made the `barMaxWidth` has higher priority than `barWidth`. But it only works when auto-calculated bar width is bigger than the giving `barWidth`. So the behavior seems weird. This fix revert it and use the strategy: `barWidth` always has higher priority than `barMaxWidth`. --- src/chart/bar/BaseBarSeries.js | 4 + src/chart/custom.js | 1 + src/layout/barGrid.js | 35 ++++- test/bar-width.html | 289 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 322 insertions(+), 7 deletions(-) diff --git a/src/chart/bar/BaseBarSeries.js b/src/chart/bar/BaseBarSeries.js index 7c8b603..e27f0a7 100644 --- a/src/chart/bar/BaseBarSeries.js +++ b/src/chart/bar/BaseBarSeries.js @@ -66,6 +66,10 @@ export default SeriesModel.extend({ progressiveChunkMode: 'mod', // barMaxWidth: null, + + // In cartesian, the default value is 1. Otherwise null. + // barMinWidth: null, + // 默认自适应 // barWidth: null, // 柱间距离,默认为柱形宽度的30%,可设固定值 diff --git a/src/chart/custom.js b/src/chart/custom.js index 784e59c..c1dd8be 100644 --- a/src/chart/custom.js +++ b/src/chart/custom.js @@ -539,6 +539,7 @@ function makeRenderItem(customSeries, data, ecModel, api) { * @param {number} opt.count Positive interger. * @param {number} [opt.barWidth] * @param {number} [opt.barMaxWidth] + * @param {number} [opt.barMinWidth] * @param {number} [opt.barGap] * @param {number} [opt.barCategoryGap] * @return {Object} {width, offset, offsetCenter} is not support, return undefined. diff --git a/src/layout/barGrid.js b/src/layout/barGrid.js index 069cc25..a287938 100644 --- a/src/layout/barGrid.js +++ b/src/layout/barGrid.js @@ -43,6 +43,7 @@ function getAxisKey(axis) { * @param {number} opt.count Positive interger. * @param {number} [opt.barWidth] * @param {number} [opt.barMaxWidth] + * @param {number} [opt.barMinWidth] * @param {number} [opt.barGap] * @param {number} [opt.barCategoryGap] * @return {Object} {width, offset, offsetCenter} If axis.type is not 'category', return undefined. @@ -187,6 +188,11 @@ export function makeColumnLayout(barSeries) { var barMaxWidth = parsePercent( seriesModel.get('barMaxWidth'), bandWidth ); + var barMinWidth = parsePercent( + // barMinWidth by default is 1 in cartesian. Because in value axis, + // the auto-calculated bar width might be less than 1. + seriesModel.get('barMinWidth') || 1, bandWidth + ); var barGap = seriesModel.get('barGap'); var barCategoryGap = seriesModel.get('barCategoryGap'); @@ -194,6 +200,7 @@ export function makeColumnLayout(barSeries) { bandWidth: bandWidth, barWidth: barWidth, barMaxWidth: barMaxWidth, + barMinWidth: barMinWidth, barGap: barGap, barCategoryGap: barCategoryGap, axisKey: getAxisKey(baseAxis), @@ -248,6 +255,8 @@ function doCalBarWidthAndOffset(seriesInfoList) { var barMaxWidth = seriesInfo.barMaxWidth; barMaxWidth && (stacks[stackId].maxWidth = barMaxWidth); + var barMinWidth = seriesInfo.barMinWidth; + barMinWidth && (stacks[stackId].minWidth = barMinWidth); var barGap = seriesInfo.barGap; (barGap != null) && (columnsOnAxis.gap = barGap); var barCategoryGap = seriesInfo.barCategoryGap; @@ -273,14 +282,26 @@ function doCalBarWidthAndOffset(seriesInfoList) { // Find if any auto calculated bar exceeded maxBarWidth zrUtil.each(stacks, function (column, stack) { + if (column.width) { + return; + } var maxWidth = column.maxWidth; - if (maxWidth && maxWidth < autoWidth) { - maxWidth = Math.min(maxWidth, remainedWidth); - if (column.width) { - maxWidth = Math.min(maxWidth, column.width); - } - remainedWidth -= maxWidth; - column.width = maxWidth; + var minWidth = column.minWidth; + var finalWidth = autoWidth; + if (maxWidth && maxWidth < finalWidth) { + finalWidth = Math.min(finalWidth, maxWidth, remainedWidth); + } + // `minWidth` has higher priority. `minWidth` decide that wheter the + // bar is able to be visible. So `minWidth` should not be restricted + // by `maxWidth` or `remainedWidth` (which is from `bandWidth`). In + // the extreme cases for `value` axis, bars are allowed to overlap + // with each other if `minWidth` specified. + if (minWidth && minWidth > finalWidth) { + finalWidth = Math.max(finalWidth, minWidth); + } + if (finalWidth !== autoWidth) { + column.width = finalWidth; + remainedWidth -= finalWidth; autoWidthCount--; } }); diff --git a/test/bar-width.html b/test/bar-width.html new file mode 100644 index 0000000..e788d04 --- /dev/null +++ b/test/bar-width.html @@ -0,0 +1,289 @@ + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> + +<html> + <head> + <meta charset="utf-8"> + <script src="lib/esl.js"></script> + <script src="lib/config.js"></script> + <script src="lib/jquery.min.js"></script> + <script src="lib/facePrint.js"></script> + <script src="lib/testHelper.js"></script> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <link rel="stylesheet" href="lib/reset.css"> + </head> + <body> + <style> + h1 { + line-height: 60px; + height: 60px; + background: #146402; + text-align: center; + font-weight: bold; + color: #eee; + font-size: 14px; + } + .chart { + height: 400px; + } + </style> + + <div class="chart" id="main1"></div> + <div class="chart" id="main2"></div> + <div class="chart" id="main3"></div> + + + <script> + + require([ + 'echarts' + ], function (echarts) { + var data = [ + [7880,6.52], + [7881,3.18], // very near 7880, which makes the bar very thin + [6110,2.68], + [7390,9.55], + [7250,5.59], + [7300,7.43], + [3980,8.54], + [4290,3.22], + [500,4.68], + [1720,5.15], + [900,9], + [910,10] + ]; + + function makeOption() { + var option = { + tooltip: {}, + xAxis: { + }, + yAxis: { + }, + dataZoom: + [{ + type: 'inside' + }, { + type: 'slider' + }], + series: { + type: 'bar', + label: { + show: true, + position: 'top' + }, + data: data + }, + title: { + text: 'no barMinWidth, no barMaxWidth specifed' + } + }; + return option; + } + + var chart = testHelper.create(echarts, 'main1', { + title: [ + 'On `value` axis.', + 'Test **barMinWidth** and **barMaxWidth**: move dataZoom, ', + 'bar should be **visible** ', + '**bar width** should be correct as the title described.' + ], + height: 200, + option: makeOption(), + buttons: [{ + text: 'barMinWidth: 10', + onclick: function () { + var option = makeOption(); + option.title.text = 'barMinWidth: 10, no barMaxWidth'; + option.series.barMinWidth = 10; + chart.setOption(option, true); + } + }, { + text: 'barMinWidth: 10, barMaxWidth: 40', + onclick: function () { + var option = makeOption(); + option.title.text = 'barMinWidth: 10, barMaxWidth: 40'; + option.series.barMinWidth = 10; + option.series.barMaxWidth = 40; + chart.setOption(option, true); + } + }, { + text: 'barMaxWidth: 40', + onclick: function () { + var option = makeOption(); + option.title.text = 'no barMinWidth, barMaxWidth: 40'; + option.series.barMaxWidth = 40; + chart.setOption(option, true); + } + }] + }); + }); + + </script> + + + + + + + + + <script> + + require([ + 'echarts' + ], function (echarts) { + var data = []; + for (var i = 0; i < 80; i++) { + data.push(['a' + i, 10]); + } + + function makeOption() { + var option = { + tooltip: {}, + xAxis: { + type: 'category' + }, + yAxis: { + }, + dataZoom: + [{ + type: 'inside' + }, { + type: 'slider' + }], + series: { + type: 'bar', + data: data + }, + title: { + text: 'no barMinWidth, no barMaxWidth specifed' + } + }; + return option; + } + + var chart = testHelper.create(echarts, 'main2', { + title: [ + 'On `category` axis.', + 'Test **barMinWidth** and **barMaxWidth**: move dataZoom, ', + 'bar should be **visible**.', + '**bar width** should be correct as the title described.' + ], + height: 200, + width: 600, + option: makeOption(), + buttons: [{ + text: 'barMinWidth: 10', + onclick: function () { + var option = makeOption(); + option.title.text = 'barMinWidth: 10, no barMaxWidth'; + option.series.barMinWidth = 10; + chart.setOption(option, true); + } + }, { + text: 'barMinWidth: 10, barMaxWidth: 40', + onclick: function () { + var option = makeOption(); + option.title.text = 'barMinWidth: 10, barMaxWidth: 40'; + option.series.barMinWidth = 10; + option.series.barMaxWidth = 40; + chart.setOption(option, true); + } + }, { + text: 'barMaxWidth: 40', + onclick: function () { + var option = makeOption(); + option.title.text = 'no barMinWidth, barMaxWidth: 40'; + option.series.barMaxWidth = 40; + chart.setOption(option, true); + } + }] + }); + }); + + </script> + + + + + <script> + + require([ + 'echarts' + ], function (echarts) { + var data = [ + [7880,6.52], + [7881,3.18], + [6110,2.68], + [7390,9.55], + [7250,5.59], + [7300,7.43], + [3980,8.54], + [4290,3.22], + [500,4.68], + [1720,5.15], + [900,9], + [910,10] + ]; + + var option = { + tooltip: {}, + xAxis: { + type: 'category' + }, + yAxis: { + }, + dataZoom: + [{ + type: 'inside' + }, { + type: 'slider' + }], + series: { + type: 'bar', + label: { + show: true, + position: 'top' + }, + barWidth: 40, + // Smaller than `barWidth` + barMaxWidth: 10, + data: data + } + }; + + var chart = testHelper.create(echarts, 'main3', { + title: [ + 'Test: **barWidth** should have higher priority then **barMaxWidth**', + 'Zoom the data, the bar width should **keep 40px**' + ], + height: 200, + option: option + }); + }); + + </script> + + + + + </body> +</html> \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@echarts.apache.org For additional commands, e-mail: commits-h...@echarts.apache.org