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 2018/04/05 20:35:30 UTC

[incubator-echarts] branch master updated (aa16ddc -> d81f062)

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

sushuang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git.


    from aa16ddc  Merge pull request #7956 from apache/sankey
     new eaa6b44  Fix lines update layout in not large but incremental mode.
     new 904cb02  tweak lines tooltip.
     new 00b93a2  Fix lines rendering in large but not incrementalDisplayable mode.
     new df15e36  Merge branch 'master' of https://github.com/apache/incubator-echarts
     new b18189d  add example.
     new 634a05e  Refactor and optimize boxplot.
     new 346af22  refactor candlestick.
     new 096a88e  optimize candlestick.
     new d81f062  Merge branch 'master' of https://github.com/apache/incubator-echarts

The 9 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/chart/boxplot/BoxplotView.js                   | 152 +++++++++--
 src/chart/boxplot/boxplotLayout.js                 | 127 ++++-----
 src/chart/candlestick/CandlestickSeries.js         |  11 +-
 src/chart/candlestick/CandlestickView.js           | 285 ++++++++++++++++++--
 src/chart/candlestick/candlestickLayout.js         |  93 ++++---
 src/chart/candlestick/candlestickVisual.js         |  38 ++-
 src/chart/candlestick/helper.js                    |  28 --
 src/chart/helper/LargeLineDraw.js                  |   1 +
 src/chart/helper/LineDraw.js                       |   8 +
 src/chart/helper/WhiskerBoxDraw.js                 | 300 ---------------------
 src/chart/helper/createRenderPlanner.js            |   4 +-
 src/chart/helper/whiskerBoxCommon.js               |  32 ---
 src/chart/lines/LinesView.js                       |   3 +-
 src/chart/lines/linesLayout.js                     |   2 +-
 src/data/Graph.js                                  |   2 +-
 src/stream/Scheduler.js                            |   8 +-
 src/view/Chart.js                                  |   4 +-
 test/-cases.js                                     |   4 +
 test/boxplot-multi.html                            |   5 +
 test/candlestick-large.html                        |  12 +-
 ...dlestick-large.html => candlestick-large2.html} | 177 ++++++------
 ...dlestick-large.html => candlestick-large3.html} | 155 +++++------
 test/candlestick.html                              |   5 +
 test/lib/frameInsight.js                           |   4 +-
 test/line-large.html                               |   2 +-
 test/lines-flight.html                             |   2 +-
 test/lines-stream-large.html                       | 143 ++++++++++
 ...nes-flight.html => lines-stream-not-large.html} |  29 +-
 test/scatter-stream-large.html                     | 149 ++++++++++
 test/scatter-stream-not-large.html                 | 149 ++++++++++
 test/tree-basic.html                               |  15 ++
 31 files changed, 1238 insertions(+), 711 deletions(-)
 delete mode 100644 src/chart/candlestick/helper.js
 delete mode 100644 src/chart/helper/WhiskerBoxDraw.js
 copy test/{candlestick-large.html => candlestick-large2.html} (68%)
 copy test/{candlestick-large.html => candlestick-large3.html} (73%)
 create mode 100644 test/lines-stream-large.html
 copy test/{lines-flight.html => lines-stream-not-large.html} (85%)
 create mode 100644 test/scatter-stream-large.html
 create mode 100644 test/scatter-stream-not-large.html

-- 
To stop receiving notification emails like this one, please contact
sushuang@apache.org.

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


[incubator-echarts] 06/09: Refactor and optimize boxplot.

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 634a05e659612c9932b4b0e705ac3f0191eef744
Author: sushuang <su...@gmail.com>
AuthorDate: Wed Apr 4 01:26:43 2018 +0800

    Refactor and optimize boxplot.
---
 src/chart/boxplot/BoxplotView.js   | 152 ++++++++++++++++++++++++++++++++-----
 src/chart/boxplot/boxplotLayout.js | 127 ++++++++++++++-----------------
 test/boxplot-multi.html            |   5 ++
 3 files changed, 193 insertions(+), 91 deletions(-)

diff --git a/src/chart/boxplot/BoxplotView.js b/src/chart/boxplot/BoxplotView.js
index a0d4b53..4e356a1 100644
--- a/src/chart/boxplot/BoxplotView.js
+++ b/src/chart/boxplot/BoxplotView.js
@@ -1,43 +1,155 @@
 import * as zrUtil from 'zrender/src/core/util';
 import ChartView from '../../view/Chart';
 import * as graphic from '../../util/graphic';
-import {viewMixin} from '../helper/whiskerBoxCommon';
+import Path from 'zrender/src/graphic/Path';
+
+// Update common properties
+var NORMAL_ITEM_STYLE_PATH = ['itemStyle'];
+var EMPHASIS_ITEM_STYLE_PATH = ['emphasis', 'itemStyle'];
 
 var BoxplotView = ChartView.extend({
 
     type: 'boxplot',
 
-    getStyleUpdater: function () {
-        return updateStyle;
+    render: function (seriesModel, ecModel, api) {
+        var data = seriesModel.getData();
+        var group = this.group;
+        var oldData = this._data;
+
+        // There is no old data only when first rendering or switching from
+        // stream mode to normal mode, where previous elements should be removed.
+        if (!this._data) {
+            group.removeAll();
+        }
+
+        var constDim = seriesModel.get('layout') === 'horizontal' ? 1 : 0;
+
+        data.diff(oldData)
+            .add(function (newIdx) {
+                if (data.hasValue(newIdx)) {
+                    var itemLayout = data.getItemLayout(newIdx);
+                    var symbolEl = createNormalBox(itemLayout, data, newIdx, constDim, true);
+                    data.setItemGraphicEl(newIdx, symbolEl);
+                    group.add(symbolEl);
+                }
+            })
+            .update(function (newIdx, oldIdx) {
+                var symbolEl = oldData.getItemGraphicEl(oldIdx);
+
+                // Empty data
+                if (!data.hasValue(newIdx)) {
+                    group.remove(symbolEl);
+                    return;
+                }
+
+                var itemLayout = data.getItemLayout(newIdx);
+                if (!symbolEl) {
+                    symbolEl = createNormalBox(itemLayout, data, newIdx, constDim);
+                }
+                else {
+                    updateNormalBoxData(itemLayout, symbolEl, data, newIdx);
+                }
+
+                group.add(symbolEl);
+
+                data.setItemGraphicEl(newIdx, symbolEl);
+            })
+            .remove(function (oldIdx) {
+                var el = oldData.getItemGraphicEl(oldIdx);
+                el && group.remove(el);
+            })
+            .execute();
+
+        this._data = data;
     },
 
-    dispose: zrUtil.noop
+    remove: function (ecModel) {
+        var group = this.group;
+        var data = this._data;
+        this._data = null;
+        data && data.eachItemGraphicEl(function (el) {
+            el && group.remove(el);
+        });
+    }
+
 });
 
-zrUtil.mixin(BoxplotView, viewMixin, true);
 
-// Update common properties
-var normalStyleAccessPath = ['itemStyle'];
-var emphasisStyleAccessPath = ['emphasis', 'itemStyle'];
+var BoxPath = Path.extend({
+
+    type: 'boxplotBoxPath',
+
+    shape: {},
 
-function updateStyle(data, idx, boxEl, whiskerEl, bodyEl) {
-    var itemModel = data.getItemModel(idx);
-    var normalItemStyleModel = itemModel.getModel(normalStyleAccessPath);
-    var borderColor = data.getItemVisual(idx, 'color');
+    buildPath: function (ctx, shape) {
+        var ends = shape.points;
+
+        var i = 0;
+        ctx.moveTo(ends[i][0], ends[i][1]);
+        i++;
+        for (; i < 4; i++) {
+            ctx.lineTo(ends[i][0], ends[i][1]);
+        }
+        ctx.closePath();
+
+        for (; i < ends.length; i++) {
+            ctx.moveTo(ends[i][0], ends[i][1]);
+            i++;
+            ctx.lineTo(ends[i][0], ends[i][1]);
+        }
+    }
+});
+
+
+function createNormalBox(itemLayout, data, dataIndex, constDim, isInit) {
+    var ends = itemLayout.ends;
+
+    var el = new BoxPath({
+        shape: {
+            points: isInit
+                ? transInit(ends, constDim, itemLayout)
+                : ends
+        }
+    });
+
+    updateNormalBoxData(itemLayout, el, data, dataIndex, isInit);
+
+    return el;
+}
+
+function updateNormalBoxData(itemLayout, el, data, dataIndex, isInit) {
+    var seriesModel = data.hostModel;
+    var updateMethod = graphic[isInit ? 'initProps' : 'updateProps'];
+
+    updateMethod(
+        el,
+        {shape: {points: itemLayout.ends}},
+        seriesModel,
+        dataIndex
+    );
+
+    var itemModel = data.getItemModel(dataIndex);
+    var normalItemStyleModel = itemModel.getModel(NORMAL_ITEM_STYLE_PATH);
+    var borderColor = data.getItemVisual(dataIndex, 'color');
 
     // Exclude borderColor.
     var itemStyle = normalItemStyleModel.getItemStyle(['borderColor']);
+    itemStyle.stroke = borderColor;
+    itemStyle.strokeNoScale = true;
+    el.useStyle(itemStyle);
 
-    whiskerEl.style.set(itemStyle);
-    whiskerEl.style.stroke = borderColor;
-    whiskerEl.dirty();
+    el.z2 = 100;
 
-    bodyEl.style.set(itemStyle);
-    bodyEl.style.stroke = borderColor;
-    bodyEl.dirty();
+    var hoverStyle = itemModel.getModel(EMPHASIS_ITEM_STYLE_PATH).getItemStyle();
+    graphic.setHoverStyle(el, hoverStyle);
+}
 
-    var hoverStyle = itemModel.getModel(emphasisStyleAccessPath).getItemStyle();
-    graphic.setHoverStyle(boxEl, hoverStyle);
+function transInit(points, dim, itemLayout) {
+    return zrUtil.map(points, function (point) {
+        point = point.slice();
+        point[dim] = itemLayout.initBaseline;
+        return point;
+    });
 }
 
 export default BoxplotView;
diff --git a/src/chart/boxplot/boxplotLayout.js b/src/chart/boxplot/boxplotLayout.js
index 84c80ea..ba82605 100644
--- a/src/chart/boxplot/boxplotLayout.js
+++ b/src/chart/boxplot/boxplotLayout.js
@@ -108,86 +108,71 @@ function layoutSingleSeries(seriesModel, offset, boxWidth) {
     var coordSys = seriesModel.coordinateSystem;
     var data = seriesModel.getData();
     var halfWidth = boxWidth / 2;
-    var chartLayout = seriesModel.get('layout');
-    var variableDim = chartLayout === 'horizontal' ? 0 : 1;
-    var constDim = 1 - variableDim;
+    var cDimIdx = seriesModel.get('layout') === 'horizontal' ? 0 : 1;
+    var vDimIdx = 1 - cDimIdx;
     var coordDims = ['x', 'y'];
-    var vDims = [];
-    var cDim;
-
-    zrUtil.each(data.dimensions, function (dimName) {
-        var dimInfo = data.getDimensionInfo(dimName);
-        var coordDim = dimInfo.coordDim;
-        if (coordDim === coordDims[constDim]) {
-            vDims.push(dimName);
-        }
-        else if (coordDim === coordDims[variableDim]) {
-            cDim = dimName;
-        }
-    });
+    var cDim = data.mapDimension(coordDims[cDimIdx]);
+    var vDims = data.mapDimension(coordDims[vDimIdx], true);
 
     if (cDim == null || vDims.length < 5) {
         return;
     }
 
-    data.each([cDim].concat(vDims), function () {
-        var args = arguments;
-        var axisDimVal = args[0];
-        var idx = args[vDims.length + 1];
-
-        var median = getPoint(args[3]);
-        var end1 = getPoint(args[1]);
-        var end5 = getPoint(args[5]);
-        var whiskerEnds = [
-            [end1, getPoint(args[2])],
-            [end5, getPoint(args[4])]
-        ];
-        layEndLine(end1);
-        layEndLine(end5);
-        layEndLine(median);
-
-        var bodyEnds = [];
-        addBodyEnd(whiskerEnds[0][1], 0);
-        addBodyEnd(whiskerEnds[1][1], 1);
-
-        data.setItemLayout(idx, {
-            chartLayout: chartLayout,
-            initBaseline: median[constDim],
-            median: median,
-            bodyEnds: bodyEnds,
-            whiskerEnds: whiskerEnds
+    for (var dataIndex = 0; dataIndex < data.count(); dataIndex++) {
+        var axisDimVal = data.get(cDim, dataIndex);
+
+        var median = getPoint(axisDimVal, vDims[2], dataIndex);
+        var end1 = getPoint(axisDimVal, vDims[0], dataIndex);
+        var end2 = getPoint(axisDimVal, vDims[1], dataIndex);
+        var end4 = getPoint(axisDimVal, vDims[3], dataIndex);
+        var end5 = getPoint(axisDimVal, vDims[4], dataIndex);
+
+        var ends = [];
+        addBodyEnd(ends, end2, 0);
+        addBodyEnd(ends, end4, 1);
+
+        ends.push(end1, end2, end5, end4);
+        layEndLine(ends, end1);
+        layEndLine(ends, end5);
+        layEndLine(ends, median);
+
+        data.setItemLayout(dataIndex, {
+            initBaseline: median[vDimIdx],
+            ends: ends
         });
+    }
 
-        function getPoint(val) {
-            var p = [];
-            p[variableDim] = axisDimVal;
-            p[constDim] = val;
-            var point;
-            if (isNaN(axisDimVal) || isNaN(val)) {
-                point = [NaN, NaN];
-            }
-            else {
-                point = coordSys.dataToPoint(p);
-                point[variableDim] += offset;
-            }
-            return point;
+    function getPoint(axisDimVal, dimIdx, dataIndex) {
+        var val = data.get(dimIdx, dataIndex);
+        var p = [];
+        p[cDimIdx] = axisDimVal;
+        p[vDimIdx] = val;
+        var point;
+        if (isNaN(axisDimVal) || isNaN(val)) {
+            point = [NaN, NaN];
         }
-
-        function addBodyEnd(point, start) {
-            var point1 = point.slice();
-            var point2 = point.slice();
-            point1[variableDim] += halfWidth;
-            point2[variableDim] -= halfWidth;
-            start
-                ? bodyEnds.push(point1, point2)
-                : bodyEnds.push(point2, point1);
+        else {
+            point = coordSys.dataToPoint(p);
+            point[cDimIdx] += offset;
         }
+        return point;
+    }
 
-        function layEndLine(endCenter) {
-            var line = [endCenter.slice(), endCenter.slice()];
-            line[0][variableDim] -= halfWidth;
-            line[1][variableDim] += halfWidth;
-            whiskerEnds.push(line);
-        }
-    });
+    function addBodyEnd(ends, point, start) {
+        var point1 = point.slice();
+        var point2 = point.slice();
+        point1[cDimIdx] += halfWidth;
+        point2[cDimIdx] -= halfWidth;
+        start
+            ? ends.push(point1, point2)
+            : ends.push(point2, point1);
+    }
+
+    function layEndLine(ends, endCenter) {
+        var from = endCenter.slice();
+        var to = endCenter.slice();
+        from[cDimIdx] -= halfWidth;
+        to[cDimIdx] += halfWidth;
+        ends.push(from, to);
+    }
 }
diff --git a/test/boxplot-multi.html b/test/boxplot-multi.html
index 6593486..cc8c060 100644
--- a/test/boxplot-multi.html
+++ b/test/boxplot-multi.html
@@ -124,6 +124,11 @@
                             {
                                 name: 'category0',
                                 type: 'boxplot',
+                                itemStyle: {
+                                    color: '#a32',
+                                    borderColor: '#429',
+                                    borderWidth: 3
+                                },
                                 data: data[0].boxData
                             },
                             {

-- 
To stop receiving notification emails like this one, please contact
sushuang@apache.org.

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


[incubator-echarts] 07/09: refactor candlestick.

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 346af22dc00cc3a084d908eafafdc6d35067d110
Author: sushuang <su...@gmail.com>
AuthorDate: Wed Apr 4 02:55:51 2018 +0800

    refactor candlestick.
---
 src/chart/candlestick/CandlestickView.js   | 255 ++++++++++++++++++++++--
 src/chart/candlestick/candlestickLayout.js |  43 ++---
 src/chart/candlestick/candlestickVisual.js |  26 ++-
 src/chart/helper/WhiskerBoxDraw.js         | 300 -----------------------------
 src/chart/helper/whiskerBoxCommon.js       |  32 ---
 test/candlestick.html                      |   5 +
 6 files changed, 276 insertions(+), 385 deletions(-)

diff --git a/src/chart/candlestick/CandlestickView.js b/src/chart/candlestick/CandlestickView.js
index 622cf79..6f8d960 100644
--- a/src/chart/candlestick/CandlestickView.js
+++ b/src/chart/candlestick/CandlestickView.js
@@ -1,30 +1,173 @@
 import * as zrUtil from 'zrender/src/core/util';
 import ChartView from '../../view/Chart';
 import * as graphic from '../../util/graphic';
-import {viewMixin} from '../helper/whiskerBoxCommon';
+import Path from 'zrender/src/graphic/Path';
+
+var NORMAL_ITEM_STYLE_PATH = ['itemStyle'];
+var EMPHASIS_ITEM_STYLE_PATH = ['emphasis', 'itemStyle'];
 
 var CandlestickView = ChartView.extend({
 
     type: 'candlestick',
 
-    getStyleUpdater: function () {
-        return updateStyle;
+    render: function (seriesModel, ecModel, api) {
+        var group = this.group;
+        var data = seriesModel.getData();
+        var oldData = this._data;
+        var pipelineContext = seriesModel.pipelineContext;
+        var isLargeRender = pipelineContext.large;
+        var largePoints = isLargeRender && data.getLayout('largePoints');
+
+        // There is no old data only when first rendering or switching from
+        // stream mode to normal mode, where previous elements should be removed.
+        if (!this._data) {
+            group.removeAll();
+        }
+
+        data.diff(oldData)
+            .add(function (newIdx) {
+                if (data.hasValue(newIdx)) {
+                    var symbolEl = isLargeRender
+                        ? createLargeBox(data, largePoints, newIdx)
+                        : createNormalBox(data, newIdx, true);
+                    data.setItemGraphicEl(newIdx, symbolEl);
+                    group.add(symbolEl);
+                }
+            })
+            .update(function (newIdx, oldIdx) {
+                var symbolEl = oldData.getItemGraphicEl(oldIdx);
+
+                // Empty data
+                if (!data.hasValue(newIdx)) {
+                    group.remove(symbolEl);
+                    return;
+                }
+
+                if (symbolEl && symbolEl.__largeWhiskerBox ^ isLargeRender) {
+                    group.remove(symbolEl);
+                    symbolEl = null;
+                }
+
+                if (!symbolEl) {
+                    symbolEl = isLargeRender
+                        ? createLargeBox(data, largePoints, newIdx)
+                        : createNormalBox(data, newIdx);
+                }
+                else {
+                    isLargeRender
+                        ? updateLargeBoxData(symbolEl, data, newIdx)
+                        : updateNormalBoxData(symbolEl, data, newIdx);
+                }
+
+                // Add back
+                group.add(symbolEl);
+
+                data.setItemGraphicEl(newIdx, symbolEl);
+            })
+            .remove(function (oldIdx) {
+                var el = oldData.getItemGraphicEl(oldIdx);
+                el && group.remove(el);
+            })
+            .execute();
+
+        this._data = data;
     },
 
-    dispose: zrUtil.noop
+    incrementalPrepareRender: function (seriesModel, ecModel, api) {
+        this.group.removeAll();
+        this._data = null;
+    },
+
+    incrementalRender: function (params, seriesModel, ecModel, api) {
+        var data = seriesModel.getData();
+        var pipelineContext = seriesModel.pipelineContext;
+        var isLargeRender = pipelineContext.large;
+        var largePoints = isLargeRender && data.getLayout('largePoints');
+
+        for (var idx = params.start; idx < params.end; idx++) {
+            var symbolEl = isLargeRender
+                ? createLargeBox(data, largePoints, idx, params.start)
+                : createNormalBox(data, idx, this.styleUpdater, true);
+            symbolEl.incremental = true;
+            this.group.add(symbolEl);
+        }
+    },
+
+    remove: function (ecModel) {
+        var group = this.group;
+        var data = this._data;
+        this._data = null;
+        data && data.eachItemGraphicEl(function (el) {
+            el && group.remove(el);
+        });
+    }
+
 });
 
-zrUtil.mixin(CandlestickView, viewMixin, true);
 
-// Update common properties
-var normalStyleAccessPath = ['itemStyle'];
-var emphasisStyleAccessPath = ['emphasis', 'itemStyle'];
 
-function updateStyle(data, idx, boxEl, whiskerEl, bodyEl) {
-    var itemModel = data.getItemModel(idx);
-    var normalItemStyleModel = itemModel.getModel(normalStyleAccessPath);
-    var color = data.getItemVisual(idx, 'color');
-    var borderColor = data.getItemVisual(idx, 'borderColor') || color;
+
+
+// ---------------------
+// -- Normal Renderer --
+// ---------------------
+
+var NormalBoxPath = Path.extend({
+
+    type: 'candlestickBox',
+
+    shape: {},
+
+    buildPath: function (ctx, shape) {
+        var ends = shape.points;
+
+        ctx.moveTo(ends[0][0], ends[0][1]);
+        ctx.lineTo(ends[1][0], ends[1][1]);
+        ctx.lineTo(ends[2][0], ends[2][1]);
+        ctx.lineTo(ends[3][0], ends[3][1]);
+        ctx.closePath();
+
+        ctx.moveTo(ends[4][0], ends[4][1]);
+        ctx.lineTo(ends[5][0], ends[5][1]);
+        ctx.moveTo(ends[6][0], ends[6][1]);
+        ctx.lineTo(ends[7][0], ends[7][1]);
+    }
+});
+
+function createNormalBox(data, dataIndex, isInit) {
+    var itemLayout = data.getItemLayout(dataIndex);
+    var ends = itemLayout.ends;
+
+    var el = new NormalBoxPath({
+        shape: {
+            points: isInit
+                ? transInit(ends, itemLayout)
+                : ends
+        },
+        z2: 100
+    });
+
+    updateNormalBoxData(el, data, dataIndex, isInit);
+
+    return el;
+}
+
+function updateNormalBoxData(el, data, dataIndex, isInit) {
+    var seriesModel = data.hostModel;
+    var itemLayout = data.getItemLayout(dataIndex);
+    var updateMethod = graphic[isInit ? 'initProps' : 'updateProps'];
+
+    updateMethod(
+        el,
+        {shape: {points: itemLayout.ends}},
+        seriesModel,
+        dataIndex
+    );
+
+    var itemModel = data.getItemModel(dataIndex);
+    var normalItemStyleModel = itemModel.getModel(NORMAL_ITEM_STYLE_PATH);
+    var color = data.getItemVisual(dataIndex, 'color');
+    var borderColor = data.getItemVisual(dataIndex, 'borderColor') || color;
 
     // Color must be excluded.
     // Because symbol provide setColor individually to set fill and stroke
@@ -32,15 +175,89 @@ function updateStyle(data, idx, boxEl, whiskerEl, bodyEl) {
         ['color', 'color0', 'borderColor', 'borderColor0']
     );
 
-    whiskerEl.useStyle(itemStyle);
-    whiskerEl.style.stroke = borderColor;
+    el.useStyle(itemStyle);
+    el.style.strokeNoScale = true;
+    el.style.fill = color;
+    el.style.stroke = borderColor;
 
-    bodyEl.useStyle(itemStyle);
-    bodyEl.style.fill = color;
-    bodyEl.style.stroke = borderColor;
+    var hoverStyle = itemModel.getModel(EMPHASIS_ITEM_STYLE_PATH).getItemStyle();
+    graphic.setHoverStyle(el, hoverStyle);
+}
+
+function transInit(points, itemLayout) {
+    return zrUtil.map(points, function (point) {
+        point = point.slice();
+        point[1] = itemLayout.initBaseline;
+        return point;
+    });
+}
+
+
+
+
+
+
+// --------------------
+// -- Large Renderer --
+// --------------------
+
+var NORMAL_STYLE_ACCESS_PATH = ['itemStyle'];
+var EMPHASIS_STYLE_ACCESS_PATH = ['emphasis', 'itemStyle'];
+
+function createLargeBox(data, largePoints, dataIndex, segmentStart) {
+    var boxEl = new graphic.Line({
+        shape: largeBoxMakeShape(largePoints, dataIndex, segmentStart)
+    });
+
+    boxEl.__largeWhiskerBox = true;
+
+    largeBoxSetStyle(boxEl, data, dataIndex);
+
+    return boxEl;
+}
+
+function largeBoxMakeShape(largePoints, dataIndex, segmentStart) {
+    var baseIdx = (dataIndex - (segmentStart || 0)) * 5;
+    return {
+        x1: largePoints[baseIdx + 1],
+        y1: largePoints[baseIdx + 2],
+        x2: largePoints[baseIdx + 3],
+        y2: largePoints[baseIdx + 4]
+    };
+}
 
-    var hoverStyle = itemModel.getModel(emphasisStyleAccessPath).getItemStyle();
+function updateLargeBoxData(boxEl, data, dataIndex) {
+    graphic.updateProps(
+        boxEl,
+        {shape: largeBoxMakeShape(data.getLayout('largePoints'), dataIndex, 0)},
+        data.hostModel,
+        dataIndex
+    );
+
+    largeBoxSetStyle(boxEl, data, dataIndex);
+}
+
+function largeBoxSetStyle(boxEl, data, dataIndex) {
+    var itemModel = data.getItemModel(dataIndex);
+    var normalItemStyleModel = itemModel.getModel(NORMAL_STYLE_ACCESS_PATH);
+    var color = data.getItemVisual(dataIndex, 'color');
+    var borderColor = data.getItemVisual(dataIndex, 'borderColor') || color;
+
+    // Color must be excluded.
+    // Because symbol provide setColor individually to set fill and stroke
+    var itemStyle = normalItemStyleModel.getItemStyle(
+        ['color', 'color0', 'borderColor', 'borderColor0']
+    );
+
+    boxEl.useStyle(itemStyle);
+    boxEl.style.stroke = borderColor;
+
+    var hoverStyle = itemModel.getModel(EMPHASIS_STYLE_ACCESS_PATH).getItemStyle();
     graphic.setHoverStyle(boxEl, hoverStyle);
 }
 
+
+
+
 export default CandlestickView;
+
diff --git a/src/chart/candlestick/candlestickLayout.js b/src/chart/candlestick/candlestickLayout.js
index 929d93b..6fa8fda 100644
--- a/src/chart/candlestick/candlestickLayout.js
+++ b/src/chart/candlestick/candlestickLayout.js
@@ -18,9 +18,8 @@ export default {
         var coordSys = seriesModel.coordinateSystem;
         var data = seriesModel.getData();
         var candleWidth = calculateCandleWidth(seriesModel, data);
-        var chartLayout = seriesModel.get('layout');
-        var cDimIdx = chartLayout === 'horizontal' ? 0 : 1;
-        var vDimIdx = 1 - cDimIdx;
+        var cDimIdx = 0;
+        var vDimIdx = 1;
         var coordDims = ['x', 'y'];
         var cDim = data.mapDimension(coordDims[cDimIdx]);
         var vDims = data.mapDimension(coordDims[vDimIdx], true);
@@ -39,10 +38,7 @@ export default {
         function normalProgress(params, data) {
 
             for (var dataIndex = params.start; dataIndex < params.end; dataIndex++) {
-                layoutDataItem(dataIndex);
-            }
 
-            function layoutDataItem(dataIndex) {
                 var axisDimVal = data.get(cDim, dataIndex);
                 var openVal = data.get(openDim, dataIndex);
                 var closeVal = data.get(closeDim, dataIndex);
@@ -57,28 +53,22 @@ export default {
                 var lowestPoint = getPoint(lowestVal, axisDimVal);
                 var highestPoint = getPoint(highestVal, axisDimVal);
 
-                var whiskerEnds = [
-                    [
-                        subPixelOptimizePoint(highestPoint),
-                        subPixelOptimizePoint(ocHighPoint)
-                    ],
-                    [
-                        subPixelOptimizePoint(lowestPoint),
-                        subPixelOptimizePoint(ocLowPoint)
-                    ]
-                ];
-
-                var bodyEnds = [];
-                addBodyEnd(bodyEnds, ocHighPoint, 0);
-                addBodyEnd(bodyEnds, ocLowPoint, 1);
+                var ends = [];
+                addBodyEnd(ends, ocHighPoint, 0);
+                addBodyEnd(ends, ocLowPoint, 1);
+
+                ends.push(
+                    subPixelOptimizePoint(highestPoint),
+                    subPixelOptimizePoint(ocHighPoint),
+                    subPixelOptimizePoint(lowestPoint),
+                    subPixelOptimizePoint(ocLowPoint)
+                );
 
                 data.setItemLayout(dataIndex, {
-                    chartLayout: chartLayout,
                     sign: getSign(data, dataIndex, openVal, closeVal, closeDim),
                     initBaseline: openVal > closeVal
                         ? ocHighPoint[vDimIdx] : ocLowPoint[vDimIdx], // open point.
-                    bodyEnds: bodyEnds,
-                    whiskerEnds: whiskerEnds,
+                    ends: ends,
                     brushRect: makeBrushRect(lowestVal, highestVal, axisDimVal)
                 });
             }
@@ -92,7 +82,7 @@ export default {
                     : coordSys.dataToPoint(p);
             }
 
-            function addBodyEnd(bodyEnds, point, start) {
+            function addBodyEnd(ends, point, start) {
                 var point1 = point.slice();
                 var point2 = point.slice();
 
@@ -104,8 +94,8 @@ export default {
                 );
 
                 start
-                    ? bodyEnds.push(point1, point2)
-                    : bodyEnds.push(point2, point1);
+                    ? ends.push(point1, point2)
+                    : ends.push(point2, point1);
             }
 
             function makeBrushRect(lowestVal, highestVal, axisDimVal) {
@@ -168,7 +158,6 @@ export default {
 
             data.setLayout('largePoints', points);
             data.setLayout('candleWidth', candleWidth);
-            data.setLayout('candleWidth', candleWidth);
         }
     }
 };
diff --git a/src/chart/candlestick/candlestickVisual.js b/src/chart/candlestick/candlestickVisual.js
index d4cf012..ad94894 100644
--- a/src/chart/candlestick/candlestickVisual.js
+++ b/src/chart/candlestick/candlestickVisual.js
@@ -22,7 +22,11 @@ export default {
         var largePoints = isLargeRender && data.getLayout('largePoints');
 
         data.setVisual({
-            legendSymbol: 'roundRect'
+            legendSymbol: 'roundRect',
+            colorP: getColor(1, seriesModel),
+            colorN: getColor(-1, seriesModel),
+            borderColorP: getBorderColor(1, seriesModel),
+            borderColorN: getBorderColor(-1, seriesModel)
         });
 
         // Only visible series has each data be visual encoded
@@ -40,17 +44,25 @@ export default {
                 data.setItemVisual(
                     dataIndex,
                     {
-                        color: itemModel.get(
-                            sign > 0 ? positiveColorQuery : negativeColorQuery
-                        ),
-                        borderColor: itemModel.get(
-                            sign > 0 ? positiveBorderColorQuery : negativeBorderColorQuery
-                        )
+                        color: getColor(sign, itemModel),
+                        borderColor: getBorderColor(sign, itemModel)
                     }
                 );
             }
         }
 
+        function getColor(sign, model) {
+            return model.get(
+                sign > 0 ? positiveColorQuery : negativeColorQuery
+            );
+        }
+
+        function getBorderColor(sign, model) {
+            return model.get(
+                sign > 0 ? positiveBorderColorQuery : negativeBorderColorQuery
+            );
+        }
+
         return {progress: progress};
     }
 
diff --git a/src/chart/helper/WhiskerBoxDraw.js b/src/chart/helper/WhiskerBoxDraw.js
deleted file mode 100644
index 1753633..0000000
--- a/src/chart/helper/WhiskerBoxDraw.js
+++ /dev/null
@@ -1,300 +0,0 @@
-/**
- * @module echarts/chart/helper/Symbol
- */
-
-import * as zrUtil from 'zrender/src/core/util';
-import * as graphic from '../../util/graphic';
-import Path from 'zrender/src/graphic/Path';
-
-
-
-
-// ------------------
-// -- Whisker Path --
-// ------------------
-
-var WhiskerPath = Path.extend({
-
-    type: 'whiskerInBox',
-
-    shape: {},
-
-    buildPath: function (ctx, shape) {
-        for (var i in shape) {
-            if (shape.hasOwnProperty(i) && i.indexOf('ends') === 0) {
-                var pts = shape[i];
-                ctx.moveTo(pts[0][0], pts[0][1]);
-                ctx.lineTo(pts[1][0], pts[1][1]);
-            }
-        }
-    }
-});
-
-
-
-
-// ----------------
-// -- Normal Box --
-// ----------------
-
-
-var BODY_INDEX = 0;
-var WHISKER_INDEX = 1;
-
-/**
- * @param {module:echarts/data/List} data
- * @param {number} idx
- * @param {Function} styleUpdater
- * @param {boolean} isInit
- */
-function createNormalBox(data, dataIndex, styleUpdater, isInit) {
-    var boxEl = new graphic.Group();
-
-    var itemLayout = data.getItemLayout(dataIndex);
-    var constDim = itemLayout.chartLayout === 'horizontal' ? 1 : 0;
-
-    // Whisker element.
-    boxEl.add(new graphic.Polygon({
-        shape: {
-            points: isInit
-                ? transInit(itemLayout.bodyEnds, constDim, itemLayout)
-                : itemLayout.bodyEnds
-        },
-        style: {strokeNoScale: true},
-        z2: 100
-    }));
-
-    // Box element.
-    var whiskerEnds = zrUtil.map(itemLayout.whiskerEnds, function (ends) {
-        return isInit ? transInit(ends, constDim, itemLayout) : ends;
-    });
-    boxEl.add(new WhiskerPath({
-        shape: makeWhiskerEndsShape(whiskerEnds),
-        style: {strokeNoScale: true},
-        z2: 100
-    }));
-
-    updateNormalBoxData(boxEl, data, dataIndex, styleUpdater, isInit);
-
-    return boxEl;
-}
-
-function updateNormalBoxData(boxEl, data, dataIndex, styleUpdater, isInit) {
-    var seriesModel = boxEl._seriesModel = data.hostModel;
-    var itemLayout = data.getItemLayout(dataIndex);
-    var updateMethod = graphic[isInit ? 'initProps' : 'updateProps'];
-    var whiskerEl = boxEl.childAt(WHISKER_INDEX);
-    var bodyEl = boxEl.childAt(BODY_INDEX);
-
-    updateMethod(
-        bodyEl,
-        {shape: {points: itemLayout.bodyEnds}},
-        seriesModel, dataIndex
-    );
-    updateMethod(
-        whiskerEl,
-        {shape: makeWhiskerEndsShape(itemLayout.whiskerEnds)},
-        seriesModel, dataIndex
-    );
-
-    styleUpdater(data, dataIndex, boxEl, whiskerEl, bodyEl);
-}
-
-function transInit(points, dim, itemLayout) {
-    return zrUtil.map(points, function (point) {
-        point = point.slice();
-        point[dim] = itemLayout.initBaseline;
-        return point;
-    });
-}
-
-function makeWhiskerEndsShape(whiskerEnds) {
-    // zr animation only support 2-dim array.
-    var shape = {};
-    zrUtil.each(whiskerEnds, function (ends, i) {
-        shape['ends' + i] = ends;
-    });
-    return shape;
-}
-
-
-
-
-// ---------------
-// -- Large Box --
-// ---------------
-
-var NORMAL_STYLE_ACCESS_PATH = ['itemStyle'];
-var EMPHASIS_STYLE_ACCESS_PATH = ['emphasis', 'itemStyle'];
-
-function createLargeBox(data, largePoints, dataIndex, segmentStart) {
-    var boxEl = new graphic.Line({
-        shape: largeBoxMakeShape(largePoints, dataIndex, segmentStart)
-    });
-
-    boxEl.__largeWhiskerBox = true;
-
-    largeBoxSetStyle(boxEl, data, dataIndex);
-
-    return boxEl;
-}
-
-function largeBoxMakeShape(largePoints, dataIndex, segmentStart) {
-    var baseIdx = (dataIndex - (segmentStart || 0)) * 5;
-    return {
-        x1: largePoints[baseIdx + 1],
-        y1: largePoints[baseIdx + 2],
-        x2: largePoints[baseIdx + 3],
-        y2: largePoints[baseIdx + 4]
-    };
-}
-
-function updateLargeBoxData(boxEl, data, dataIndex) {
-    graphic.updateProps(
-        boxEl,
-        {shape: largeBoxMakeShape(data.getLayout('largePoints'), dataIndex, 0)},
-        data.hostModel,
-        dataIndex
-    );
-
-    largeBoxSetStyle(boxEl, data, dataIndex);
-}
-
-function largeBoxSetStyle(boxEl, data, dataIndex) {
-    var itemModel = data.getItemModel(dataIndex);
-    var normalItemStyleModel = itemModel.getModel(NORMAL_STYLE_ACCESS_PATH);
-    var color = data.getItemVisual(dataIndex, 'color');
-    var borderColor = data.getItemVisual(dataIndex, 'borderColor') || color;
-
-    // Color must be excluded.
-    // Because symbol provide setColor individually to set fill and stroke
-    var itemStyle = normalItemStyleModel.getItemStyle(
-        ['color', 'color0', 'borderColor', 'borderColor0']
-    );
-
-    boxEl.useStyle(itemStyle);
-    boxEl.style.stroke = borderColor;
-
-    var hoverStyle = itemModel.getModel(EMPHASIS_STYLE_ACCESS_PATH).getItemStyle();
-    graphic.setHoverStyle(boxEl, hoverStyle);
-}
-
-
-
-
-// --------------------
-// -- WhiskerBoxDraw --
-// --------------------
-
-/**
- * @constructor
- * @alias module:echarts/chart/helper/WhiskerBoxDraw
- */
-function WhiskerBoxDraw(styleUpdater) {
-    this.group = new graphic.Group();
-    this.styleUpdater = styleUpdater;
-}
-
-var whiskerBoxDrawProto = WhiskerBoxDraw.prototype;
-
-/**
- * Update symbols draw by new data
- * @param {module:echarts/data/List} data
- */
-whiskerBoxDrawProto.updateData = function (data) {
-    var group = this.group;
-    var oldData = this._data;
-    var styleUpdater = this.styleUpdater;
-    var pipelineContext = data.hostModel.pipelineContext;
-    var isLargeRender = pipelineContext.large;
-    var largePoints = isLargeRender && data.getLayout('largePoints');
-
-    // There is no old data only when first rendering or switching from
-    // stream mode to normal mode, where previous elements should be removed.
-    if (!this._data) {
-        group.removeAll();
-    }
-
-    data.diff(oldData)
-        .add(function (newIdx) {
-            if (data.hasValue(newIdx)) {
-                var symbolEl = isLargeRender
-                    ? createLargeBox(data, largePoints, newIdx)
-                    : createNormalBox(data, newIdx, styleUpdater, true);
-                data.setItemGraphicEl(newIdx, symbolEl);
-                group.add(symbolEl);
-            }
-        })
-        .update(function (newIdx, oldIdx) {
-            var symbolEl = oldData.getItemGraphicEl(oldIdx);
-
-            // Empty data
-            if (!data.hasValue(newIdx)) {
-                group.remove(symbolEl);
-                return;
-            }
-
-            if (symbolEl && symbolEl.__largeWhiskerBox ^ isLargeRender) {
-                group.remove(symbolEl);
-                symbolEl = null;
-            }
-
-            if (!symbolEl) {
-                symbolEl = isLargeRender
-                    ? createLargeBox(data, largePoints, newIdx)
-                    : createNormalBox(data, newIdx, styleUpdater);
-            }
-            else {
-                isLargeRender
-                    ? updateLargeBoxData(symbolEl, data, newIdx)
-                    : updateNormalBoxData(symbolEl, data, newIdx, styleUpdater);
-            }
-
-            // Add back
-            group.add(symbolEl);
-
-            data.setItemGraphicEl(newIdx, symbolEl);
-        })
-        .remove(function (oldIdx) {
-            var el = oldData.getItemGraphicEl(oldIdx);
-            el && group.remove(el);
-        })
-        .execute();
-
-    this._data = data;
-};
-
-whiskerBoxDrawProto.incrementalPrepareUpdate = function (seriesModel, ecModel, api) {
-    this.group.removeAll();
-    this._data = null;
-};
-
-whiskerBoxDrawProto.incrementalUpdate = function (params, seriesModel, ecModel, api) {
-    var data = seriesModel.getData();
-    var pipelineContext = seriesModel.pipelineContext;
-    var isLargeRender = pipelineContext.large;
-    var largePoints = isLargeRender && data.getLayout('largePoints');
-
-    for (var idx = params.start; idx < params.end; idx++) {
-        var symbolEl = isLargeRender
-            ? createLargeBox(data, largePoints, idx, params.start)
-            : createNormalBox(data, idx, this.styleUpdater, true);
-        symbolEl.incremental = true;
-        this.group.add(symbolEl);
-    }
-};
-
-/**
- * Remove symbols.
- * @param {module:echarts/data/List} data
- */
-whiskerBoxDrawProto.remove = function () {
-    var group = this.group;
-    var data = this._data;
-    this._data = null;
-    data && data.eachItemGraphicEl(function (el) {
-        el && group.remove(el);
-    });
-};
-
-export default WhiskerBoxDraw;
diff --git a/src/chart/helper/whiskerBoxCommon.js b/src/chart/helper/whiskerBoxCommon.js
index b9fd4e2..714cd44 100644
--- a/src/chart/helper/whiskerBoxCommon.js
+++ b/src/chart/helper/whiskerBoxCommon.js
@@ -1,6 +1,5 @@
 
 import createListSimply from '../helper/createListSimply';
-import WhiskerBoxDraw from '../helper/WhiskerBoxDraw';
 import * as zrUtil from 'zrender/src/core/util';
 import {getDimensionTypeByAxis} from '../../data/helper/dimensionHelper';
 
@@ -110,34 +109,3 @@ export var seriesModelMixin = {
     }
 
 };
-
-export var viewMixin = {
-
-    init: function () {
-        /**
-         * Old data.
-         * @private
-         * @type {module:echarts/chart/helper/WhiskerBoxDraw}
-         */
-        var whiskerBoxDraw = this._whiskerBoxDraw = new WhiskerBoxDraw(
-            this.getStyleUpdater()
-        );
-        this.group.add(whiskerBoxDraw.group);
-    },
-
-    render: function (seriesModel, ecModel, api) {
-        this._whiskerBoxDraw.updateData(seriesModel.getData());
-    },
-
-    incrementalPrepareRender: function (seriesModel, ecModel, api) {
-        this._whiskerBoxDraw.incrementalPrepareUpdate(seriesModel, ecModel, api);
-    },
-
-    incrementalRender: function (params, seriesModel, ecModel, api) {
-        this._whiskerBoxDraw.incrementalUpdate(params, seriesModel, ecModel, api);
-    },
-
-    remove: function (ecModel) {
-        this._whiskerBoxDraw.remove();
-    }
-};
diff --git a/test/candlestick.html b/test/candlestick.html
index 14d3bbc..3150b86 100644
--- a/test/candlestick.html
+++ b/test/candlestick.html
@@ -150,6 +150,11 @@
                             name: '上证指数',
                             type: 'candlestick',
                             data: data.values,
+                            // itemStyle: {
+                            //     borderColor: '#345',
+                            //     borderColor0: '#998',
+                            //     borderWidth: 2
+                            // },
                             tooltip: {
                                 formatter: function (param) {
                                     var param = param[0];

-- 
To stop receiving notification emails like this one, please contact
sushuang@apache.org.

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


[incubator-echarts] 02/09: tweak lines tooltip.

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 904cb028bafa8f520f868fa342eb17dcbfa51c3a
Author: sushuang <su...@gmail.com>
AuthorDate: Mon Apr 2 20:30:16 2018 +0800

    tweak lines tooltip.
---
 src/chart/helper/LineDraw.js |  2 ++
 src/data/Graph.js            |  2 +-
 test/tree-basic.html         | 15 +++++++++++++++
 3 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/src/chart/helper/LineDraw.js b/src/chart/helper/LineDraw.js
index b1f1982..0af0fa3 100644
--- a/src/chart/helper/LineDraw.js
+++ b/src/chart/helper/LineDraw.js
@@ -117,7 +117,9 @@ lineDrawProto.incrementalUpdate = function (taskParams, lineData) {
         if (lineNeedsDraw(itemLayout)) {
             var el = new this._ctor(lineData, idx, this._seriesScope);
             el.traverse(updateIncrementalAndHover);
+
             this.group.add(el);
+            lineData.setItemGraphicEl(idx, el);
         }
     }
 };
diff --git a/src/data/Graph.js b/src/data/Graph.js
index 3df752c..1864bee 100644
--- a/src/data/Graph.js
+++ b/src/data/Graph.js
@@ -441,7 +441,7 @@ function Edge(n1, n2, dataIndex) {
  * @param {string} [path]
  * @return {module:echarts/model/Model}
  */
-    Edge.prototype.getModel = function (path) {
+Edge.prototype.getModel = function (path) {
     if (this.dataIndex < 0) {
         return;
     }
diff --git a/test/tree-basic.html b/test/tree-basic.html
index de663f2..62cc5af 100644
--- a/test/tree-basic.html
+++ b/test/tree-basic.html
@@ -47,6 +47,7 @@
                             series:[
                                 {
                                     type: 'tree',
+                                    id: 'a',
 
                                     data: [data],
 
@@ -78,6 +79,20 @@
                                 }
                             ]
                         });
+
+
+                        setTimeout(function () {
+                            var newData = echarts.util.clone(data);
+                            newData.children.splice(0, 1);
+
+                            chart.setOption({
+                                series: {
+                                    id: 'a',
+                                    data: [newData]
+                                }
+                            });
+                        }, 1000);
+
                     });
                 });
         </script>

-- 
To stop receiving notification emails like this one, please contact
sushuang@apache.org.

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


[incubator-echarts] 04/09: Merge branch 'master' of https://github.com/apache/incubator-echarts

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit df15e36abe0543700541bbad7934028cc7fd35c7
Merge: 00b93a2 fe2749b
Author: sushuang <su...@gmail.com>
AuthorDate: Tue Apr 3 14:31:51 2018 +0800

    Merge branch 'master' of https://github.com/apache/incubator-echarts

 src/chart/sankey/SankeySeries.js         | 2 +-
 src/chart/themeRiver/ThemeRiverSeries.js | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)

-- 
To stop receiving notification emails like this one, please contact
sushuang@apache.org.

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


[incubator-echarts] 08/09: optimize candlestick.

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 096a88e5aba1cf452787711edd22cbc51c7e6ad9
Author: sushuang <su...@gmail.com>
AuthorDate: Thu Apr 5 03:21:16 2018 +0800

    optimize candlestick.
---
 src/chart/boxplot/BoxplotView.js                   |   4 +-
 src/chart/candlestick/CandlestickSeries.js         |  11 +-
 src/chart/candlestick/CandlestickView.js           | 280 +++++++++++----------
 src/chart/candlestick/candlestickLayout.js         |  50 +++-
 src/chart/candlestick/candlestickVisual.js         |  12 +-
 src/chart/candlestick/helper.js                    |  28 ---
 test/candlestick-large.html                        |  12 +-
 ...dlestick-large.html => candlestick-large2.html} | 177 +++++++------
 ...dlestick-large.html => candlestick-large3.html} | 155 ++++++------
 test/lib/frameInsight.js                           |   4 +-
 10 files changed, 395 insertions(+), 338 deletions(-)

diff --git a/src/chart/boxplot/BoxplotView.js b/src/chart/boxplot/BoxplotView.js
index 4e356a1..5032356 100644
--- a/src/chart/boxplot/BoxplotView.js
+++ b/src/chart/boxplot/BoxplotView.js
@@ -70,7 +70,9 @@ var BoxplotView = ChartView.extend({
         data && data.eachItemGraphicEl(function (el) {
             el && group.remove(el);
         });
-    }
+    },
+
+    dispose: zrUtil.noop
 
 });
 
diff --git a/src/chart/candlestick/CandlestickSeries.js b/src/chart/candlestick/CandlestickSeries.js
index e9ec988..682cb7e 100644
--- a/src/chart/candlestick/CandlestickSeries.js
+++ b/src/chart/candlestick/CandlestickSeries.js
@@ -1,7 +1,6 @@
 import * as zrUtil from 'zrender/src/core/util';
 import SeriesModel from '../../model/Series';
 import {seriesModelMixin} from '../helper/whiskerBoxCommon';
-// import {calculateCandleWidth} from './helper';
 
 var CandlestickSeries = SeriesModel.extend({
 
@@ -57,7 +56,10 @@ var CandlestickSeries = SeriesModel.extend({
         barWidth: null,
 
         large: true,
-        largeThreshold: 500,
+        largeThreshold: 600,
+
+        progressive: 5e3,
+        progressiveThreshold: 1e4,
 
         animationUpdate: false,
         animationEasing: 'linear',
@@ -77,11 +79,6 @@ var CandlestickSeries = SeriesModel.extend({
         return itemLayout && selectors.rect(itemLayout.brushRect);
     }
 
-    // isLargeMode: function (data) {
-    //     // Experience number
-    //     return calculateCandleWidth(this, data) <= 1;
-    // }
-
 });
 
 zrUtil.mixin(CandlestickSeries, seriesModelMixin, true);
diff --git a/src/chart/candlestick/CandlestickView.js b/src/chart/candlestick/CandlestickView.js
index 6f8d960..527f62a 100644
--- a/src/chart/candlestick/CandlestickView.js
+++ b/src/chart/candlestick/CandlestickView.js
@@ -5,18 +5,51 @@ import Path from 'zrender/src/graphic/Path';
 
 var NORMAL_ITEM_STYLE_PATH = ['itemStyle'];
 var EMPHASIS_ITEM_STYLE_PATH = ['emphasis', 'itemStyle'];
+var SKIP_PROPS = ['color', 'color0', 'borderColor', 'borderColor0'];
+
 
 var CandlestickView = ChartView.extend({
 
     type: 'candlestick',
 
     render: function (seriesModel, ecModel, api) {
-        var group = this.group;
+        this._updateDrawMode(seriesModel);
+
+        this._isLargeDraw
+            ? this._renderLarge(seriesModel)
+            : this._renderNormal(seriesModel);
+    },
+
+    incrementalPrepareRender: function (seriesModel, ecModel, api) {
+        this._clear();
+        this._updateDrawMode(seriesModel);
+    },
+
+    incrementalRender: function (params, seriesModel, ecModel, api) {
+        this._isLargeDraw
+             ? this._incrementalRenderLarge(params, seriesModel)
+             : this._incrementalRenderNormal(params, seriesModel);
+    },
+
+    _updateDrawMode: function (seriesModel) {
+        var isLargeDraw = seriesModel.pipelineContext.large;
+        if (this._isLargeDraw == null || isLargeDraw ^ this._isLargeDraw) {
+            this._isLargeDraw = isLargeDraw;
+            this._clear();
+        }
+    },
+
+    _clear: function () {
+        this.group.removeAll();
+        this._data = null;
+    },
+
+    _renderNormal: function (seriesModel) {
+        // var largePoints = data.getLayout('largePoints');
         var data = seriesModel.getData();
         var oldData = this._data;
-        var pipelineContext = seriesModel.pipelineContext;
-        var isLargeRender = pipelineContext.large;
-        var largePoints = isLargeRender && data.getLayout('largePoints');
+        var group = this.group;
+        var isSimpleBox = data.getLayout('isSimpleBox');
 
         // There is no old data only when first rendering or switching from
         // stream mode to normal mode, where previous elements should be removed.
@@ -27,42 +60,39 @@ var CandlestickView = ChartView.extend({
         data.diff(oldData)
             .add(function (newIdx) {
                 if (data.hasValue(newIdx)) {
-                    var symbolEl = isLargeRender
-                        ? createLargeBox(data, largePoints, newIdx)
-                        : createNormalBox(data, newIdx, true);
-                    data.setItemGraphicEl(newIdx, symbolEl);
-                    group.add(symbolEl);
+                    var el;
+
+                    var itemLayout = data.getItemLayout(newIdx);
+                    el = createNormalBox(itemLayout, newIdx, true);
+                    graphic.initProps(el, {shape: {points: itemLayout.ends}}, seriesModel, newIdx);
+
+                    setBoxCommon(el, data, newIdx, isSimpleBox);
+
+                    group.add(el);
+                    data.setItemGraphicEl(newIdx, el);
                 }
             })
             .update(function (newIdx, oldIdx) {
-                var symbolEl = oldData.getItemGraphicEl(oldIdx);
+                var el = oldData.getItemGraphicEl(oldIdx);
 
                 // Empty data
                 if (!data.hasValue(newIdx)) {
-                    group.remove(symbolEl);
+                    group.remove(el);
                     return;
                 }
 
-                if (symbolEl && symbolEl.__largeWhiskerBox ^ isLargeRender) {
-                    group.remove(symbolEl);
-                    symbolEl = null;
-                }
-
-                if (!symbolEl) {
-                    symbolEl = isLargeRender
-                        ? createLargeBox(data, largePoints, newIdx)
-                        : createNormalBox(data, newIdx);
+                var itemLayout = data.getItemLayout(newIdx);
+                if (!el) {
+                    el = createNormalBox(itemLayout, newIdx);
                 }
                 else {
-                    isLargeRender
-                        ? updateLargeBoxData(symbolEl, data, newIdx)
-                        : updateNormalBoxData(symbolEl, data, newIdx);
+                    graphic.updateProps(el, {shape: {points: itemLayout.ends}}, seriesModel, newIdx);
                 }
 
-                // Add back
-                group.add(symbolEl);
+                setBoxCommon(el, data, newIdx, isSimpleBox);
 
-                data.setItemGraphicEl(newIdx, symbolEl);
+                group.add(el);
+                data.setItemGraphicEl(newIdx, el);
             })
             .remove(function (oldIdx) {
                 var el = oldData.getItemGraphicEl(oldIdx);
@@ -73,26 +103,34 @@ var CandlestickView = ChartView.extend({
         this._data = data;
     },
 
-    incrementalPrepareRender: function (seriesModel, ecModel, api) {
-        this.group.removeAll();
-        this._data = null;
+    _renderLarge: function (seriesModel) {
+        var group = this.group;
+
+        group.removeAll();
+
+        createLarge(seriesModel, group);
     },
 
-    incrementalRender: function (params, seriesModel, ecModel, api) {
+    _incrementalRenderNormal: function (params, seriesModel) {
         var data = seriesModel.getData();
-        var pipelineContext = seriesModel.pipelineContext;
-        var isLargeRender = pipelineContext.large;
-        var largePoints = isLargeRender && data.getLayout('largePoints');
-
-        for (var idx = params.start; idx < params.end; idx++) {
-            var symbolEl = isLargeRender
-                ? createLargeBox(data, largePoints, idx, params.start)
-                : createNormalBox(data, idx, this.styleUpdater, true);
-            symbolEl.incremental = true;
-            this.group.add(symbolEl);
+        var isSimpleBox = data.getLayout('isSimpleBox');
+
+        for (var dataIndex = params.start; dataIndex < params.end; dataIndex++) {
+            var el;
+
+            var itemLayout = data.getItemLayout(dataIndex);
+            el = createNormalBox(itemLayout, dataIndex);
+            setBoxCommon(el, data, dataIndex, isSimpleBox);
+
+            el.incremental = true;
+            this.group.add(el);
         }
     },
 
+    _incrementalRenderLarge: function (params, seriesModel) {
+        createLarge(seriesModel, this.group, true);
+    },
+
     remove: function (ecModel) {
         var group = this.group;
         var data = this._data;
@@ -100,45 +138,44 @@ var CandlestickView = ChartView.extend({
         data && data.eachItemGraphicEl(function (el) {
             el && group.remove(el);
         });
-    }
-
-});
-
-
+    },
 
+    dispose: zrUtil.noop
 
+});
 
-// ---------------------
-// -- Normal Renderer --
-// ---------------------
 
 var NormalBoxPath = Path.extend({
 
-    type: 'candlestickBox',
+    type: 'normalCandlestickBox',
 
     shape: {},
 
     buildPath: function (ctx, shape) {
         var ends = shape.points;
 
-        ctx.moveTo(ends[0][0], ends[0][1]);
-        ctx.lineTo(ends[1][0], ends[1][1]);
-        ctx.lineTo(ends[2][0], ends[2][1]);
-        ctx.lineTo(ends[3][0], ends[3][1]);
-        ctx.closePath();
-
-        ctx.moveTo(ends[4][0], ends[4][1]);
-        ctx.lineTo(ends[5][0], ends[5][1]);
-        ctx.moveTo(ends[6][0], ends[6][1]);
-        ctx.lineTo(ends[7][0], ends[7][1]);
+        if (this.__simpleBox) {
+            ctx.moveTo(ends[4][0], ends[4][1]);
+            ctx.lineTo(ends[6][0], ends[6][1]);
+        }
+        else {
+            ctx.moveTo(ends[0][0], ends[0][1]);
+            ctx.lineTo(ends[1][0], ends[1][1]);
+            ctx.lineTo(ends[2][0], ends[2][1]);
+            ctx.lineTo(ends[3][0], ends[3][1]);
+            ctx.closePath();
+
+            ctx.moveTo(ends[4][0], ends[4][1]);
+            ctx.lineTo(ends[5][0], ends[5][1]);
+            ctx.moveTo(ends[6][0], ends[6][1]);
+            ctx.lineTo(ends[7][0], ends[7][1]);
+        }
     }
 });
 
-function createNormalBox(data, dataIndex, isInit) {
-    var itemLayout = data.getItemLayout(dataIndex);
+function createNormalBox(itemLayout, dataIndex, isInit) {
     var ends = itemLayout.ends;
-
-    var el = new NormalBoxPath({
+    return new NormalBoxPath({
         shape: {
             points: isInit
                 ? transInit(ends, itemLayout)
@@ -146,24 +183,9 @@ function createNormalBox(data, dataIndex, isInit) {
         },
         z2: 100
     });
-
-    updateNormalBoxData(el, data, dataIndex, isInit);
-
-    return el;
 }
 
-function updateNormalBoxData(el, data, dataIndex, isInit) {
-    var seriesModel = data.hostModel;
-    var itemLayout = data.getItemLayout(dataIndex);
-    var updateMethod = graphic[isInit ? 'initProps' : 'updateProps'];
-
-    updateMethod(
-        el,
-        {shape: {points: itemLayout.ends}},
-        seriesModel,
-        dataIndex
-    );
-
+function setBoxCommon(el, data, dataIndex, isSimpleBox) {
     var itemModel = data.getItemModel(dataIndex);
     var normalItemStyleModel = itemModel.getModel(NORMAL_ITEM_STYLE_PATH);
     var color = data.getItemVisual(dataIndex, 'color');
@@ -171,15 +193,15 @@ function updateNormalBoxData(el, data, dataIndex, isInit) {
 
     // Color must be excluded.
     // Because symbol provide setColor individually to set fill and stroke
-    var itemStyle = normalItemStyleModel.getItemStyle(
-        ['color', 'color0', 'borderColor', 'borderColor0']
-    );
+    var itemStyle = normalItemStyleModel.getItemStyle(SKIP_PROPS);
 
     el.useStyle(itemStyle);
     el.style.strokeNoScale = true;
     el.style.fill = color;
     el.style.stroke = borderColor;
 
+    el.__simpleBox = isSimpleBox;
+
     var hoverStyle = itemModel.getModel(EMPHASIS_ITEM_STYLE_PATH).getItemStyle();
     graphic.setHoverStyle(el, hoverStyle);
 }
@@ -194,70 +216,72 @@ function transInit(points, itemLayout) {
 
 
 
+var LargeBoxPath = Path.extend({
 
+    type: 'largeCandlestickBox',
 
+    shape: {},
 
-// --------------------
-// -- Large Renderer --
-// --------------------
+    buildPath: function (ctx, shape) {
+        // Drawing lines is more efficient than drawing
+        // a whole line or drawing rects.
+        var points = shape.points;
+        for (var i = 0; i < points.length;) {
+            if (this.__sign === points[i++]) {
+                var x = points[i++];
+                ctx.moveTo(x, points[i++]);
+                ctx.lineTo(x, points[i++]);
+            }
+            else {
+                i += 3;
+            }
+        }
+    }
+});
 
-var NORMAL_STYLE_ACCESS_PATH = ['itemStyle'];
-var EMPHASIS_STYLE_ACCESS_PATH = ['emphasis', 'itemStyle'];
+function createLarge(seriesModel, group, incremental) {
+    var data = seriesModel.getData();
+    var largePoints = data.getLayout('largePoints');
 
-function createLargeBox(data, largePoints, dataIndex, segmentStart) {
-    var boxEl = new graphic.Line({
-        shape: largeBoxMakeShape(largePoints, dataIndex, segmentStart)
+    var elP = new LargeBoxPath({
+        shape: {points: largePoints},
+        __sign: 1
     });
+    group.add(elP);
+    var elN = new LargeBoxPath({
+        shape: {points: largePoints},
+        __sign: -1
+    });
+    group.add(elN);
 
-    boxEl.__largeWhiskerBox = true;
-
-    largeBoxSetStyle(boxEl, data, dataIndex);
-
-    return boxEl;
-}
+    setLargeStyle(1, elP, seriesModel, data);
+    setLargeStyle(-1, elN, seriesModel, data);
 
-function largeBoxMakeShape(largePoints, dataIndex, segmentStart) {
-    var baseIdx = (dataIndex - (segmentStart || 0)) * 5;
-    return {
-        x1: largePoints[baseIdx + 1],
-        y1: largePoints[baseIdx + 2],
-        x2: largePoints[baseIdx + 3],
-        y2: largePoints[baseIdx + 4]
-    };
+    if (incremental) {
+        elP.incremental = true;
+        elN.incremental = true;
+    }
 }
 
-function updateLargeBoxData(boxEl, data, dataIndex) {
-    graphic.updateProps(
-        boxEl,
-        {shape: largeBoxMakeShape(data.getLayout('largePoints'), dataIndex, 0)},
-        data.hostModel,
-        dataIndex
-    );
+function setLargeStyle(sign, el, seriesModel, data) {
+    var normalItemStyleModel = seriesModel.getModel(NORMAL_ITEM_STYLE_PATH);
+    var suffix = sign > 0 ? 'P' : 'N';
 
-    largeBoxSetStyle(boxEl, data, dataIndex);
-}
-
-function largeBoxSetStyle(boxEl, data, dataIndex) {
-    var itemModel = data.getItemModel(dataIndex);
-    var normalItemStyleModel = itemModel.getModel(NORMAL_STYLE_ACCESS_PATH);
-    var color = data.getItemVisual(dataIndex, 'color');
-    var borderColor = data.getItemVisual(dataIndex, 'borderColor') || color;
+    var color = data.getVisual('color' + suffix);
+    var borderColor = data.getVisual('borderColor' + suffix) || color;
 
     // Color must be excluded.
     // Because symbol provide setColor individually to set fill and stroke
-    var itemStyle = normalItemStyleModel.getItemStyle(
-        ['color', 'color0', 'borderColor', 'borderColor0']
-    );
+    var itemStyle = normalItemStyleModel.getItemStyle(SKIP_PROPS);
 
-    boxEl.useStyle(itemStyle);
-    boxEl.style.stroke = borderColor;
-
-    var hoverStyle = itemModel.getModel(EMPHASIS_STYLE_ACCESS_PATH).getItemStyle();
-    graphic.setHoverStyle(boxEl, hoverStyle);
+    el.useStyle(itemStyle);
+    el.style.fill = null;
+    el.style.stroke = borderColor;
+    // No different
+    // el.style.lineWidth = .5;
 }
 
 
 
-
 export default CandlestickView;
 
diff --git a/src/chart/candlestick/candlestickLayout.js b/src/chart/candlestick/candlestickLayout.js
index 6fa8fda..3aa8d5c 100644
--- a/src/chart/candlestick/candlestickLayout.js
+++ b/src/chart/candlestick/candlestickLayout.js
@@ -1,6 +1,7 @@
 import {subPixelOptimize} from '../../util/graphic';
 import createRenderPlanner from '../helper/createRenderPlanner';
-import {calculateCandleWidth} from './helper';
+import {parsePercent} from '../../util/number';
+import {retrieve2} from 'zrender/src/core/util';
 
 var LargeArr = typeof Float32Array !== 'undefined' ? Float32Array : Array;
 
@@ -12,9 +13,6 @@ export default {
 
     reset: function (seriesModel) {
 
-        var pipelineContext = seriesModel.pipelineContext;
-        var isLargeRender = pipelineContext.large;
-
         var coordSys = seriesModel.coordinateSystem;
         var data = seriesModel.getData();
         var candleWidth = calculateCandleWidth(seriesModel, data);
@@ -28,12 +26,20 @@ export default {
         var lowestDim = vDims[2];
         var highestDim = vDims[3];
 
+        data.setLayout({
+            candleWidth: candleWidth,
+            // The value is experimented visually.
+            isSimpleBox: candleWidth <= 1.3
+        });
+
         if (cDim == null || vDims.length < 4) {
             return;
         }
 
-        return {progress: isLargeRender ? largeProgress : normalProgress};
-
+        return {
+            progress: seriesModel.pipelineContext.large
+                ? largeProgress : normalProgress
+        };
 
         function normalProgress(params, data) {
 
@@ -121,7 +127,7 @@ export default {
 
         function largeProgress(params, data) {
             var segCount = params.end - params.start;
-            // Structure: [sign, x1, y1, x2, y2, sign, x1, y1, x2, y2, ...]
+            // Structure: [sign, x, yhigh, ylow, sign, x, yhigh, ylow, ...]
             var points = new LargeArr(segCount * 5);
 
             for (
@@ -149,15 +155,12 @@ export default {
                 point = coordSys.dataToPoint(tmpIn, null, tmpOut);
                 points[offset++] = point ? point[0] : NaN;
                 points[offset++] = point ? point[1] : NaN;
-
                 tmpIn[vDimIdx] = highestVal;
                 point = coordSys.dataToPoint(tmpIn, null, tmpOut);
-                points[offset++] = point ? point[0] : NaN;
                 points[offset++] = point ? point[1] : NaN;
             }
 
             data.setLayout('largePoints', points);
-            data.setLayout('candleWidth', candleWidth);
         }
     }
 };
@@ -180,3 +183,30 @@ function getSign(data, dataIndex, openVal, closeVal, closeDim) {
 
     return sign;
 }
+
+function calculateCandleWidth(seriesModel, data) {
+    var baseAxis = seriesModel.getBaseAxis();
+    var extent;
+
+    var bandWidth = baseAxis.type === 'category'
+        ? baseAxis.getBandWidth()
+        : (
+            extent = baseAxis.getExtent(),
+            Math.abs(extent[1] - extent[0]) / data.count()
+        );
+
+    var barMaxWidth = parsePercent(
+        retrieve2(seriesModel.get('barMaxWidth'), bandWidth),
+        bandWidth
+    );
+    var barMinWidth = parsePercent(
+        retrieve2(seriesModel.get('barMinWidth'), 1),
+        bandWidth
+    );
+    var barWidth = seriesModel.get('barWidth');
+
+    return barWidth != null
+        ? parsePercent(barWidth, bandWidth)
+        // Put max outer to ensure bar visible in spite of overlap.
+        : Math.max(Math.min(bandWidth / 2, barMaxWidth), barMinWidth);
+}
diff --git a/src/chart/candlestick/candlestickVisual.js b/src/chart/candlestick/candlestickVisual.js
index ad94894..9273480 100644
--- a/src/chart/candlestick/candlestickVisual.js
+++ b/src/chart/candlestick/candlestickVisual.js
@@ -17,9 +17,7 @@ export default {
     reset: function (seriesModel, ecModel) {
 
         var data = seriesModel.getData();
-        var pipelineContext = seriesModel.pipelineContext;
-        var isLargeRender = pipelineContext.large;
-        var largePoints = isLargeRender && data.getLayout('largePoints');
+        var isLargeRender = seriesModel.pipelineContext.large;
 
         data.setVisual({
             legendSymbol: 'roundRect',
@@ -34,12 +32,13 @@ export default {
             return;
         }
 
+        return !isLargeRender && {progress: progress};
+
+
         function progress(params, data) {
             for (var dataIndex = params.start; dataIndex < params.end; dataIndex++) {
                 var itemModel = data.getItemModel(dataIndex);
-                var sign = isLargeRender
-                    ? largePoints[(dataIndex - params.start) * 5]
-                    : data.getItemLayout(dataIndex).sign;
+                var sign = data.getItemLayout(dataIndex).sign;
 
                 data.setItemVisual(
                     dataIndex,
@@ -63,7 +62,6 @@ export default {
             );
         }
 
-        return {progress: progress};
     }
 
 };
\ No newline at end of file
diff --git a/src/chart/candlestick/helper.js b/src/chart/candlestick/helper.js
deleted file mode 100644
index a0b778e..0000000
--- a/src/chart/candlestick/helper.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import {parsePercent} from '../../util/number';
-import {retrieve2} from 'zrender/src/core/util';
-
-export function calculateCandleWidth(seriesModel, data) {
-    var baseAxis = seriesModel.getBaseAxis();
-    var extent;
-
-    var bandWidth = baseAxis.type === 'category'
-        ? baseAxis.getBandWidth()
-        : (
-            extent = baseAxis.getExtent(),
-            Math.abs(extent[1] - extent[0]) / data.count()
-        );
-
-    var barMaxWidth = parsePercent(
-        retrieve2(seriesModel.get('barMaxWidth'), bandWidth),
-        bandWidth
-    );
-    var barMinWidth = parsePercent(
-        retrieve2(seriesModel.get('barMinWidth'), 1),
-        bandWidth
-    );
-    var barWidth = seriesModel.get('barWidth');
-    return barWidth != null
-        ? parsePercent(barWidth, bandWidth)
-        // Put max outer to ensure bar visible in spite of overlap.
-        : Math.max(Math.min(bandWidth / 2, barMaxWidth), barMinWidth);
-}
diff --git a/test/candlestick-large.html b/test/candlestick-large.html
index e5b797c..e6665f3 100644
--- a/test/candlestick-large.html
+++ b/test/candlestick-large.html
@@ -183,22 +183,28 @@
                         {
                             type: 'inside',
                             // xAxisIndex: [0, 1],
-                            // start: 10,
+                            // start: 99,
                             // end: 100
+                            // startValue: '2010-08-17',
+                            // endValue: '2012-08-06'
                         },
                         {
                             show: true,
                             // xAxisIndex: [0, 1],
                             type: 'slider',
                             bottom: 10,
-                            // start: 10,
+                            // start: 99,
                             // end: 100
+                            // startValue: '2010-08-17',
+                            // endValue: '2012-08-06'
                         }
                     ],
+                    animation: false,
                     series: [
                         {
                             name: 'Dow-Jones index',
                             type: 'candlestick',
+                            // large: false,
                             encode: {
                                 x: 0,
                                 y: [1, 2, 3, 4]
@@ -271,7 +277,7 @@
 
                 var panel = document.getElementById('panel0');
                 var chart = testHelper.create(echarts, 'main0', {
-                    title: 'Use dataset',
+                    title: 'Use dataset. Check item tooltip in large mode.',
                     option: option,
                     height: 550
                 });
diff --git a/test/candlestick-large.html b/test/candlestick-large2.html
similarity index 68%
copy from test/candlestick-large.html
copy to test/candlestick-large2.html
index e5b797c..ec99971 100644
--- a/test/candlestick-large.html
+++ b/test/candlestick-large2.html
@@ -3,7 +3,7 @@
     <head>
         <meta charset="utf-8">
         <meta name="viewport" content="width=device-width, initial-scale=1" />
-        <script src="lib/esl.js"></script>
+        <script src="../dist/echarts.js"></script>
         <script src="lib/config.js"></script>
         <script src="lib/jquery.min.js"></script>
         <script src="lib/facePrint.js"></script>
@@ -28,81 +28,106 @@
 
         <script>
 
-            /**
-             * @see <https://en.wikipedia.org/wiki/Michelson%E2%80%93Morley_experiment>
-             * @see <http://bl.ocks.org/mbostock/4061502>
-             */
-            require([
-                'echarts',
-                'data/stock-DJI.json'
-            ], update)
-
-            function splitData(rawData) {
-                var categoryData = [];
-                var values = [];
-                var volumns = [];
-                for (var i = 0; i < rawData.length; i++) {
-                    categoryData.push(rawData[i].splice(0, 1)[0]);
-                    values.push(rawData[i])
-                    volumns.push(rawData[i][4]);
+            // The data count is from a real requirement.
+            var rawDataCount = 2e5;
+            var progressive = 4e3;
+
+            function run() {
+                var data = generateOHLC(rawDataCount);
+                var result = reorder(data);
+                init(result.data, result.categoryData);
+            }
+
+            function generateOHLC(count) {
+                var data = [];
+
+                var xValue = +new Date(2011, 0, 1);
+                var minute = 60 * 1000;
+                var baseValue = Math.random() * 12000;
+                var tmpVals = new Array(4);
+                var dayRange = 12;
+
+                for (var i = 0; i < count; i++) {
+                    baseValue = baseValue + Math.random() * 20 - 10;
+
+                    for (var j = 0; j < 4; j++) {
+                        tmpVals[j] = (Math.random() - 0.5) * dayRange + baseValue;
+                    }
+                    tmpVals.sort();
+
+                    var idxRandom = Math.random();
+                    var openIdx = Math.round(Math.random() * 3);
+                    var closeIdx = Math.round(Math.random() * 2);
+                    if (closeIdx === openIdx) {
+                        closeIdx++;
+                    }
+
+                    // ['open', 'close', 'lowest', 'highest']
+                    // [1, 4, 3, 2]
+                    data.push([
+                        echarts.format.formatTime('yyyy-MM-dd hh:mm:ss', xValue += minute),
+                        +tmpVals[openIdx].toFixed(2), // open
+                        +tmpVals[3].toFixed(2), // highest
+                        +tmpVals[0].toFixed(2), // lowest
+                        +tmpVals[closeIdx].toFixed(2)  // close
+                    ]);
                 }
-                return {
-                    categoryData: categoryData,
-                    values: values,
-                    volumns: volumns
-                };
+
+                return data;
             }
 
-            function calculateMA(dayCount, rawData) {
+            function reorder(data) {
+                var categoryData = new Array(data.length);
+                var categoryMap = {};
+                for (var i = 0; i < data.length; i++) {
+                    categoryData[i] = data[i][0];
+                    categoryMap[categoryData[i]] = i;
+                }
+
+                var newData = new Array(data.length);
+                var step = Math.round(data.length / progressive);
+                var newOffset = 0;
+                for (var offset = 0; offset < step; offset++) {
+                    for (var i = offset; i < data.length; i += step) {
+                        var item = data[i].slice();
+                        newData[newOffset++] = item;
+                        item[0] = categoryMap[item[0]];
+                    }
+                }
+                return {data: newData, categoryData: categoryData};
+            }
+
+            function calculateMA(dayCount, data) {
                 var result = [];
-                for (var i = 0, len = rawData.length; i < len; i++) {
+                for (var i = 0, len = data.length; i < len; i++) {
                     if (i < dayCount) {
                         result.push('-');
                         continue;
                     }
                     var sum = 0;
                     for (var j = 0; j < dayCount; j++) {
-                        sum += rawData[i - j][2];
+                        sum += data[i - j][2];
                     }
                     result.push(+(sum / dayCount).toFixed(3));
                 }
                 return result;
             }
 
-            function update(echarts, rawData) {
-
-                // var data = splitData(rawData);
+            function init(rawData, categoryData) {
 
                 var option = {
                     dataset: {
                         source: rawData
                     },
                     backgroundColor: '#eee',
+                    // animation: false,
                     legend: {
-                        left: 0,
+                        left: 0
                     },
                     tooltip: {
                         trigger: 'axis',
                         axisPointer: {
-                            type: 'cross'
-                        },
-                        backgroundColor: 'rgba(245, 245, 245, 0.8)',
-                        borderWidth: 1,
-                        borderColor: '#ccc',
-                        padding: 10,
-                        textStyle: {
-                            color: '#000'
-                        },
-                        position: function (pos, params, el, elRect, size) {
-                            var obj = {top: 10};
-                            obj[['left', 'right'][+(pos[0] < size.viewSize[0] / 2)]] = 30;
-                            return obj;
-                        }
-                    },
-                    axisPointer: {
-                        link: {xAxisIndex: 'all'},
-                        label: {
-                            backgroundColor: '#777'
+                            type: 'line'
                         }
                     },
                     toolbox: {
@@ -115,13 +140,13 @@
                             }
                         }
                     },
-                    brush: {
-                        xAxisIndex: 'all',
-                        brushLink: 'all',
-                        outOfBrush: {
-                            colorAlpha: 0.1
-                        }
-                    },
+                    // brush: {
+                    //     xAxisIndex: 'all',
+                    //     brushLink: 'all',
+                    //     outOfBrush: {
+                    //         colorAlpha: 0.1
+                    //     }
+                    // },
                     grid: [
                         {
                             left: '10%',
@@ -138,14 +163,14 @@
                     xAxis: [
                         {
                             type: 'category',
-                            // data: data.categoryData,
                             scale: true,
                             boundaryGap : false,
                             axisLine: {onZero: false},
                             splitLine: {show: false},
                             splitNumber: 20,
                             min: 'dataMin',
-                            max: 'dataMax'
+                            max: 'dataMax',
+                            data: categoryData
                         },
                         // {
                         //     type: 'category',
@@ -183,32 +208,28 @@
                         {
                             type: 'inside',
                             // xAxisIndex: [0, 1],
-                            // start: 10,
-                            // end: 100
+                            start: 10,
+                            end: 100
                         },
                         {
                             show: true,
                             // xAxisIndex: [0, 1],
                             type: 'slider',
                             bottom: 10,
-                            // start: 10,
-                            // end: 100
+                            start: 10,
+                            end: 100
                         }
                     ],
                     series: [
                         {
-                            name: 'Dow-Jones index',
+                            name: 'Fake index',
                             type: 'candlestick',
+                            // data: data,
                             encode: {
                                 x: 0,
-                                y: [1, 2, 3, 4]
-                            },
-                            itemStyle: {
-                                normal: {
-                                    borderColor: null,
-                                    borderColor0: null
-                                }
+                                y: [1, 4, 3, 2]
                             },
+                            progressive: progressive
                             // tooltip: {
                             //     formatter: function (param) {
                             //         var param = param[0];
@@ -221,12 +242,11 @@
                             //         ].join('')
                             //     }
                             // }
-                        },
+                        } //,
                         // {
                         //     name: 'MA5',
                         //     type: 'line',
-                        //     sampling: 'max',
-                        //     data: calculateMA(5, rawData),
+                        //     data: calculateMA(5, data),
                         //     smooth: true,
                         //     lineStyle: {
                         //         normal: {opacity: 0.5}
@@ -235,7 +255,7 @@
                         // {
                         //     name: 'MA10',
                         //     type: 'line',
-                        //     data: calculateMA(10, rawData),
+                        //     data: calculateMA(10, data),
                         //     smooth: true,
                         //     lineStyle: {
                         //         normal: {opacity: 0.5}
@@ -244,7 +264,7 @@
                         // {
                         //     name: 'MA20',
                         //     type: 'line',
-                        //     data: calculateMA(20, rawData),
+                        //     data: calculateMA(20, data),
                         //     smooth: true,
                         //     lineStyle: {
                         //         normal: {opacity: 0.5}
@@ -253,7 +273,7 @@
                         // {
                         //     name: 'MA30',
                         //     type: 'line',
-                        //     data: calculateMA(30, rawData),
+                        //     data: calculateMA(30, data),
                         //     smooth: true,
                         //     lineStyle: {
                         //         normal: {opacity: 0.5}
@@ -271,7 +291,7 @@
 
                 var panel = document.getElementById('panel0');
                 var chart = testHelper.create(echarts, 'main0', {
-                    title: 'Use dataset',
+                    title: 'Fake OHLC data',
                     option: option,
                     height: 550
                 });
@@ -312,8 +332,11 @@
                 //         }
                 //     ]
                 // });
+
             }
 
+            run();
+
         </script>
 
 
diff --git a/test/candlestick-large.html b/test/candlestick-large3.html
similarity index 73%
copy from test/candlestick-large.html
copy to test/candlestick-large3.html
index e5b797c..9d3f579 100644
--- a/test/candlestick-large.html
+++ b/test/candlestick-large3.html
@@ -3,11 +3,12 @@
     <head>
         <meta charset="utf-8">
         <meta name="viewport" content="width=device-width, initial-scale=1" />
-        <script src="lib/esl.js"></script>
+        <script src="../dist/echarts.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="lib/frameInsight.js"></script>
         <link rel="stylesheet" href="lib/reset.css" />
     </head>
     <body>
@@ -21,6 +22,7 @@
 
         <div id="main0"></div>
         <div id="panel0"></div>
+        <div id="duration"></div>
 
 
 
@@ -28,81 +30,86 @@
 
         <script>
 
-            /**
-             * @see <https://en.wikipedia.org/wiki/Michelson%E2%80%93Morley_experiment>
-             * @see <http://bl.ocks.org/mbostock/4061502>
-             */
-            require([
-                'echarts',
-                'data/stock-DJI.json'
-            ], update)
-
-            function splitData(rawData) {
-                var categoryData = [];
-                var values = [];
-                var volumns = [];
-                for (var i = 0; i < rawData.length; i++) {
-                    categoryData.push(rawData[i].splice(0, 1)[0]);
-                    values.push(rawData[i])
-                    volumns.push(rawData[i][4]);
+            // The data count is from a real requirement.
+            var rawDataCount = 2e5;
+
+            function run() {
+                var data = generateOHLC(rawDataCount);
+                // var result = reorder(data);
+                init(data);
+            }
+
+            function generateOHLC(count) {
+                var data = [];
+
+                var xValue = +new Date(2011, 0, 1);
+                var minute = 60 * 1000;
+                var baseValue = Math.random() * 12000;
+                var tmpVals = new Array(4);
+                var dayRange = 12;
+
+                for (var i = 0; i < count; i++) {
+                    baseValue = baseValue + Math.random() * 20 - 10;
+
+                    for (var j = 0; j < 4; j++) {
+                        tmpVals[j] = (Math.random() - 0.5) * dayRange + baseValue;
+                    }
+                    tmpVals.sort();
+
+                    var idxRandom = Math.random();
+                    var openIdx = Math.round(Math.random() * 3);
+                    var closeIdx = Math.round(Math.random() * 2);
+                    if (closeIdx === openIdx) {
+                        closeIdx++;
+                    }
+
+                    // ['open', 'close', 'lowest', 'highest']
+                    // [1, 4, 3, 2]
+                    data.push([
+                        echarts.format.formatTime('yyyy-MM-dd hh:mm:ss', xValue += minute),
+                        +tmpVals[openIdx].toFixed(2), // open
+                        +tmpVals[3].toFixed(2), // highest
+                        +tmpVals[0].toFixed(2), // lowest
+                        +tmpVals[closeIdx].toFixed(2)  // close
+                    ]);
                 }
-                return {
-                    categoryData: categoryData,
-                    values: values,
-                    volumns: volumns
-                };
+
+                return data;
             }
 
-            function calculateMA(dayCount, rawData) {
+            function calculateMA(dayCount, data) {
                 var result = [];
-                for (var i = 0, len = rawData.length; i < len; i++) {
+                for (var i = 0, len = data.length; i < len; i++) {
                     if (i < dayCount) {
                         result.push('-');
                         continue;
                     }
                     var sum = 0;
                     for (var j = 0; j < dayCount; j++) {
-                        sum += rawData[i - j][2];
+                        sum += data[i - j][2];
                     }
                     result.push(+(sum / dayCount).toFixed(3));
                 }
                 return result;
             }
 
-            function update(echarts, rawData) {
+            function init(rawData) {
 
-                // var data = splitData(rawData);
+                frameInsight.init(echarts, 'duration');
 
                 var option = {
                     dataset: {
                         source: rawData
                     },
                     backgroundColor: '#eee',
+                    // animation: false,
                     legend: {
-                        left: 0,
+                        left: 0
                     },
                     tooltip: {
                         trigger: 'axis',
                         axisPointer: {
-                            type: 'cross'
-                        },
-                        backgroundColor: 'rgba(245, 245, 245, 0.8)',
-                        borderWidth: 1,
-                        borderColor: '#ccc',
-                        padding: 10,
-                        textStyle: {
-                            color: '#000'
-                        },
-                        position: function (pos, params, el, elRect, size) {
-                            var obj = {top: 10};
-                            obj[['left', 'right'][+(pos[0] < size.viewSize[0] / 2)]] = 30;
-                            return obj;
-                        }
-                    },
-                    axisPointer: {
-                        link: {xAxisIndex: 'all'},
-                        label: {
-                            backgroundColor: '#777'
+                            type: 'line'
                         }
                     },
                     toolbox: {
@@ -115,13 +122,13 @@
                             }
                         }
                     },
-                    brush: {
-                        xAxisIndex: 'all',
-                        brushLink: 'all',
-                        outOfBrush: {
-                            colorAlpha: 0.1
-                        }
-                    },
+                    // brush: {
+                    //     xAxisIndex: 'all',
+                    //     brushLink: 'all',
+                    //     outOfBrush: {
+                    //         colorAlpha: 0.1
+                    //     }
+                    // },
                     grid: [
                         {
                             left: '10%',
@@ -138,7 +145,6 @@
                     xAxis: [
                         {
                             type: 'category',
-                            // data: data.categoryData,
                             scale: true,
                             boundaryGap : false,
                             axisLine: {onZero: false},
@@ -183,32 +189,29 @@
                         {
                             type: 'inside',
                             // xAxisIndex: [0, 1],
-                            // start: 10,
-                            // end: 100
+                            start: 10,
+                            end: 100
                         },
                         {
                             show: true,
                             // xAxisIndex: [0, 1],
                             type: 'slider',
                             bottom: 10,
-                            // start: 10,
-                            // end: 100
+                            start: 10,
+                            end: 100
                         }
                     ],
                     series: [
                         {
-                            name: 'Dow-Jones index',
+                            name: 'Fake index',
                             type: 'candlestick',
+                            // data: data,
                             encode: {
                                 x: 0,
-                                y: [1, 2, 3, 4]
-                            },
-                            itemStyle: {
-                                normal: {
-                                    borderColor: null,
-                                    borderColor0: null
-                                }
+                                y: [1, 4, 3, 2]
                             },
+                            // progressive: false
+                            // progressive: progressive
                             // tooltip: {
                             //     formatter: function (param) {
                             //         var param = param[0];
@@ -221,12 +224,11 @@
                             //         ].join('')
                             //     }
                             // }
-                        },
+                        } //,
                         // {
                         //     name: 'MA5',
                         //     type: 'line',
-                        //     sampling: 'max',
-                        //     data: calculateMA(5, rawData),
+                        //     data: calculateMA(5, data),
                         //     smooth: true,
                         //     lineStyle: {
                         //         normal: {opacity: 0.5}
@@ -235,7 +237,7 @@
                         // {
                         //     name: 'MA10',
                         //     type: 'line',
-                        //     data: calculateMA(10, rawData),
+                        //     data: calculateMA(10, data),
                         //     smooth: true,
                         //     lineStyle: {
                         //         normal: {opacity: 0.5}
@@ -244,7 +246,7 @@
                         // {
                         //     name: 'MA20',
                         //     type: 'line',
-                        //     data: calculateMA(20, rawData),
+                        //     data: calculateMA(20, data),
                         //     smooth: true,
                         //     lineStyle: {
                         //         normal: {opacity: 0.5}
@@ -253,7 +255,7 @@
                         // {
                         //     name: 'MA30',
                         //     type: 'line',
-                        //     data: calculateMA(30, rawData),
+                        //     data: calculateMA(30, data),
                         //     smooth: true,
                         //     lineStyle: {
                         //         normal: {opacity: 0.5}
@@ -271,7 +273,7 @@
 
                 var panel = document.getElementById('panel0');
                 var chart = testHelper.create(echarts, 'main0', {
-                    title: 'Use dataset',
+                    title: 'Fake OHLC data',
                     option: option,
                     height: 550
                 });
@@ -312,8 +314,11 @@
                 //         }
                 //     ]
                 // });
+
             }
 
+            run();
+
         </script>
 
 
diff --git a/test/lib/frameInsight.js b/test/lib/frameInsight.js
index b19c6f3..1a397e9 100644
--- a/test/lib/frameInsight.js
+++ b/test/lib/frameInsight.js
@@ -139,9 +139,9 @@
         var domStyle = dom.style;
         // domStyle.border = '2px solid #333';
         domStyle.boxShadow = '0 0 3px #000';
-        domStyle.backgroundColor = '#fff';
+        domStyle.backgroundColor = '#eee';
         domStyle.padding = '0';
-        domStyle.height = '80px';
+        domStyle.height = '60px';
         domStyle.margin = '10px 20px';
 
         var domWidth = getSize(dom, 0);

-- 
To stop receiving notification emails like this one, please contact
sushuang@apache.org.

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


[incubator-echarts] 01/09: Fix lines update layout in not large but incremental mode.

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit eaa6b44eaba6350e94813c3cb96e15f1966227d4
Author: sushuang <su...@gmail.com>
AuthorDate: Mon Apr 2 12:35:32 2018 +0800

    Fix lines update layout in not large but incremental mode.
---
 src/chart/helper/LargeLineDraw.js       |   1 +
 src/chart/helper/LineDraw.js            |   6 ++
 src/chart/helper/createRenderPlanner.js |   4 +-
 src/chart/lines/LinesView.js            |   3 +-
 src/stream/Scheduler.js                 |   8 +-
 src/view/Chart.js                       |   4 +-
 test/-cases.js                          |   1 +
 test/lines-stream-not-large.html        | 141 ++++++++++++++++++++++++++++++++
 8 files changed, 159 insertions(+), 9 deletions(-)

diff --git a/src/chart/helper/LargeLineDraw.js b/src/chart/helper/LargeLineDraw.js
index 6cc523c..1683435 100644
--- a/src/chart/helper/LargeLineDraw.js
+++ b/src/chart/helper/LargeLineDraw.js
@@ -163,6 +163,7 @@ largeLineProto.incrementalUpdate = function (taskParams, data) {
     lineEl.setShape({
         segs: data.getLayout('linesPoints')
     });
+
     this._setCommon(lineEl, data, !!this._incremental);
 
     if (!this._incremental) {
diff --git a/src/chart/helper/LineDraw.js b/src/chart/helper/LineDraw.js
index 4d40a3a..b1f1982 100644
--- a/src/chart/helper/LineDraw.js
+++ b/src/chart/helper/LineDraw.js
@@ -87,6 +87,12 @@ function doUpdate(lineDraw, oldLineData, newLineData, oldIdx, newIdx, seriesScop
 
 lineDrawProto.updateLayout = function () {
     var lineData = this._lineData;
+
+    // Do not support update layout in incremental mode.
+    if (!lineData) {
+        return;
+    }
+
     lineData.eachItemGraphicEl(function (el, idx) {
         el.updateLayout(lineData, idx);
     }, this);
diff --git a/src/chart/helper/createRenderPlanner.js b/src/chart/helper/createRenderPlanner.js
index d90cd46..eb8c057 100644
--- a/src/chart/helper/createRenderPlanner.js
+++ b/src/chart/helper/createRenderPlanner.js
@@ -11,10 +11,10 @@ export default function () {
         var pipelineContext = seriesModel.pipelineContext;
 
         var originalLarge = fields.large;
-        var originalProgressive = fields.canProgressiveRender;
+        var originalProgressive = fields.progressiveRender;
 
         var large = fields.large = pipelineContext.large;
-        var progressive = fields.canProgressiveRender = pipelineContext.canProgressiveRender;
+        var progressive = fields.progressiveRender = pipelineContext.progressiveRender;
 
         return !!((originalLarge ^ large) || (originalProgressive ^ progressive)) && 'reset';
     };
diff --git a/src/chart/lines/LinesView.js b/src/chart/lines/LinesView.js
index f4c4e3e..6f52713 100644
--- a/src/chart/lines/LinesView.js
+++ b/src/chart/lines/LinesView.js
@@ -82,8 +82,9 @@ export default echarts.extendChartView({
 
     updateTransform: function (seriesModel, ecModel, api) {
         var data = seriesModel.getData();
+        var pipelineContext = seriesModel.pipelineContext;
 
-        if (!this._finished || seriesModel.pipelineContext.large) {
+        if (!this._finished || pipelineContext.large || pipelineContext.progressiveRender) {
             // TODO Don't have to do update in large mode. Only do it when there are millions of data.
             return {
                 update: true
diff --git a/src/stream/Scheduler.js b/src/stream/Scheduler.js
index d7d833a..4dfcf80 100644
--- a/src/stream/Scheduler.js
+++ b/src/stream/Scheduler.js
@@ -90,7 +90,7 @@ proto.getPerformArgs = function (task, isBlock) {
     var pCtx = pipeline.context;
     var incremental = !isBlock
         && pipeline.progressiveEnabled
-        && (!pCtx || pCtx.canProgressiveRender)
+        && (!pCtx || pCtx.progressiveRender)
         && task.__idxInPipeline > pipeline.bockIndex;
 
     return {step: incremental ? pipeline.step : null};
@@ -112,19 +112,19 @@ proto.updateStreamModes = function (seriesModel, view) {
     var data = seriesModel.getData();
     var dataLen = data.count();
 
-    // `canProgressiveRender` means that can render progressively in each
+    // `progressiveRender` means that can render progressively in each
     // animation frame. Note that some types of series do not provide
     // `view.incrementalPrepareRender` but support `chart.appendData`. We
     // use the term `incremental` but not `progressive` to describe the
     // case that `chart.appendData`.
-    var canProgressiveRender = pipeline.progressiveEnabled
+    var progressiveRender = pipeline.progressiveEnabled
         && view.incrementalPrepareRender
         && dataLen >= pipeline.threshold;
 
     var large = seriesModel.get('large') && dataLen >= seriesModel.get('largeThreshold');
 
     seriesModel.pipelineContext = pipeline.context = {
-        canProgressiveRender: canProgressiveRender,
+        progressiveRender: progressiveRender,
         large: large
     };
 };
diff --git a/src/view/Chart.js b/src/view/Chart.js
index 9f03019..3aa6809 100644
--- a/src/view/Chart.js
+++ b/src/view/Chart.js
@@ -189,11 +189,11 @@ function renderTaskReset(context) {
     var api = context.api;
     var payload = context.payload;
     // ???! remove updateView updateVisual
-    var canProgressiveRender = seriesModel.pipelineContext.canProgressiveRender;
+    var progressiveRender = seriesModel.pipelineContext.progressiveRender;
     var view = context.view;
 
     var updateMethod = payload && inner(payload).updateMethod;
-    var methodName = canProgressiveRender
+    var methodName = progressiveRender
         ? 'incrementalPrepareRender'
         : (updateMethod && view[updateMethod])
         ? updateMethod
diff --git a/test/-cases.js b/test/-cases.js
index 202cef5..d0d2353 100644
--- a/test/-cases.js
+++ b/test/-cases.js
@@ -39,6 +39,7 @@
             'scatter-gps.html',
             'scatter-weibo.html',
             'lines-flight.html',
+            'lines-stream-not-large.html',
             'stream-filter.html',
             'scatter-stream-visual.html'
         ]
diff --git a/test/lines-stream-not-large.html b/test/lines-stream-not-large.html
new file mode 100644
index 0000000..c475437
--- /dev/null
+++ b/test/lines-stream-not-large.html
@@ -0,0 +1,141 @@
+<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/dat.gui.min.js"></script>
+        <meta name='viewport' content='width=device-width, initial-scale=1' />
+    </head>
+    <body>
+        <style>
+            html, body, #main {
+                width: 100%;
+                height: 100%;
+                margin: 0;
+            }
+            #info {
+                position: fixed;
+                left: 5;
+                top: 5;
+                height: 100px;
+                width: 200px;
+                background: #fff;
+                border: 2px solid #999;
+                z-index: 9999;
+            }
+        </style>
+        <div id="info">Rendering (large: false), please wait ...</div>
+        <div id='main'></div>
+        <script>
+
+        var xs = [440000, 450000];
+        var ys = [4368000, 4537000];
+
+        var dataURL = './data/flight.json';
+
+        require([
+            'echarts'
+
+            // 'echarts/chart/lines',
+            // 'echarts/component/legend',
+            // 'extension/bmap'
+        ], function (echarts) {
+
+            $.get('../map/json/world.json', function (worldJson) {
+                echarts.registerMap('world', worldJson);
+
+                $.get(dataURL, function (data) {
+                    var config = {
+                        dataLoading: 'whole',
+                        streamThreshold: 0,
+                        streamRender: true,
+                        largeModel: true
+                    };
+
+                    var chart;
+                    var infoEl = document.getElementById('info');
+
+                    init();
+
+                    function init() {
+                        if (chart) {
+                            chart.dispose();
+                        }
+
+                        chart = echarts.init(document.getElementById('main'));
+
+                        function getAirportCoord(idx) {
+                            return [data.airports[idx][3], data.airports[idx][4]];
+                        }
+                        var routes = data.routes.map(function (airline) {
+                            return [
+                                getAirportCoord(airline[1]),
+                                getAirportCoord(airline[2])
+                            ];
+                        });
+
+                        var option = {
+                            streamStep: 4000,
+                            title: {
+                                text: 'World Flights',
+                                left: 'center',
+                                textStyle: {
+                                    color: '#eee'
+                                }
+                            },
+                            backgroundColor: '#003',
+                            tooltip: {
+                                formatter: function (param) {
+                                    var route = data.routes[param.dataIndex];
+                                    return data.airports[route[1]][1] + ' > ' + data.airports[route[2]][1];
+                                }
+                            },
+                            geo: {
+                                map: 'world',
+                                left: 0,
+                                right: 0,
+                                roam: true,
+                                silent: true,
+                                itemStyle: {
+                                    normal: {
+                                        borderColor: '#003',
+                                        color: '#005'
+                                    }
+                                }
+                            },
+                            series: [{
+                                type: 'lines',
+                                coordinateSystem: 'geo',
+                                blendModel: 'lighter',
+                                data: routes,
+                                // Test not large mode.
+                                large: false,
+                                largeThreshold: 100,
+                                lineStyle: {
+                                    normal: {
+                                        opacity: 0.05,
+                                        width: 0.5,
+                                        curveness: 0.3
+                                    }
+                                },
+                                // 设置混合模式为叠加
+                                blendMode: 'lighter'
+                            }]
+                        };
+
+                        chart.on('finished', function () {
+                            infoEl.innerHTML = 'Finished (large: false). Please test roam (in not large mode, should no error thrown';
+                        });
+
+                        chart.setOption(option);
+                    }
+
+                });
+
+            });
+        });
+
+        </script>
+    </body>
+</html>
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
sushuang@apache.org.

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


[incubator-echarts] 05/09: add example.

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit b18189d9a0978c5cad898bddf1365bc5c74bf430
Author: sushuang <su...@gmail.com>
AuthorDate: Tue Apr 3 16:06:53 2018 +0800

    add example.
---
 test/scatter-stream-large.html     | 149 +++++++++++++++++++++++++++++++++++++
 test/scatter-stream-not-large.html | 149 +++++++++++++++++++++++++++++++++++++
 2 files changed, 298 insertions(+)

diff --git a/test/scatter-stream-large.html b/test/scatter-stream-large.html
new file mode 100644
index 0000000..2295b1c
--- /dev/null
+++ b/test/scatter-stream-large.html
@@ -0,0 +1,149 @@
+<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/testHelper.js'></script>
+        <link rel="stylesheet" href="lib/reset.css" />
+        <meta name='viewport' content='width=device-width, initial-scale=1' />
+    </head>
+    <body>
+        <style>
+            html, body, #main0 {
+                width: 100%;
+                height: 100%;
+                margin: 0;
+            }
+        </style>
+        <div id='main0'></div>
+        <script>
+
+        var xs = [440000, 450000];
+        var ys = [4368000, 4537000];
+
+        require([
+            'echarts'
+        ], function (echarts) {
+
+            $.get('../map/json/world.json', function (worldJson) {
+                echarts.registerMap('world', worldJson);
+
+                var count = 35663;
+                var lngCount = 1000;
+                var chart;
+
+                var points = [];
+
+                var lngStep = 0.3;
+                var latStep = 1;
+                var lng0 = -160;
+                var lng1 = lng0 + lngCount * lngStep;
+                var lat0 = 0;
+                var lat1 = lat0 + Math.floor(count / lngCount) * latStep;
+
+                for (var i = 0; i < count; i++) {
+                    var iLng = i % lngCount;
+                    var iLat = Math.floor(i / lngCount);
+                    var lng = lng0 + iLng * lngStep;
+                    var lat = lat0 + iLat * latStep;
+                    points.push([lng, lat]);
+                }
+
+                var option = {
+                    title: {
+                        text: 'World Flights',
+                        left: 'center',
+                        textStyle: {
+                            color: '#eee'
+                        }
+                    },
+                    backgroundColor: '#003',
+                    tooltip: {
+                        formatter: function (param) {
+                            return 'Point: ' + param.value[0] + ', ' + param.value[1];
+                        }
+                    },
+                    geo: {
+                        map: 'world',
+                        left: 0,
+                        right: 0,
+                        zoom: 0.5,
+                        roam: true,
+                        silent: true,
+                        itemStyle: {
+                            normal: {
+                                borderColor: '#003',
+                                color: '#005'
+                            }
+                        }
+                    },
+                    series: [{
+                        type: 'scatter',
+                        coordinateSystem: 'geo',
+                        blendModel: 'lighter',
+                        data: points,
+                        symbol: 'rect',
+                        symbolSize: 6,
+                        large: true,
+                        // large: false,
+                        largeThreshold: 100,
+                        progressiveThreshold: 101
+                    }, {
+                        type: 'scatter',
+                        coordinateSystem: 'geo',
+                        symbolSize: 5,
+                        color: ['green'],
+                        data: [
+                            {
+                                value: [lng0, lat0],
+                                label: {
+                                    show: true,
+                                    position: 'top',
+                                    formatter: 'bottom-left'
+                                }
+                            }, {
+                                value: [lng1, lat0],
+                                label: {
+                                    show: true,
+                                    position: 'top',
+                                    formatter: 'bottom-right'
+                                }
+                            }, {
+                                value: [lng0, lat1],
+                                label: {
+                                    show: true,
+                                    position: 'bottom',
+                                    formatter: 'top-left'
+                                }
+                            }, {
+                                value: [lng1, lat1],
+                                label: {
+                                    show: true,
+                                    position: 'bottom',
+                                    formatter: 'top-right'
+                                }
+                            }
+                        ]
+                    }]
+                };
+
+                var chart = testHelper.create(echarts, 'main0', {
+                    title: [
+                        count + ' points should be rendered in the area of the 4 green points',
+                        '( large:true and el.incremetal = true) ',
+                        'And check roam.'
+                    ],
+                    option: option,
+                    height: 550
+                });
+                chart.on('finished', function () {
+                    console.log('finished');
+                });
+
+            });
+        });
+
+        </script>
+    </body>
+</html>
\ No newline at end of file
diff --git a/test/scatter-stream-not-large.html b/test/scatter-stream-not-large.html
new file mode 100644
index 0000000..8afede3
--- /dev/null
+++ b/test/scatter-stream-not-large.html
@@ -0,0 +1,149 @@
+<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/testHelper.js'></script>
+        <link rel="stylesheet" href="lib/reset.css" />
+        <meta name='viewport' content='width=device-width, initial-scale=1' />
+    </head>
+    <body>
+        <style>
+            html, body, #main0 {
+                width: 100%;
+                height: 100%;
+                margin: 0;
+            }
+        </style>
+        <div id='main0'></div>
+        <script>
+
+        var xs = [440000, 450000];
+        var ys = [4368000, 4537000];
+
+        require([
+            'echarts'
+        ], function (echarts) {
+
+            $.get('../map/json/world.json', function (worldJson) {
+                echarts.registerMap('world', worldJson);
+
+                var count = 35663;
+                var lngCount = 1000;
+                var chart;
+
+                var points = [];
+
+                var lngStep = 0.3;
+                var latStep = 1;
+                var lng0 = -160;
+                var lng1 = lng0 + lngCount * lngStep;
+                var lat0 = 0;
+                var lat1 = lat0 + Math.floor(count / lngCount) * latStep;
+
+                for (var i = 0; i < count; i++) {
+                    var iLng = i % lngCount;
+                    var iLat = Math.floor(i / lngCount);
+                    var lng = lng0 + iLng * lngStep;
+                    var lat = lat0 + iLat * latStep;
+                    points.push([lng, lat]);
+                }
+
+                var option = {
+                    title: {
+                        text: 'World Flights',
+                        left: 'center',
+                        textStyle: {
+                            color: '#eee'
+                        }
+                    },
+                    backgroundColor: '#003',
+                    tooltip: {
+                        formatter: function (param) {
+                            return 'Point: ' + param.value[0] + ', ' + param.value[1];
+                        }
+                    },
+                    geo: {
+                        map: 'world',
+                        left: 0,
+                        right: 0,
+                        zoom: 0.5,
+                        roam: true,
+                        silent: true,
+                        itemStyle: {
+                            normal: {
+                                borderColor: '#003',
+                                color: '#005'
+                            }
+                        }
+                    },
+                    series: [{
+                        type: 'scatter',
+                        coordinateSystem: 'geo',
+                        blendModel: 'lighter',
+                        data: points,
+                        symbol: 'rect',
+                        symbolSize: 6,
+                        // large: true,
+                        large: false,
+                        largeThreshold: 100,
+                        progressiveThreshold: 101
+                    }, {
+                        type: 'scatter',
+                        coordinateSystem: 'geo',
+                        symbolSize: 5,
+                        color: ['green'],
+                        data: [
+                            {
+                                value: [lng0, lat0],
+                                label: {
+                                    show: true,
+                                    position: 'top',
+                                    formatter: 'bottom-left'
+                                }
+                            }, {
+                                value: [lng1, lat0],
+                                label: {
+                                    show: true,
+                                    position: 'top',
+                                    formatter: 'bottom-right'
+                                }
+                            }, {
+                                value: [lng0, lat1],
+                                label: {
+                                    show: true,
+                                    position: 'bottom',
+                                    formatter: 'top-left'
+                                }
+                            }, {
+                                value: [lng1, lat1],
+                                label: {
+                                    show: true,
+                                    position: 'bottom',
+                                    formatter: 'top-right'
+                                }
+                            }
+                        ]
+                    }]
+                };
+
+                var chart = testHelper.create(echarts, 'main0', {
+                    title: [
+                        count + ' points should be rendered in the area of the 4 green points',
+                        '( large:true and el.incremetal = true) ',
+                        'And check roam.'
+                    ],
+                    option: option,
+                    height: 550
+                });
+                chart.on('finished', function () {
+                    console.log('finished');
+                });
+
+            });
+        });
+
+        </script>
+    </body>
+</html>
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
sushuang@apache.org.

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


[incubator-echarts] 09/09: Merge branch 'master' of https://github.com/apache/incubator-echarts

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit d81f06209eb71ec860319344cbcd259d5504ca2e
Merge: 096a88e aa16ddc
Author: sushuang <su...@gmail.com>
AuthorDate: Fri Apr 6 03:28:16 2018 +0800

    Merge branch 'master' of https://github.com/apache/incubator-echarts

 src/chart/sankey/sankeyLayout.js |   2 +-
 test/sankey-test.html            | 133 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 134 insertions(+), 1 deletion(-)

-- 
To stop receiving notification emails like this one, please contact
sushuang@apache.org.

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


[incubator-echarts] 03/09: Fix lines rendering in large but not incrementalDisplayable mode.

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 00b93a2e431141740ad582aa5730c41439ed5223
Author: sushuang <su...@gmail.com>
AuthorDate: Tue Apr 3 14:31:40 2018 +0800

    Fix lines rendering in large but not incrementalDisplayable mode.
---
 src/chart/lines/linesLayout.js |   2 +-
 test/-cases.js                 |   3 +
 test/line-large.html           |   2 +-
 test/lines-flight.html         |   2 +-
 test/lines-stream-large.html   | 143 +++++++++++++++++++++++++++++++++++++++++
 5 files changed, 149 insertions(+), 3 deletions(-)

diff --git a/src/chart/lines/linesLayout.js b/src/chart/lines/linesLayout.js
index 7b5666d..6fc5602 100644
--- a/src/chart/lines/linesLayout.js
+++ b/src/chart/lines/linesLayout.js
@@ -23,7 +23,7 @@ export default {
                     points = new Float32Array(segCount + totalCoordsCount * 2);
                 }
                 else {
-                    points = new Float32Array(segCount * 2);
+                    points = new Float32Array(segCount * 4);
                 }
 
                 var offset = 0;
diff --git a/test/-cases.js b/test/-cases.js
index d0d2353..826f18d 100644
--- a/test/-cases.js
+++ b/test/-cases.js
@@ -34,11 +34,14 @@
         name: 'stream-cases',
         whiteList: [
             'lines-ny-appendData.html',
+            'scatter-stream-large.html',
+            'scatter-stream-not-large.html',
             'scatter-random-stream.html',
             'scatter-random-stream-fix-axis.html',
             'scatter-gps.html',
             'scatter-weibo.html',
             'lines-flight.html',
+            'lines-stream-large.html',
             'lines-stream-not-large.html',
             'stream-filter.html',
             'scatter-stream-visual.html'
diff --git a/test/line-large.html b/test/line-large.html
index d37a945..9921ea8 100644
--- a/test/line-large.html
+++ b/test/line-large.html
@@ -59,7 +59,7 @@
                     },
                     yAxis: {
                     },
-                    dataZoom: [{}, {type: 'inside'}],
+                    dataZoom: [{end: 90}, {type: 'inside', end: 90}],
                     series: [{
                         name: 'large-line',
                         type: 'line',
diff --git a/test/lines-flight.html b/test/lines-flight.html
index 4c2c802..c495947 100644
--- a/test/lines-flight.html
+++ b/test/lines-flight.html
@@ -111,7 +111,7 @@
                                 largeThreshold: 100,
                                 lineStyle: {
                                     normal: {
-                                        opacity: 0.05,
+                                        opacity: 0.5,
                                         width: 0.5,
                                         curveness: 0.3
                                     }
diff --git a/test/lines-stream-large.html b/test/lines-stream-large.html
new file mode 100644
index 0000000..a0e209d
--- /dev/null
+++ b/test/lines-stream-large.html
@@ -0,0 +1,143 @@
+<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/testHelper.js'></script>
+        <link rel="stylesheet" href="lib/reset.css" />
+        <meta name='viewport' content='width=device-width, initial-scale=1' />
+    </head>
+    <body>
+        <style>
+            html, body, #main0 {
+                width: 100%;
+                height: 100%;
+                margin: 0;
+            }
+        </style>
+        <div id='main0'></div>
+        <script>
+
+        var xs = [440000, 450000];
+        var ys = [4368000, 4537000];
+
+        require([
+            'echarts'
+        ], function (echarts) {
+
+            $.get('../map/json/world.json', function (worldJson) {
+                echarts.registerMap('world', worldJson);
+
+                var linesCount = 35663;
+                var chart;
+
+                var routes = [];
+
+                var lngStep = 0.01;
+                var lng0 = -160;
+                var lng1 = lng0 + linesCount * lngStep;
+
+                for (var i = 0; i < linesCount; i++) {
+                    var lng = lng0 + i * lngStep;
+                    var lat0 = 0;
+                    var lat1 = 90;
+
+                    // if (i % 1000 < 500) {
+                    //     lat0 = 30;
+                    //     lat1 = 120;
+                    // }
+                    routes.push([[lng, lat0], [lng, lat1]]);
+                }
+
+                var option = {
+                    title: {
+                        text: 'World Flights',
+                        left: 'center',
+                        textStyle: {
+                            color: '#eee'
+                        }
+                    },
+                    backgroundColor: '#003',
+                    tooltip: {
+                        formatter: function (param) {
+                            return 'Line: ' + param.dataIndex;
+                        }
+                    },
+                    geo: {
+                        map: 'world',
+                        left: 0,
+                        right: 0,
+                        zoom: 0.3,
+                        roam: true,
+                        silent: true,
+                        itemStyle: {
+                            normal: {
+                                borderColor: '#003',
+                                color: '#005'
+                            }
+                        }
+                    },
+                    series: [{
+                        type: 'lines',
+                        coordinateSystem: 'geo',
+                        blendModel: 'lighter',
+                        data: routes,
+                        large: true,
+                        // large: false,
+                        largeThreshold: 0,
+                        // progressive: 5e3,
+                        progressiveThreshold: 101,
+                        lineStyle: {
+                            normal: {
+                                opacity: 1,
+                                width: 1,
+                                // curveness: 0.3
+                            }
+                        },
+                        // blendMode: 'lighter'
+                    }, {
+                        type: 'scatter',
+                        coordinateSystem: 'geo',
+                        symbolSize: 5,
+                        color: ['green'],
+                        data: [
+                            {
+                                value: [lng0, 30],
+                                label: {
+                                    show: true,
+                                    position: 'top',
+                                    formatter: 'longitude start'
+                                }
+                            }, {
+                                value: [lng1, 30],
+                                label: {
+                                    show: true,
+                                    position: 'top',
+                                    formatter: 'longitude end'
+                                }
+                            }
+                        ]
+                    }]
+                };
+
+                var chart = testHelper.create(echarts, 'main0', {
+                    title: [
+                        linesCount + ' lines should be rendered vertically side by side ',
+                        'from the left green point to the right green point, NO GAP.',
+                        '( large:true and el.incremetal = true) ',
+                        'And check roam.'
+                    ],
+                    option: option,
+                    height: 550
+                });
+                chart.on('finished', function () {
+                    console.log('finished');
+                });
+
+            });
+        });
+
+        </script>
+    </body>
+</html>
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
sushuang@apache.org.

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