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