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

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


The following commit(s) were added to refs/heads/master by this push:
     new f1955e4  basic download video
f1955e4 is described below

commit f1955e481e5d77aa3337c7f5a6819f20c83f3dcc
Author: Ovilia <zwl.s...@gmail.com>
AuthorDate: Wed Aug 18 17:23:16 2021 +0800

    basic download video
---
 package-lock.json         |  13 ++++++
 package.json              |   1 +
 src/components/BBody.vue  |  49 ++++++++++++++++++++++-
 src/components/BChart.vue | 100 ++++++++++++++++++++++++++++++++++++----------
 src/components/BTable.vue |   7 ++--
 5 files changed, 142 insertions(+), 28 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index c79ab35..6650c61 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1047,6 +1047,14 @@
             "integrity": 
"sha512-BmkbxLfStqiPA7IEzQpIk0UFZFf3A4E6fzjPJ6OR+bFC2L8ES9J8zGA/asoi47p8XDVkev+WJo2I2Nc8c/34Yg==",
             "dev": true
         },
+        "canvas-record": {
+            "version": "3.0.0",
+            "resolved": 
"https://registry.nlark.com/canvas-record/download/canvas-record-3.0.0.tgz";,
+            "integrity": "sha1-FQAe83heyQaBsiE2h2SoMsbN9ig=",
+            "requires": {
+                "file-extension": "^4.0.5"
+            }
+        },
         "ccount": {
             "version": "1.1.0",
             "resolved": 
"https://registry.npm.taobao.org/ccount/download/ccount-1.1.0.tgz";,
@@ -1689,6 +1697,11 @@
                 "format": "^0.2.0"
             }
         },
+        "file-extension": {
+            "version": "4.0.5",
+            "resolved": 
"https://registry.nlark.com/file-extension/download/file-extension-4.0.5.tgz";,
+            "integrity": "sha1-rmzvNMKOcxOpK6pKqVV1XKzfDOM="
+        },
         "fill-range": {
             "version": "7.0.1",
             "resolved": 
"https://registry.npm.taobao.org/fill-range/download/fill-range-7.0.1.tgz";,
diff --git a/package.json b/package.json
index a1c27cf..dcf46a6 100644
--- a/package.json
+++ b/package.json
@@ -30,6 +30,7 @@
         "yargs": "^6.6.0"
     },
     "dependencies": {
+        "canvas-record": "^3.0.0",
         "color": "^3.1.3",
         "echarts": "^5.1.1",
         "element-plus": "^1.0.2-beta.44",
diff --git a/src/components/BBody.vue b/src/components/BBody.vue
index e176d78..b7a363d 100644
--- a/src/components/BBody.vue
+++ b/src/components/BBody.vue
@@ -44,9 +44,39 @@
                             >
                             </el-input>
                         </div>
+                        <div class="grid grid-cols-3 form-row">
+                            <label class="col-span-1">视频宽度</label>
+                            <el-input
+                                type="number"
+                                size="medium"
+                                class="col-span-2"
+                                v-model="width"
+                            >
+                            </el-input>
+                        </div>
+                        <div class="grid grid-cols-3 form-row">
+                            <label class="col-span-1">视频高度</label>
+                            <el-input
+                                type="number"
+                                size="medium"
+                                class="col-span-2"
+                                v-model="height"
+                            >
+                            </el-input>
+                        </div>
                         <el-form-item>
-                            <el-button @click="download">下载</el-button>
+                            <el-button @click="download" 
type="primary">下载代码</el-button>
+                            <el-button @click="downloadVideo">生成视频</el-button>
                         </el-form-item>
+
+                        <div class="grid grid-cols-3 form-row">
+                            <label class="col-span-1">视频生成中</label>
+                            <el-progress class="col-span-2"
+                                :text-inside="true"
+                                :stroke-width="20"
+                                :percentage="videoPercentage">
+                            </el-progress>
+                        </div>
                     </el-form>
                 </div>
             </el-card>
@@ -89,7 +119,10 @@ export default defineComponent({
             title: this.$i18n.t('defaultChartTitle'),
             maxDataCnt: null,
             chartData: null,
-            animationDuration: 3000
+            animationDuration: 3000,
+            width: 1280,
+            height: 720,
+            videoPercentage: 40
         }
     },
     components: {
@@ -127,6 +160,18 @@ export default defineComponent({
             document.body.appendChild(element);
             element.click();
             document.body.removeChild(element);
+        },
+
+        async downloadVideo() {
+            const isSuccess = await (this.$refs.bchart as 
any).captureVideo(this.width, this.height);
+            if (!isSuccess) {
+                // this.$notify.error({
+                //     title: '导出失败!',
+                //     message: '建议使用最新版 Chrome 或 Firefox',
+                //     duration: 0,
+                //     position: 'bottom-left'
+                // });
+            }
         }
     }
 })
diff --git a/src/components/BChart.vue b/src/components/BChart.vue
index 570666e..f011be7 100644
--- a/src/components/BChart.vue
+++ b/src/components/BChart.vue
@@ -9,7 +9,12 @@
         <div
             id="bar-race-preview"
             ref="chart"
-            class="absolute bottom-4 top-14 left-5 right-5 border">
+            class="absolute bottom-4 top-14 left-5 right-5 border"
+            :class="isHidden ? 'hidden' : ''"
+        >
+        </div>
+        <div id="chart-hint" v-if="isHidden">
+            视频生成中无法预览
         </div>
     </div>
 </template>
@@ -17,6 +22,7 @@
 <script lang="ts">
 import {defineComponent} from 'vue';
 import * as echarts from 'echarts';
+import canvasRecord from 'canvas-record';
 
 const colorAll = [
     '#5470c6',
@@ -42,7 +48,8 @@ export default defineComponent({
     },
     data() {
         return {
-            timeoutHandlers: []
+            timeoutHandlers: [],
+            isHidden: false
         };
     },
     watch: {
@@ -54,6 +61,48 @@ export default defineComponent({
     },
     methods: {
         run() {
+            this.doResetChart();
+            this.doRun();
+        },
+
+        clearTimeoutHandlers() {
+            for (let i = 0; i < this.timeoutHandlers.length; ++i) {
+                clearTimeout(this.timeoutHandlers[i]);
+            }
+            this.timeoutHandlers = [];
+        },
+
+        removeTimeoutHandlers(handler: number) {
+            for (let i = 0; i < this.timeoutHandlers.length; ++i) {
+                if (this.timeoutHandlers[i] === handler) {
+                    this.timeoutHandlers.splice(i, 1);
+                }
+            }
+        },
+
+        captureVideo(width?: number, height?: number): Promise<boolean> {
+            return new Promise(resolve => {
+                try {
+                    this.isHidden = true;
+                    this.doResetChart(width, height);
+                    const canvas = chart.getDom().children[0].children[0] as 
HTMLCanvasElement;
+                    const recorder = canvasRecord(canvas);
+
+                    this.doRun(5000, () => {
+                        recorder.stop();
+                        this.isHidden = false;
+                        resolve(true);
+                    });
+                }
+                catch (e) {
+                    console.error(e);
+                    this.isHidden = false;
+                    resolve(false);
+                }
+            });
+        },
+
+        doResetChart(width?: number, height?: number) {
             this.clearTimeoutHandlers();
             if (chart) {
                 chart.dispose();
@@ -64,9 +113,14 @@ export default defineComponent({
                 return;
             }
 
-            chart = echarts.init(this.$refs.chart as HTMLElement);
+            chart = echarts.init(this.$refs.chart as HTMLElement, null, {
+                width: width || undefined,
+                height: height || undefined
+            });
+
             const animationDuration = this.animationDuration;
             const option = {
+                backgroundColor: '#fff',
                 xAxis: {
                     type: 'value',
                     max: 'dataMax'
@@ -119,50 +173,52 @@ export default defineComponent({
                 animationEasingUpdate: 'linear'
             };
             chart.setOption(option as echarts.EChartsOption, true);
+        },
 
+        doRun(timePadding?: number, onCompleted?: Function) {
             const dataCnt = this.chartData.length - headerLength - 1;
             const that = this;
             for (let i = 0; i < dataCnt; ++i) {
                 (function (i: number) {
                     let timeout: number;
                     const timeoutCb = function () {
+                        const row = that.chartData[headerLength + i + 1] as 
string[];
                         chart.setOption({
                             series: [{
                                 type: 'bar',
                                 id: 'bar',
-                                data: (that.chartData[headerLength + i + 1] as 
string[]).slice(1).map(str => parseInt(str, 10)),
+                                data: row.slice(1).map(str => parseInt(str, 
10)),
                                 label: {
                                     valueAnimation: true
                                 }
+                            }],
+                            title: [{
+                                text: row[0]
                             }]
                         });
                         that.removeTimeoutHandlers(timeout);
+                        if (i === dataCnt - 1 && typeof onCompleted === 
'function') {
+                            setTimeout(onCompleted, timePadding);
+                        }
                     };
-                    timeout = window.setTimeout(timeoutCb, i * 
animationDuration);
+                    timeout = window.setTimeout(timeoutCb, i * 
that.animationDuration);
                     that.timeoutHandlers.push(timeout);
                 })(i);
             }
-        },
-
-        clearTimeoutHandlers() {
-            for (let i = 0; i < this.timeoutHandlers.length; ++i) {
-                clearTimeout(this.timeoutHandlers[i]);
-            }
-            this.timeoutHandlers = [];
-        },
-
-        removeTimeoutHandlers(handler: number) {
-            for (let i = 0; i < this.timeoutHandlers.length; ++i) {
-                if (this.timeoutHandlers[i] === handler) {
-                    this.timeoutHandlers.splice(i, 1);
-                }
-            }
         }
     }
 })
 </script>
 
-<style scoped>
-@layer utilities {
+<style>
+.hidden {
+    visibility: hidden;
+}
+
+#chart-hint {
+    position: absolute;
+    top: 55px;
+    left: 20px;
+    color: #999;
 }
 </style>
diff --git a/src/components/BTable.vue b/src/components/BTable.vue
index 72ec297..81a0c33 100644
--- a/src/components/BTable.vue
+++ b/src/components/BTable.vue
@@ -2,9 +2,6 @@
     <div>
         <div slot='header' class='clearfix text-base'>
             {{$t('data')}}
-            <a href="javascript:;" @click="run()">
-                <i class="el-icon-refresh"></i>
-            </a>
         </div>
         <div ref='table' id='table-panel' class='overflow-auto absolute 
bottom-4 top-14 left-5 right-5 border'>
         </div>
@@ -49,7 +46,9 @@ export default defineComponent({
                 [this.$i18n.t('color'), '', '', '', ''],
                 ['2017', '13', '11', '12', '14'],
                 ['2018', '20', '44', '34', '39'],
-                ['2019', '62', '75', '58', '63']
+                ['2019', '62', '75', '58', '63'],
+                ['2020', '98', '81', '78', '93'],
+                ['2021', '139', '98', '88', '143']
             ],
             table: null,
             debouncedTableChange: null

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

Reply via email to