You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by ov...@apache.org on 2023/02/02 10:25:07 UTC

[echarts] 01/01: fix(markArea): markArea range in bar series #18130

This is an automated email from the ASF dual-hosted git repository.

ovilia pushed a commit to branch fix-18130
in repository https://gitbox.apache.org/repos/asf/echarts.git

commit 8401d1abedbea13206016898db2e8669b2e781c2
Author: Ovilia <zw...@gmail.com>
AuthorDate: Thu Feb 2 18:23:54 2023 +0800

    fix(markArea): markArea range in bar series #18130
---
 src/chart/bar/BaseBarSeries.ts |  71 ++++++++-
 test/bar-markArea.html         | 326 ++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 388 insertions(+), 9 deletions(-)

diff --git a/src/chart/bar/BaseBarSeries.ts b/src/chart/bar/BaseBarSeries.ts
index bff11b883..d9349ac2e 100644
--- a/src/chart/bar/BaseBarSeries.ts
+++ b/src/chart/bar/BaseBarSeries.ts
@@ -94,20 +94,77 @@ class BaseBarSeriesModel<Opts extends BaseBarSeriesOption<unknown> = BaseBarSeri
         const coordSys = this.coordinateSystem;
         if (coordSys && coordSys.clampData) {
             // PENDING if clamp ?
-            const pt = coordSys.dataToPoint(coordSys.clampData(value));
+            const clampData = coordSys.clampData(value);
+            const pt = coordSys.dataToPoint(clampData);
             if (startingAtTick) {
                 each(coordSys.getAxes(), function (axis: Axis2D, idx: number) {
                     // If axis type is category, use tick coords instead
                     if (axis.type === 'category') {
                         const tickCoords = axis.getTicksCoords();
-                        let tickIdx = coordSys.clampData(value)[idx];
+
+                        let targetTickId = clampData[idx];
                         // The index of rightmost tick of markArea is 1 larger than x1/y1 index
-                        if (dims && (dims[idx] === 'x1' || dims[idx] === 'y1')) {
-                            tickIdx += 1;
+                        const isEnd = dims[idx] === 'x1' || dims[idx] === 'y1';
+                        if (dims && isEnd) {
+                            targetTickId += 1;
+                        }
+
+                        // The only contains one tick, tickCoords is
+                        // like [{coord: 0, tickValue: 0}, {coord: 0}]
+                        // to the length should always be larger than 1
+                        if (tickCoords.length < 2) {
+                            return;
+                        }
+                        else if (tickCoords.length === 2) {
+                            // The left value and right value of the axis are
+                            // the same. coord is 0 in both items. Use the max
+                            // value of the axis as the coord
+                            pt[idx] = axis.toGlobalCoord(
+                                axis.getExtent()[isEnd ? 1 : 0]
+                            );
+                            return;
+                        }
+
+                        let leftCoord;
+                        let coord;
+                        let stepTickValue = 1;
+                        for (let i = 0; i < tickCoords.length; i++) {
+                            const tickCoord = tickCoords[i].coord;
+                            // The last item of tickCoords doesn't contain
+                            // tickValue
+                            const tickValue = i === tickCoords.length - 1
+                                ? tickCoords[i - 1].tickValue + stepTickValue
+                                : tickCoords[i].tickValue;
+                            if (tickValue === targetTickId) {
+                                coord = tickCoord;
+                                break;
+                            }
+                            else if (tickValue < targetTickId) {
+                                leftCoord = tickCoord;
+                            }
+                            else if (leftCoord != null && tickValue > targetTickId) {
+                                coord = (tickCoord + leftCoord) / 2;
+                                break;
+                            }
+                            if (i === 1) {
+                                // Here we assume the step of category axes is
+                                // the same
+                                stepTickValue = tickValue - tickCoords[0].tickValue;
+                            }
+                        }
+                        if (coord == null) {
+                            if (!leftCoord) {
+                                // targetTickId is smaller than all tick ids in the
+                                // visible area, use the leftmost tick coord
+                                coord = tickCoords[0].coord;
+                            }
+                            else if (leftCoord) {
+                                // targetTickId is larger than all tick ids in the
+                                // visible area, use the rightmost tick coord
+                                coord = tickCoords[tickCoords.length - 1].coord;
+                            }
                         }
-                        (tickIdx > tickCoords.length - 1) && (tickIdx = tickCoords.length - 1);
-                        (tickIdx < 0) && (tickIdx = 0);
-                        tickCoords[tickIdx] && (pt[idx] = axis.toGlobalCoord(tickCoords[tickIdx].coord));
+                        pt[idx] = axis.toGlobalCoord(coord);
                     }
                 });
             }
diff --git a/test/bar-markArea.html b/test/bar-markArea.html
index 2f96ce9f7..8473f0a43 100644
--- a/test/bar-markArea.html
+++ b/test/bar-markArea.html
@@ -38,7 +38,11 @@ under the License.
 
         <div id="main0"></div>
         <div id="main1"></div>
-
+        <div id="main2"></div>
+        <div id="main3"></div>
+        <div id="main4"></div>
+        <div id="main5"></div>
+        <div id="main6"></div>
 
         <script>
         require([
@@ -168,7 +172,325 @@ under the License.
     });
     </script>
 
+      <script>
+        require([
+            'echarts'
+        ], function (echarts) {
+            var option;
+            // This bug only occurs when end is large enough for some of the
+            // axis labels to be hidden due to overlapping.
+            var end = 70;
+
+            var xData = [];
+            for (let i = 0; i < end; ++i) {
+              xData.push(i);
+            }
+
+            option = {
+              xAxis: [
+                {
+                  data: xData,
+                  show: true
+                }
+              ],
+              yAxis: [{ type: 'value', show: true, max: 100 }],
+              grid: [{}],
+              series: [
+                {
+                  type: 'bar',
+                  data: [[end - 1, 100, 22]],
+
+                  barWidth: 10,
+                  itemStyle: {
+                    opacity: 0.5
+                  },
+                  markArea: {
+                    itemStyle: {
+                      color: 'red',
+                      opacity: 0.5
+                    },
+                    data: [
+                      [
+                        {
+                          xAxis: 20
+                        },
+                        {
+                          xAxis: end - 10
+                        }
+                      ]
+                    ]
+                  }
+                }
+              ]
+            };
+            var chart = testHelper.create(echarts, 'main2', {
+                title: [
+                    'There should be a red markArea at x position 20~60 (the position between 60 and 62)',
+                    'Fix #18130'
+                ],
+                option: option
+            });
+        });
+        </script>
+
+        <script>
+          require([
+              'echarts'
+          ], function (echarts) {
+              var option;
+              var end = 70;
+
+              var xData = [];
+              for (let i = 0; i < end; ++i) {
+                xData.push(i);
+              }
+
+              option = {
+                xAxis: [
+                  {
+                    data: xData,
+                    show: true
+                  }
+                ],
+                yAxis: [{ type: 'value', show: true, max: 100 }],
+                grid: [{}],
+                dataZoom: {
+                  type: 'slider',
+                  xAxisIndex: 0,
+                  start: 50,
+                  end: 100
+                },
+                series: [
+                  {
+                    type: 'bar',
+                    data: [[end - 1, 100, 22]],
 
+                    barWidth: 10,
+                    itemStyle: {
+                      opacity: 0.5
+                    },
+                    markArea: {
+                      itemStyle: {
+                        color: 'red',
+                        opacity: 0.5
+                      },
+                      data: [
+                        [
+                          {
+                            xAxis: 20
+                          },
+                          {
+                            xAxis: end - 10
+                          }
+                        ]
+                      ]
+                    }
+                  }
+                ]
+              };
+              var chart = testHelper.create(echarts, 'main3', {
+                  title: [
+                      'There should be a red markArea at x position 35~60',
+                      'Fix #18130'
+                  ],
+                  option: option
+              });
+          });
+        </script>
+
+        <script>
+          require([
+              'echarts'
+          ], function (echarts) {
+              var option;
+              var end = 70;
+
+              var xData = [];
+              for (let i = 0; i < end; ++i) {
+                xData.push(i);
+              }
+
+              option = {
+                xAxis: [
+                  {
+                    data: xData,
+                    show: true
+                  }
+                ],
+                yAxis: [{ type: 'value', show: true, max: 100 }],
+                grid: [{}],
+                dataZoom: {
+                  type: 'slider',
+                  xAxisIndex: 0,
+                  start: 0,
+                  end: 50
+                },
+                series: [
+                  {
+                    type: 'bar',
+                    data: [[end - 1, 100, 22]],
+
+                    barWidth: 10,
+                    itemStyle: {
+                      opacity: 0.5
+                    },
+                    markArea: {
+                      itemStyle: {
+                        color: 'red',
+                        opacity: 0.5
+                      },
+                      data: [
+                        [
+                          {
+                            xAxis: 20
+                          },
+                          {
+                            xAxis: end - 10
+                          }
+                        ]
+                      ]
+                    }
+                  }
+                ]
+              };
+              var chart = testHelper.create(echarts, 'main4', {
+                  title: [
+                      'There should be a red markArea at x position 20~35',
+                      'Fix #18130'
+                  ],
+                  option: option
+              });
+          });
+        </script>
+
+        <script>
+          require([
+              'echarts'
+          ], function (echarts) {
+              var option;
+              var end = 70;
+
+              var xData = [];
+              for (let i = 0; i < end; ++i) {
+                xData.push(i);
+              }
+
+              option = {
+                xAxis: [
+                  {
+                    data: xData,
+                    show: true
+                  }
+                ],
+                yAxis: [{ type: 'value', show: true, max: 100 }],
+                grid: [{}],
+                dataZoom: {
+                  type: 'slider',
+                  xAxisIndex: 0,
+                  start: 60,
+                  end: 60
+                },
+                series: [
+                  {
+                    type: 'bar',
+                    data: [[end - 1, 100, 22]],
+
+                    barWidth: 10,
+                    itemStyle: {
+                      opacity: 0.5
+                    },
+                    markArea: {
+                      itemStyle: {
+                        color: 'red',
+                        opacity: 0.5
+                      },
+                      data: [
+                        [
+                          {
+                            xAxis: 20
+                          },
+                          {
+                            xAxis: end - 10
+                          }
+                        ]
+                      ]
+                    }
+                  }
+                ]
+              };
+              var chart = testHelper.create(echarts, 'main5', {
+                  title: [
+                      'There should be a red markArea at the full grid area',
+                      'Fix #18130'
+                  ],
+                  option: option
+              });
+          });
+        </script>
+
+        <script>
+          require([
+              'echarts'
+          ], function (echarts) {
+              var option;
+              var end = 70;
+
+              var xData = [];
+              for (let i = 0; i < end; ++i) {
+                xData.push(i);
+              }
+
+              option = {
+                xAxis: [
+                  {
+                    data: xData,
+                    show: true
+                  }
+                ],
+                yAxis: [{ type: 'value', show: true, max: 100 }],
+                grid: [{}],
+                dataZoom: {
+                  type: 'slider',
+                  xAxisIndex: 0,
+                  startValue: 0,
+                  endValue: 61
+                },
+                series: [
+                  {
+                    type: 'bar',
+                    data: [[end - 1, 100, 22]],
+
+                    barWidth: 10,
+                    itemStyle: {
+                      opacity: 0.5
+                    },
+                    markArea: {
+                      itemStyle: {
+                        color: 'red',
+                        opacity: 0.5
+                      },
+                      data: [
+                        [
+                          {
+                            xAxis: 20
+                          },
+                          {
+                            xAxis: end - 10
+                          }
+                        ]
+                      ]
+                    }
+                  }
+                ]
+              };
+              var chart = testHelper.create(echarts, 'main6', {
+                  title: [
+                      'There should be a red markArea at 20~60. **Note the right should NOT be at the right boundary.**',
+                      'Fix #18130'
+                  ],
+                  option: option
+              });
+          });
+        </script>
     </body>
 </html>
-


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org