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/14 15:35:47 UTC

[incubator-echarts-doc] branch live-example updated: update option after editing in control ui

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 ef912e3  update option after editing in control ui
ef912e3 is described below

commit ef912e38eed987c80c631cf254cc3382cf23d287
Author: pissang <bm...@gmail.com>
AuthorDate: Sun Jun 14 23:35:33 2020 +0800

    update option after editing in control ui
---
 src/components/DocContentItemCard.vue       | 12 ++++-
 src/components/LiveExample.vue              | 73 ++++++++++++++++-------------
 src/components/OptionControl.vue            | 19 ++++++--
 src/controls/ControlBoolean.vue             | 15 +++++-
 src/controls/ControlColor.vue               | 27 +++++++++--
 src/controls/ControlNumber.vue              | 21 +++++++--
 src/controls/ControlVector.vue              | 19 +++++++-
 src/store.js                                | 42 +++++++++++++++++
 zh/option/partial/component-common-style.md |  2 +-
 9 files changed, 183 insertions(+), 47 deletions(-)

diff --git a/src/components/DocContentItemCard.vue b/src/components/DocContentItemCard.vue
index 44af60c..51c5086 100644
--- a/src/components/DocContentItemCard.vue
+++ b/src/components/DocContentItemCard.vue
@@ -77,7 +77,7 @@ import {
 import PropertiesList from './PropertiesList.vue';
 import OptionControl from './OptionControl.vue';
 
-import {store} from '../store';
+import {store, changeOption} from '../store';
 
 export default {
     name: 'DocContentItemCard',
@@ -100,6 +100,16 @@ export default {
     created() {
     },
 
+    watch: {
+        enableUIControl(newVal) {
+            if (!newVal) {
+                this.shared.previewOption = Object.freeze(changeOption(
+                    this.shared.previewOption, this.nodeData.path, undefined
+                ));
+            }
+        }
+    },
+
     computed: {
 
         itemId() {
diff --git a/src/components/LiveExample.vue b/src/components/LiveExample.vue
index e4252aa..c4d5b92 100644
--- a/src/components/LiveExample.vue
+++ b/src/components/LiveExample.vue
@@ -23,6 +23,7 @@ import 'codemirror/lib/codemirror.css';
 import 'codemirror/theme/paraiso-dark.css';
 import 'codemirror/mode/javascript/javascript.js'
 import beautify from 'js-beautify';
+import throttle from 'lodash.throttle';
 
 let echartsLoadPromise;
 
@@ -39,6 +40,38 @@ function fetchECharts() {
     }));
 }
 
+function updateOption(option) {
+    const viewport = this.$el.querySelector('.preview-main');
+    if (typeof echarts === 'undefined') {
+        fetchECharts().then(() => {
+            if (!this.echartsInstance) {
+                this.chartInstance = echarts.init(viewport);
+            }
+            this.chartInstance.setOption(option);
+        })
+    }
+    else {
+        if (!this.echartsInstance) {
+            this.chartInstance = echarts.init(viewport);
+        }
+        this.chartInstance.setOption(option);
+    }
+
+    if (!this.cmInstance) {
+        this.cmInstance = CodeMirror(this.$el.querySelector('.codemirror-main'), {
+            value: this.formattedOptionCodeStr,
+            mode: 'javascript',
+            theme: 'paraiso-dark',
+            readOnly: true
+        });
+    }
+    else {
+        // TODO: Highlight the diff lines.
+        // TODO: Only change the changed line. optimize
+        this.cmInstance.setValue(this.formattedOptionCodeStr);
+    }
+}
+
 export default {
 
     data() {
@@ -65,43 +98,17 @@ export default {
     watch: {
         'shared.previewOption'(newVal) {
             if (newVal) {
-                this.updateOption(newVal);
-                this.updateCode();
+                this.updateOptionThrottled(newVal);
             }
         }
     },
 
     methods: {
-        updateOption(option) {
-            const viewport = this.$el.querySelector('.preview-main');
-            if (typeof echarts === 'undefined') {
-                fetchECharts().then(() => {
-                    if (!this.echartsInstance) {
-                        this.chartInstance = echarts.init(viewport);
-                    }
-                    this.chartInstance.setOption(option);
-                })
-            }
-            else {
-                if (!this.echartsInstance) {
-                    this.chartInstance = echarts.init(viewport);
-                }
-                this.chartInstance.setOption(option);
-            }
-        },
+        updateOption,
 
-        updateCode() {
-            if (!this.cmInstance) {
-                this.cmInstance = CodeMirror(this.$el.querySelector('.codemirror-main'), {
-                    value: this.formattedOptionCodeStr,
-                    mode: 'javascript',
-                    theme: 'paraiso-dark'
-                });
-            }
-            else {
-                this.cmInstance.setValue(this.formattedOptionCodeStr);
-            }
-        }
+        updateOptionThrottled: throttle(updateOption, 300, {
+            leading: false
+        })
     },
 
     computed: {
@@ -110,7 +117,9 @@ export default {
         },
 
         formattedOptionCodeStr() {
-            return beautify.js(this.optionCodeStr.replace(/"(\w+)"\s*:/g, '$1:'));
+            return beautify.js(this.optionCodeStr.replace(/"(\w+)"\s*:/g, '$1:'), {
+                indent_size: 2
+            });
         }
     }
 }
diff --git a/src/components/OptionControl.vue b/src/components/OptionControl.vue
index 5451d90..9ade77d 100644
--- a/src/components/OptionControl.vue
+++ b/src/components/OptionControl.vue
@@ -3,7 +3,8 @@
     <component
         :is="uiComponent"
         v-bind="uiAttrs"
-        value="default">
+        :value="defaultValue"
+         @change="onValueChange">
     </component>
 </div>
 </template>
@@ -13,7 +14,7 @@ import ControlColor from '../controls/ControlColor.vue';
 import ControlBoolean from '../controls/ControlBoolean.vue';
 import ControlNumber from '../controls/ControlNumber.vue';
 import ControlVector from '../controls/ControlVector.vue';
-import {store} from '../store';
+import {store, changeOption} from '../store';
 
 const uiComponentMap = {
     boolean: ControlBoolean,
@@ -45,6 +46,7 @@ function omitTypeAndDefault(obj) {
     return newObj;
 }
 
+
 export default {
     name: 'OptionControl',
 
@@ -65,12 +67,23 @@ export default {
             return omitTypeAndDefault(this.controlConfig);
         },
 
-        default() {
+        defaultValue() {
             const controlConfig = this.controlConfig;
             return controlConfig.default != null
                 ? controlConfig.default
                 : (uiComponentDefault[controlConfig.type] && uiComponentDefault[controlConfig.type](controlConfig));
         }
+    },
+
+    methods: {
+        onValueChange(value) {
+            // console.log(this.optionPath, value);
+            if (this.shared.previewOption) {
+                this.shared.previewOption = Object.freeze(
+                    changeOption(this.shared.previewOption, this.optionPath, value)
+                );
+            }
+        }
     }
 }
 </script>
diff --git a/src/controls/ControlBoolean.vue b/src/controls/ControlBoolean.vue
index f34741c..e291996 100644
--- a/src/controls/ControlBoolean.vue
+++ b/src/controls/ControlBoolean.vue
@@ -1,6 +1,6 @@
 <template>
 <div class="control-boolean">
-<el-switch v-model="value" :active-text="$t('example.booleanDesc')"></el-switch>
+<el-switch v-model="innerValue" :active-text="$t('example.booleanDesc')" @change="onValueChange"></el-switch>
 </div>
 </template>
 
@@ -9,6 +9,19 @@ export default {
     props: ['value'],
     data() {
         return {
+            innerValue: this.value
+        }
+    },
+
+    watch: {
+        value(val) {
+            this.innerValue = val;
+        }
+    },
+
+    methods: {
+        onValueChange() {
+            this.$emit('change', this.innerValue);
         }
     }
 }
diff --git a/src/controls/ControlColor.vue b/src/controls/ControlColor.vue
index 994cf16..43ab730 100644
--- a/src/controls/ControlColor.vue
+++ b/src/controls/ControlColor.vue
@@ -1,8 +1,11 @@
 <template>
 <div class="control-color">
-<el-color-picker v-model="value" show-alpha="true"></el-color-picker>
-<span :style="{color: value || '#aaa'}">
-    {{value || $t('example.defaultColor')}}
+<el-color-picker v-model="innerValue" :show-alpha="true"
+    @change="onValueChange"
+    @active-change="onActiveChange"
+    ></el-color-picker>
+<span :style="{color: innerValue || '#aaa'}">
+    {{innerValue || $t('example.defaultColor')}}
 </span>
 </div>
 </template>
@@ -11,9 +14,25 @@
 export default {
 
     props: ['value'],
-
     data() {
         return {
+            innerValue: this.value
+        }
+    },
+
+    watch: {
+        value(val) {
+            this.innerValue = val;
+        }
+    },
+
+    methods: {
+        onValueChange() {
+            this.$emit('change', this.innerValue);
+        },
+        onActiveChange(val) {
+            // this.innerValue = val;
+            // this.$emit('change', val);
         }
     }
 }
diff --git a/src/controls/ControlNumber.vue b/src/controls/ControlNumber.vue
index 665f8d4..2e0e347 100644
--- a/src/controls/ControlNumber.vue
+++ b/src/controls/ControlNumber.vue
@@ -1,12 +1,13 @@
 <template>
 <div class="control-number">
     <el-input-number
-        v-model="value"
+        v-model="innerValue"
         controls-position="right"
         :min="+min"
-        :max="max == null ? Infinity : +max"
+        :max="max == null ? 1e4 : +max"
         :step="step == null ? 1 : +step"
         size="mini"
+         @change="onValueChange"
     ></el-input-number>
 </div>
 </template>
@@ -17,7 +18,21 @@ export default {
     props: ['value', 'min', 'max', 'step'],
 
     data() {
-        return {}
+        return {
+            innerValue: this.value
+        }
+    },
+
+    watch: {
+        value(val) {
+            this.innerValue = val;
+        }
+    },
+
+    methods: {
+        onValueChange() {
+            this.$emit('change', this.innerValue);
+        }
     }
 }
 </script>
diff --git a/src/controls/ControlVector.vue b/src/controls/ControlVector.vue
index 5ef5dbe..8559d02 100644
--- a/src/controls/ControlVector.vue
+++ b/src/controls/ControlVector.vue
@@ -7,9 +7,10 @@
             v-model="value[index]"
             controls-position="right"
             :min="+min"
-            :max="max == null ? Infinity : +max"
+            :max="max == null ? 1e4 : +max"
             :step="step == null ? 1 : +step"
             size="mini"
+             @change="onValueChange"
         ></el-input-number>
     </div>
 </div>
@@ -21,13 +22,27 @@ export default {
     props: ['value', 'min', 'max', "step", 'dims'],
 
     data() {
-        return {};
+        return {
+            innerValue: this.value
+        };
     },
 
     computed: {
         dimsArr() {
             return this.dims.split(',').map(dim => dim.trim());
         }
+    },
+
+    watch:  {
+        value(newVal) {
+            this.innerValue = newVal;
+        }
+    },
+
+    methods: {
+        onValueChange() {
+            this.$emit('change', this.innerValue);
+        }
     }
 }
 </script>
diff --git a/src/store.js b/src/store.js
index acb0bf2..19feb3c 100644
--- a/src/store.js
+++ b/src/store.js
@@ -36,4 +36,46 @@ export function getPagePath() {
 export function isOptionDoc() {
     return store.docType === 'option'
         || store.docType === 'option-gl';
+}
+
+export function changeOption(option, path, value) {
+
+    function changeOptionRecursive(obj, pathParts) {
+        const item = pathParts.shift();
+        // Clone a new object because the original one is freezed and cant be changed.
+        obj = Object.assign({}, obj);
+        if (!pathParts.length) {
+            if (value === undefined) {
+                delete obj[item];
+                return obj;
+            }
+            else {
+                obj[item] = value;
+                return obj;
+            }
+        }
+
+        const subtypeItems = item.split('-');
+        const key = subtypeItems[0];
+        const subtype = subtypeItems[1];
+        const prop = obj[key] || {};
+        if (Array.isArray(prop)) {
+            obj[key] = prop.map(function (childObj, idx) {
+                if (subtype && childObj.type !== subtype) {
+                    return childObj;
+                }
+                return changeOptionRecursive(childObj, pathParts.slice());
+            });
+        }
+        else {
+            if (subtype && prop.type !== subtype) {
+                obj[key] = prop;
+            }
+            obj[key] = changeOptionRecursive(prop, pathParts.slice());
+        }
+
+        return obj;
+    }
+
+    return changeOptionRecursive(option, path.split('.'));
 }
\ No newline at end of file
diff --git a/zh/option/partial/component-common-style.md b/zh/option/partial/component-common-style.md
index f9cedeb..3a83d8c 100644
--- a/zh/option/partial/component-common-style.md
+++ b/zh/option/partial/component-common-style.md
@@ -42,7 +42,7 @@ ${componentName}的边框线宽。
 
 #${prefix} ${propName|default('borderRadius')}(number|Array) = 0
 
-<ExampleUIControlVector value="0" min="0" dims="Top, Right, Bottom, Left"  />
+<ExampleUIControlVector value="0" min="0" dims="LT, RT, RB, LB"  />
 
 圆角半径,单位px,支持传入数组分别指定 4 个圆角半径。
 如:


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