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

[incubator-echarts-doc] branch live-example updated: example: highlight the changed lines and scroll to the changed line

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

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


The following commit(s) were added to refs/heads/live-example by this push:
     new 1b72e63  example: highlight the changed lines and scroll to the changed line
1b72e63 is described below

commit 1b72e63a93bc1f594f1e992866b474c9c7c6456d
Author: pissang <bm...@gmail.com>
AuthorDate: Fri Jun 19 09:25:21 2020 +0800

    example: highlight the changed lines and scroll to the changed line
---
 package-lock.json              |   5 ++
 package.json                   |   3 +-
 src/components/LiveExample.vue | 112 +++++++++++++++++++++++++++++++++++++++--
 3 files changed, 115 insertions(+), 5 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index b93edf2..1419215 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13079,6 +13079,11 @@
         "camelcase": "^5.0.0",
         "decamelize": "^1.2.0"
       }
+    },
+    "zrender": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/zrender/-/zrender-4.3.1.tgz",
+      "integrity": "sha512-CeH2TpJeCdG0TAGYoPSAcFX2ogdug1K7LIn9UO/q9HWqQ54gWhrMAlDP9AwWYMUDhrPe4VeazQ4DW3msD96nUQ=="
     }
   }
 }
diff --git a/package.json b/package.json
index 8e579ed..ec0e2f2 100644
--- a/package.json
+++ b/package.json
@@ -65,6 +65,7 @@
     "vue-custom-scrollbar": "^1.2.0",
     "vue-i18n": "^8.18.2",
     "vue-text-highlight": "^2.0.10",
-    "whatwg-fetch": "^3.0.0"
+    "whatwg-fetch": "^3.0.0",
+    "zrender": "^4.3.1"
   }
 }
diff --git a/src/components/LiveExample.vue b/src/components/LiveExample.vue
index 6aa73ea..f377fe4 100644
--- a/src/components/LiveExample.vue
+++ b/src/components/LiveExample.vue
@@ -41,6 +41,8 @@ import 'codemirror/theme/paraiso-dark.css';
 import 'codemirror/mode/javascript/javascript.js'
 import beautify from 'js-beautify';
 import throttle from 'lodash.throttle';
+import arrayDiff from 'zrender/src/core/arrayDiff';
+import scrollIntoView from 'scroll-into-view';
 
 let echartsLoadPromise;
 
@@ -57,7 +59,76 @@ function fetchECharts() {
     }));
 }
 
-function updateOption(option) {
+function diffUpdateCode(oldCode, newCode, cmInstance) {
+    const oldLines = oldCode.split(/\n/);
+    const newLines = newCode.split(/\n/);
+    const result = arrayDiff(oldLines, newLines);
+
+    const changedLines = [];
+    const len = result.length;
+
+    for (let i = len - 1; i >= 0; i--) {
+        const item = result[i];
+        if (item.cmd === '-') {
+            cmInstance.replaceRange(
+                '', {line: item.idx, ch: 0}, {line: item.idx + 1, ch: 0}
+            );
+        }
+    }
+
+    for (let i = 0; i < len; i++) {
+        const item = result[i];
+        if (item.cmd === '+') {
+            cmInstance.replaceRange(
+                newLines[item.idx] + '\n', {line: item.idx, ch: 0}
+            );
+            changedLines.push(item.idx);
+        }
+    }
+
+    changedLines.forEach(function (idx) {
+        cmInstance.addLineClass(idx, 'wrap', 'option-changed');
+    });
+
+    if (len) {
+        setTimeout(() => {
+            // const existsEl = cmInstance.getWrapperElement().querySelector('.option-changed');
+            // if (existsEl) {
+            //     // If the element is near to the view and has been rendered.
+            //     scrollIntoView(existsEl, {
+            //         time: 400,
+            //         align: {
+            //             top: 0,
+            //             topOffset: -50
+            //         }
+            //     });
+            // }
+            // else {
+            if (window.scrollTo) {
+                const {top} = cmInstance.charCoords({line: changedLines[0], ch: 0});
+                const el = cmInstance.getScrollerElement();
+                // Because the
+                // el.style.top = oldTop + 'px';
+                el.scrollTo({
+                    top,
+                    left: 0,
+                    behavior: 'smooth'
+                });
+            }
+            else {
+                cmInstance.scrollIntoView({
+                    line: changedLines[0],
+                    ch: 0
+                }, cmInstance.getWrapperElement().clientHeight - 50);
+            }
+            // }
+        }, 20);
+    }
+
+    return changedLines;
+}
+
+function updateOption(option, isRefreshForce) {
     if (this.shared.currentExampleName !== this.lastUpdateExampleName) {
         this.lastUpdateExampleName = this.shared.currentExampleName;
         // Refresh all if example base option is changed.
@@ -113,7 +184,22 @@ function updateOption(option) {
     else {
         // TODO: Highlight the diff lines.
         // TODO: Only change the changed line. optimize
-        this.cmInstance.setValue(this.formattedOptionCodeStr);
+        const oldCode = this.cmInstance.getValue();
+        const newCode = this.formattedOptionCodeStr;
+
+        if (this.oldHighlightedLines) {
+            this.oldHighlightedLines.forEach((idx) => {
+                this.cmInstance.removeLineClass(idx, 'wrap', 'option-changed');
+            });
+        }
+
+        if (!isRefreshForce) {
+            this.oldHighlightedLines = diffUpdateCode(oldCode, newCode, this.cmInstance);
+        }
+        else {
+            this.cmInstance.setValue(newCode);
+            this.oldHighlightedLines = [];
+        }
     }
 
     this.lastUpdateExampleName = this.shared.currentExampleName;
@@ -129,7 +215,9 @@ export default {
 
             hasError: false,
 
-            lastUpdateExampleName: ''
+            lastUpdateExampleName: '',
+
+            oldHighlightedLines: []
         };
     },
 
@@ -210,7 +298,7 @@ export default {
                     this.chartInstance.dispose();
                     this.chartInstance = null;
                 }
-                this.updateOption(this.shared.currentExampleOption);
+                this.updateOption(this.shared.currentExampleOption, true);
             }
         },
 
@@ -322,6 +410,22 @@ export default {
             .CodeMirror {
                 height: 100%;
                 overflow-y: scroll;
+                // font-family: Monaco, 'Source Code Pro', monospace;
+
+                ::-webkit-scrollbar-thumb {
+                    width: 8px;
+                    min-height: 15px;
+                    background: rgba(255, 255, 255, 0.3) !important;
+                    -webkit-transition: all 0.3s ease-in-out;
+                    transition: all 0.3s ease-in-out;
+                    border-radius: 2px
+                }
+
+                .option-changed {
+                    background: rgba(255, 255, 255, 0.1);
+                    border-left: 3px solid #32dde6;
+                    margin-left: -3px;
+                }
             }
         }
     }


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