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 ebc588c WIP: use timeline ebc588c is described below commit ebc588c6430df7f598af0ebf25af0312dd02c98f Author: Ovilia <zwl.s...@gmail.com> AuthorDate: Mon Feb 21 14:53:16 2022 +0800 WIP: use timeline --- _body.html | 1 - index.html | 3 + src/App.vue | 13 ++- src/components/BBody.vue | 8 +- src/components/BChart.vue | 5 +- src/components/BTable.vue | 2 +- src/helper/timeline.ts | 226 ++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 249 insertions(+), 9 deletions(-) diff --git a/_body.html b/_body.html index 6587141..b207dca 100644 --- a/_body.html +++ b/_body.html @@ -1,5 +1,4 @@ <!-- Body HTML that will be final deployed --> -<link href="https://cdn.jsdelivr.net/npm/handsontable@6.2.2/dist/handsontable.min.css" rel="stylesheet" media="screen"> <div id="echarts-spa-app"></div> diff --git a/index.html b/index.html index fb9c74f..118b727 100644 --- a/index.html +++ b/index.html @@ -6,6 +6,9 @@ <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>ECharts WWW SPA Boilerplate</title> <style> + html { + font-size: 10px; + } body { padding: 0; margin: 0; diff --git a/src/App.vue b/src/App.vue index 7402473..e6f0df3 100644 --- a/src/App.vue +++ b/src/App.vue @@ -12,12 +12,11 @@ import BBody from './components/BBody.vue'; </script> -<style scoped lang="scss"> +<style> #echarts-spa-app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; - text-align: center; color: #2c3e50; position: absolute; @@ -29,10 +28,18 @@ import BBody from './components/BBody.vue'; .el-container { height: 100%; - margin-top: -50px; } .el-main { padding: 5px; } + +.text-base { + font-size: 1.5rem; + font-weight: bold; +} + +.text-sm { + font-size: 1.4rem; +} </style> \ No newline at end of file diff --git a/src/components/BBody.vue b/src/components/BBody.vue index 4033af5..8a60a1f 100644 --- a/src/components/BBody.vue +++ b/src/components/BBody.vue @@ -10,7 +10,7 @@ <h2>{{$t('chartConfigs')}}</h2> <el-row> <el-select v-model="selectedDemo" - @change="onTitleChanged()" + @change="onTitleChanged($event)" > <el-option value="complicated" @@ -245,7 +245,8 @@ export default defineComponent({ }); }, - onTitleChanged() { + onTitleChanged(event) { + console.log(event.target.value) if (this.selectedDemo === 'simple') { this.demoData = fruit; this.title = this.titleComplicated; @@ -337,11 +338,12 @@ export default defineComponent({ h1 { margin-bottom: 15px; font-weight: bold; + font-size: 1.5rem; } h2 { margin-bottom: 15px; - font-size: 16px; + font-size: 1.4rem; font-weight: bold; } diff --git a/src/components/BChart.vue b/src/components/BChart.vue index 192ffbb..b1e9d41 100644 --- a/src/components/BChart.vue +++ b/src/components/BChart.vue @@ -13,7 +13,7 @@ <div id="bar-race-preview" ref="chart" - class="absolute bottom-4 top-14 left-5 right-5 border" + class="absolute bottom-4 top-16 left-5 right-5 border" > </div> </div> @@ -23,6 +23,7 @@ import {defineComponent} from 'vue'; import * as echarts from 'echarts'; import canvasRecord from 'canvas-record'; +import * as timeline from '../helper/timeline'; const headerLength = 2; let chart: echarts.ECharts; @@ -71,6 +72,7 @@ export default defineComponent({ }, captureVideo(width: number, height: number, fps: number): Promise<boolean> { + timeline.startMock(); return new Promise(resolve => { try { this.isExportingVideo = true; @@ -105,6 +107,7 @@ export default defineComponent({ hasError = true; } + timeline.stopMock(); this.isExportingVideo = false; setTimeout(() => { this.run(); diff --git a/src/components/BTable.vue b/src/components/BTable.vue index 7c85ca5..9361d3c 100644 --- a/src/components/BTable.vue +++ b/src/components/BTable.vue @@ -3,7 +3,7 @@ <div slot='header' class='clearfix text-base'> {{$t('data')}} </div> - <div ref='table' id='table-panel' class='overflow-auto absolute bottom-4 top-14 left-5 right-5 border'> + <div ref='table' id='table-panel' class='overflow-auto absolute bottom-4 top-16 left-5 right-5 border'> </div> </div> </template> diff --git a/src/helper/timeline.ts b/src/helper/timeline.ts new file mode 100644 index 0000000..57a23f8 --- /dev/null +++ b/src/helper/timeline.ts @@ -0,0 +1,226 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +declare const window, __VRT_PLAYBACK_SPEED__, __VRT_LOG_ERRORS__, __VRT_TIMELINE_PAUSED__; + +let mockedRaf = null; +let mockedTimeout = null; +let mockedTimeoutClear = null; +let mockedInterval = null; +let mockedIntervalClear = null; + +if (typeof __VRT_PLAYBACK_SPEED__ === 'undefined') { + window.__VRT_PLAYBACK_SPEED__ = 1; +} +const nativeRaf = window.requestAnimationFrame; +const nativeSetTimeout = window.setTimeout; +const nativeSetInterval = window.setInterval; +const nativeClearTimeout = window.clearTimeout; +const nativeClearInterval = window.clearInterval; + +const FIXED_FRAME_TIME = 16; +const MAX_FRAME_TIME = 80; +const TIMELINE_START = 1566458693300; + +window.__VRT_TIMELINE_PAUSED__ = true; + +let realFrameStartTime = 0; + +/** Control timeline loop */ +let rafCbs = []; +let frameIdx = 0; +let timelineTime = 0; + +function runFrame() { + realFrameStartTime = NativeDate.now(); + frameIdx++; + timelineTime += FIXED_FRAME_TIME; + const currentRafCbs = rafCbs; + // Clear before calling the callbacks. raf may be registered in the callback + rafCbs = []; + currentRafCbs.forEach((cb) => { + try { + cb(); + } + catch (e) { + // Catch error to avoid following tasks. + __VRT_LOG_ERRORS__(e.toString()); + } + }); + flushTimeoutHandlers(); + flushIntervalHandlers(); +} +function timelineLoop() { + if (!__VRT_TIMELINE_PAUSED__) { + runFrame(); + } + nativeRaf(timelineLoop); +} +nativeRaf(timelineLoop); + +mockedRaf = function (cb) { + rafCbs.push(cb); +}; + +/** Mock setTimeout, setInterval */ +let timeoutHandlers = []; +let intervalHandlers = []; + +let timeoutId = 1; +let intervalId = 1; + +mockedTimeout = function (cb, timeout) { + const elapsedFrame = Math.ceil(Math.max(timeout || 0, 1) / FIXED_FRAME_TIME); + timeoutHandlers.push({ + callback: cb, + id: timeoutId, + frame: frameIdx + elapsedFrame + }); + + return timeoutId++; +} + +mockedTimeoutClear = function (id) { + const idx = timeoutHandlers.findIndex(handler => { + return handler.id === id + }); + if (idx >= 0) { + timeoutHandlers.splice(idx, 1); + } +} + +function flushTimeoutHandlers() { + // Copy the array. In case setTimeout/clearTimeout is invoked in the callback. + const savedTimeoutHandlers = timeoutHandlers.slice(); + for (let i = 0; i < savedTimeoutHandlers.length; i++) { + const handler = savedTimeoutHandlers[i]; + if (handler.frame === frameIdx) { + // Need find index again. In case setTimeout/clearTimeout is invoked in the callback. + const idx = timeoutHandlers.indexOf(handler); + timeoutHandlers.splice(idx, 1); + try { + handler.callback(); + } + catch (e) { + // Catch error to avoid following tasks. + __VRT_LOG_ERRORS__(e.toString()); + } + } + } +} + +mockedInterval = function (cb, interval) { + const intervalFrame = Math.ceil(Math.max(interval || 0, 1) / FIXED_FRAME_TIME); + intervalHandlers.push({ + callback: cb, + id: intervalId, + intervalFrame, + frame: frameIdx + intervalFrame + }); + + return intervalId++; +} + +mockedIntervalClear = function (id) { + const idx = intervalHandlers.findIndex(handler => { + return handler.id === id; + }); + if (idx >= 0) { + intervalHandlers.splice(idx, 1); + } +} + +function flushIntervalHandlers() { + // Copy the array. In case setInterval/clearInterval is invoked in the callback. + const savedIntervalHandlers = intervalHandlers.slice(); + for (let i = 0; i < savedIntervalHandlers.length; i++) { + const handler = savedIntervalHandlers[i]; + if (handler.frame === frameIdx) { + try { + handler.callback(); + } + catch (e) { + // Catch error to avoid following tasks. + __VRT_LOG_ERRORS__(e.toString()); + } + handler.frame += handler.intervalFrame; + } + } +} + +/** Mock Date */ + +const NativeDate = window.Date; + +const mockNow = function () { + // // Use same time in one frame. + // var realFrameTime = NativeDate.now(); + // // Split frame. Add 8ms offset on the second half + // // Avoid infinite loop when some logic determine whether to break the loop based on the execution time. + // // For example https://github.com/apache/echarts/blob/737e23c0054e6b501ecc6f562920cffae953b5c6/src/core/echarts.ts#L537 + // var frameDeltaTime = realFrameTime - realFrameStartTime; + var frameDeltaTime = 0; + // Use same time in one frame. + return TIMELINE_START + (timelineTime + frameDeltaTime) * window.__VRT_PLAYBACK_SPEED__; +}; +function MockDate(...args) { + if (!args.length) { + return new NativeDate(mockNow()); + } + else { + return new NativeDate(...args); + } +} +MockDate.prototype = Object.create(NativeDate.prototype); +Object.setPrototypeOf(MockDate, NativeDate); +MockDate.now = mockNow; +window.Date = MockDate; + +// TODO Do we need to mock performance? Or leave some API that can keep real. + + +export function start() { + window.__VRT_TIMELINE_PAUSED__ = false; +} + +export function pause() { + window.__VRT_TIMELINE_PAUSED__ = true; +} + +export function resume() { + window.__VRT_TIMELINE_PAUSED__ = false; +} + +export function startMock() { + window.requestAnimationFrame = mockedRaf; + window.setTimeout = mockedTimeout; + window.setInterval = mockedInterval; + window.clearTimeout = mockedTimeoutClear; + window.clearInterval = mockedIntervalClear; +} + +export function stopMock() { + window.requestAnimationFrame = nativeRaf; + window.setTimeout = nativeSetTimeout; + window.setInterval = nativeSetInterval; + window.clearTimeout = nativeClearTimeout; + window.clearInterval = nativeClearInterval; +} + +export { nativeRaf, nativeSetInterval, nativeSetTimeout }; --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@echarts.apache.org For additional commands, e-mail: commits-h...@echarts.apache.org