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

Reply via email to