You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by su...@apache.org on 2019/11/06 21:15:29 UTC
[incubator-echarts] 01/01: 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 big [...]
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 <su...@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-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org