You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by sh...@apache.org on 2020/06/05 09:10:32 UTC

[incubator-echarts] branch label-enhancement updated: feat(label: add shift-x, shift-y option for moveOverlap in labelLayout

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

shenyi pushed a commit to branch label-enhancement
in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git


The following commit(s) were added to refs/heads/label-enhancement by this push:
     new ca57e80  feat(label: add shift-x, shift-y option for moveOverlap in labelLayout
ca57e80 is described below

commit ca57e8034a8d3e8e69f657cbc8ca9f5be6733776
Author: pissang <bm...@gmail.com>
AuthorDate: Fri Jun 5 17:10:07 2020 +0800

    feat(label: add shift-x, shift-y option for moveOverlap in labelLayout
---
 src/chart/pie/labelLayout.ts   |   9 +-
 src/echarts.ts                 |   4 +-
 src/label/LabelManager.ts      | 111 +++++-----------------
 src/label/labelLayoutHelper.ts | 210 ++++++++++++++++++++++++++++++++++++++++-
 src/util/types.ts              |   8 +-
 test/label-layout.html         | 122 +++++++++++++++++++++++-
 test/labelLine.html            | 126 -------------------------
 7 files changed, 358 insertions(+), 232 deletions(-)

diff --git a/src/chart/pie/labelLayout.ts b/src/chart/pie/labelLayout.ts
index 9e30c26..473cf5f 100644
--- a/src/chart/pie/labelLayout.ts
+++ b/src/chart/pie/labelLayout.ts
@@ -72,15 +72,10 @@ function adjustSingleSide(
             list[j].y += delta;
             adjusted = true;
 
-            // const textHeight = list[j].textRect.height;
-            // if (list[j].y + textHeight / 2 > viewTop + viewHeight) {
-            //     list[j].y = viewTop + viewHeight - textHeight / 2;
-            // }
-
-            if (j > start
-                && j + 1 < end
+            if (j > start && j + 1 < end
                 && list[j + 1].y > list[j].y + list[j].textRect.height
             ) {
+                // Shift up so it can be more equaly distributed.
                 shiftUp(j, delta / 2);
                 return;
             }
diff --git a/src/echarts.ts b/src/echarts.ts
index d4d32c8..4ce37ef 100644
--- a/src/echarts.ts
+++ b/src/echarts.ts
@@ -1096,7 +1096,7 @@ class ECharts extends Eventful {
     updateLabelLayout() {
         const labelManager = this._labelManager;
         labelManager.updateLayoutConfig(this._api);
-        labelManager.layout();
+        labelManager.layout(this._api);
         labelManager.processLabelsOverall();
     }
 
@@ -1732,7 +1732,7 @@ class ECharts extends Eventful {
             scheduler.unfinished = unfinished || scheduler.unfinished;
 
             labelManager.updateLayoutConfig(api);
-            labelManager.layout();
+            labelManager.layout(api);
             labelManager.processLabelsOverall();
 
             ecModel.eachSeries(function (seriesModel) {
diff --git a/src/label/LabelManager.ts b/src/label/LabelManager.ts
index 194c222..5c5d320 100644
--- a/src/label/LabelManager.ts
+++ b/src/label/LabelManager.ts
@@ -20,16 +20,13 @@
 // TODO: move labels out of viewport.
 
 import {
-    OrientedBoundingRect,
     Text as ZRText,
-    Point,
     BoundingRect,
     getECData,
     Polyline,
     updateProps,
     initProps
 } from '../util/graphic';
-import { MatrixArray } from 'zrender/src/core/matrix';
 import ExtensionAPI from '../ExtensionAPI';
 import {
     ZRTextAlign,
@@ -47,20 +44,12 @@ import Transformable from 'zrender/src/core/Transformable';
 import { updateLabelLinePoints, setLabelLineStyle } from './labelGuideHelper';
 import SeriesModel from '../model/Series';
 import { makeInner } from '../util/model';
-import { retrieve2, each, keys, isFunction } from 'zrender/src/core/util';
+import { retrieve2, each, keys, isFunction, filter } from 'zrender/src/core/util';
 import { PathStyleProps } from 'zrender/src/graphic/Path';
 import Model from '../model/Model';
+import { LabelLayoutInfo, prepareLayoutList, hideOverlap, shiftLayoutOnX, shiftLayoutOnY } from './labelLayoutHelper';
 
-interface DisplayedLabelItem {
-    label: ZRText
-    rect: BoundingRect
-    localRect: BoundingRect
-    obb?: OrientedBoundingRect
-    axisAligned: boolean
-    transform: MatrixArray
-}
-
-interface LabelLayoutDesc {
+interface LabelDesc {
     label: ZRText
     labelLine: Polyline
 
@@ -102,7 +91,7 @@ interface SavedLabelAttr {
     rect: RectLike
 }
 
-function prepareLayoutCallbackParams(labelItem: LabelLayoutDesc): LabelLayoutOptionCallbackParams {
+function prepareLayoutCallbackParams(labelItem: LabelDesc): LabelLayoutOptionCallbackParams {
     const labelAttr = labelItem.defaultAttr;
     const label = labelItem.label;
     return {
@@ -144,7 +133,7 @@ type LabelLineOptionMixin = {
 
 class LabelManager {
 
-    private _labelList: LabelLayoutDesc[] = [];
+    private _labelList: LabelDesc[] = [];
     private _chartViewList: ChartView[] = [];
 
     constructor() {}
@@ -162,7 +151,7 @@ class LabelManager {
         dataType: string,
         seriesModel: SeriesModel,
         label: ZRText,
-        layoutOption: LabelLayoutDesc['layoutOption']
+        layoutOption: LabelDesc['layoutOption']
     ) {
         const labelStyle = label.style;
         const hostEl = label.__hostTarget;
@@ -353,84 +342,26 @@ class LabelManager {
         }
     }
 
-    layout() {
-        // TODO: sort by priority(area)
-        const labelList = this._labelList;
-
-        const displayedLabels: DisplayedLabelItem[] = [];
-        const mvt = new Point();
+    layout(api: ExtensionAPI) {
+        const width = api.getWidth();
+        const height = api.getHeight();
 
-        // TODO, render overflow visible first, put in the displayedLabels.
-        labelList.sort(function (a, b) {
-            return b.priority - a.priority;
+        const labelList = prepareLayoutList(this._labelList);
+        const labelsNeedsAdjustOnX = filter(labelList, function (item) {
+            return item.layoutOption.moveOverlap === 'shift-x';
+        });
+        const labelsNeedsAdjustOnY = filter(labelList, function (item) {
+            return item.layoutOption.moveOverlap === 'shift-y';
         });
 
-        for (let i = 0; i < labelList.length; i++) {
-            const labelItem = labelList[i];
-            if (labelItem.defaultAttr.ignore) {
-                continue;
-            }
-
-            const layoutOption = labelItem.computedLayoutOption;
-            const label = labelItem.label;
-            const transform = label.getComputedTransform();
-            // NOTE: Get bounding rect after getComputedTransform, or label may not been updated by the host el.
-            const localRect = label.getBoundingRect();
-            const isAxisAligned = !transform || (transform[1] < 1e-5 && transform[2] < 1e-5);
-
-            const globalRect = localRect.clone();
-            globalRect.applyTransform(transform);
-
-            let obb = isAxisAligned ? new OrientedBoundingRect(localRect, transform) : null;
-            let overlapped = false;
-            const minMargin = layoutOption.minMargin || 0;
-            const marginSqr = minMargin * minMargin;
-            for (let j = 0; j < displayedLabels.length; j++) {
-                const existsTextCfg = displayedLabels[j];
-                // Fast rejection.
-                if (!globalRect.intersect(existsTextCfg.rect, mvt) && mvt.lenSquare() > marginSqr) {
-                    continue;
-                }
-
-                if (isAxisAligned && existsTextCfg.axisAligned) {   // Is overlapped
-                    overlapped = true;
-                    break;
-                }
-
-                if (!existsTextCfg.obb) { // If self is not axis aligned. But other is.
-                    existsTextCfg.obb = new OrientedBoundingRect(existsTextCfg.localRect, existsTextCfg.transform);
-                }
-
-                if (!obb) { // If self is axis aligned. But other is not.
-                    obb = new OrientedBoundingRect(localRect, transform);
-                }
+        shiftLayoutOnX(labelsNeedsAdjustOnX, 0, width);
+        shiftLayoutOnY(labelsNeedsAdjustOnY, 0, height);
 
-                if (obb.intersect(existsTextCfg.obb, mvt) || mvt.lenSquare() < marginSqr) {
-                    overlapped = true;
-                    break;
-                }
-            }
+        const labelsNeedsHideOverlap = filter(labelList, function (item) {
+            return item.layoutOption.hideOverlap;
+        });
 
-            const labelLine = labelItem.labelLine;
-            // TODO Callback to determine if this overlap should be handled?
-            if (overlapped && layoutOption.hideOverlap) {
-                label.hide();
-                labelLine && labelLine.hide();
-            }
-            else {
-                label.attr('ignore', labelItem.defaultAttr.ignore);
-                labelLine && labelLine.attr('ignore', labelItem.defaultAttr.labelGuideIgnore);
-
-                displayedLabels.push({
-                    label,
-                    rect: globalRect,
-                    localRect,
-                    obb,
-                    axisAligned: isAxisAligned,
-                    transform
-                });
-            }
-        }
+        hideOverlap(labelsNeedsHideOverlap);
     }
 
     /**
diff --git a/src/label/labelLayoutHelper.ts b/src/label/labelLayoutHelper.ts
index c1df9b6..861012d 100644
--- a/src/label/labelLayoutHelper.ts
+++ b/src/label/labelLayoutHelper.ts
@@ -18,26 +18,226 @@
 */
 
 import ZRText from 'zrender/src/graphic/Text';
+import { LabelLayoutOption } from '../util/types';
+import { BoundingRect, OrientedBoundingRect, Polyline } from '../util/graphic';
 
+interface LabelLayoutListPrepareInput {
+    label: ZRText
+    labelLine: Polyline
+    computedLayoutOption: LabelLayoutOption
+    priority: number
+    defaultAttr: {
+        ignore: boolean
+        labelGuideIgnore: boolean
+    }
+}
+
+export interface LabelLayoutInfo {
+    label: ZRText
+    labelLine: Polyline
+    priority: number
+    rect: BoundingRect // Global rect
+    localRect: BoundingRect
+    obb?: OrientedBoundingRect  // Only available when axisAligned is true
+    axisAligned: boolean
+    layoutOption: LabelLayoutOption
+    defaultAttr: {
+        ignore: boolean
+        labelGuideIgnore: boolean
+    }
+    transform: number[]
+}
+
+export function prepareLayoutList(input: LabelLayoutListPrepareInput[]): LabelLayoutInfo[] {
+    const list: LabelLayoutInfo[] = [];
+
+    for (let i = 0; i < input.length; i++) {
+        const rawItem = input[i];
+        if (rawItem.defaultAttr.ignore) {
+            continue;
+        }
+
+        const layoutOption = rawItem.computedLayoutOption;
+        const label = rawItem.label;
+        const transform = label.getComputedTransform();
+        // NOTE: Get bounding rect after getComputedTransform, or label may not been updated by the host el.
+        const localRect = label.getBoundingRect();
+        const isAxisAligned = !transform || (transform[1] < 1e-5 && transform[2] < 1e-5);
+
+        // Text has a default 1px stroke. Exclude this.
+        const minMargin = (layoutOption.minMargin || 0) + 2.2;
+        const globalRect = localRect.clone();
+        globalRect.applyTransform(transform);
+        globalRect.x -= minMargin / 2;
+        globalRect.y -= minMargin / 2;
+        globalRect.width += minMargin;
+        globalRect.height += minMargin;
+
+        const obb = isAxisAligned ? new OrientedBoundingRect(localRect, transform) : null;
+
+        list.push({
+            label,
+            labelLine: rawItem.labelLine,
+            rect: globalRect,
+            localRect,
+            obb,
+            priority: rawItem.priority,
+            defaultAttr: rawItem.defaultAttr,
+            layoutOption: rawItem.computedLayoutOption,
+            axisAligned: isAxisAligned,
+            transform
+        });
+    }
+    return list;
+}
+
+function shiftLayout(
+    list: LabelLayoutInfo[],
+    xyDim: 'x' | 'y',
+    sizeDim: 'width' | 'height',
+    minBound: number,
+    maxBound: number
+) {
+    if (!list.length) {
+        return;
+    }
+
+    list.sort(function (a, b) {
+        return a.label[xyDim] - b.label[xyDim];
+    });
+
+    function shiftForward(start: number, end: number, delta: number) {
+        for (let j = start; j < end; j++) {
+            list[j].label[xyDim] += delta;
+
+            const rect = list[j].rect;
+            rect[xyDim] += delta;
+
+            if (j > start && j + 1 < end
+                && list[j + 1].rect[xyDim] > rect[xyDim] + rect[sizeDim]
+            ) {
+                // Shift up so it can be more equaly distributed.
+                shiftBackward(j, delta / 2);
+                return;
+            }
+        }
+
+        shiftBackward(end - 1, delta / 2);
+    }
+
+    function shiftBackward(end: number, delta: number) {
+        for (let j = end; j >= 0; j--) {
+            list[j].label[xyDim] -= delta;
+
+            const rect = list[j].rect;
+            rect[xyDim] -= delta;
+
+            // const textSize = rect[sizeDim];
+            const diffToMinBound = rect[xyDim] - minBound;
+            if (diffToMinBound < 0) {
+                rect[xyDim] -= diffToMinBound;
+                list[j].label[xyDim] -= diffToMinBound;
+            }
+
+            if (j > 0
+                && rect[xyDim] > list[j - 1].rect[xyDim] + list[j - 1].rect[sizeDim]
+            ) {
+                break;
+            }
+        }
+    }
+    let lastPos = 0;
+    let delta;
+    const len = list.length;
+    for (let i = 0; i < len; i++) {
+        delta = list[i].label[xyDim] - lastPos;
+        if (delta < 0) {
+            shiftForward(i, len, -delta);
+        }
+        lastPos = list[i].label[xyDim] + list[i].rect[sizeDim];
+    }
+    if (maxBound - lastPos < 0) {
+        shiftBackward(len - 1, lastPos - maxBound);
+    }
+}
 
 /**
  * Adjust labels on x direction to avoid overlap.
  */
-export function adjustLayoutOnX(
-    list: ZRText[],
+export function shiftLayoutOnX(
+    list: LabelLayoutInfo[],
     leftBound: number,
     rightBound: number
 ) {
-
+    shiftLayout(list, 'x', 'width', leftBound, rightBound);
 }
 
 /**
  * Adjust labels on y direction to avoid overlap.
  */
-export function adjustLayoutOnY(
-    list: ZRText[],
+export function shiftLayoutOnY(
+    list: LabelLayoutInfo[],
     topBound: number,
     bottomBound: number
 ) {
+    shiftLayout(list, 'y', 'height', topBound, bottomBound);
+}
+
+export function hideOverlap(labelList: LabelLayoutInfo[]) {
+    const displayedLabels: LabelLayoutInfo[] = [];
+
+    // TODO, render overflow visible first, put in the displayedLabels.
+    labelList.sort(function (a, b) {
+        return b.priority - a.priority;
+    });
+
+    for (let i = 0; i < labelList.length; i++) {
+        const labelItem = labelList[i];
+        const globalRect = labelItem.rect;
+        const isAxisAligned = labelItem.axisAligned;
+        const localRect = labelItem.localRect;
+        const transform = labelItem.transform;
+        const label = labelItem.label;
+        const labelLine = labelItem.labelLine;
+
+        let obb = labelItem.obb;
+        let overlapped = false;
+        for (let j = 0; j < displayedLabels.length; j++) {
+            const existsTextCfg = displayedLabels[j];
+            // Fast rejection.
+            if (!globalRect.intersect(existsTextCfg.rect)) {
+                continue;
+            }
+
+            if (isAxisAligned && existsTextCfg.axisAligned) {   // Is overlapped
+                overlapped = true;
+                break;
+            }
+
+            if (!existsTextCfg.obb) { // If self is not axis aligned. But other is.
+                existsTextCfg.obb = new OrientedBoundingRect(existsTextCfg.localRect, existsTextCfg.transform);
+            }
+
+            if (!obb) { // If self is axis aligned. But other is not.
+                obb = new OrientedBoundingRect(localRect, transform);
+            }
+
+            if (obb.intersect(existsTextCfg.obb)) {
+                overlapped = true;
+                break;
+            }
+        }
+
+        // TODO Callback to determine if this overlap should be handled?
+        if (overlapped) {
+            label.hide();
+            labelLine && labelLine.hide();
+        }
+        else {
+            label.attr('ignore', labelItem.defaultAttr.ignore);
+            labelLine && labelLine.attr('ignore', labelItem.defaultAttr.labelGuideIgnore);
 
+            displayedLabels.push(labelItem);
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/util/types.ts b/src/util/types.ts
index fc20b96..7c7228a 100644
--- a/src/util/types.ts
+++ b/src/util/types.ts
@@ -826,8 +826,14 @@ export interface LabelLayoutOption {
     /**
      * If move the overlapped label. If label is still overlapped after moved.
      * It will determine if to hide this label with `hideOverlap` policy.
+     *
+     * shift-x/y will keep the order on x/y
+     * shuffle-x/y will move the label around the original position randomly.
      */
-    moveOverlap?: 'x' | 'y' | boolean
+    moveOverlap?: 'shift-x'
+        | 'shift-y'
+        | 'shuffle-x'
+        | 'shuffle-y'
     /**
      * If hide the overlapped label. It will be handled after move.
      * @default 'none'
diff --git a/test/label-layout.html b/test/label-layout.html
index a3eaf35..f6fe7e6 100644
--- a/test/label-layout.html
+++ b/test/label-layout.html
@@ -46,6 +46,8 @@ under the License.
         <div id="main3"></div>
         <div id="main4"></div>
         <div id="main5"></div>
+        <div id="main6"></div>
+        <div id="main7"></div>
 
 
 
@@ -153,7 +155,7 @@ under the License.
 
                 var data = [Math.round(Math.random() * 300)];
 
-                for (var i = 1; i < 200; i++) {
+                for (var i = 1; i < 50; i++) {
                     var now = new Date(base += oneDay);
                     date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'));
                     data.push(Math.round((Math.random() - 0.5) * 20 + data[i - 1]));
@@ -200,6 +202,7 @@ under the License.
                     ]
                 };
                 var chart = testHelper.create(echarts, 'main1', {
+                    width: 600,
                     title: [
                         'Overlap of line.'
                     ],
@@ -343,6 +346,123 @@ under the License.
         </script>
 
 
+        <script>
+            require(['echarts'/*, 'map/js/china' */], function (echarts) {
+                var option;
+                var data = [
+                    [[28604,77,17096869,'Australia',1990],[31163,77.4,27662440,'Canada',1990],[1516,68,1154605773,'China',1990],[13670,74.7,10582082,'Cuba',1990],[28599,75,4986705,'Finland',1990],[29476,77.1,56943299,'France',1990],[31476,75.4,78958237,'Germany',1990],[28666,78.1,254830,'Iceland',1990],[1777,57.7,870601776,'India',1990],[29550,79.1,122249285,'Japan',1990],[2076,67.9,20194354,'North Korea',1990],[12087,72,42972254,'South Korea',1990],[24021,75.4,3397534,'New Zealand',1990 [...]
+                    [[44056,81.8,23968973,'Australia',2015],[43294,81.7,35939927,'Canada',2015],[13334,76.9,1376048943,'China',2015],[21291,78.5,11389562,'Cuba',2015],[38923,80.8,5503457,'Finland',2015],[37599,81.9,64395345,'France',2015],[44053,81.1,80688545,'Germany',2015],[42182,82.8,329425,'Iceland',2015],[5903,66.8,1311050527,'India',2015],[36162,83.5,126573481,'Japan',2015],[1390,71.4,25155317,'North Korea',2015],[34644,80.7,50293439,'South Korea',2015],[34186,80.6,4528526,'New Zea [...]
+                ];
+
+                option = {
+                    xAxis: {},
+                    yAxis: {
+                        scale: true
+                    },
+                    series: [{
+                        name: '1990',
+                        data: data[0],
+                        type: 'scatter',
+                        symbolSize: function (data) {
+                            return Math.sqrt(data[2]) / 5e2;
+                        },
+                        labelLayout: {
+                            y: 20,
+                            draggable: true,
+                            align: 'center',
+                            moveOverlap: 'shift-x',
+                            hideOverlap: true,
+                            minMargin: 10
+                        },
+                        labelLine: {
+                            show: true,
+                            length2: 5,
+                            lineStyle: {
+                                color: '#bbb'
+                            }
+                        },
+                        label: {
+                            show: true,
+                            formatter: function (param) {
+                                return param.data[3];
+                            },
+                            color: '#333',
+                            textBorderColor: '#fff',
+                            textBorderWidth: 1,
+                            position: 'top'
+                        }
+                    }]
+                };
+
+                var chart = testHelper.create(echarts, 'main6', {
+                    title: [
+                        'Overlap Shift X'
+                    ],
+                    option: option
+                });
+            });
+        </script>
+
+
+        <script>
+            require(['echarts'/*, 'map/js/china' */], function (echarts) {
+                var option;
+                var data = [
+                    [[28604,77,17096869,'Australia',1990],[31163,77.4,27662440,'Canada',1990],[1516,68,1154605773,'China',1990],[13670,74.7,10582082,'Cuba',1990],[28599,75,4986705,'Finland',1990],[29476,77.1,56943299,'France',1990],[31476,75.4,78958237,'Germany',1990],[28666,78.1,254830,'Iceland',1990],[1777,57.7,870601776,'India',1990],[29550,79.1,122249285,'Japan',1990],[2076,67.9,20194354,'North Korea',1990],[12087,72,42972254,'South Korea',1990],[24021,75.4,3397534,'New Zealand',1990 [...]
+                    [[44056,81.8,23968973,'Australia',2015],[43294,81.7,35939927,'Canada',2015],[13334,76.9,1376048943,'China',2015],[21291,78.5,11389562,'Cuba',2015],[38923,80.8,5503457,'Finland',2015],[37599,81.9,64395345,'France',2015],[44053,81.1,80688545,'Germany',2015],[42182,82.8,329425,'Iceland',2015],[5903,66.8,1311050527,'India',2015],[36162,83.5,126573481,'Japan',2015],[1390,71.4,25155317,'North Korea',2015],[34644,80.7,50293439,'South Korea',2015],[34186,80.6,4528526,'New Zea [...]
+                ];
+
+                option = {
+                    xAxis: {},
+                    yAxis: {
+                        scale: true
+                    },
+                    grid: {
+                        width: 300
+                    },
+                    series: [{
+                        name: '1990',
+                        data: data[0],
+                        type: 'scatter',
+                        symbolSize: function (data) {
+                            return Math.sqrt(data[2]) / 5e2;
+                        },
+                        labelLayout: {
+                            x: 500,
+                            draggable: true,
+                            align: 'center',
+                            moveOverlap: 'shift-y',
+                            // hideOverlap: true,
+                            minMargin: 2
+                        },
+                        labelLine: {
+                            show: true,
+                            length2: 5,
+                            lineStyle: {
+                                color: '#bbb'
+                            }
+                        },
+                        label: {
+                            show: true,
+                            formatter: function (param) {
+                                return param.data[3];
+                            },
+                            color: '#333',
+                            textBorderColor: '#fff',
+                            textBorderWidth: 1,
+                            position: 'top'
+                        }
+                    }]
+                };
+
+                var chart = testHelper.create(echarts, 'main7', {
+                    title: [
+                        'Overlap Shift Y'
+                    ],
+                    option: option
+                });
+            });
+        </script>
     </body>
 </html>
 
diff --git a/test/labelLine.html b/test/labelLine.html
deleted file mode 100644
index d02d1eb..0000000
--- a/test/labelLine.html
+++ /dev/null
@@ -1,126 +0,0 @@
-<!DOCTYPE html>
-<!--
-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">
-        <meta name="viewport" content="width=device-width, initial-scale=1" />
-        <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>
-        <!-- <script src="ut/lib/canteen.js"></script> -->
-        <link rel="stylesheet" href="lib/reset.css" />
-    </head>
-    <body>
-        <style>
-        </style>
-
-
-
-        <div id="main0"></div>
-
-
-
-
-
-
-
-
-
-        <script>
-        require(['echarts'/*, 'map/js/china' */], function (echarts) {
-            var option;
-            var data = [
-                [[28604,77,17096869,'Australia',1990],[31163,77.4,27662440,'Canada',1990],[1516,68,1154605773,'China',1990],[13670,74.7,10582082,'Cuba',1990],[28599,75,4986705,'Finland',1990],[29476,77.1,56943299,'France',1990],[31476,75.4,78958237,'Germany',1990],[28666,78.1,254830,'Iceland',1990],[1777,57.7,870601776,'India',1990],[29550,79.1,122249285,'Japan',1990],[2076,67.9,20194354,'North Korea',1990],[12087,72,42972254,'South Korea',1990],[24021,75.4,3397534,'New Zealand',1990],[4 [...]
-                [[44056,81.8,23968973,'Australia',2015],[43294,81.7,35939927,'Canada',2015],[13334,76.9,1376048943,'China',2015],[21291,78.5,11389562,'Cuba',2015],[38923,80.8,5503457,'Finland',2015],[37599,81.9,64395345,'France',2015],[44053,81.1,80688545,'Germany',2015],[42182,82.8,329425,'Iceland',2015],[5903,66.8,1311050527,'India',2015],[36162,83.5,126573481,'Japan',2015],[1390,71.4,25155317,'North Korea',2015],[34644,80.7,50293439,'South Korea',2015],[34186,80.6,4528526,'New Zealand [...]
-            ];
-
-            option = {
-                xAxis: {},
-                yAxis: {},
-                series: [{
-                    name: '1990',
-                    data: data[0],
-                    type: 'scatter',
-                    symbolSize: function (data) {
-                        return Math.sqrt(data[2]) / 5e2;
-                    },
-                    labelLayout: {
-                        y: 20,
-                        draggable: true,
-                        align: 'center',
-                        hideOverlap: true
-                    },
-                    labelLine: {
-                        show: true,
-                        length2: 10
-                    },
-                    label: {
-                        show: true,
-                        formatter: function (param) {
-                            return param.data[3];
-                        },
-                        position: 'top'
-                    }
-                }, {
-                    name: '2015',
-                    data: data[1],
-                    type: 'scatter',
-                    symbolSize: function (data) {
-                        return Math.sqrt(data[2]) / 5e2;
-                    },
-                    labelLayout: {
-                        y: 40,
-                        draggable: true,
-                        align: 'center',
-                        hideOverlap: true
-                    },
-                    labelLine: {
-                        show: true,
-                        length2: 10
-                    },
-                    label: {
-                        show: true,
-                        formatter: function (param) {
-                            return param.data[3];
-                        },
-                        position: 'top'
-                    }
-                }]
-            };
-
-            var chart = testHelper.create(echarts, 'main0', {
-                title: [
-                ],
-                option: option
-                // height: 300,
-                // buttons: [{text: 'btn-txt', onclick: function () {}}],
-                // recordCanvas: true,
-            });
-        });
-        </script>
-
-
-    </body>
-</html>
-


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