diff --git a/common/config/rush/pnpm-config.json b/common/config/rush/pnpm-config.json
index ca3a5c86..333d8ab6 100644
--- a/common/config/rush/pnpm-config.json
+++ b/common/config/rush/pnpm-config.json
@@ -89,7 +89,10 @@
* PNPM documentation: https://pnpm.io/package_json#pnpmoverrides
*/
"globalOverrides": {
- // "example1": "^1.0.0",
+ "@visactor/vrender": "0.19.20-alpha.2",
+ "@visactor/vrender-core": "0.19.20-alpha.2",
+ "@visactor/vrender-kits": "0.19.20-alpha.2",
+ "@visactor/vrender-components": "0.19.20-alpha.2"
// "example2": "npm:@company/example2@^1.0.0"
},
diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml
index 5105620c..0d83d6f4 100644
--- a/common/config/rush/pnpm-lock.yaml
+++ b/common/config/rush/pnpm-lock.yaml
@@ -1,5 +1,11 @@
lockfileVersion: 5.4
+overrides:
+ '@visactor/vrender': 0.19.20-alpha.2
+ '@visactor/vrender-core': 0.19.20-alpha.2
+ '@visactor/vrender-kits': 0.19.20-alpha.2
+ '@visactor/vrender-components': 0.19.20-alpha.2
+
importers:
.:
@@ -70,10 +76,10 @@ importers:
'@types/react': ^18.0.0
'@types/react-dom': ^18.0.0
'@visactor/vchart': 1.11.5
- '@visactor/vrender': 0.19.11
- '@visactor/vrender-components': 0.19.11
- '@visactor/vrender-core': 0.19.11
- '@visactor/vrender-kits': 0.19.11
+ '@visactor/vrender': 0.19.20-alpha.2
+ '@visactor/vrender-components': 0.19.20-alpha.2
+ '@visactor/vrender-core': 0.19.20-alpha.2
+ '@visactor/vrender-kits': 0.19.20-alpha.2
'@visactor/vutils': ~0.18.4
'@vitejs/plugin-react': 3.1.0
canvas: 2.11.2
@@ -90,10 +96,10 @@ importers:
vite: 3.2.6
dependencies:
'@visactor/vchart': 1.11.5
- '@visactor/vrender': 0.19.11
- '@visactor/vrender-components': 0.19.11
- '@visactor/vrender-core': 0.19.11
- '@visactor/vrender-kits': 0.19.11
+ '@visactor/vrender': 0.19.20-alpha.2
+ '@visactor/vrender-components': 0.19.20-alpha.2
+ '@visactor/vrender-core': 0.19.20-alpha.2
+ '@visactor/vrender-kits': 0.19.20-alpha.2
'@visactor/vutils': 0.18.8
devDependencies:
'@douyinfe/semi-ui': 2.62.1_nnrd3gsncyragczmpvfhocinkq
@@ -1965,7 +1971,6 @@ packages:
- supports-color
- ts-node
- utf-8-validate
- dev: true
/@jest/core/26.6.3_canvas@2.11.2:
resolution: {integrity: sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==}
@@ -2005,6 +2010,7 @@ packages:
- supports-color
- ts-node
- utf-8-validate
+ dev: true
/@jest/environment/24.9.0:
resolution: {integrity: sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ==}
@@ -2150,7 +2156,6 @@ packages:
- supports-color
- ts-node
- utf-8-validate
- dev: true
/@jest/test-sequencer/26.6.3_canvas@2.11.2:
resolution: {integrity: sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==}
@@ -2167,6 +2172,7 @@ packages:
- supports-color
- ts-node
- utf-8-validate
+ dev: true
/@jest/transform/24.9.0:
resolution: {integrity: sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==}
@@ -2287,6 +2293,7 @@ packages:
transitivePeerDependencies:
- encoding
- supports-color
+ dev: true
/@mdx-js/mdx/3.0.1:
resolution: {integrity: sha512-eIQ4QTrOWyL3LWEe/bu6Taqzq2HQvHcyTMaOrI95P2/LmJE7AsfPfgJGuFLPVqBUE1BC1rik3VIhU+s9u72arA==}
@@ -3217,9 +3224,9 @@ packages:
'@visactor/vgrammar-venn': 0.13.10
'@visactor/vgrammar-wordcloud': 0.13.10
'@visactor/vgrammar-wordcloud-shape': 0.13.10
- '@visactor/vrender-components': 0.19.11
- '@visactor/vrender-core': 0.19.11
- '@visactor/vrender-kits': 0.19.11
+ '@visactor/vrender-components': 0.19.20-alpha.2
+ '@visactor/vrender-core': 0.19.20-alpha.2
+ '@visactor/vrender-kits': 0.19.20-alpha.2
'@visactor/vscale': 0.18.9
'@visactor/vutils': 0.18.9
'@visactor/vutils-extension': 1.11.5
@@ -3260,9 +3267,9 @@ packages:
'@visactor/vdataset': 0.18.9
'@visactor/vgrammar-coordinate': 0.13.10
'@visactor/vgrammar-util': 0.13.10
- '@visactor/vrender-components': 0.19.11
- '@visactor/vrender-core': 0.19.11
- '@visactor/vrender-kits': 0.19.11
+ '@visactor/vrender-components': 0.19.20-alpha.2
+ '@visactor/vrender-core': 0.19.20-alpha.2
+ '@visactor/vrender-kits': 0.19.20-alpha.2
'@visactor/vscale': 0.18.9
'@visactor/vutils': 0.18.9
dev: false
@@ -3272,8 +3279,8 @@ packages:
dependencies:
'@visactor/vgrammar-core': 0.13.10
'@visactor/vgrammar-util': 0.13.10
- '@visactor/vrender-core': 0.19.11
- '@visactor/vrender-kits': 0.19.11
+ '@visactor/vrender-core': 0.19.20-alpha.2
+ '@visactor/vrender-kits': 0.19.20-alpha.2
'@visactor/vutils': 0.18.9
dev: false
@@ -3291,8 +3298,8 @@ packages:
dependencies:
'@visactor/vgrammar-core': 0.13.10
'@visactor/vgrammar-util': 0.13.10
- '@visactor/vrender-core': 0.19.11
- '@visactor/vrender-kits': 0.19.11
+ '@visactor/vrender-core': 0.19.20-alpha.2
+ '@visactor/vrender-kits': 0.19.20-alpha.2
'@visactor/vutils': 0.18.9
dev: false
@@ -3307,8 +3314,8 @@ packages:
dependencies:
'@visactor/vgrammar-core': 0.13.10
'@visactor/vgrammar-util': 0.13.10
- '@visactor/vrender-core': 0.19.11
- '@visactor/vrender-kits': 0.19.11
+ '@visactor/vrender-core': 0.19.20-alpha.2
+ '@visactor/vrender-kits': 0.19.20-alpha.2
'@visactor/vutils': 0.18.9
dev: false
@@ -3317,8 +3324,8 @@ packages:
dependencies:
'@visactor/vgrammar-core': 0.13.10
'@visactor/vgrammar-util': 0.13.10
- '@visactor/vrender-core': 0.19.11
- '@visactor/vrender-kits': 0.19.11
+ '@visactor/vrender-core': 0.19.20-alpha.2
+ '@visactor/vrender-kits': 0.19.20-alpha.2
'@visactor/vscale': 0.18.9
'@visactor/vutils': 0.18.9
dev: false
@@ -3328,41 +3335,41 @@ packages:
dependencies:
'@visactor/vgrammar-core': 0.13.10
'@visactor/vgrammar-util': 0.13.10
- '@visactor/vrender-core': 0.19.11
- '@visactor/vrender-kits': 0.19.11
+ '@visactor/vrender-core': 0.19.20-alpha.2
+ '@visactor/vrender-kits': 0.19.20-alpha.2
'@visactor/vutils': 0.18.9
dev: false
- /@visactor/vrender-components/0.19.11:
- resolution: {integrity: sha512-K9967q364GojufVIlEVxr9duE/ce7tHsBTHxWHjx+uGAiJy3gmG3Vx2Ch38yoDZorR47X+YFjBSJoIqNVOwi8Q==}
+ /@visactor/vrender-components/0.19.20-alpha.2:
+ resolution: {integrity: sha512-Clk9lFbdMDF1vOAyf4S/MBjCzLKurYSZZZLAzzTqRIimjFoaiZ0EqsspID4lscmmlBn4ENv396cusw4Aeoi3Kw==}
dependencies:
- '@visactor/vrender-core': 0.19.11
- '@visactor/vrender-kits': 0.19.11
+ '@visactor/vrender-core': 0.19.20-alpha.2
+ '@visactor/vrender-kits': 0.19.20-alpha.2
'@visactor/vscale': 0.18.9
- '@visactor/vutils': 0.18.9
+ '@visactor/vutils': 0.18.12
dev: false
- /@visactor/vrender-core/0.19.11:
- resolution: {integrity: sha512-an0zfDMJy9ygsXY1w2xSN2nWbUmy97YrBNDEvm0Nb/kS6tNpeB8G6z5t8KO2ivq5aVZihCIJv8342/yGOnDHfg==}
+ /@visactor/vrender-core/0.19.20-alpha.2:
+ resolution: {integrity: sha512-N0SN+lW5pFtBrUIl74n6VK//poLw4pdKga4EHsAJpPwDZUHLQdHG/69sMx9BMt60vKXgD5EnagH5uoh3DiJPkA==}
dependencies:
- '@visactor/vutils': 0.18.9
+ '@visactor/vutils': 0.18.12
color-convert: 2.0.1
dev: false
- /@visactor/vrender-kits/0.19.11:
- resolution: {integrity: sha512-ZzVZKVrRCuxC8+awhG3yxTwE8/qZpSTNCettTsTNs12oifeN6m+z2mvCSdHcOUn5Hw/FJyTFm2Bv2HmFNerQhw==}
+ /@visactor/vrender-kits/0.19.20-alpha.2:
+ resolution: {integrity: sha512-Jg7r1ebMHjDWRaSJTneZBtNHkk9vVZp2YWtPbsLEmgrNso0bdSnA9O5RVooQ47UPhNjcdr4PnN+DApHcezFULA==}
dependencies:
'@resvg/resvg-js': 2.4.1
- '@visactor/vrender-core': 0.19.11
- '@visactor/vutils': 0.18.9
+ '@visactor/vrender-core': 0.19.20-alpha.2
+ '@visactor/vutils': 0.18.12
roughjs: 4.5.2
dev: false
- /@visactor/vrender/0.19.11:
- resolution: {integrity: sha512-Gf/UivpfLuAn9ZL6Tai1y0CISll65ddQq4uJuzRidLtNQ0sCqZ0ognvey9KV4R+d4p7iklMBkWG4v8JQ3594hg==}
+ /@visactor/vrender/0.19.20-alpha.2:
+ resolution: {integrity: sha512-FdBRAbs5ibctEzvMJnY3VK+IopHaJ0iF/gdktCXCISKuaVESke3L8GVPkZ0+CD7LA5ZPryf61KgYDKaJGPPE1g==}
dependencies:
- '@visactor/vrender-core': 0.19.11
- '@visactor/vrender-kits': 0.19.11
+ '@visactor/vrender-core': 0.19.20-alpha.2
+ '@visactor/vrender-kits': 0.19.20-alpha.2
dev: false
/@visactor/vscale/0.18.9:
@@ -3378,6 +3385,14 @@ packages:
'@visactor/vutils': 0.18.9
dev: false
+ /@visactor/vutils/0.18.12:
+ resolution: {integrity: sha512-yPidlYp0daHX2bjR6CM8cAm6w3vK4MJhIuDMB41zoeFOeT8eP3kh6eLEU96DDOGxrxKZ/vDdBFJfqlPxZ3q6lw==}
+ dependencies:
+ '@turf/helpers': 6.5.0
+ '@turf/invariant': 6.5.0
+ eventemitter3: 4.0.7
+ dev: false
+
/@visactor/vutils/0.18.8:
resolution: {integrity: sha512-9+YODg9msVyObDbamt94lsEF/idV8gyW3lf31DhuKsLKbuB/ajvSg6jNKD/FTMoXpmCNwfZgZ0F6wXLwI5aIpw==}
dependencies:
@@ -3455,6 +3470,7 @@ packages:
/abbrev/1.1.1:
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
+ dev: true
/abs-svg-path/0.1.1:
resolution: {integrity: sha512-d8XPSGjfyzlXC3Xx891DJRyZfqk5JU0BJrDQcsWomFIV1/BIzPW5HDH5iDdWpqWaav0YVIEzT1RHTwWr0FFshA==}
@@ -3628,6 +3644,7 @@ packages:
/aproba/2.0.0:
resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==}
+ dev: true
/archy/1.0.0:
resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==}
@@ -3640,6 +3657,7 @@ packages:
dependencies:
delegates: 1.0.0
readable-stream: 3.6.2
+ dev: true
/arg/4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
@@ -4305,6 +4323,7 @@ packages:
transitivePeerDependencies:
- encoding
- supports-color
+ dev: true
/capture-exit/2.0.0:
resolution: {integrity: sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==}
@@ -4419,6 +4438,7 @@ packages:
/chownr/2.0.0:
resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
engines: {node: '>=10'}
+ dev: true
/ci-info/2.0.0:
resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==}
@@ -4670,6 +4690,7 @@ packages:
/console-control-strings/1.1.0:
resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
+ dev: true
/convert-source-map/1.9.0:
resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==}
@@ -4927,6 +4948,7 @@ packages:
engines: {node: '>=8'}
dependencies:
mimic-response: 2.1.0
+ dev: true
/deep-eql/4.1.3:
resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==}
@@ -5004,6 +5026,7 @@ packages:
/delegates/1.0.0:
resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
+ dev: true
/dequal/2.0.3:
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
@@ -5018,6 +5041,7 @@ packages:
/detect-libc/2.0.3:
resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
engines: {node: '>=8'}
+ dev: true
/detect-newline/2.1.0:
resolution: {integrity: sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg==}
@@ -6246,6 +6270,7 @@ packages:
engines: {node: '>= 8'}
dependencies:
minipass: 3.3.6
+ dev: true
/fs-mkdirp-stream/1.0.0:
resolution: {integrity: sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ==}
@@ -6308,6 +6333,7 @@ packages:
string-width: 4.2.3
strip-ansi: 6.0.1
wide-align: 1.1.5
+ dev: true
/gensync/1.0.0-beta.2:
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
@@ -6741,6 +6767,7 @@ packages:
/has-unicode/2.0.1:
resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==}
+ dev: true
/has-value/0.3.1:
resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==}
@@ -7470,7 +7497,6 @@ packages:
- supports-color
- ts-node
- utf-8-validate
- dev: true
/jest-cli/26.6.3_canvas@2.11.2:
resolution: {integrity: sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==}
@@ -7496,6 +7522,7 @@ packages:
- supports-color
- ts-node
- utf-8-validate
+ dev: true
/jest-config/24.9.0:
resolution: {integrity: sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ==}
@@ -7554,7 +7581,6 @@ packages:
- canvas
- supports-color
- utf-8-validate
- dev: true
/jest-config/26.6.3_canvas@2.11.2:
resolution: {integrity: sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==}
@@ -7588,6 +7614,7 @@ packages:
- canvas
- supports-color
- utf-8-validate
+ dev: true
/jest-diff/24.9.0:
resolution: {integrity: sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==}
@@ -7702,7 +7729,6 @@ packages:
- canvas
- supports-color
- utf-8-validate
- dev: true
/jest-environment-jsdom/26.6.2_canvas@2.11.2:
resolution: {integrity: sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==}
@@ -7720,6 +7746,7 @@ packages:
- canvas
- supports-color
- utf-8-validate
+ dev: true
/jest-environment-node/24.9.0:
resolution: {integrity: sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA==}
@@ -7860,7 +7887,6 @@ packages:
- supports-color
- ts-node
- utf-8-validate
- dev: true
/jest-jasmine2/26.6.3_canvas@2.11.2:
resolution: {integrity: sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==}
@@ -7890,6 +7916,7 @@ packages:
- supports-color
- ts-node
- utf-8-validate
+ dev: true
/jest-leak-detector/24.9.0:
resolution: {integrity: sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA==}
@@ -8098,7 +8125,6 @@ packages:
- supports-color
- ts-node
- utf-8-validate
- dev: true
/jest-runner/26.6.3_canvas@2.11.2:
resolution: {integrity: sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==}
@@ -8130,6 +8156,7 @@ packages:
- supports-color
- ts-node
- utf-8-validate
+ dev: true
/jest-runtime/24.9.0:
resolution: {integrity: sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw==}
@@ -8201,7 +8228,6 @@ packages:
- supports-color
- ts-node
- utf-8-validate
- dev: true
/jest-runtime/26.6.3_canvas@2.11.2:
resolution: {integrity: sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==}
@@ -8241,6 +8267,7 @@ packages:
- supports-color
- ts-node
- utf-8-validate
+ dev: true
/jest-serializer/24.9.0:
resolution: {integrity: sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==}
@@ -8388,7 +8415,6 @@ packages:
- supports-color
- ts-node
- utf-8-validate
- dev: true
/jest/26.6.3_canvas@2.11.2:
resolution: {integrity: sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==}
@@ -8404,6 +8430,7 @@ packages:
- supports-color
- ts-node
- utf-8-validate
+ dev: true
/js-string-escape/1.0.1:
resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==}
@@ -8501,7 +8528,6 @@ packages:
- bufferutil
- supports-color
- utf-8-validate
- dev: true
/jsdom/16.7.0_canvas@2.11.2:
resolution: {integrity: sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==}
@@ -8544,6 +8570,7 @@ packages:
- bufferutil
- supports-color
- utf-8-validate
+ dev: true
/jsesc/0.5.0:
resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==}
@@ -9586,6 +9613,7 @@ packages:
/mimic-response/2.1.0:
resolution: {integrity: sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==}
engines: {node: '>=8'}
+ dev: true
/minimatch/3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
@@ -9615,10 +9643,12 @@ packages:
engines: {node: '>=8'}
dependencies:
yallist: 4.0.0
+ dev: true
/minipass/5.0.0:
resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==}
engines: {node: '>=8'}
+ dev: true
/minizlib/2.1.2:
resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==}
@@ -9626,6 +9656,7 @@ packages:
dependencies:
minipass: 3.3.6
yallist: 4.0.0
+ dev: true
/mixin-deep/1.3.2:
resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==}
@@ -9735,6 +9766,7 @@ packages:
optional: true
dependencies:
whatwg-url: 5.0.0
+ dev: true
/node-int64/0.4.0:
resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==}
@@ -9760,6 +9792,7 @@ packages:
hasBin: true
dependencies:
abbrev: 1.1.1
+ dev: true
/normalize-package-data/2.5.0:
resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==}
@@ -9825,6 +9858,7 @@ packages:
console-control-strings: 1.1.0
gauge: 3.0.2
set-blocking: 2.0.0
+ dev: true
/number-is-nan/1.0.1:
resolution: {integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==}
@@ -11365,6 +11399,7 @@ packages:
/simple-concat/1.0.1:
resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==}
+ dev: true
/simple-get/3.1.1:
resolution: {integrity: sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==}
@@ -11372,6 +11407,7 @@ packages:
decompress-response: 4.2.1
once: 1.4.0
simple-concat: 1.0.1
+ dev: true
/simple-statistics/7.8.3:
resolution: {integrity: sha512-JFvMY00t6SBGtwMuJ+nqgsx9ylkMiJ5JlK9bkj8AdvniIe5615wWQYkKHXe84XtSuc40G/tlrPu0A5/NlJvv8A==}
@@ -11827,6 +11863,7 @@ packages:
minizlib: 2.1.2
mkdirp: 1.0.4
yallist: 4.0.0
+ dev: true
/terminal-link/2.1.1:
resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==}
@@ -12038,6 +12075,7 @@ packages:
/tr46/0.0.3:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
+ dev: true
/tr46/1.0.1:
resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==}
@@ -12070,7 +12108,7 @@ packages:
bs-logger: 0.2.6
buffer-from: 1.1.2
fast-json-stable-stringify: 2.1.0
- jest: 26.6.3_canvas@2.11.2
+ jest: 26.6.3
jest-util: 26.6.2
json5: 2.2.3
lodash: 4.17.21
@@ -12788,6 +12826,7 @@ packages:
/webidl-conversions/3.0.1:
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
+ dev: true
/webidl-conversions/4.0.2:
resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==}
@@ -12819,6 +12858,7 @@ packages:
dependencies:
tr46: 0.0.3
webidl-conversions: 3.0.1
+ dev: true
/whatwg-url/6.5.0:
resolution: {integrity: sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==}
@@ -12896,6 +12936,7 @@ packages:
resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
dependencies:
string-width: 4.2.3
+ dev: true
/word-wrap/1.2.5:
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
diff --git a/packages/vstory/demo/src/App.tsx b/packages/vstory/demo/src/App.tsx
index 62aef789..3841a316 100644
--- a/packages/vstory/demo/src/App.tsx
+++ b/packages/vstory/demo/src/App.tsx
@@ -1,14 +1,12 @@
import React, { Component, useCallback, useState } from 'react';
import { Nav } from '@douyinfe/semi-ui';
import { createRoot } from 'react-dom/client';
-import { SimpleBar } from './demos/SimpleBar';
-import { RankingBar } from './demos/RankingBar';
import { StoryBarDemo } from './demos/StoryBarDemo';
-import { StorySceneDemo } from './demos/StoryScene';
-import { AreaWithTag } from './demos/AreaWithTag';
-import { StoryLineDemo } from './demos/StoryLineDemo';
+// import { StorySceneDemo } from './demos/StoryScene';
+// import { AreaWithTag } from './demos/AreaWithTag';
+// import { StoryLineDemo } from './demos/StoryLineDemo';
import { useLocalStorage } from './hooks/useLocalStorage';
-import { StoryPieDemo } from './demos/StoryPieDemo';
+// import { StoryPieDemo } from './demos/StoryPieDemo';
import { GraphicActionDemo } from './demos/graphicAction';
import { VChartSiteDemo } from './demos/VChartSite/VChartSite';
import { DisAppear } from './demos/DisAppear';
@@ -18,6 +16,8 @@ import { GraphicEdit } from './demos/GraphicEdit';
import { Playground } from './demos/Playground';
import { Pictogram } from './demos/infographics/Pictogram';
import { LV_BAR1 } from './demos/lv/bar1';
+import { BarLineSeries } from './demos/BarLineSeries';
+import { wordcloud } from './demos/wordcloud';
type MenusType = (
| {
@@ -38,26 +38,18 @@ type MenusType = (
const App = () => {
const [activeName, setActiveName] = useLocalStorage('menuName', '');
const menus = [
- {
- name: 'SimpleBar',
- component: SimpleBar
- },
- {
- name: 'RankingBar',
- component: RankingBar
- },
{
name: 'Bar',
component: StoryBarDemo
},
- {
- name: 'Line',
- component: StoryLineDemo
- },
- {
- name: 'Pie',
- component: StoryPieDemo
- },
+ // {
+ // name: 'Line',
+ // component: StoryLineDemo
+ // },
+ // {
+ // name: 'Pie',
+ // component: StoryPieDemo
+ // },
// {
// name: 'StoryScene',
// component: StorySceneDemo
@@ -98,6 +90,14 @@ const App = () => {
name: 'Infographic-Pictogram',
component: Pictogram
},
+ {
+ name: 'BarLineSeries',
+ component: BarLineSeries
+ },
+ {
+ name: 'wordcloud',
+ component: wordcloud
+ },
{
name: 'lv_chart',
subMenus: [
diff --git a/packages/vstory/demo/src/demos/AreaWithTag.tsx b/packages/vstory/demo/src/demos/AreaWithTag.tsx
index e747eeeb..cbb51c76 100644
--- a/packages/vstory/demo/src/demos/AreaWithTag.tsx
+++ b/packages/vstory/demo/src/demos/AreaWithTag.tsx
@@ -1,160 +1,160 @@
-import React, { useEffect } from 'react';
-import VChart, { IAreaChartSpec } from '@visactor/vchart';
-import { StoryArea } from '../../../src/dsl/story-chart';
-import { StoryExecutor } from '../../../src/dsl/story-executor';
+// import React, { useEffect } from 'react';
+// import VChart, { IAreaChartSpec } from '@visactor/vchart';
+// import { StoryArea } from '../../../src/dsl/story-chart';
+// import { StoryExecutor } from '../../../src/dsl/story-executor';
-const values = [
- { type: 'Nail polish', country: 'Africa', value: 4229 },
- { type: 'Nail polish', country: 'EU', value: 4376 },
- { type: 'Nail polish', country: 'China', value: 3054 },
- { type: 'Nail polish', country: 'USA', value: 12814 },
- { type: 'Eyebrow pencil', country: 'Africa', value: 3932 },
- { type: 'Eyebrow pencil', country: 'EU', value: 3987 },
- { type: 'Eyebrow pencil', country: 'China', value: 5067 },
- { type: 'Eyebrow pencil', country: 'USA', value: 13012 },
- { type: 'Rouge', country: 'Africa', value: 5221 },
- { type: 'Rouge', country: 'EU', value: 3574 },
- { type: 'Rouge', country: 'China', value: 7004 },
- { type: 'Rouge', country: 'USA', value: 11624 },
- { type: 'Lipstick', country: 'Africa', value: 9256 },
- { type: 'Lipstick', country: 'EU', value: 4376 },
- { type: 'Lipstick', country: 'China', value: 9054 },
- { type: 'Lipstick', country: 'USA', value: 8814 },
- { type: 'Eyeshadows', country: 'Africa', value: 3308 },
- { type: 'Eyeshadows', country: 'EU', value: 4572 },
- { type: 'Eyeshadows', country: 'China', value: 12043 },
- { type: 'Eyeshadows', country: 'USA', value: 12998 },
- { type: 'Eyeliner', country: 'Africa', value: 5432 },
- { type: 'Eyeliner', country: 'EU', value: 3417 },
- { type: 'Eyeliner', country: 'China', value: 15067 },
- { type: 'Eyeliner', country: 'USA', value: 12321 },
- { type: 'Foundation', country: 'Africa', value: 13701 },
- { type: 'Foundation', country: 'EU', value: 5231 },
- { type: 'Foundation', country: 'China', value: 10119 },
- { type: 'Foundation', country: 'USA', value: 10342 },
- { type: 'Lip gloss', country: 'Africa', value: 4008 },
- { type: 'Lip gloss', country: 'EU', value: 4572 },
- { type: 'Lip gloss', country: 'China', value: 12043 },
- { type: 'Lip gloss', country: 'USA', value: 22998 },
- { type: 'Mascara', country: 'Africa', value: 18712 },
- { type: 'Mascara', country: 'EU', value: 6134 },
- { type: 'Mascara', country: 'China', value: 10419 },
- { type: 'Mascara', country: 'USA', value: 11261 }
-];
+// const values = [
+// { type: 'Nail polish', country: 'Africa', value: 4229 },
+// { type: 'Nail polish', country: 'EU', value: 4376 },
+// { type: 'Nail polish', country: 'China', value: 3054 },
+// { type: 'Nail polish', country: 'USA', value: 12814 },
+// { type: 'Eyebrow pencil', country: 'Africa', value: 3932 },
+// { type: 'Eyebrow pencil', country: 'EU', value: 3987 },
+// { type: 'Eyebrow pencil', country: 'China', value: 5067 },
+// { type: 'Eyebrow pencil', country: 'USA', value: 13012 },
+// { type: 'Rouge', country: 'Africa', value: 5221 },
+// { type: 'Rouge', country: 'EU', value: 3574 },
+// { type: 'Rouge', country: 'China', value: 7004 },
+// { type: 'Rouge', country: 'USA', value: 11624 },
+// { type: 'Lipstick', country: 'Africa', value: 9256 },
+// { type: 'Lipstick', country: 'EU', value: 4376 },
+// { type: 'Lipstick', country: 'China', value: 9054 },
+// { type: 'Lipstick', country: 'USA', value: 8814 },
+// { type: 'Eyeshadows', country: 'Africa', value: 3308 },
+// { type: 'Eyeshadows', country: 'EU', value: 4572 },
+// { type: 'Eyeshadows', country: 'China', value: 12043 },
+// { type: 'Eyeshadows', country: 'USA', value: 12998 },
+// { type: 'Eyeliner', country: 'Africa', value: 5432 },
+// { type: 'Eyeliner', country: 'EU', value: 3417 },
+// { type: 'Eyeliner', country: 'China', value: 15067 },
+// { type: 'Eyeliner', country: 'USA', value: 12321 },
+// { type: 'Foundation', country: 'Africa', value: 13701 },
+// { type: 'Foundation', country: 'EU', value: 5231 },
+// { type: 'Foundation', country: 'China', value: 10119 },
+// { type: 'Foundation', country: 'USA', value: 10342 },
+// { type: 'Lip gloss', country: 'Africa', value: 4008 },
+// { type: 'Lip gloss', country: 'EU', value: 4572 },
+// { type: 'Lip gloss', country: 'China', value: 12043 },
+// { type: 'Lip gloss', country: 'USA', value: 22998 },
+// { type: 'Mascara', country: 'Africa', value: 18712 },
+// { type: 'Mascara', country: 'EU', value: 6134 },
+// { type: 'Mascara', country: 'China', value: 10419 },
+// { type: 'Mascara', country: 'USA', value: 11261 }
+// ];
-export const AreaWithTag = () => {
- const id = 'areaWithTag';
+// export const AreaWithTag = () => {
+// const id = 'areaWithTag';
- useEffect(() => {
- // 准备一个图表
- const spec: IAreaChartSpec = {
- type: 'area',
- theme: 'dark',
- data: [
- {
- id: 'data',
- values: []
- }
- ],
- height: 500,
- padding: { left: 50, right: 50 },
- title: {
- visible: true,
- text: '100% stacked area chart of cosmetic products sales'
- },
- percent: true,
- xField: 'type',
- yField: 'value',
- seriesField: 'country',
- axes: [
- {
- orient: 'left',
- visible: false
- },
- {
- orient: 'bottom',
- trimPadding: true
- }
- ]
- };
+// useEffect(() => {
+// // 准备一个图表
+// const spec: IAreaChartSpec = {
+// type: 'area',
+// theme: 'dark',
+// data: [
+// {
+// id: 'data',
+// values: []
+// }
+// ],
+// height: 500,
+// padding: { left: 50, right: 50 },
+// title: {
+// visible: true,
+// text: '100% stacked area chart of cosmetic products sales'
+// },
+// percent: true,
+// xField: 'type',
+// yField: 'value',
+// seriesField: 'country',
+// axes: [
+// {
+// orient: 'left',
+// visible: false
+// },
+// {
+// orient: 'bottom',
+// trimPadding: true
+// }
+// ]
+// };
- const chartInstance = new VChart(spec, {
- dom: id
- });
+// const chartInstance = new VChart(spec, {
+// dom: id
+// });
- chartInstance.renderSync();
+// chartInstance.renderSync();
- // 创建叙事
- const area = new StoryArea();
+// // 创建叙事
+// const area = new StoryArea();
- const markPoint = area.createMarkPoint(
- {
- type: 'Nail polish',
- value: 0.05
- },
- {
- itemContent: {
- offsetY: -10,
- offsetX: -30,
- type: 'text',
- autoRotate: false,
- text: {
- text: '5%',
- dx: -10,
- style: {
- fill: 'black',
- fontSize: 14,
- fontWeight: 'bold'
- },
- labelBackground: {
- padding: [5, 10, 5, 10],
- style: {
- fill: 'rgb(122,209,182)',
- cornerRadius: 20
- }
- }
- }
- },
- itemLine: {
- endSymbol: {
- visible: false
- },
- startSymbol: { visible: false },
- line: {
- style: {
- visible: false
- }
- }
- }
- }
- );
+// const markPoint = area.createMarkPoint(
+// {
+// type: 'Nail polish',
+// value: 0.05
+// },
+// {
+// itemContent: {
+// offsetY: -10,
+// offsetX: -30,
+// type: 'text',
+// autoRotate: false,
+// text: {
+// text: '5%',
+// dx: -10,
+// style: {
+// fill: 'black',
+// fontSize: 14,
+// fontWeight: 'bold'
+// },
+// labelBackground: {
+// padding: [5, 10, 5, 10],
+// style: {
+// fill: 'rgb(122,209,182)',
+// cornerRadius: 20
+// }
+// }
+// }
+// },
+// itemLine: {
+// endSymbol: {
+// visible: false
+// },
+// startSymbol: { visible: false },
+// line: {
+// style: {
+// visible: false
+// }
+// }
+// }
+// }
+// );
- // 数据
- const usaData = values.filter(v => v.country === 'USA');
- const chinaData = values.filter(v => v.country === 'China');
- const EUData = values.filter(v => v.country === 'EU');
- const africaData = values.filter(v => v.country === 'Africa');
+// // 数据
+// const usaData = values.filter(v => v.country === 'USA');
+// const chinaData = values.filter(v => v.country === 'China');
+// const EUData = values.filter(v => v.country === 'EU');
+// const africaData = values.filter(v => v.country === 'Africa');
- area.add({ id: 'data', values: usaData });
- area.add({ id: 'data', values: EUData });
+// area.add({ id: 'data', values: usaData });
+// area.add({ id: 'data', values: EUData });
- markPoint.flicker();
+// markPoint.flicker();
- area.add({ id: 'data', values: chinaData });
- area.add({ id: 'data', values: africaData });
+// area.add({ id: 'data', values: chinaData });
+// area.add({ id: 'data', values: africaData });
- // TODO: executor 接口需要调整
- const storyPlayer = new StoryExecutor(area, {
- chartInstance,
- spec
- });
+// // TODO: executor 接口需要调整
+// const storyPlayer = new StoryExecutor(area, {
+// chartInstance,
+// spec
+// });
- storyPlayer.play();
+// storyPlayer.play();
- return () => {
- chartInstance.release();
- };
- }, []);
+// return () => {
+// chartInstance.release();
+// };
+// }, []);
- return
;
-};
+// return ;
+// };
diff --git a/packages/vstory/demo/src/demos/BarLineSeries.tsx b/packages/vstory/demo/src/demos/BarLineSeries.tsx
new file mode 100644
index 00000000..078bac3d
--- /dev/null
+++ b/packages/vstory/demo/src/demos/BarLineSeries.tsx
@@ -0,0 +1,136 @@
+import React, { useEffect } from 'react';
+import { IStorySpec } from '../../../src/story/interface';
+import { Story } from '../../../src/story/story';
+import '../../../src/story/index';
+// import { Animate } from '@visactor/vrender-core';
+
+// Animate.AddInterpolate('clipRange', (k, r, from, to, target, out) => {
+// console.log('animate', k, r, from, to);
+// });
+
+export const BarLineSeries = () => {
+ const id = 'storyBar';
+
+ useEffect(() => {
+ // 准备一个图表
+ const tempSpec: IStorySpec = {
+ characters: [
+ {
+ type: 'VChart',
+ id: 'bar-series',
+ zIndex: 10,
+ position: {
+ top: 40,
+ left: 50,
+ width: 500,
+ height: 500
+ },
+ options: {
+ spec: {
+ type: 'common',
+ animation: false,
+ seriesField: 'color',
+ data: [
+ {
+ id: 'id0',
+ values: [
+ { x: '周一', type: '早餐', y: 15 },
+ { x: '周一', type: '午餐', y: 25 },
+ { x: '周二', type: '早餐', y: 12 },
+ { x: '周二', type: '午餐', y: 30 },
+ { x: '周三', type: '早餐', y: 15 },
+ { x: '周三', type: '午餐', y: 24 },
+ { x: '周四', type: '早餐', y: 10 },
+ { x: '周四', type: '午餐', y: 25 },
+ { x: '周五', type: '早餐', y: 13 },
+ { x: '周五', type: '午餐', y: 20 },
+ { x: '周六', type: '早餐', y: 10 },
+ { x: '周六', type: '午餐', y: 22 },
+ { x: '周日', type: '早餐', y: 12 },
+ { x: '周日', type: '午餐', y: 19 }
+ ]
+ },
+ {
+ id: 'id1',
+ values: [
+ { x: '周一', type: '饮料', y: 22 },
+ { x: '周二', type: '饮料', y: 43 },
+ { x: '周三', type: '饮料', y: 33 },
+ { x: '周四', type: '饮料', y: 22 },
+ { x: '周五', type: '饮料', y: 10 },
+ { x: '周六', type: '饮料', y: 30 },
+ { x: '周日', type: '饮料', y: 50 }
+ ]
+ }
+ ],
+ series: [
+ {
+ type: 'bar',
+ id: 'bar',
+ dataIndex: 0,
+ label: { visible: true },
+ seriesField: 'type',
+ dataIndex: 0,
+ xField: ['x', 'type'],
+ yField: 'y'
+ },
+ {
+ type: 'line',
+ id: 'line',
+ dataIndex: 1,
+ label: { visible: true },
+ seriesField: 'type',
+ xField: 'x',
+ yField: 'y',
+ stack: false
+ }
+ ],
+ axes: [
+ { orient: 'left', seriesIndex: [0] },
+ { orient: 'right', seriesId: ['line'], grid: { visible: false } },
+ { orient: 'bottom', label: { visible: true }, type: 'band' }
+ ],
+ legends: {
+ visible: true,
+ orient: 'bottom'
+ }
+ }
+ }
+ }
+ ],
+ acts: [
+ {
+ id: 'default-chapter',
+ scenes: [
+ {
+ id: 'scene0',
+ actions: [
+ {
+ characterId: 'bar-series',
+ characterActions: [
+ {
+ startTime: 10,
+ action: 'appear',
+ selector: '*',
+ payload: {
+ style: {},
+ animation: {
+ duration: 10000,
+ easing: 'linear'
+ } as any
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ };
+ const story = new Story(tempSpec, { dom: id });
+ story.play();
+ }, []);
+
+ return ;
+};
diff --git a/packages/vstory/demo/src/demos/RankingBar.tsx b/packages/vstory/demo/src/demos/RankingBar.tsx
deleted file mode 100644
index fb51d6a1..00000000
--- a/packages/vstory/demo/src/demos/RankingBar.tsx
+++ /dev/null
@@ -1,87 +0,0 @@
-import React, { useEffect } from 'react';
-
-import { Bar } from '../../../src/template/charts/simple-chart';
-import { Scene } from '../../../src/scene';
-import { Title, textWriter } from '../../../src/component/title';
-
-import { RankingBar as RankingBarChart } from '../../../src/template/ranking-bar/ranking-bar';
-import { yearsData, countryImage } from '../../data/ranking-bar';
-
-export const RankingBar = () => {
- const domId = 'ranking';
- useEffect(() => {
- const allData: any[] = [];
- yearsData.forEach(value => {
- allData.push(...value);
- });
-
- const scene = new Scene({
- dom: domId
- });
- const rankingBar = new RankingBarChart({
- data: allData,
- timeField: 'Year',
- xField: 'Value',
- yField: 'CountryName',
- icon: Array.from(countryImage).reduce((obj: any, [key, value]) => {
- obj[key] = value;
- return obj;
- }, {}),
- // iconPosition: 'bar-end',
- // duration: 30000,
- interval: 400,
- // iconShape: 'rect',
- // iconPosition: 'axis',
- color: {
- China: 'red',
- USA: 'rgb(0,43,127)',
- India: '#FF9933',
- Russia: '#D52B1E',
- Japan: 'rgb(79,66,95)',
- Brazil: ' #009B3A',
- Mexico: 'rgb(1,101,69)',
- Indonesia: '#CE1126',
- Italy: '#009246',
- UK: 'rgb(27,63,126)',
- Germany: '#000000',
- France: '#0055A4',
- Pakistan: '#006600',
- Nigeria: '#008000'
- },
- nameLabel: {
- visible: true,
- position: 'bar-start',
- style: {
- // fill: 'white'
- }
- },
- timeLabel: {
- // visible: false
- },
- yAxis: {
- // domainLine: {
- // stroke: 'red',
- // lineWidth: 10
- // }
- }
- });
- (window as any).rankingBar = rankingBar;
-
- const title = new Title({
- text: 'A Ranking Bar Chart Demo',
- x: 0,
- y: 0,
- textStyle: {
- fontSize: 20
- }
- });
-
- scene.wait(800);
- scene.play(textWriter(title, 1000));
- scene.wait(1200);
-
- scene.add(rankingBar);
- }, []);
-
- return ;
-};
diff --git a/packages/vstory/demo/src/demos/SimpleBar.tsx b/packages/vstory/demo/src/demos/SimpleBar.tsx
deleted file mode 100644
index 9c595927..00000000
--- a/packages/vstory/demo/src/demos/SimpleBar.tsx
+++ /dev/null
@@ -1,81 +0,0 @@
-import React, { useEffect } from 'react';
-
-import { Bar } from '../../../src/template/charts/simple-chart';
-import { Scene } from '../../../src/scene';
-import { highlight } from '../../../src/animate/highlight';
-import { Title, textWriter } from '../../../src/component/title';
-import { yearsData } from '../../data/ranking-bar';
-
-export const SimpleBar = () => {
- const domId = 'simpleBar';
- useEffect(() => {
- const allData: any[] = [];
- yearsData.forEach(value => {
- allData.push(...value);
- });
-
- const scene = new Scene({
- dom: domId
- });
-
- const bar = new Bar({
- type: 'bar',
- width: 400,
- height: 300,
- data: [
- {
- id: 'barData',
- values: [
- { month: 'Monday', sales: 22 },
- { month: 'Tuesday', sales: 13 },
- { month: 'Wednesday', sales: 25 },
- { month: 'Thursday', sales: 29 },
- { month: 'Friday', sales: 38 }
- ]
- }
- ],
- xField: 'month',
- yField: 'sales',
- bar: {
- id: 'bar',
- state: {
- highlight: {}
- }
- }
- });
-
- const title = new Title({
- text: 'A Bar Chart Demo',
- x: 0,
- y: 0,
- textStyle: {
- fontSize: 20
- }
- });
-
- scene.wait(800);
- scene.play(textWriter(title, 1000));
- scene.wait(1200);
-
- scene.add(bar);
-
- // scene.wait(1000);
- // const ani = highlight(bar, [{ month: 'Friday' }, { month: 'Monday' }], { fill: 'green' });
- // scene.wait(1000);
-
- // ani && scene.play(ani);
- // scene.wait(2000);
-
- // const ani2 = highlight(bar, [{ month: 'Tuesday' }], {
- // fill: 'red',
- // shadowColor: 'rgba(0, 0, 0, 0.8)',
- // shadowBlur: 10
- // });
- // ani2 && scene.play(ani2);
- // scene.wait(1000);
- // scene.remove(title);
- // scene.remove(bar);
- }, []);
-
- return ;
-};
diff --git a/packages/vstory/demo/src/demos/StoryBarDemoPlay.tsx b/packages/vstory/demo/src/demos/StoryBarDemoPlay.tsx
index 5285930e..fa737541 100644
--- a/packages/vstory/demo/src/demos/StoryBarDemoPlay.tsx
+++ b/packages/vstory/demo/src/demos/StoryBarDemoPlay.tsx
@@ -1,101 +1,101 @@
-import React, { useEffect } from 'react';
-import VChart, { IChartSpec } from '@visactor/vchart';
-import { StoryBar } from '../../../src/dsl/story-chart';
-import { StoryExecutor } from '../../../src/dsl/story-executor';
-
-// class Player {
-// canvas: HTMLCanvasElement;
-// dpr: number;
-// width: number;
-// height: number;
-// constructor(canvas: HTMLCanvasElement, width: number, height: number) {
-// this.canvas = canvas;
-// this.dpr = window.devicePixelRatio;
-// this.width = width;
-// this.height = height;
-// this.canvas.width = width * this.dpr;
-// this.canvas.height = height * this.dpr;
-// }
-// addElements() {
-
-// }
-// tickTo() {
-
-// }
-// play() {
-
-// }
-// }
-
-export const StoryBarDemo = () => {
- const id = 'storyBar';
-
- useEffect(() => {
- // 准备一个图表
- const spec: IChartSpec = {
- type: 'bar',
- data: [
- {
- id: 'data',
- values: [{ value: 80, name: 'A' }]
- }
- ],
- xField: 'name',
- yField: 'value',
- bar: {
- state: {
- updateStyle: {}
- }
- },
- animationUpdate: {
- duration: 500
- }
- };
-
- const chartInstance = new VChart(spec, {
- dom: id
- });
-
- // chartInstance.renderSync();
-
- // 创建叙事
- const bar = new StoryBar();
-
- // 数据
- const data = [
- { key: 'a', value: 80, name: 'B' },
- { key: 'b', value: 120, name: 'C' },
- { key: 'c', value: 100, name: 'D' },
- { key: 'd', value: 300, name: 'E' }
- ];
-
- data.forEach(val => {
- bar.add(val, {
- style: {
- fillOpacity: 0.5
- }
- });
- });
-
- data.reverse().forEach(val => {
- bar.updateStyle(val, {
- style: {
- fill: 'red'
- }
- });
- });
-
- const storyPlayer = new StoryExecutor(bar, {
- chartInstance,
- spec
- });
-
- storyPlayer.play();
-
- return () => {
- chartInstance.release();
- };
- }, []);
-
- return ;
-};
+// import React, { useEffect } from 'react';
+// import VChart, { IChartSpec } from '@visactor/vchart';
+// import { StoryBar } from '../../../src/dsl/story-chart';
+// import { StoryExecutor } from '../../../src/dsl/story-executor';
+
+// // class Player {
+// // canvas: HTMLCanvasElement;
+// // dpr: number;
+// // width: number;
+// // height: number;
+// // constructor(canvas: HTMLCanvasElement, width: number, height: number) {
+// // this.canvas = canvas;
+// // this.dpr = window.devicePixelRatio;
+// // this.width = width;
+// // this.height = height;
+// // this.canvas.width = width * this.dpr;
+// // this.canvas.height = height * this.dpr;
+// // }
+// // addElements() {
+
+// // }
+// // tickTo() {
+
+// // }
+// // play() {
+
+// // }
+// // }
+
+// export const StoryBarDemo = () => {
+// const id = 'storyBar';
+
+// useEffect(() => {
+// // 准备一个图表
+// const spec: IChartSpec = {
+// type: 'bar',
+// data: [
+// {
+// id: 'data',
+// values: [{ value: 80, name: 'A' }]
+// }
+// ],
+// xField: 'name',
+// yField: 'value',
+// bar: {
+// state: {
+// updateStyle: {}
+// }
+// },
+// animationUpdate: {
+// duration: 500
+// }
+// };
+
+// const chartInstance = new VChart(spec, {
+// dom: id
+// });
+
+// // chartInstance.renderSync();
+
+// // 创建叙事
+// const bar = new StoryBar();
+
+// // 数据
+// const data = [
+// { key: 'a', value: 80, name: 'B' },
+// { key: 'b', value: 120, name: 'C' },
+// { key: 'c', value: 100, name: 'D' },
+// { key: 'd', value: 300, name: 'E' }
+// ];
+
+// data.forEach(val => {
+// bar.add(val, {
+// style: {
+// fillOpacity: 0.5
+// }
+// });
+// });
+
+// data.reverse().forEach(val => {
+// bar.updateStyle(val, {
+// style: {
+// fill: 'red'
+// }
+// });
+// });
+
+// const storyPlayer = new StoryExecutor(bar, {
+// chartInstance,
+// spec
+// });
+
+// storyPlayer.play();
+
+// return () => {
+// chartInstance.release();
+// };
+// }, []);
+
+// return ;
+// };
diff --git a/packages/vstory/demo/src/demos/StoryLineDemo.tsx b/packages/vstory/demo/src/demos/StoryLineDemo.tsx
index d6a242c1..8f0079e6 100644
--- a/packages/vstory/demo/src/demos/StoryLineDemo.tsx
+++ b/packages/vstory/demo/src/demos/StoryLineDemo.tsx
@@ -1,97 +1,97 @@
-import VChart, { ISpec, IVChart } from '@visactor/vchart';
-import React, { useEffect } from 'react';
-import { StoryExecutor } from '../../../src/dsl/story-executor';
-import { StoryLine } from '../../../src/dsl/story-chart/line';
+// import VChart, { ISpec, IVChart } from '@visactor/vchart';
+// import React, { useEffect } from 'react';
+// import { StoryExecutor } from '../../../src/dsl/story-executor';
+// import { StoryLine } from '../../../src/dsl/story-chart/line';
-export const StoryLineDemo = () => {
- const id = 'line';
+// export const StoryLineDemo = () => {
+// const id = 'line';
- useEffect(() => {
- // 准备一个图表
- const dataId = 'data';
- // 数据
- const values = [
- {
- time: '2:00',
- value: 8
- },
- {
- time: '4:00',
- value: 9
- },
- {
- time: '6:00',
- value: 11
- },
- {
- time: '8:00',
- value: 14
- },
- {
- time: '10:00',
- value: 16
- },
- {
- time: '12:00',
- value: 17
- },
- {
- time: '14:00',
- value: 17
- },
- {
- time: '16:00',
- value: 16
- },
- {
- time: '18:00',
- value: 15
- }
- ];
- const data = {
- id: dataId,
- values: values
- };
- const spec = {
- type: 'line',
- data: data,
- xField: 'time',
- yField: 'value'
- };
+// useEffect(() => {
+// // 准备一个图表
+// const dataId = 'data';
+// // 数据
+// const values = [
+// {
+// time: '2:00',
+// value: 8
+// },
+// {
+// time: '4:00',
+// value: 9
+// },
+// {
+// time: '6:00',
+// value: 11
+// },
+// {
+// time: '8:00',
+// value: 14
+// },
+// {
+// time: '10:00',
+// value: 16
+// },
+// {
+// time: '12:00',
+// value: 17
+// },
+// {
+// time: '14:00',
+// value: 17
+// },
+// {
+// time: '16:00',
+// value: 16
+// },
+// {
+// time: '18:00',
+// value: 15
+// }
+// ];
+// const data = {
+// id: dataId,
+// values: values
+// };
+// const spec = {
+// type: 'line',
+// data: data,
+// xField: 'time',
+// yField: 'value'
+// };
- const chartInstance = new VChart(spec, {
- dom: id
- });
+// const chartInstance = new VChart(spec, {
+// dom: id
+// });
- chartInstance.renderSync();
+// chartInstance.renderSync();
- // 创建叙事
- const line = new StoryLine();
- line.setInstance(chartInstance as IVChart);
+// // 创建叙事
+// const line = new StoryLine();
+// line.setInstance(chartInstance as IVChart);
- values.forEach((val, index) => {
- line.symbolStyle(val, {
- size: 15 + 10 * index,
- fill: 'red',
- fillOpacity: Math.random()
- });
- });
+// values.forEach((val, index) => {
+// line.symbolStyle(val, {
+// size: 15 + 10 * index,
+// fill: 'red',
+// fillOpacity: Math.random()
+// });
+// });
- line.lineStyle(values[1], {
- stroke: 'red'
- });
+// line.lineStyle(values[1], {
+// stroke: 'red'
+// });
- const storyPlayer = new StoryExecutor(line, {
- chartInstance: line.getInstance(),
- spec
- });
+// const storyPlayer = new StoryExecutor(line, {
+// chartInstance: line.getInstance(),
+// spec
+// });
- storyPlayer.play();
+// storyPlayer.play();
- return () => {
- chartInstance.release();
- };
- }, []);
+// return () => {
+// chartInstance.release();
+// };
+// }, []);
- return ;
-};
+// return ;
+// };
diff --git a/packages/vstory/demo/src/demos/StoryPieDemo.tsx b/packages/vstory/demo/src/demos/StoryPieDemo.tsx
index 466a4598..31746200 100644
--- a/packages/vstory/demo/src/demos/StoryPieDemo.tsx
+++ b/packages/vstory/demo/src/demos/StoryPieDemo.tsx
@@ -1,72 +1,72 @@
-import React, { useEffect } from 'react';
-import VChart, { IPieChartSpec } from '@visactor/vchart';
-import { StoryPie } from '../../../src/dsl/story-chart';
-import { StoryExecutor } from '../../../src/dsl/story-executor';
+// import React, { useEffect } from 'react';
+// import VChart, { IPieChartSpec } from '@visactor/vchart';
+// import { StoryPie } from '../../../src/dsl/story-chart';
+// import { StoryExecutor } from '../../../src/dsl/story-executor';
-export const StoryPieDemo = () => {
- const id = 'storyBar';
+// export const StoryPieDemo = () => {
+// const id = 'storyBar';
- useEffect(() => {
- // 数据
- const values = new Array(10).fill(0).map((d, i) => ({
- type: i + 1,
- value: i + 1
- }));
- const dataId = 'data';
- const data = {
- id: dataId,
- values: []
- };
+// useEffect(() => {
+// // 数据
+// const values = new Array(10).fill(0).map((d, i) => ({
+// type: i + 1,
+// value: i + 1
+// }));
+// const dataId = 'data';
+// const data = {
+// id: dataId,
+// values: []
+// };
- // 准备一个图表
- const spec: IPieChartSpec = {
- type: 'pie',
- data: data,
- outerRadius: 0.1,
- valueField: 'value',
- categoryField: 'type',
- animationUpdate: {
- duration: 300
- },
- label: {
- visible: true
- },
- animationAppear: {
- duration: 300
- }
- };
+// // 准备一个图表
+// const spec: IPieChartSpec = {
+// type: 'pie',
+// data: data,
+// outerRadius: 0.1,
+// valueField: 'value',
+// categoryField: 'type',
+// animationUpdate: {
+// duration: 300
+// },
+// label: {
+// visible: true
+// },
+// animationAppear: {
+// duration: 300
+// }
+// };
- const chartInstance = new VChart(spec, {
- dom: id
- });
+// const chartInstance = new VChart(spec, {
+// dom: id
+// });
- chartInstance.renderSync();
+// chartInstance.renderSync();
- // 创建叙事
- const pie = new StoryPie();
- pie.setInstance(chartInstance);
+// // 创建叙事
+// const pie = new StoryPie();
+// pie.setInstance(chartInstance);
- values.forEach((val, index) => {
- pie.add({ id: dataId, values: val }, {});
- });
+// values.forEach((val, index) => {
+// pie.add({ id: dataId, values: val }, {});
+// });
- values.forEach((val, index) => {
- pie.arcStyle(val, {
- outerRadius: 100 + index * 10
- });
- });
+// values.forEach((val, index) => {
+// pie.arcStyle(val, {
+// outerRadius: 100 + index * 10
+// });
+// });
- const storyPlayer = new StoryExecutor(pie, {
- chartInstance,
- spec
- });
+// const storyPlayer = new StoryExecutor(pie, {
+// chartInstance,
+// spec
+// });
- storyPlayer.play();
+// storyPlayer.play();
- return () => {
- chartInstance.release();
- };
- }, []);
+// return () => {
+// chartInstance.release();
+// };
+// }, []);
- return ;
-};
+// return ;
+// };
diff --git a/packages/vstory/demo/src/demos/wordcloud.tsx b/packages/vstory/demo/src/demos/wordcloud.tsx
new file mode 100644
index 00000000..5a896b3d
--- /dev/null
+++ b/packages/vstory/demo/src/demos/wordcloud.tsx
@@ -0,0 +1,110 @@
+import React, { useEffect } from 'react';
+import { IStorySpec } from '../../../src/story/interface';
+import { Story } from '../../../src/story/story';
+import '../../../src/story/index';
+// import { Animate } from '@visactor/vrender-core';
+
+// Animate.AddInterpolate('clipRange', (k, r, from, to, target, out) => {
+// console.log('animate', k, r, from, to);
+// });
+
+export const wordcloud = () => {
+ const id = 'storyBar';
+
+ useEffect(() => {
+ // 准备一个图表
+ const tempSpec: IStorySpec = {
+ characters: [
+ {
+ type: 'VChart',
+ id: 'bar-series',
+ zIndex: 10,
+ position: {
+ top: 40,
+ left: 50,
+ width: 500,
+ height: 500
+ },
+ options: {
+ spec: {
+ type: 'wordCloud',
+ nameField: 'name',
+ valueField: 'value',
+ wordCloudConfig: {
+ zoomToFit: {
+ enlarge: true,
+ fontSizeLimitMax: 20
+ }
+ },
+ data: {
+ name: 'baseData',
+ values: [
+ {
+ name: '螺蛳粉',
+ value: 957
+ },
+ {
+ name: '钵钵鸡',
+ value: 942
+ },
+ {
+ name: '板栗',
+ value: 842
+ },
+ {
+ name: '胡辣汤',
+ value: 828
+ },
+ {
+ name: '关东煮',
+ value: 665
+ },
+ {
+ name: '羊肉汤',
+ value: 627
+ },
+ {
+ name: '热干面',
+ value: 574
+ }
+ ]
+ }
+ }
+ }
+ }
+ ],
+ acts: [
+ {
+ id: 'default-chapter',
+ scenes: [
+ {
+ id: 'scene0',
+ actions: [
+ {
+ characterId: 'bar-series',
+ characterActions: [
+ {
+ startTime: 10,
+ action: 'appear',
+ payload: {
+ style: {},
+ animation: {
+ duration: 10000,
+ easing: 'linear'
+ } as any
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ };
+ const story = new Story(tempSpec, { dom: id });
+ story.play();
+ }, []);
+
+ return ;
+};
diff --git a/packages/vstory/package.json b/packages/vstory/package.json
index 0f0d26cd..d0625f66 100644
--- a/packages/vstory/package.json
+++ b/packages/vstory/package.json
@@ -25,11 +25,11 @@
},
"dependencies": {
"@visactor/vchart": "1.11.5",
- "@visactor/vrender": "0.19.11",
- "@visactor/vrender-core": "0.19.11",
- "@visactor/vrender-kits": "0.19.11",
- "@visactor/vutils": "~0.18.4",
- "@visactor/vrender-components": "0.19.11"
+ "@visactor/vrender": "0.19.20-alpha.2",
+ "@visactor/vrender-core": "0.19.20-alpha.2",
+ "@visactor/vrender-kits": "0.19.20-alpha.2",
+ "@visactor/vrender-components": "0.19.20-alpha.2",
+ "@visactor/vutils": "~0.18.4"
},
"devDependencies": {
"@internal/bundler": "workspace:*",
diff --git a/packages/vstory/src/animate/animate.ts b/packages/vstory/src/animate/animate.ts
index 16c88e4e..52c6ba11 100644
--- a/packages/vstory/src/animate/animate.ts
+++ b/packages/vstory/src/animate/animate.ts
@@ -1,32 +1,32 @@
-import type { IAnimate as IVRenderAnimate, IGraphic } from '@visactor/vrender';
-import type { IContext } from '../interface/type';
-import type { ITask, TaskCb } from '../task';
-import { AbstractTask } from '../task';
+// import type { IAnimate as IVRenderAnimate, IGraphic } from '@visactor/vrender';
+// import type { IContext } from '../interface/type';
+// import type { ITask, TaskCb } from '../task';
+// import { AbstractTask } from '../task';
-export class GraphicAnimate extends AbstractTask {
- protected _animate: IVRenderAnimate;
+// export class GraphicAnimate extends AbstractTask {
+// protected _animate: IVRenderAnimate;
- prev: ITask;
- next: ITask;
+// prev: ITask;
+// next: ITask;
- protected _target: IGraphic;
+// protected _target: IGraphic;
- constructor(target: IGraphic) {
- super();
- this._target = target;
- if (this._target) {
- this._animate = this._target.animate().afterAll(Array.from(this._target.animates.values()));
- }
- }
+// constructor(target: IGraphic) {
+// super();
+// this._target = target;
+// if (this._target) {
+// this._animate = this._target.animate().afterAll(Array.from(this._target.animates.values()));
+// }
+// }
- runCb(cb: TaskCb) {
- if (this._animate) {
- this._animate.runCb(cb);
- }
- }
+// runCb(cb: TaskCb) {
+// if (this._animate) {
+// this._animate.runCb(cb);
+// }
+// }
- // 覆写这个方法
- run(context: Partial) {
- return;
- }
-}
+// // 覆写这个方法
+// run(context: Partial) {
+// return;
+// }
+// }
diff --git a/packages/vstory/src/animate/highlight.ts b/packages/vstory/src/animate/highlight.ts
index f5f51882..4dc7cb71 100644
--- a/packages/vstory/src/animate/highlight.ts
+++ b/packages/vstory/src/animate/highlight.ts
@@ -1,54 +1,54 @@
-import type { Dict } from '@visactor/vutils';
-import { isArray } from '@visactor/vutils';
-import type { Template } from '../template/base-template';
-import type { Data, MaybeArray } from '../type/common';
-import { getAllSeriesMarksWithoutRoot } from '../util/vchart-api';
-import { GraphicAnimate } from './animate';
-import { Action } from '../scene/action';
+// import type { Dict } from '@visactor/vutils';
+// import { isArray } from '@visactor/vutils';
+// import type { Template } from '../template/base-template';
+// import type { Data, MaybeArray } from '../type/common';
+// import { getAllSeriesMarksWithoutRoot } from '../util/vchart-api';
+// import { GraphicAnimate } from './animate';
+// import { Action } from '../scene/action';
-export function highlight(template: Template, data: MaybeArray, style: Dict) {
- if (!data || !template) {
- return null;
- }
- const highlight = new HighLight(template, data, style);
- return new Action(highlight, highlight => {
- highlight.run();
- });
-}
+// export function highlight(template: Template, data: MaybeArray, style: Dict) {
+// if (!data || !template) {
+// return null;
+// }
+// const highlight = new HighLight(template, data, style);
+// return new Action(highlight, highlight => {
+// highlight.run();
+// });
+// }
-class HighLight extends GraphicAnimate {
- type = 'highlight';
+// class HighLight extends GraphicAnimate {
+// type = 'highlight';
- protected _duration: number;
- protected _dataList: Data[];
- protected _template: Template;
- protected _style: any;
+// protected _duration: number;
+// protected _dataList: Data[];
+// protected _template: Template;
+// protected _style: any;
- constructor(target: Template, data: MaybeArray, style: any, duration?: number) {
- super(null);
- this._duration = duration;
- this._dataList = isArray(data) ? data : [data];
- this._template = target;
- this._style = style;
- }
+// constructor(target: Template, data: MaybeArray, style: any, duration?: number) {
+// super(null);
+// this._duration = duration;
+// this._dataList = isArray(data) ? data : [data];
+// this._template = target;
+// this._style = style;
+// }
- run() {
- if (this._dataList.length) {
- const { _dataList, _style } = this;
- const vchart = this._template.vchartInstance();
- if (vchart) {
- const marks = getAllSeriesMarksWithoutRoot(vchart);
- if (marks && marks.length) {
- marks.forEach(mark => {
- mark.getProduct().encodeState('highlight', _style);
- });
- vchart.updateState({
- highlight: {
- filter: { datums: _dataList, dataKeys: undefined } as any
- }
- });
- }
- }
- }
- }
-}
+// run() {
+// if (this._dataList.length) {
+// const { _dataList, _style } = this;
+// const vchart = this._template.vchartInstance();
+// if (vchart) {
+// const marks = getAllSeriesMarksWithoutRoot(vchart);
+// if (marks && marks.length) {
+// marks.forEach(mark => {
+// mark.getProduct().encodeState('highlight', _style);
+// });
+// vchart.updateState({
+// highlight: {
+// filter: { datums: _dataList, dataKeys: undefined } as any
+// }
+// });
+// }
+// }
+// }
+// }
+// }
diff --git a/packages/vstory/src/component/title.ts b/packages/vstory/src/component/title.ts
deleted file mode 100644
index c18d1df2..00000000
--- a/packages/vstory/src/component/title.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-import type { IAnimate as IVRenderAnimate } from '@visactor/vrender';
-import { InputText } from '@visactor/vrender';
-import { GraphicAnimate } from '../animate/animate';
-import type { Title } from '@visactor/vrender-components';
-import type { IContext } from '../interface/type';
-import { Action } from '../scene/action';
-import type { TaskCb } from '../task';
-
-export function textWriter(title: Title, duration: number) {
- const _textWriter = new TextWriter(title, duration);
- return new Action(_textWriter, (_textWriter, context) => {
- if (context && context.stage) {
- context.stage.defaultLayer.add(_textWriter.getEntity());
- _textWriter.run();
- }
- });
-}
-
-export class TextWriter extends GraphicAnimate {
- protected _title: Title;
- getEntity() {
- return this._title;
- }
- protected _duration: number;
-
- protected _mainAnimate: IVRenderAnimate;
- protected _subAnimate: IVRenderAnimate;
-
- constructor(title: Title, duration: number) {
- super(null);
- this._title = title;
- this._duration = duration;
- }
-
- run(context: Partial): void {
- if (this._title && this._duration > 0) {
- // @ts-ignore
- const { _subtitle: subtitle, _mainTitle: mainTitle } = this._title;
- if (mainTitle) {
- this._mainAnimate = mainTitle.animate().play(
- new InputText(
- { text: '' },
- {
- text: mainTitle.attribute.text[0]
- },
- this._duration,
- 'linear'
- )
- );
- }
- if (subtitle) {
- this._subAnimate = subtitle.animate().play(
- new InputText(
- { text: '' },
- {
- text: subtitle.attribute.text
- },
- this._duration,
- 'linear'
- )
- );
- }
- }
- }
-
- runCb(cb: TaskCb): void {
- if (this._mainAnimate) {
- this._mainAnimate.runCb(cb);
- }
-
- if (this._subAnimate) {
- this._subAnimate.runCb(cb);
- }
- }
-}
-
-export { Title } from '@visactor/vrender-components';
diff --git a/packages/vstory/src/constants/action.ts b/packages/vstory/src/constants/action.ts
new file mode 100644
index 00000000..ab03b83f
--- /dev/null
+++ b/packages/vstory/src/constants/action.ts
@@ -0,0 +1,3 @@
+export const ACTION_TYPE = {
+ APPEAR: 'appear'
+};
diff --git a/packages/vstory/src/constants/character.ts b/packages/vstory/src/constants/character.ts
new file mode 100644
index 00000000..f4015003
--- /dev/null
+++ b/packages/vstory/src/constants/character.ts
@@ -0,0 +1,21 @@
+export const enum StoryChartType {
+ VCHART = 'VChart'
+}
+
+export enum StoryGraphicType {
+ RECT = 'RectComponent',
+ SHAPE = 'ShapeComponent',
+ LINE = 'LineComponent',
+ ARC = 'ArcComponent',
+ // AREA = 'AreaComponent',
+ PATH = 'PathComponent',
+ TEXT = 'TextComponent',
+ RICH_TEXT = 'RichTextComponent',
+ QIPAO = 'QipaoComponent',
+ IMAGE = 'ImageComponent'
+}
+
+export const enum StoryChartComponentType {
+ MARK_POINT = 'markPoint',
+ TITLE = 'title'
+}
diff --git a/packages/vstory/src/dsl/constant/index.ts b/packages/vstory/src/dsl/constant/index.ts
index 53b2a506..5ec7902f 100644
--- a/packages/vstory/src/dsl/constant/index.ts
+++ b/packages/vstory/src/dsl/constant/index.ts
@@ -1,17 +1,18 @@
export const enum StoryChartType {
- CHARACTER_CHART = 'CharacterChart',
- BAR = 'BarChart',
- LINE = 'LineChart',
- AREA = 'AreaChart',
- HISTOGRAM = 'HistogramChart',
- PIE = 'PieChart',
- ROSE = 'RoseChart',
- RADAR = 'RadarChart',
- RANGE_COLUMN = 'RangeColumnChart',
- SCATTER = 'ScatterChart',
- WORD_CLOUD = 'WordCloudChart',
- TREE_MAP = 'TreeMapChart',
- SUNBURST = 'SunburstChart'
+ // CHARACTER_CHART = 'CharacterChart',
+ // BAR = 'BarChart',
+ // LINE = 'LineChart',
+ // AREA = 'AreaChart',
+ // HISTOGRAM = 'HistogramChart',
+ // PIE = 'PieChart',
+ // ROSE = 'RoseChart',
+ // RADAR = 'RadarChart',
+ // RANGE_COLUMN = 'RangeColumnChart',
+ // SCATTER = 'ScatterChart',
+ // WORD_CLOUD = 'WordCloudChart',
+ // TREE_MAP = 'TreeMapChart',
+ // SUNBURST = 'SunburstChart',
+ VCHART = 'VChart'
}
export enum StoryGraphicType {
RECT = 'RectComponent',
diff --git a/packages/vstory/src/dsl/story-executor/index.ts b/packages/vstory/src/dsl/story-executor/index.ts
index 3b995050..d884f7d4 100644
--- a/packages/vstory/src/dsl/story-executor/index.ts
+++ b/packages/vstory/src/dsl/story-executor/index.ts
@@ -1,52 +1,52 @@
-import { IVChart, IChartSpec } from '@visactor/vchart';
-import { StoryChart } from '../story-chart';
-import { processorMap } from '../story-processor';
-import { ActionNode } from '../types';
-
-export interface StoryPlayerOption {
- chartInstance: IVChart;
- spec: IChartSpec;
-}
-
-export class StoryExecutor {
- private storyChart: StoryChart;
- protected processor: Record = {};
-
- private option: StoryPlayerOption;
- private snapshots: ActionNode[] = [];
-
- constructor(storyChart: StoryChart, option: StoryPlayerOption) {
- this.storyChart = storyChart;
- this.processor = processorMap[storyChart.storyChartType];
- this.option = option;
- this.snapshots = this.storyChart.exportSnapshot();
- }
-
- play = async () => {
- console.log(this.snapshots);
- for (let i = 0; i < this.snapshots.length; i++) {
- // TODO: 上个动作执行完后, 执行下一个.
- // eslint-disable-next-line promise/param-names
- await new Promise(res => {
- setTimeout(res, 500);
- });
-
- const snapshot = this.snapshots[i];
- const { action, elementId, elementType, callback } = snapshot;
-
- let processor;
- if (elementId === this.storyChart.uid) {
- processor = this.processor[action];
- } else {
- processor = processorMap[elementType][action];
- }
-
- if (processor) {
- await processor(this.option.chartInstance, this.option.spec, snapshot);
- if (callback) {
- callback(this.option.chartInstance, this.option.spec, snapshot as any);
- }
- }
- }
- };
-}
+// import { IVChart, IChartSpec } from '@visactor/vchart';
+// import { StoryChart } from '../story-chart';
+// import { processorMap } from '../story-processor';
+// import { ActionNode } from '../types';
+
+// export interface StoryPlayerOption {
+// chartInstance: IVChart;
+// spec: IChartSpec;
+// }
+
+// export class StoryExecutor {
+// private storyChart: StoryChart;
+// protected processor: Record = {};
+
+// private option: StoryPlayerOption;
+// private snapshots: ActionNode[] = [];
+
+// constructor(storyChart: StoryChart, option: StoryPlayerOption) {
+// this.storyChart = storyChart;
+// this.processor = processorMap[storyChart.storyChartType];
+// this.option = option;
+// this.snapshots = this.storyChart.exportSnapshot();
+// }
+
+// play = async () => {
+// console.log(this.snapshots);
+// for (let i = 0; i < this.snapshots.length; i++) {
+// // TODO: 上个动作执行完后, 执行下一个.
+// // eslint-disable-next-line promise/param-names
+// await new Promise(res => {
+// setTimeout(res, 500);
+// });
+
+// const snapshot = this.snapshots[i];
+// const { action, elementId, elementType, callback } = snapshot;
+
+// let processor;
+// if (elementId === this.storyChart.uid) {
+// processor = this.processor[action];
+// } else {
+// processor = processorMap[elementType][action];
+// }
+
+// if (processor) {
+// await processor(this.option.chartInstance, this.option.spec, snapshot);
+// if (callback) {
+// callback(this.option.chartInstance, this.option.spec, snapshot as any);
+// }
+// }
+// }
+// };
+// }
diff --git a/packages/vstory/src/dsl/story-processor/processorMap/processorMap.ts b/packages/vstory/src/dsl/story-processor/processorMap/processorMap.ts
index 7e7eac98..3073b273 100644
--- a/packages/vstory/src/dsl/story-processor/processorMap/processorMap.ts
+++ b/packages/vstory/src/dsl/story-processor/processorMap/processorMap.ts
@@ -60,52 +60,52 @@ export const componentProcessor = {
// 图表processor
export const processorChartMap = {
- [StoryChartType.CHARACTER_CHART]: commonProcessorMap,
- // [StoryChartType.CHARACTER_CHART]: characterProcessorMap,
- [StoryChartType.BAR]: {
- // 大多数都是通用的, 可以复用.
- ...editProcessor,
- ...viewProcessor,
- // 通用的, 但实现不同的, 可以直接覆盖
- createMarkPoint: createMarkPointProcessor,
- createTitle: createTitleProcessor,
- // 不通用的, 可直接覆盖, 重新定义
- barStyle: createMarkStyleProcessorByMarkType('rect'),
- appear: barAppearProcessor,
- disappear: barDisappearProcessor,
- dance: danceProcessor
- },
- [StoryChartType.LINE]: {
- ...editProcessor,
- ...viewProcessor,
- ...componentProcessor,
- lineStyle: lineStyleProcessor,
- appear: lineAppearProcessor,
- symbolStyle: createMarkStyleProcessorByMarkType('symbol')
- },
- [StoryChartType.PIE]: {
- ...editProcessor,
- ...viewProcessor,
- ...componentProcessor,
- arcStyle: createMarkStyleProcessorByMarkType('arc'),
- appear: pieAppearProcessor,
- disappear: pieDisappearProcessor
- },
- [StoryChartType.AREA]: {
- ...editProcessor,
- ...viewProcessor,
- ...componentProcessor,
- appear: areaAppearProcessor,
- disappear: areaDisappearProcessor,
- arcStyle: createMarkStyleProcessorByMarkType('arc')
- },
- [StoryChartType.RANGE_COLUMN]: rangeColumnProcessorMap,
- [StoryChartType.SCATTER]: scatterProcessorMap,
- [StoryChartType.ROSE]: roseProcessorMap,
- [StoryChartType.RADAR]: radarProcessorMap,
- [StoryChartType.WORD_CLOUD]: wordCloudProcessorMap,
- [StoryChartType.TREE_MAP]: treeMapProcessorMap,
- [StoryChartType.SUNBURST]: sunburstProcessorMap
+ // [StoryChartType.CHARACTER_CHART]: commonProcessorMap,
+ // // [StoryChartType.CHARACTER_CHART]: characterProcessorMap,
+ // [StoryChartType.BAR]: {
+ // // 大多数都是通用的, 可以复用.
+ // ...editProcessor,
+ // ...viewProcessor,
+ // // 通用的, 但实现不同的, 可以直接覆盖
+ // createMarkPoint: createMarkPointProcessor,
+ // createTitle: createTitleProcessor,
+ // // 不通用的, 可直接覆盖, 重新定义
+ // barStyle: createMarkStyleProcessorByMarkType('rect'),
+ // appear: barAppearProcessor,
+ // disappear: barDisappearProcessor,
+ // dance: danceProcessor
+ // },
+ // [StoryChartType.LINE]: {
+ // ...editProcessor,
+ // ...viewProcessor,
+ // ...componentProcessor,
+ // lineStyle: lineStyleProcessor,
+ // appear: lineAppearProcessor,
+ // symbolStyle: createMarkStyleProcessorByMarkType('symbol')
+ // },
+ // [StoryChartType.PIE]: {
+ // ...editProcessor,
+ // ...viewProcessor,
+ // ...componentProcessor,
+ // arcStyle: createMarkStyleProcessorByMarkType('arc'),
+ // appear: pieAppearProcessor,
+ // disappear: pieDisappearProcessor
+ // },
+ // [StoryChartType.AREA]: {
+ // ...editProcessor,
+ // ...viewProcessor,
+ // ...componentProcessor,
+ // appear: areaAppearProcessor,
+ // disappear: areaDisappearProcessor,
+ // arcStyle: createMarkStyleProcessorByMarkType('arc')
+ // },
+ // [StoryChartType.RANGE_COLUMN]: rangeColumnProcessorMap,
+ // [StoryChartType.SCATTER]: scatterProcessorMap,
+ // [StoryChartType.ROSE]: roseProcessorMap,
+ // [StoryChartType.RADAR]: radarProcessorMap,
+ // [StoryChartType.WORD_CLOUD]: wordCloudProcessorMap,
+ // [StoryChartType.TREE_MAP]: treeMapProcessorMap,
+ // [StoryChartType.SUNBURST]: sunburstProcessorMap
};
// 组件processor
@@ -127,7 +127,7 @@ export const commonMarkProcessor = {
bounce: bounceProcessor
};
-export const processorMarkMap = {};
+export const processorMarkMap: Record = {};
Object.values(StoryGraphicType).forEach(type => {
processorMarkMap[type] = commonMarkProcessor;
});
diff --git a/packages/vstory/src/player/encode.ts b/packages/vstory/src/player/encode.ts
new file mode 100644
index 00000000..e8817470
--- /dev/null
+++ b/packages/vstory/src/player/encode.ts
@@ -0,0 +1,67 @@
+// import { FFmpeg, createFFmpeg, fetchFile } from '@ffmpeg/ffmpeg';
+
+// export class Encoder {
+// private _FFMPEG: FFmpeg | null = null;
+// private _FFMPEG_Loaded = false;
+
+// constructor() {
+// this.initFFMPEG();
+// }
+
+// async initFFMPEG() {
+// this._FFMPEG = createFFmpeg({ log: true });
+// await this.loadFFmpeg();
+// }
+// async loadFFmpeg() {
+// if (this._FFMPEG_Loaded) {
+// return;
+// }
+// if (!this._FFMPEG) {
+// this._FFMPEG = createFFmpeg({ log: true });
+// }
+// await this._FFMPEG.load();
+// console.log('加载');
+// this._FFMPEG_Loaded = true;
+// }
+
+// async exportVideo(frameNum: number, fps: number, cb: (i: number) => Promise) {
+// const outName = `out`;
+// await this.loadFFmpeg();
+// const ffmpeg = this._FFMPEG;
+// if (!ffmpeg) {
+// return;
+// }
+// console.log(ffmpeg.isLoaded());
+
+// for (let i = 0; i < frameNum; i++) {
+// const data = await cb(i);
+// console.log(frameNum, i, data);
+// const num = `0000${i}`.slice(-3);
+
+// ffmpeg.FS('writeFile', `vstory.${num}.png`, await fetchFile(data));
+// }
+
+// await ffmpeg.run(
+// '-framerate',
+// fps.toString(),
+// '-pattern_type',
+// 'glob',
+// '-i',
+// '*.png',
+// '-c:v',
+// 'libx264',
+// '-pix_fmt',
+// 'yuv420p',
+// `${outName}.mp4`
+// );
+// for (let i = 0; i < frameNum; i++) {
+// const num = `0000${i}`.slice(-3);
+// ffmpeg.FS('unlink', `vstory.${num}.png`);
+// }
+// console.log('readFile');
+// const data = (this._FFMPEG as FFmpeg).FS('readFile', `${outName}.mp4`);
+// console.log('data', data);
+// const objUrl = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }));
+// return objUrl;
+// }
+// }
diff --git a/packages/vstory/src/player/interface/player.ts b/packages/vstory/src/player/interface/player.ts
new file mode 100644
index 00000000..cb637749
--- /dev/null
+++ b/packages/vstory/src/player/interface/player.ts
@@ -0,0 +1,11 @@
+import { ICharacter } from '../../story/character';
+import type { IActSpec } from '../../story/interface/dsl-interface';
+
+export interface IPlayer {
+ tickTo: (t: number) => void;
+ play: () => void;
+ encodeToVideo: (millsecond: number, fps: number) => Promise;
+ pause: () => void;
+ release: () => void;
+ initActs: (acts: IActSpec[]) => void;
+}
diff --git a/packages/vstory/src/player/interface/scheduler.ts b/packages/vstory/src/player/interface/scheduler.ts
new file mode 100644
index 00000000..81bd401a
--- /dev/null
+++ b/packages/vstory/src/player/interface/scheduler.ts
@@ -0,0 +1,7 @@
+import type { IActSpec } from '../../story/interface';
+import type { IActionItem } from '../scheduler';
+
+export interface IScheduler {
+ initActs: (acts: IActSpec[]) => void;
+ getActionsInRange: (fromTime: number, toTime: number) => IActionItem[];
+}
diff --git a/packages/vstory/src/player/player.ts b/packages/vstory/src/player/player.ts
new file mode 100644
index 00000000..724effc4
--- /dev/null
+++ b/packages/vstory/src/player/player.ts
@@ -0,0 +1,139 @@
+import type { IActSpec, IStory } from '../story/interface';
+import { IAction } from '../story/interface';
+import type { ICharacter } from '../story/character';
+import type { IPlayer } from './interface/player';
+import type { IActionProcessor } from './processor/interface/action-processor';
+import { ActionProcessor } from './processor/processor';
+import { processorMap } from './processor/processorMap';
+import type { IScheduler } from './interface/scheduler';
+import { Scheduler } from './scheduler';
+
+export class Ticker {
+ cb?: (delta: number) => void;
+ rafIdx = 0;
+ start(cb: (t: number) => void) {
+ this.stop();
+ this.cb = cb;
+ this._tick(0);
+ }
+
+ _tick = (lt: number) => {
+ const ct = Date.now();
+ this.cb && this.cb(lt === 0 ? 0 : ct - lt);
+ this.rafIdx = requestAnimationFrame(() => this._tick(ct));
+ };
+
+ stop() {
+ this.rafIdx && cancelAnimationFrame(this.rafIdx);
+ this.rafIdx = 0;
+ }
+}
+
+export class Player implements IPlayer {
+ protected _story: IStory;
+ protected _ticker: Ticker;
+ protected _currTime: number;
+ // protected _encoder: Encoder;
+ protected _actionProcessor: IActionProcessor;
+ protected _scheduler: IScheduler;
+
+ constructor(story: IStory, options?: { scaleX?: number; scaleY?: number }) {
+ this._story = story;
+ this._ticker = new Ticker();
+ this._currTime = 0;
+ this._story.canvas.getStage().defaultLayer.setAttributes({
+ scaleX: options?.scaleX ?? 1,
+ scaleY: options?.scaleY ?? 1
+ });
+ // this._encoder = new Encoder();
+ this._actionProcessor = new ActionProcessor(story, processorMap);
+ this._scheduler = new Scheduler(this._actionProcessor);
+ }
+
+ initActs(acts: IActSpec[]) {
+ this._scheduler.initActs(acts);
+ }
+
+ // 清除当前状态,一般用于回放操作
+ reset() {
+ return;
+ }
+
+ tickTo(t: number) {
+ // console.log(t);
+ const lastTime = this._currTime;
+ if (lastTime > t) {
+ this.reset();
+ this._currTime = 0;
+ this.tickTo(0);
+ }
+
+ const actions = this._scheduler.getActionsInRange(lastTime, t);
+ const characterSet = new Set();
+ actions.forEach(action => {
+ const character = this._story.getCharactersById(action.characterId);
+ characterSet.add(character);
+ this._actionProcessor.doAction(character.spec.type, action.actionSpec.action, character, action.actionSpec);
+ });
+
+ // 将character show出来
+ // TODO 后续放在appear处理,因为现在创建之后就会展示,所以只能先visible为false
+ characterSet.forEach(character => {
+ character.show();
+ });
+
+ this._currTime = t;
+ this._story.canvas.getStage().ticker.tickAt(t);
+ this._story.canvas.getStage().render();
+ }
+
+ play(): void {
+ this._ticker.stop();
+ this._currTime = 0;
+ this.reset();
+ this._ticker.start(t => {
+ this.tickTo(this._currTime + t);
+ });
+ }
+
+ async encodeToVideo(millsecond: number, fps: number): Promise {
+ // // if (!this._currChapter) {
+ // // return;
+ // // }
+ // const frameNum = (millsecond / 1000) * fps;
+ // const deltaT = 1000 / fps;
+ // this.tickTo(0);
+ // const objUrl = await this._encoder.exportVideo(frameNum, fps, async i => {
+ // const t = deltaT * i;
+ // this.tickTo(t);
+ // return new Promise((resolve, reject) => {
+ // this._canvas
+ // .getStage()
+ // .window.getContext()
+ // .canvas.nativeCanvas.toBlob((blob: any) => {
+ // if (blob) {
+ // resolve(blob);
+ // } else {
+ // // console.log('no blob');
+ // reject('no blob');
+ // }
+ // }, `image/png`);
+ // });
+ // });
+
+ // return objUrl;
+ return null;
+ }
+
+ pause(): void {
+ this._ticker.stop();
+ }
+
+ resume(): void {
+ this._ticker._tick(this._currTime);
+ }
+
+ release(): void {
+ return;
+ }
+}
diff --git a/packages/vstory/src/player/processor/chart/component/commonAppear.ts b/packages/vstory/src/player/processor/chart/component/commonAppear.ts
new file mode 100644
index 00000000..d47fca05
--- /dev/null
+++ b/packages/vstory/src/player/processor/chart/component/commonAppear.ts
@@ -0,0 +1,32 @@
+import type { IGroup } from '@visactor/vrender-core';
+import type { IChartAppearAction } from '../../interface/appear-action';
+
+export const commonGrow = (
+ instance: IGroup,
+ animation: IChartAppearAction['payload']['animation'],
+ option: { disappear: boolean }
+) => {
+ const { duration, easing } = animation;
+ const { disappear } = option;
+
+ instance = instance.getChildAt(0) as IGroup;
+ const width = instance.AABBBounds.width();
+ const height = instance.AABBBounds.height();
+ const opacityMap = disappear ? { from: width, to: 0 } : { from: 0, to: width };
+
+ instance.setAttributes({ width: opacityMap.from, height, clip: true });
+ instance.animate().to({ width: opacityMap.to }, duration, easing);
+};
+
+export const commonFade = (
+ instance: IGroup,
+ animation: IChartAppearAction['payload']['animation'],
+ option: { disappear: boolean }
+) => {
+ const { duration, easing } = animation;
+ const { disappear } = option;
+ const opacityMap = disappear ? { from: 1, to: 0 } : { from: 0, to: 1 };
+
+ instance.setAttributes({ baseOpacity: opacityMap.from });
+ instance.animate().to({ baseOpacity: opacityMap.to }, duration, easing);
+};
diff --git a/packages/vstory/src/player/processor/chart/component/legendsAppear.ts b/packages/vstory/src/player/processor/chart/component/legendsAppear.ts
new file mode 100644
index 00000000..35004bec
--- /dev/null
+++ b/packages/vstory/src/player/processor/chart/component/legendsAppear.ts
@@ -0,0 +1,21 @@
+import type { IChartAppearAction } from '../../interface/appear-action';
+import { commonFade, commonGrow } from './commonAppear';
+import type { IGroup } from '@visactor/vrender-core';
+
+export const runLegendsAppear = (
+ instance: IGroup,
+ animation: IChartAppearAction['payload']['animation'],
+ option: { disappear: boolean }
+) => {
+ switch (animation.effect) {
+ case 'grow': {
+ return commonGrow(instance, animation, option);
+ }
+ case 'fade': {
+ return commonFade(instance, animation, option);
+ }
+ default: {
+ return commonFade(instance, animation, option);
+ }
+ }
+};
diff --git a/packages/vstory/src/player/processor/chart/seriesmark/commonTransformMarkAppear.ts b/packages/vstory/src/player/processor/chart/seriesmark/commonTransformMarkAppear.ts
new file mode 100644
index 00000000..cacf079a
--- /dev/null
+++ b/packages/vstory/src/player/processor/chart/seriesmark/commonTransformMarkAppear.ts
@@ -0,0 +1,40 @@
+import type VChart from '@visactor/vchart';
+import type { IChartAppearAction } from '../../interface/appear-action';
+
+export const commonGrow = (
+ instance: VChart,
+ animation: IChartAppearAction['payload']['animation'],
+ typeList: string[],
+ option: { markIndex: number; disappear: boolean }
+) => {
+ const { duration, loop, oneByOne, easing } = animation;
+ const { disappear } = option;
+
+ const type = disappear ? typeList[1] : typeList[0];
+
+ return {
+ type,
+ duration,
+ loop,
+ oneByOne,
+ easing
+ };
+};
+
+export const commonFade = (
+ instance: VChart,
+ animation: IChartAppearAction['payload']['animation'],
+ option: { markIndex: number; disappear: boolean }
+) => {
+ const { duration, loop, oneByOne, easing } = animation;
+ const { disappear } = option;
+ const type = disappear ? 'fadeOut' : 'fadeIn';
+
+ return {
+ type,
+ duration,
+ loop,
+ oneByOne,
+ easing
+ };
+};
diff --git a/packages/vstory/src/player/processor/chart/seriesmark/transformLineAppear.ts b/packages/vstory/src/player/processor/chart/seriesmark/transformLineAppear.ts
new file mode 100644
index 00000000..d705c4ec
--- /dev/null
+++ b/packages/vstory/src/player/processor/chart/seriesmark/transformLineAppear.ts
@@ -0,0 +1,21 @@
+import type VChart from '@visactor/vchart';
+import type { IChartAppearAction } from '../../interface/appear-action';
+import { commonFade, commonGrow } from './commonTransformMarkAppear';
+
+export const transformLineAppear = (
+ instance: VChart,
+ animation: IChartAppearAction['payload']['animation'],
+ option: { markIndex: number; disappear: boolean }
+) => {
+ switch (animation.effect) {
+ case 'grow': {
+ return commonGrow(instance, animation, ['clipIn', 'clipOut'], option);
+ }
+ case 'fade': {
+ return commonFade(instance, animation, option);
+ }
+ default: {
+ return commonFade(instance, animation, option);
+ }
+ }
+};
diff --git a/packages/vstory/src/player/processor/chart/seriesmark/transformRectAppear.ts b/packages/vstory/src/player/processor/chart/seriesmark/transformRectAppear.ts
new file mode 100644
index 00000000..335fa66c
--- /dev/null
+++ b/packages/vstory/src/player/processor/chart/seriesmark/transformRectAppear.ts
@@ -0,0 +1,96 @@
+import type VChart from '@visactor/vchart';
+// import type { IChartAppearAction } from '../../../../types/chart/appear';
+import type { IOrientType } from '@visactor/vrender-components';
+import type { IChartAppearAction } from '../../interface/appear-action';
+import { commonFade } from './commonTransformMarkAppear';
+
+// 将payload转换为chart内置的动画type
+export const transformRectAppear = (
+ instance: VChart,
+ animation: IChartAppearAction['payload']['animation'],
+ option: { markIndex: number; disappear: boolean }
+) => {
+ switch (animation.effect) {
+ case 'grow': {
+ return rectGrow(instance, animation, {
+ ...option,
+ center: false
+ });
+ }
+ case 'centerGrow': {
+ return rectGrow(instance, animation, {
+ ...option,
+ center: true
+ });
+ }
+ case 'fade': {
+ return commonFade(instance, animation, {
+ ...option
+ });
+ }
+ }
+};
+
+const rectGrow = (
+ instance: VChart,
+ animation: IChartAppearAction['payload']['animation'],
+ option = { center: false, disappear: false }
+) => {
+ const { duration, loop, oneByOne, easing } = animation;
+ const { center, disappear } = option;
+ const direction = instance.getChart().getSpec().direction ?? 'vertical';
+ const xField = instance.getChart().getSpec().xField;
+ const yField = instance.getChart().getSpec().yField;
+ const [xAxis, yAxis] = getXYAxis(instance);
+
+ const type = disappear ? (center ? 'growCenterOut' : 'growHeightOut') : center ? 'growCenterIn' : 'growHeightIn';
+
+ return {
+ type: type,
+ duration,
+ loop,
+ oneByOne,
+ easing,
+ options: (datum: any, element: any, params: any) => {
+ const field = direction === 'vertical' ? yField : xField;
+ const data = datum?.[field];
+
+ if (direction === 'vertical') {
+ return {
+ overall: yAxis?.getScale(0).scale(0),
+ orient: data > 0 ? 'negative' : 'positive'
+ };
+ }
+ return {
+ overall: xAxis?.getScale(0).scale(0),
+ orient: data > 0 ? 'negative' : 'positive'
+ };
+ }
+ };
+};
+
+function isXAxis(orient: IOrientType) {
+ return orient === 'bottom' || orient === 'top';
+}
+
+function isYAxis(orient: IOrientType) {
+ return orient === 'left' || orient === 'right';
+}
+
+const getXYAxis = (instance: VChart) => {
+ const axes = instance.getChart().getComponentsByKey('axes');
+ const xAxis = axes.find(axis => {
+ const orient = (axis as any).getOrient();
+ if (isXAxis(orient)) {
+ return true;
+ }
+ }) as any;
+ const yAxis = axes.find(axis => {
+ const orient = (axis as any).getOrient();
+ if (isYAxis(orient)) {
+ return true;
+ }
+ }) as any;
+
+ return [xAxis, yAxis];
+};
diff --git a/packages/vstory/src/player/processor/chart/seriesmark/transformSymbolAppear.ts b/packages/vstory/src/player/processor/chart/seriesmark/transformSymbolAppear.ts
new file mode 100644
index 00000000..21cebe8d
--- /dev/null
+++ b/packages/vstory/src/player/processor/chart/seriesmark/transformSymbolAppear.ts
@@ -0,0 +1,21 @@
+import type VChart from '@visactor/vchart';
+import type { IChartAppearAction } from '../../interface/appear-action';
+import { commonFade, commonGrow } from './commonTransformMarkAppear';
+
+export const transformSymbolAppear = (
+ instance: VChart,
+ animation: IChartAppearAction['payload']['animation'],
+ option: { markIndex: number; disappear: boolean }
+) => {
+ switch (animation.effect) {
+ case 'grow': {
+ return commonGrow(instance, animation, ['scaleIn', 'scaleOut'], option);
+ }
+ case 'fade': {
+ return commonFade(instance, animation, option);
+ }
+ default: {
+ return commonFade(instance, animation, option);
+ }
+ }
+};
diff --git a/packages/vstory/src/player/processor/chart/seriesmark/transformTextAppear.ts b/packages/vstory/src/player/processor/chart/seriesmark/transformTextAppear.ts
new file mode 100644
index 00000000..e62e9cb9
--- /dev/null
+++ b/packages/vstory/src/player/processor/chart/seriesmark/transformTextAppear.ts
@@ -0,0 +1,25 @@
+import type VChart from '@visactor/vchart';
+import type { IChartAppearAction } from '../../interface/appear-action';
+import { commonFade, commonGrow } from './commonTransformMarkAppear';
+
+// 将payload转换为chart内置的动画type
+export const transformTextAppear = (
+ instance: VChart,
+ animation: IChartAppearAction['payload']['animation'],
+ option: {
+ disappear: boolean;
+ markIndex: number;
+ }
+) => {
+ switch (animation.effect) {
+ case 'grow': {
+ return commonGrow(instance, animation, ['scaleIn', 'scaleOut'], option);
+ }
+ case 'fade': {
+ return commonFade(instance, animation, option);
+ }
+ default: {
+ return commonFade(instance, animation, option);
+ }
+ }
+};
diff --git a/packages/vstory/src/player/processor/chart/transformMap.ts b/packages/vstory/src/player/processor/chart/transformMap.ts
new file mode 100644
index 00000000..3544e008
--- /dev/null
+++ b/packages/vstory/src/player/processor/chart/transformMap.ts
@@ -0,0 +1,17 @@
+import { runLegendsAppear } from './component/legendsAppear';
+import { transformLineAppear } from './seriesmark/transformLineAppear';
+import { transformRectAppear } from './seriesmark/transformRectAppear';
+import { transformSymbolAppear } from './seriesmark/transformSymbolAppear';
+import { transformTextAppear } from './seriesmark/transformTextAppear';
+
+export const transformMap = {
+ appear: {
+ // series & mark
+ rect: transformRectAppear,
+ line: transformLineAppear,
+ symbol: transformSymbolAppear,
+ text: transformTextAppear,
+ // component
+ legends: runLegendsAppear
+ }
+};
diff --git a/packages/vstory/src/player/processor/chart/vchart.ts b/packages/vstory/src/player/processor/chart/vchart.ts
new file mode 100644
index 00000000..0f60d7be
--- /dev/null
+++ b/packages/vstory/src/player/processor/chart/vchart.ts
@@ -0,0 +1,118 @@
+import type { IComponent, ISeries, IVChart } from '@visactor/vchart';
+import { merge } from '@visactor/vutils';
+import type { ICharacter } from '../../../story/character';
+import type { IAction } from '../../../story/interface';
+import { ActionProcessorItem } from '../processor-item';
+import { transformMap } from './transformMap';
+import type { IChartAppearAction } from '../interface/appear-action';
+
+export class VChartAppearActionProcessor extends ActionProcessorItem {
+ name: 'appear';
+
+ constructor() {
+ super();
+ }
+
+ getStartTimeAndDuration(action: IAction): { startTime: number; duration: number } {
+ const { startTime: globalStartTime = 0, duration: globalDuration } = action;
+ const { startTime = 0, duration = 0 } = action.payload?.animation ?? ({} as any);
+
+ const st = globalStartTime + startTime;
+ const d = globalDuration ?? duration;
+ return {
+ startTime: st,
+ duration: d
+ };
+ }
+
+ run(character: ICharacter, actionSpec: IAction): void {
+ const vchart = character.graphic._vchart as IVChart;
+ // series & mark
+ const seriesList = vchart.getChart().getAllSeries();
+ seriesList.forEach(series => {
+ this.commonSeriesAppear(vchart, series, actionSpec);
+ });
+ // component
+ const components = vchart.getChart().getAllComponents();
+ components.forEach(component => {
+ this.componentAppear(vchart, component, actionSpec);
+ });
+ }
+
+ protected componentAppear(vchart: IVChart, component: IComponent, actionSpec: IAction) {
+ if (component.type === 'label') {
+ this.labelComponentAppear(vchart, component, actionSpec);
+ } else if (component.specKey === 'legends') {
+ this.legendsComponentAppear(vchart, component, actionSpec);
+ }
+ }
+
+ protected labelComponentAppear(vchart: IVChart, component: IComponent, actionSpec: IAction) {
+ const vrenderComponents = component.getVRenderComponents();
+ vrenderComponents.forEach(group => {
+ return;
+ });
+ }
+ protected legendsComponentAppear(vchart: IVChart, component: IComponent, actionSpec: IAction) {
+ const vrenderComponents = component.getVRenderComponents();
+
+ vrenderComponents.forEach(group => {
+ const appearTransformFunc = (transformMap.appear as any).legends;
+ const { payload } = actionSpec;
+ const mergePayload = merge(
+ {},
+ (VChartAppearActionProcessor as any).legendsPayload || {},
+ payload
+ ) as IChartAppearAction['payload'];
+ appearTransformFunc(group, mergePayload.animation, {
+ disappear: false
+ });
+ });
+ }
+
+ protected seriesTypeToMarkType(seriesType: string) {
+ if (seriesType === 'bar') {
+ return 'rect';
+ }
+ return seriesType;
+ }
+
+ protected commonSeriesAppear(vchart: IVChart, series: ISeries, actionSpec: IAction) {
+ const marks = series.getMarksWithoutRoot();
+ if (!marks.length) {
+ return;
+ }
+ const { payload } = actionSpec;
+ marks.forEach((mark, markIndex) => {
+ const mergePayload = merge(
+ {},
+ (VChartAppearActionProcessor as any)[`${mark.type}Payload`] || {},
+ payload
+ ) as IChartAppearAction['payload'];
+ const product = mark.getProduct();
+ const appearTransform = (transformMap.appear as any)[mark.type];
+ const config =
+ appearTransform &&
+ appearTransform(vchart as any, mergePayload.animation, {
+ index: markIndex,
+ disappear: false
+ });
+ // @ts-ignore
+ product && product.animate.run(config || {});
+ });
+ }
+
+ static rectPayload: IChartAppearAction['payload'] = {
+ animation: {
+ effect: 'grow',
+ duration: 2000,
+ easing: 'cubicOut',
+ oneByOne: false,
+ loop: false
+ }
+ };
+ static linePayload: IChartAppearAction['payload'] = VChartAppearActionProcessor.rectPayload;
+ static symbolPayload: IChartAppearAction['payload'] = VChartAppearActionProcessor.rectPayload;
+ static textPayload: IChartAppearAction['payload'] = VChartAppearActionProcessor.rectPayload;
+ static legendsPayload: IChartAppearAction['payload'] = VChartAppearActionProcessor.rectPayload;
+}
diff --git a/packages/vstory/src/player/processor/interface/action-processor.ts b/packages/vstory/src/player/processor/interface/action-processor.ts
new file mode 100644
index 00000000..70e92be0
--- /dev/null
+++ b/packages/vstory/src/player/processor/interface/action-processor.ts
@@ -0,0 +1,22 @@
+import type { ICharacter } from '../../../story/character';
+import type { IAction } from '../../../story/interface';
+
+export interface IActionProcessorItem {
+ getStartTime: (action: IAction) => number;
+ getDuration: (action: IAction) => number;
+ getStartTimeAndDuration: (action: IAction) => { startTime: number; duration: number };
+
+ run: (...actionParams: any) => any;
+}
+
+export interface IActionProcessor {
+ getActInfo: (
+ characterId: string,
+ action: IAction
+ ) => {
+ startTime: number;
+ duration: number;
+ } | null;
+
+ doAction: (name: string, actionName: string, character: ICharacter, actionSpec: IAction) => void;
+}
diff --git a/packages/vstory/src/player/processor/interface/appear-action.ts b/packages/vstory/src/player/processor/interface/appear-action.ts
new file mode 100644
index 00000000..c756a1f0
--- /dev/null
+++ b/packages/vstory/src/player/processor/interface/appear-action.ts
@@ -0,0 +1,36 @@
+import type { EasingType } from '@visactor/vrender';
+
+export interface IAction {
+ action: string;
+ payload: Record;
+}
+
+export interface IAnimationParams {
+ duration: number;
+ easing?: EasingType;
+ loop?: number | boolean;
+}
+
+export interface IActionPayload {
+ animation?: IAnimationParams;
+}
+
+export interface IChartAppearPayLoad extends IActionPayload {
+ animation: IAnimationParams & {
+ oneByOne: boolean;
+ /**
+ * 柱状图支持: 'grow' | 'fade' | 'bounce'
+ * 折线图支持: 'grow' | 'fade'
+ * 饼图支持: 'grow' | 'fade' | 'growAngle' | 'growRadius'
+ */
+ effect: string;
+ };
+ fade?: { isBaseOpacity?: boolean };
+}
+
+export interface IChartAppearAction extends IAction {
+ action: 'appear';
+ payload: IChartAppearPayLoad;
+}
+
+export type AppearOption = Omit;
diff --git a/packages/vstory/src/player/processor/processor-item.ts b/packages/vstory/src/player/processor/processor-item.ts
new file mode 100644
index 00000000..c5b26a3e
--- /dev/null
+++ b/packages/vstory/src/player/processor/processor-item.ts
@@ -0,0 +1,23 @@
+import type { ICharacter } from '../../story/character';
+import type { IAction } from '../../story/interface';
+import type { IActionProcessorItem } from './interface/action-processor';
+
+export class ActionProcessorItem implements IActionProcessorItem {
+ getStartTime(action: IAction): number {
+ return this.getStartTimeAndDuration(action).startTime;
+ }
+ getDuration(action: IAction): number {
+ return this.getStartTimeAndDuration(action).duration;
+ }
+
+ getStartTimeAndDuration(action: IAction): { startTime: number; duration: number } {
+ return {
+ startTime: 0,
+ duration: 0
+ };
+ }
+
+ run(character: ICharacter, actionSpec: IAction): void {
+ return;
+ }
+}
diff --git a/packages/vstory/src/player/processor/processor.ts b/packages/vstory/src/player/processor/processor.ts
new file mode 100644
index 00000000..c0aace5d
--- /dev/null
+++ b/packages/vstory/src/player/processor/processor.ts
@@ -0,0 +1,121 @@
+import type { ICharacter } from '../../story/character';
+import type { IAction, IStory } from '../../story/interface';
+import { IActionsLink } from '../../story/interface';
+import { logger } from '../../util/output';
+import type { IActionProcessor, IActionProcessorItem } from './interface/action-processor';
+
+export type IProcessorMap = Record>;
+
+export interface IProcessorReturnType {
+ totalTime: number;
+ revertActionParams?: {
+ action: string;
+ payload: Record;
+ };
+}
+
+export class ActionProcessor implements IActionProcessor {
+ protected _processorMap: Map>;
+
+ private static _instance: ActionProcessor = null;
+ protected _story: IStory;
+
+ constructor(story: IStory, processorMap?: IProcessorMap) {
+ if (!ActionProcessor._instance) {
+ this.init(story, processorMap);
+ ActionProcessor._instance = this;
+ }
+ return ActionProcessor._instance;
+ }
+
+ protected init(story: IStory, processorMap?: IProcessorMap) {
+ this._processorMap = new Map();
+ if (processorMap) {
+ for (const key in processorMap) {
+ logger('info', `register ${key} processor.`); // TODO: remove log
+ this.registerProcessor(key, processorMap[key]);
+ }
+ }
+ this._story = story;
+ }
+
+ /**
+ * 添加Action,根据Action中的characterId添加对应的characterActions实例
+ * @param action
+ */
+ getActInfo(
+ characterId: string,
+ action: IAction
+ ): {
+ startTime: number;
+ duration: number;
+ } | null {
+ const character = this._story.getCharactersById(characterId);
+ if (!character) {
+ logger('error', `获取character失败,请检查 ${characterId} 是否绑定到一个合法的character`);
+ return null;
+ }
+
+ const processor = this.getProcessor(character.spec.type, action.action);
+
+ return processor.getStartTimeAndDuration(action);
+
+ // characterActions.forEach(action => {
+ // const processor = this.getProcessor(character.spec.type, action.action);
+ // });
+ }
+
+ /**
+ *
+ * @param name 操作对象名称
+ * @param processors 操作对象支持的 processor
+ * @returns boolean 注册是否成功
+ */
+ registerProcessor(name: string, processors: Record) {
+ if (!this._processorMap) {
+ return false;
+ }
+ // 重复注册,目前直接替代
+ this._processorMap.set(name, processors);
+ return true;
+ }
+
+ getProcessorList(name: string) {
+ return this._processorMap && this._processorMap.get(name);
+ }
+
+ getProcessor(name: string, actionName: string) {
+ return this._processorMap && this._processorMap.get(name)?.[actionName];
+ }
+
+ /**
+ * Execute action
+ * @param name
+ * @param actionName
+ * @param actionParams
+ * @returns IProcessorReturnType
+ */
+ doAction(name: string, actionName: string, character: ICharacter, actionSpec: IAction): void {
+ const processor = this.getProcessor(name, actionName);
+ if (processor) {
+ // eslint-disable-next-line no-console
+ logger('info', `Execute action => ${actionName}, character => ${name}`); // TODO: remove log
+ const actionResult = processor.run(character, actionSpec);
+ // eslint-disable-next-line no-console
+ logger('info', `Action Executed:`, actionResult); // TODO: remove log
+ return actionResult;
+ }
+ // eslint-disable-next-line no-console
+ logger('error', `Action not found: character => ${name}, action => ${actionName} `); // TODO: remove log
+ return undefined;
+ }
+
+ release() {
+ ActionProcessor._instance = null;
+
+ if (this._processorMap) {
+ this._processorMap.clear();
+ this._processorMap = null;
+ }
+ }
+}
diff --git a/packages/vstory/src/player/processor/processorMap.ts b/packages/vstory/src/player/processor/processorMap.ts
new file mode 100644
index 00000000..d72822f6
--- /dev/null
+++ b/packages/vstory/src/player/processor/processorMap.ts
@@ -0,0 +1,13 @@
+import { ACTION_TYPE } from '../../constants/action';
+import { StoryChartType } from '../../constants/character';
+import { VChartAppearActionProcessor } from './chart/vchart';
+
+export const processorChartMap = {
+ [StoryChartType.VCHART]: {
+ [ACTION_TYPE.APPEAR]: new VChartAppearActionProcessor()
+ }
+};
+
+export const processorMap = {
+ ...processorChartMap
+};
diff --git a/packages/vstory/src/player/scheduler.ts b/packages/vstory/src/player/scheduler.ts
new file mode 100644
index 00000000..a5f19192
--- /dev/null
+++ b/packages/vstory/src/player/scheduler.ts
@@ -0,0 +1,179 @@
+import { isNumber } from '@visactor/vutils';
+import type { IAction, IActSpec, ISceneSpec } from '../story/interface';
+import { IStory } from '../story/interface';
+import type { IActionProcessor } from './processor/interface/action-processor';
+import type { IScheduler } from './interface/scheduler';
+
+interface IActInfo {
+ startTime: number;
+ duration: number;
+ id: string;
+ sceneInfoList: ISceneInfo[];
+}
+interface ISceneInfo {
+ startTime: number;
+ duration: number;
+ id: string;
+ actionList: IActionItem[];
+}
+
+export interface IActionItem {
+ startTime: number;
+ duration: number;
+ actionSpec: IAction;
+ characterId: string;
+}
+
+class ActionItem implements IActionItem {
+ startTime: number;
+ duration: number;
+ actionSpec: IAction;
+ characterId: string;
+
+ constructor(st: number, d: number, as: IAction, ci: string) {
+ this.startTime = st;
+ this.duration = d;
+ this.actionSpec = as;
+ this.characterId = ci;
+ }
+}
+
+export class Scheduler implements IScheduler {
+ protected _actionProcessor: IActionProcessor;
+ protected _actsInfo: IActInfo[];
+
+ constructor(actionProcessor: IActionProcessor) {
+ this._actionProcessor = actionProcessor;
+ }
+
+ // static formatTimeInAction(time: number, action: IActInfo): number {
+ // const { duration } = action;
+ // if (time < startTime) {
+ // return time;
+ // }
+ // if (startTime + duration <= 0) {
+ // return time;
+ // }
+ // while (time > startTime + duration) {
+ // time -= startTime + duration;
+ // }
+ // return time;
+ // }
+
+ findActByTime(t: number) {
+ // 规范化t
+ const totalTime = this._actsInfo.reduce((t, actInfo) => Math.max(t, actInfo.startTime + actInfo.duration), 0);
+ if (totalTime <= 0) {
+ return {
+ actInfo: this._actsInfo[0],
+ t: 0
+ };
+ }
+ while (t > totalTime) {
+ t -= totalTime;
+ }
+ for (let i = 0; i < this._actsInfo.length; i++) {
+ const actInfo = this._actsInfo[i];
+ if (actInfo.startTime <= t && actInfo.startTime + actInfo.duration > t) {
+ return {
+ actInfo: actInfo,
+ t: t - actInfo.startTime
+ };
+ }
+ }
+ return {
+ actInfo: this._actsInfo[this._actsInfo.length - 1],
+ t: t - this._actsInfo[this._actsInfo.length - 1].startTime
+ };
+ }
+
+ /**
+ * 获取某个时间区间的所有Action,toTime实际上是当前时间,fromTime是上一次的时间
+ * 避免跳帧
+ * @param fromTime 上一次的时间
+ * @param toTime 当前时间
+ */
+ getActionsInRange(fromTime: number, toTime: number) {
+ // 先找到目前是在哪个幕中
+ const { actInfo: fromAct, t: formatFromTime } = this.findActByTime(fromTime);
+ const { actInfo: toAct, t: formatToTime } = this.findActByTime(toTime);
+ if (fromAct !== toAct) {
+ // TODO 跳帧了
+ }
+ // const formatFromTime = Scheduler.formatTimeInAction(fromTime, toAct);
+ // const formatToTime = Scheduler.formatTimeInAction(toTime, toAct);
+
+ const actions: IActionItem[] = [];
+ toAct.sceneInfoList.forEach(sceneInfo => {
+ const { startTime: sceneStartTime } = sceneInfo;
+ sceneInfo.actionList.forEach(actionInfo => {
+ const startTime = sceneStartTime + actionInfo.startTime;
+ if (startTime >= formatFromTime && startTime < formatToTime) {
+ actions.push(actionInfo);
+ }
+ });
+ });
+
+ return actions;
+ }
+
+ initActs(acts: IActSpec[]) {
+ // act与act之间是串联的
+ let startTime = 0;
+ this._actsInfo = acts.map(act => {
+ const actInfo = this._getActInfo(act, startTime);
+ startTime += actInfo.duration;
+ return actInfo;
+ });
+ }
+
+ protected _getActInfo(act: IActSpec, actStartTime: number): IActInfo {
+ let sceneStartTime = 0;
+ const sceneInfoList = act.scenes.map(scene => {
+ const sceneInfo = this._getSceneInfo(scene, sceneStartTime);
+ sceneStartTime = sceneInfo.startTime + (scene.delay ?? 0) + sceneInfo.duration;
+ return sceneInfo;
+ });
+ const startTime = sceneInfoList.reduce((st, info) => Math.min(info.startTime, st), 0);
+ const endTime = sceneInfoList.reduce((et, info) => Math.max(info.startTime + info.duration, et), 0);
+ return {
+ startTime: actStartTime,
+ duration: startTime + endTime - startTime,
+ id: act.id,
+ sceneInfoList
+ };
+ }
+
+ protected _getSceneInfo(scene: ISceneSpec, sceneStartTime: number): ISceneInfo {
+ let scene_st = 0;
+ let scene_et = 0;
+ const actionList: IActionItem[] = [];
+ scene.actions.forEach((action, actIdx) => {
+ let character_st = Infinity;
+ let character_et = -Infinity;
+ action.characterActions.forEach(ca => {
+ const info = this._actionProcessor.getActInfo(action.characterId, ca);
+ if (!info) {
+ return;
+ }
+ const item = new ActionItem(info.startTime, info.duration, ca, action.characterId);
+
+ character_st = Math.max(Math.min(item.startTime, character_st), 0);
+ character_et = Math.max(item.startTime + item.duration, character_et);
+ actionList.push(item);
+ });
+
+ scene_st = !actIdx ? character_st : Math.max(Math.min(character_st, scene_st), 0);
+ scene_et = !actIdx ? character_et : Math.max(character_et, scene_et);
+ });
+
+ const sceneInfo: ISceneInfo = {
+ startTime: sceneStartTime + scene_st,
+ duration: sceneStartTime + scene_et - scene_st,
+ id: scene.id,
+ actionList
+ };
+
+ return sceneInfo;
+ }
+}
diff --git a/packages/vstory/src/dsl/story-chart/component/title.ts b/packages/vstory/src/player/ticker.ts
similarity index 100%
rename from packages/vstory/src/dsl/story-chart/component/title.ts
rename to packages/vstory/src/player/ticker.ts
diff --git a/packages/vstory/src/scene/action.ts b/packages/vstory/src/scene/action.ts
index 5bf0c6d8..a2a06d4e 100644
--- a/packages/vstory/src/scene/action.ts
+++ b/packages/vstory/src/scene/action.ts
@@ -1,67 +1,67 @@
-import { IContext } from '../interface/type';
-import { AbstractTask, TaskCb } from '../task';
+// import { IContext } from '../interface/type';
+// import { AbstractTask, TaskCb } from '../task';
-export class Action extends AbstractTask {
- type = 'action';
+// export class Action extends AbstractTask {
+// type = 'action';
- protected _entity: any;
- protected _action: (entity: any, context?: Partial) => void;
+// protected _entity: any;
+// protected _action: (entity: any, context?: Partial) => void;
- protected _isResolved = false;
+// protected _isResolved = false;
- constructor(entity: any, add: (entity: any, context?: Partial) => void) {
- super();
- this._entity = entity;
- this._action = add;
- }
+// constructor(entity: any, add: (entity: any, context?: Partial) => void) {
+// super();
+// this._entity = entity;
+// this._action = add;
+// }
- run(context?: Partial) {
- if (this._entity && this._action) {
- this._action(this._entity, context);
- this._isResolved = true;
- }
- }
+// run(context?: Partial) {
+// if (this._entity && this._action) {
+// this._action(this._entity, context);
+// this._isResolved = true;
+// }
+// }
- runCb(cb: TaskCb): void {
- const intervalId = setInterval(() => {
- if (this._isResolved) {
- clearInterval(intervalId);
- cb();
- }
- });
- }
-}
+// runCb(cb: TaskCb): void {
+// const intervalId = setInterval(() => {
+// if (this._isResolved) {
+// clearInterval(intervalId);
+// cb();
+// }
+// });
+// }
+// }
-export class Wait extends AbstractTask {
- type = 'wait';
+// export class Wait extends AbstractTask {
+// type = 'wait';
- protected _duration: number;
+// protected _duration: number;
- protected _waiting = true;
- protected _playing = false;
+// protected _waiting = true;
+// protected _playing = false;
- constructor(duration: number) {
- super();
- this._duration = duration;
- }
+// constructor(duration: number) {
+// super();
+// this._duration = duration;
+// }
- run() {
- if (this._duration > 0 && !this._playing) {
- new Promise(resolve => {
- setTimeout(() => {
- this._waiting = false;
- }, this._duration);
- });
- this._playing = true;
- }
- }
+// run() {
+// if (this._duration > 0 && !this._playing) {
+// new Promise(resolve => {
+// setTimeout(() => {
+// this._waiting = false;
+// }, this._duration);
+// });
+// this._playing = true;
+// }
+// }
- runCb(cb: TaskCb): void {
- const intervalId = setInterval(() => {
- if (!this._waiting) {
- clearInterval(intervalId);
- cb();
- }
- });
- }
-}
+// runCb(cb: TaskCb): void {
+// const intervalId = setInterval(() => {
+// if (!this._waiting) {
+// clearInterval(intervalId);
+// cb();
+// }
+// });
+// }
+// }
diff --git a/packages/vstory/src/scene/index.ts b/packages/vstory/src/scene/index.ts
index 15df9a6f..ab04424a 100644
--- a/packages/vstory/src/scene/index.ts
+++ b/packages/vstory/src/scene/index.ts
@@ -1 +1 @@
-export * from './scene';
+// export * from './scene';
diff --git a/packages/vstory/src/scene/scene.ts b/packages/vstory/src/scene/scene.ts
index 56537984..de0c6e66 100644
--- a/packages/vstory/src/scene/scene.ts
+++ b/packages/vstory/src/scene/scene.ts
@@ -1,132 +1,132 @@
-import type { IContext } from 'src/interface/type';
-import { Template } from '../template/base-template';
-import type { INode, IStage } from '@visactor/vrender';
-import { container, createStage, preLoadAllModule, loadBrowserEnv } from '@visactor/vrender';
-import { calculateSize } from '../util/size';
-import { CreateUID } from '../util/common';
-import { AbstractComponent } from '@visactor/vrender-components';
-import type { ITask } from '../task';
-import { TaskManager } from '../task';
-import { Action, Wait } from './action';
-
-export class Scene {
- readonly id = CreateUID();
-
- protected template: Template;
-
- protected _stage: IStage;
-
- protected _container: HTMLElement;
-
- protected _canvas: HTMLCanvasElement;
-
- protected _context: IContext;
-
- private _taskManager = new TaskManager();
-
- constructor(options: any = {}) {
- const { dom, width, height } = options;
- if (document) {
- this._container = document.getElementById(dom) as HTMLCanvasElement;
- }
- if (!this._container) {
- throw Error('Container Not Found');
- }
-
- const { width: _width, height: _height } = calculateSize(this._container, { width, height });
-
- const canvas = document.createElement('canvas');
- canvas.width = _width * window.devicePixelRatio;
- canvas.height = _height * window.devicePixelRatio;
- canvas.style.width = _width + 'px';
- canvas.style.height = _height + 'px';
-
- canvas.id = `_story_chart_${this.id}_canvas`;
- this._canvas = canvas;
- this._container.append(canvas);
-
- const stage = this._initStage(_width, _height);
- this._stage = stage;
-
- this._context = {
- dom: this._container,
- canvas: this._canvas,
- width: _width,
- height: _height,
- stage
- };
- this._taskManager.setContext(this._context);
- }
-
- protected _initStage(width: number, height: number) {
- preLoadAllModule();
- loadBrowserEnv(container);
- const params = {
- width: width,
- height: height,
- disableDirtyBounds: true,
- autoRender: true,
- canvas: this._canvas,
- canvasControled: true,
- dpr: window.devicePixelRatio
- };
- return createStage(params) as unknown as IStage;
- }
-
- add(entity: Template | AbstractComponent) {
- let task: ITask;
- if (entity instanceof Template) {
- this.template = entity;
- task = new Action(entity, (entity: any) => {
- entity.render(this._context);
- });
- } else if (entity instanceof AbstractComponent && this._stage) {
- task = new Action(entity, (entity: any) => {
- this._stage.defaultLayer.add(entity as unknown as INode);
- });
- }
-
- if (task) {
- this._taskManager.next(task);
- }
-
- return this;
- }
-
- remove(entity: Template | AbstractComponent) {
- let task: ITask;
- if (entity instanceof Template) {
- this.template = entity;
- task = new Action(entity, (entity: any) => {
- entity.release();
- });
- } else if (entity instanceof AbstractComponent && this._stage) {
- task = new Action(entity, (entity: any) => {
- this._stage.defaultLayer.removeChild(entity as unknown as INode);
- });
- }
-
- if (task) {
- this._taskManager.next(task);
- }
-
- return this;
- }
-
- wait(duration: number) {
- if (duration > 0) {
- const wait = new Wait(duration);
- this._taskManager.next(wait);
- }
- }
-
- play(animate: ITask) {
- if (animate) {
- this._taskManager.next(animate);
- }
- }
-
- release() {
- return;
- }
-}
+// import type { IContext } from 'src/interface/type';
+// import { Template } from '../template/base-template';
+// import type { INode, IStage } from '@visactor/vrender';
+// import { container, createStage, preLoadAllModule, loadBrowserEnv } from '@visactor/vrender';
+// import { calculateSize } from '../util/size';
+// import { CreateUID } from '../util/common';
+// import { AbstractComponent } from '@visactor/vrender-components';
+// import type { ITask } from '../task';
+// import { TaskManager } from '../task';
+// import { Action, Wait } from './action';
+
+// export class Scene {
+// readonly id = CreateUID();
+
+// protected template: Template;
+
+// protected _stage: IStage;
+
+// protected _container: HTMLElement;
+
+// protected _canvas: HTMLCanvasElement;
+
+// protected _context: IContext;
+
+// private _taskManager = new TaskManager();
+
+// constructor(options: any = {}) {
+// const { dom, width, height } = options;
+// if (document) {
+// this._container = document.getElementById(dom) as HTMLCanvasElement;
+// }
+// if (!this._container) {
+// throw Error('Container Not Found');
+// }
+
+// const { width: _width, height: _height } = calculateSize(this._container, { width, height });
+
+// const canvas = document.createElement('canvas');
+// canvas.width = _width * window.devicePixelRatio;
+// canvas.height = _height * window.devicePixelRatio;
+// canvas.style.width = _width + 'px';
+// canvas.style.height = _height + 'px';
+
+// canvas.id = `_story_chart_${this.id}_canvas`;
+// this._canvas = canvas;
+// this._container.append(canvas);
+
+// const stage = this._initStage(_width, _height);
+// this._stage = stage;
+
+// this._context = {
+// dom: this._container,
+// canvas: this._canvas,
+// width: _width,
+// height: _height,
+// stage
+// };
+// this._taskManager.setContext(this._context);
+// }
+
+// protected _initStage(width: number, height: number) {
+// preLoadAllModule();
+// loadBrowserEnv(container);
+// const params = {
+// width: width,
+// height: height,
+// disableDirtyBounds: true,
+// autoRender: true,
+// canvas: this._canvas,
+// canvasControled: true,
+// dpr: window.devicePixelRatio
+// };
+// return createStage(params) as unknown as IStage;
+// }
+
+// add(entity: Template | AbstractComponent) {
+// let task: ITask;
+// if (entity instanceof Template) {
+// this.template = entity;
+// task = new Action(entity, (entity: any) => {
+// entity.render(this._context);
+// });
+// } else if (entity instanceof AbstractComponent && this._stage) {
+// task = new Action(entity, (entity: any) => {
+// this._stage.defaultLayer.add(entity as unknown as INode);
+// });
+// }
+
+// if (task) {
+// this._taskManager.next(task);
+// }
+
+// return this;
+// }
+
+// remove(entity: Template | AbstractComponent) {
+// let task: ITask;
+// if (entity instanceof Template) {
+// this.template = entity;
+// task = new Action(entity, (entity: any) => {
+// entity.release();
+// });
+// } else if (entity instanceof AbstractComponent && this._stage) {
+// task = new Action(entity, (entity: any) => {
+// this._stage.defaultLayer.removeChild(entity as unknown as INode);
+// });
+// }
+
+// if (task) {
+// this._taskManager.next(task);
+// }
+
+// return this;
+// }
+
+// wait(duration: number) {
+// if (duration > 0) {
+// const wait = new Wait(duration);
+// this._taskManager.next(wait);
+// }
+// }
+
+// play(animate: ITask) {
+// if (animate) {
+// this._taskManager.next(animate);
+// }
+// }
+
+// release() {
+// return;
+// }
+// }
diff --git a/packages/vstory/src/story/act/act.ts b/packages/vstory/src/story/act/act.ts
deleted file mode 100644
index de3b214d..00000000
--- a/packages/vstory/src/story/act/act.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export class Chapter {
- // 也许并不需要
-}
diff --git a/packages/vstory/src/story/canvas/canvas.ts b/packages/vstory/src/story/canvas/canvas.ts
index 6c2c77c9..a1bf0e1a 100644
--- a/packages/vstory/src/story/canvas/canvas.ts
+++ b/packages/vstory/src/story/canvas/canvas.ts
@@ -2,14 +2,14 @@ import type { Story } from '../story';
import type { IStage } from '@visactor/vrender';
import { createStage, vglobal, container, preLoadAllModule, ManualTicker } from '@visactor/vrender';
import { loadBrowserEnv } from '@visactor/vrender';
-import type { StoryEvent } from '../interface/runtime-interface';
+import type { IStoryCanvas, StoryEvent } from '../interface/runtime-interface';
import type { ICharacter } from '../character/runtime-interface';
preLoadAllModule();
loadBrowserEnv(container);
vglobal.setEnv('browser');
-export class StoryCanvas {
+export class StoryCanvas implements IStoryCanvas {
protected _story: Story;
protected _canvas: HTMLCanvasElement;
protected _stage: IStage;
diff --git a/packages/vstory/src/story/character-tree/character-tree.ts b/packages/vstory/src/story/character-tree/character-tree.ts
new file mode 100644
index 00000000..4ea8bf73
--- /dev/null
+++ b/packages/vstory/src/story/character-tree/character-tree.ts
@@ -0,0 +1,52 @@
+import type { ICharacter, ICharacterSpec } from '../character';
+import { StoryFactory } from '../factory/factory';
+import type { ICharacterTree, IStory } from '../interface';
+
+export class CharacterTree implements ICharacterTree {
+ protected _characters: { [key: string]: ICharacter } = {};
+ protected _story: IStory;
+
+ constructor(story: IStory) {
+ this._story = story;
+ }
+
+ getCharacters(): { [key: string]: ICharacter } {
+ return this._characters;
+ }
+
+ getCharactersById(key: string) {
+ return this._characters[key] || null;
+ }
+
+ addCharacter(spec: ICharacterSpec) {
+ const option = {
+ story: this._story,
+ canvas: this._story.canvas,
+ graphicParent: this._story.canvas.getStage().defaultLayer
+ };
+ if ((spec).id) {
+ if (!this._characters[(spec).id]) {
+ this._characters[(spec).id] = StoryFactory.createCharacter(spec, option);
+ }
+ return this._characters[(spec).id];
+ }
+ return null;
+ }
+
+ initCharacters(specs: ICharacterSpec[]): void {
+ const option = {
+ story: this._story,
+ canvas: this._story.canvas,
+ graphicParent: this._story.canvas.getStage().defaultLayer
+ };
+
+ specs.forEach(spec => {
+ if ((spec).id) {
+ if (!this._characters[(spec).id]) {
+ this._characters[(spec).id] = StoryFactory.createCharacter(spec, option);
+ }
+ return this._characters[(spec).id];
+ }
+ });
+ }
+}
diff --git a/packages/vstory/src/story/character/chart/character.ts b/packages/vstory/src/story/character/chart/character.ts
index 0bf55ad2..8d16dfc3 100644
--- a/packages/vstory/src/story/character/chart/character.ts
+++ b/packages/vstory/src/story/character/chart/character.ts
@@ -15,25 +15,6 @@ import { SeriesSpecRuntime } from './runtime/series-spec';
import type { StoryEvent } from '../../interface/runtime-interface';
import type { ICharacterPickInfo } from '../runtime-interface';
-const tempSpec = {
- type: 'bar',
- data: [
- {
- id: 'barData',
- values: [
- { month: 'Monday', sales: 22 },
- { month: 'Tuesday', sales: 13 },
- { month: 'Wednesday', sales: 25 },
- { month: 'Thursday', sales: 29 },
- { month: 'Friday', sales: 38 }
- ]
- }
- ],
- xField: 'month',
- yField: 'sales',
- axes: [{ orient: 'bottom', label: { visible: false } }]
-};
-
export class CharacterChart extends CharacterVisactor {
static type = 'CharacterChart';
static RunTime: IChartCharacterRuntimeConstructor[] = [
@@ -72,7 +53,7 @@ export class CharacterChart extends CharacterVisactor {
y1: layout.y,
y2: layout.y + layout.height
};
- const spec = cloneDeep(this._specProcess.getVisSpec() ?? this._spec.options.spec);
+ const spec = cloneDeep(this._specProcess.getVisSpec());
spec.width = layout.width;
spec.height = layout.height;
// @ts-ignore
diff --git a/packages/vstory/src/story/character/chart/characters/area.ts b/packages/vstory/src/story/character/chart/characters/area.ts
deleted file mode 100644
index a1c2d441..00000000
--- a/packages/vstory/src/story/character/chart/characters/area.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { StoryFactory } from '../../../factory/factory';
-import { CharacterChart } from '../character';
-import { AreaTemp } from '../temp/templates/area';
-
-StoryFactory.registerChartTemp(AreaTemp.type, AreaTemp);
-
-export class AreaChartCharacter extends CharacterChart {
- static type = 'AreaChart';
-}
diff --git a/packages/vstory/src/story/character/chart/characters/bar.ts b/packages/vstory/src/story/character/chart/characters/bar.ts
deleted file mode 100644
index 124b9ab5..00000000
--- a/packages/vstory/src/story/character/chart/characters/bar.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { StoryFactory } from '../../../factory/factory';
-import { CharacterChart } from '../character';
-import { BarTemp } from '../temp/templates/bar';
-
-StoryFactory.registerChartTemp(BarTemp.type, BarTemp);
-
-export class BarChartCharacter extends CharacterChart {
- static type = 'BarChart';
-}
diff --git a/packages/vstory/src/story/character/chart/characters/line.ts b/packages/vstory/src/story/character/chart/characters/line.ts
deleted file mode 100644
index 809357f1..00000000
--- a/packages/vstory/src/story/character/chart/characters/line.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { StoryFactory } from '../../../factory/factory';
-import { CharacterChart } from '../character';
-import { LineTemp } from '../temp/templates/line';
-
-StoryFactory.registerChartTemp(LineTemp.type, LineTemp);
-
-export class LineChartCharacter extends CharacterChart {
- static type = 'LineChart';
-}
diff --git a/packages/vstory/src/story/character/chart/characters/pie.ts b/packages/vstory/src/story/character/chart/characters/pie.ts
deleted file mode 100644
index 6ce0d72e..00000000
--- a/packages/vstory/src/story/character/chart/characters/pie.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { StoryFactory } from '../../../factory/factory';
-import { CharacterChart } from '../character';
-import { PieTemp } from '../temp/templates/pie';
-
-StoryFactory.registerChartTemp(PieTemp.type, PieTemp);
-
-export class PieChartCharacter extends CharacterChart {
- static type = 'PieChart';
-}
diff --git a/packages/vstory/src/story/character/chart/characters/radar.ts b/packages/vstory/src/story/character/chart/characters/radar.ts
deleted file mode 100644
index 0c970b9b..00000000
--- a/packages/vstory/src/story/character/chart/characters/radar.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { StoryFactory } from '../../../factory/factory';
-import { CharacterChart } from '../character';
-import { RadarTemp } from '../temp/templates/radar';
-
-StoryFactory.registerChartTemp(RadarTemp.type, RadarTemp);
-
-export class RadarChartCharacter extends CharacterChart {
- static type = 'RadarChart';
-}
diff --git a/packages/vstory/src/story/character/chart/characters/rangeColumn.ts b/packages/vstory/src/story/character/chart/characters/rangeColumn.ts
deleted file mode 100644
index 977bb17e..00000000
--- a/packages/vstory/src/story/character/chart/characters/rangeColumn.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { StoryFactory } from '../../../factory/factory';
-import { CharacterChart } from '../character';
-import { RangeColumnTemp } from '../temp/templates/rangeColumn';
-
-StoryFactory.registerChartTemp(RangeColumnTemp.type, RangeColumnTemp);
-
-export class RangeColumnChartCharacter extends CharacterChart {
- static type = 'RangeColumnChart';
-}
diff --git a/packages/vstory/src/story/character/chart/characters/rose.ts b/packages/vstory/src/story/character/chart/characters/rose.ts
deleted file mode 100644
index de0009c4..00000000
--- a/packages/vstory/src/story/character/chart/characters/rose.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { StoryFactory } from '../../../factory/factory';
-import { CharacterChart } from '../character';
-import { RoseTemp } from '../temp/templates/rose';
-
-StoryFactory.registerChartTemp(RoseTemp.type, RoseTemp);
-
-export class RoseChartCharacter extends CharacterChart {
- static type = 'RoseChart';
-}
diff --git a/packages/vstory/src/story/character/chart/characters/scatter.ts b/packages/vstory/src/story/character/chart/characters/scatter.ts
deleted file mode 100644
index 4e4104a0..00000000
--- a/packages/vstory/src/story/character/chart/characters/scatter.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { StoryFactory } from '../../../factory/factory';
-import { CharacterChart } from '../character';
-import { ScatterTemp } from '../temp/templates/scatter';
-
-StoryFactory.registerChartTemp(ScatterTemp.type, ScatterTemp);
-
-export class ScatterChartCharacter extends CharacterChart {
- static type = 'ScatterChart';
-}
diff --git a/packages/vstory/src/story/character/chart/characters/sunburst.ts b/packages/vstory/src/story/character/chart/characters/sunburst.ts
deleted file mode 100644
index 56b2e046..00000000
--- a/packages/vstory/src/story/character/chart/characters/sunburst.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { StoryFactory } from '../../../factory/factory';
-import { CharacterChart } from '../character';
-import { SunburstTemp } from '../temp/templates/sunburst';
-
-StoryFactory.registerChartTemp(SunburstTemp.type, SunburstTemp);
-
-export class SunburstChartCharacter extends CharacterChart {
- static type = 'SunburstChart';
-}
diff --git a/packages/vstory/src/story/character/chart/characters/treemap.ts b/packages/vstory/src/story/character/chart/characters/treemap.ts
deleted file mode 100644
index fedd08e4..00000000
--- a/packages/vstory/src/story/character/chart/characters/treemap.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { StoryFactory } from '../../../factory/factory';
-import { CharacterChart } from '../character';
-import { TreeMapTemp } from '../temp/templates/treemap';
-
-StoryFactory.registerChartTemp(TreeMapTemp.type, TreeMapTemp);
-
-export class TreeMapChartCharacter extends CharacterChart {
- static type = 'TreeMapChart';
-}
diff --git a/packages/vstory/src/story/character/chart/characters/vchart.ts b/packages/vstory/src/story/character/chart/characters/vchart.ts
new file mode 100644
index 00000000..9e2ddb72
--- /dev/null
+++ b/packages/vstory/src/story/character/chart/characters/vchart.ts
@@ -0,0 +1,9 @@
+import { StoryFactory } from '../../../factory/factory';
+import { CharacterChart } from '../character';
+import { VChartTemp } from '../temp/templates/vchart-temp';
+
+StoryFactory.registerChartTemp(VChartTemp.type, VChartTemp);
+
+export class VChartCharacter extends CharacterChart {
+ static type = 'VChart';
+}
diff --git a/packages/vstory/src/story/character/chart/characters/wordcloud.ts b/packages/vstory/src/story/character/chart/characters/wordcloud.ts
deleted file mode 100644
index d4a45130..00000000
--- a/packages/vstory/src/story/character/chart/characters/wordcloud.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { StoryFactory } from '../../../factory/factory';
-import { CharacterChart } from '../character';
-import { WordCloudTemp } from '../temp/templates/wordcloud';
-
-StoryFactory.registerChartTemp(WordCloudTemp.type, WordCloudTemp);
-
-export class WordCloudCharacter extends CharacterChart {
- static type = 'WordCloudChart';
-}
diff --git a/packages/vstory/src/story/character/chart/graphic/vchart-graphic.ts b/packages/vstory/src/story/character/chart/graphic/vchart-graphic.ts
index 7908cd78..b3aaa957 100644
--- a/packages/vstory/src/story/character/chart/graphic/vchart-graphic.ts
+++ b/packages/vstory/src/story/character/chart/graphic/vchart-graphic.ts
@@ -52,7 +52,7 @@ export class Chart extends Group implements IVisactorGraphic {
// viewBox: params.vi
dpr: params.dpr,
interactive: params.interactive,
- animation: params.animation,
+ animation: false,
autoFit: false,
disableTriggerEvent: params.disableTriggerEvent,
disableDirtyBounds: params.disableDirtyBounds,
diff --git a/packages/vstory/src/story/character/chart/runtime/series-spec.ts b/packages/vstory/src/story/character/chart/runtime/series-spec.ts
index 51ad9721..42fefd09 100644
--- a/packages/vstory/src/story/character/chart/runtime/series-spec.ts
+++ b/packages/vstory/src/story/character/chart/runtime/series-spec.ts
@@ -23,7 +23,7 @@ export class SeriesSpecRuntime implements IChartCharacterRuntime {
merge(rawSpec, options.seriesSpec[0].spec);
return;
}
- options.seriesSpec.forEach(seriesSpec => {
+ options.seriesSpec?.forEach(seriesSpec => {
if (!rawSpec.series) {
rawSpec.series = [{ ...seriesSpec.spec }];
return;
diff --git a/packages/vstory/src/story/character/chart/temp/constant.ts b/packages/vstory/src/story/character/chart/temp/constant.ts
index dcd9dd4c..f606975c 100644
--- a/packages/vstory/src/story/character/chart/temp/constant.ts
+++ b/packages/vstory/src/story/character/chart/temp/constant.ts
@@ -1,15 +1,5 @@
-import { StoryChartType } from '../../../../dsl/constant';
+import { StoryChartType } from '../../../../constants/character';
export const TemplateChartType = {
- bar: StoryChartType.BAR,
- area: StoryChartType.AREA,
- line: StoryChartType.LINE,
- pie: StoryChartType.PIE,
- scatter: StoryChartType.SCATTER,
- rangeColumn: StoryChartType.RANGE_COLUMN,
- rose: StoryChartType.ROSE,
- radar: StoryChartType.RADAR,
- wordcloud: StoryChartType.WORD_CLOUD,
- treemap: StoryChartType.TREE_MAP,
- sunburst: StoryChartType.SUNBURST
+ vchart: StoryChartType.VCHART
};
diff --git a/packages/vstory/src/story/character/chart/temp/templates/area.ts b/packages/vstory/src/story/character/chart/temp/templates/area.ts
deleted file mode 100644
index afc24799..00000000
--- a/packages/vstory/src/story/character/chart/temp/templates/area.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import { TemplateChartType } from '../constant';
-import { CartesianSingleSeriesTemp } from './cartesian-single';
-
-export class AreaTemp extends CartesianSingleSeriesTemp {
- static type: string = TemplateChartType.area;
- type: string = AreaTemp.type;
- // 唯一系列类型
- seriesType = 'area';
- // 是否消除维度轴的2测留白
- trimPadding = true;
-
- protected _getSeriesSpec() {
- return {
- type: 'area',
- stack: true,
- direction: this.direction,
- line: {
- style: {
- lineCap: 'butt'
- }
- }
- };
- }
-}
diff --git a/packages/vstory/src/story/character/chart/temp/templates/bar.ts b/packages/vstory/src/story/character/chart/temp/templates/bar.ts
deleted file mode 100644
index baba1420..00000000
--- a/packages/vstory/src/story/character/chart/temp/templates/bar.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import { TemplateChartType } from '../constant';
-import { CartesianSingleSeriesTemp } from './cartesian-single';
-
-export class BarTemp extends CartesianSingleSeriesTemp {
- static type: string = TemplateChartType.bar;
- type: string = BarTemp.type;
- // 唯一系列类型
- seriesType = 'bar';
- // 默认是否展示总计标签
- defaultTotalLabel = true;
-
- protected _getSeriesSpec() {
- return {
- type: 'bar',
- stack: true,
- direction: this.direction
- };
- }
-
- afterInitializeChart(): void {
- // eslint-disable-next-line no-console
- console.log('afterInitializeChart');
- }
-}
diff --git a/packages/vstory/src/story/character/chart/temp/templates/cartesian-single.ts b/packages/vstory/src/story/character/chart/temp/templates/cartesian-single.ts
deleted file mode 100644
index 1f6d8627..00000000
--- a/packages/vstory/src/story/character/chart/temp/templates/cartesian-single.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import { IChartCharacterSpec } from '../../../dsl-interface';
-import { DirectionType } from '../../const';
-import type { StandardData } from '../../data/interface';
-import { BaseTemp } from './base-temp';
-import { getCartesianCommonSpec, getCartesianSpec } from './common';
-
-export abstract class CartesianSingleSeriesTemp extends BaseTemp {
- // 唯一系列类型
- seriesType: string;
- direction: DirectionType = 'vertical';
- // 是否有维度轴分组
- multiDimensionField = false;
- // 是否堆积
- stack = true;
- // 是否默认有总计标签
- defaultTotalLabel = false;
- // 是否是百分百图表
- percent = false;
- // 是否消除维度轴的2测留白
- trimPadding = false;
- // 是否默认展示图例
- defaultLegendVisible = false;
-
- constructor(characterSpec: IChartCharacterSpec) {
- super();
- this.direction = characterSpec.options.direction ?? 'vertical';
- }
-
- checkDataEnable(data: StandardData, opt?: any): boolean {
- return !!data; // CommonStandardDataCheck(data);
- }
- getSpec(data: StandardData, opt?: any) {
- const cartesianCommonSpec = getCartesianCommonSpec(this.direction, this.percent, this.trimPadding) as any;
- if (cartesianCommonSpec.legends) {
- cartesianCommonSpec.legends.visible = this.defaultLegendVisible;
- }
-
- return getCartesianSpec(this._getSeriesSpec.bind(this), cartesianCommonSpec, this.direction, data, {
- multiDimensionField: this.multiDimensionField,
- stack: this.stack,
- xField: opt.character.specProcess.getCharacterSpec().options.xField,
- yField: opt.character.specProcess.getCharacterSpec().options.yField,
- seriesField: opt.character.specProcess.getCharacterSpec().options.seriesField
- });
- }
-
- protected abstract _getSeriesSpec(): any;
-}
diff --git a/packages/vstory/src/story/character/chart/temp/templates/common.ts b/packages/vstory/src/story/character/chart/temp/templates/common.ts
index d4d321fe..933a2b13 100644
--- a/packages/vstory/src/story/character/chart/temp/templates/common.ts
+++ b/packages/vstory/src/story/character/chart/temp/templates/common.ts
@@ -1,162 +1,5 @@
-import type { IDataValue } from '../../data/interface';
import { array } from '@visactor/vutils';
import type { DataInfo, StandardData } from '../../data/interface';
-import { ChartDimensionField, ChartTypeField, ChartValueField } from '../../const';
-
-export function getCommonSpec() {
- return {
- type: 'common',
- series: [] as any[],
- region: [
- {
- id: 'region-0'
- }
- ]
- };
-}
-
-export function getPolarCommonSpec() {
- return {
- ...getCommonSpec(),
- axes: getPolarAxesSpec()
- };
-}
-
-export function getPolarAxesSpec() {
- return [
- {
- orient: 'radius'
- },
- {
- orient: 'angle'
- }
- ];
-}
-
-export function getPolarSpec(
- seriesSpec: () => any,
- spec: any,
- data: StandardData,
- option: {
- seriesField?: string;
- categoryField: string;
- valueField: string;
- }
-) {
- spec.data = array(data);
- spec.series = spec.data.map((d: IDataValue) => {
- return fillPolarSeriesSpec(seriesSpec(), d, option);
- });
- return spec;
-}
-
-export function fillPolarSeriesSpec(
- spec: any,
- d: IDataValue,
- option: {
- seriesField?: string;
- categoryField: string;
- valueField: string;
- }
-) {
- spec.dataId = d.id;
- spec.id = `series-${d.id}`;
- spec.seriesField = option.seriesField;
- return spec;
-}
-
-export function getCartesianCommonSpec(direction: 'horizontal' | 'vertical', percent = false, trimPadding = false) {
- return {
- direction,
- ...getCommonSpec(),
- axes: getCartesianAxesSpec(direction, percent, trimPadding)
- };
-}
-
-export function getCartesianAxesSpec(direction: 'horizontal' | 'vertical', percent = false, trimPadding = false) {
- return direction === 'vertical'
- ? [
- {
- orient: 'left',
- id: 'axis-left',
- type: 'linear',
- autoIndent: false,
- maxWidth: null as number,
- maxHeight: null as number
- },
- {
- orient: 'bottom',
- id: 'axis-bottom',
- type: 'band',
- autoIndent: false,
- maxWidth: null as number,
- maxHeight: null as number,
- trimPadding,
- paddingInner: [0.2, 0],
- paddingOuter: [0.2, 0]
- }
- ]
- : [
- {
- orient: 'left',
- id: 'axis-left',
- type: 'band',
- autoIndent: false,
- maxWidth: null as number,
- maxHeight: null as number,
- trimPadding
- },
- {
- orient: 'bottom',
- id: 'axis-bottom',
- type: 'linear',
- autoIndent: false,
- maxWidth: null as number,
- maxHeight: null as number
- }
- ];
-}
-
-export function getCartesianSpec(
- seriesSpec: () => any,
- spec: any,
- direction: 'horizontal' | 'vertical',
- data: StandardData,
- option: {
- multiDimensionField?: boolean;
- stack?: boolean;
- xField: string[] | string;
- yField: string[] | string;
- seriesField: string;
- }
-) {
- spec.data = array(data);
- spec.series = spec.data.map((d: IDataValue) => {
- return fillCartesianSeriesSpec(seriesSpec(), direction, d, option);
- });
- return spec;
-}
-
-export function fillCartesianSeriesSpec(
- spec: any,
- direction: 'horizontal' | 'vertical',
- d: IDataValue,
- option: {
- multiDimensionField?: boolean;
- stack?: boolean;
- xField: string[] | string;
- yField: string[] | string;
- seriesField: string;
- }
-) {
- spec.xField = option.xField;
- spec.yField = option.yField;
- spec.dataId = d.id;
- spec.id = `series-${d.id}`;
- spec.seriesField = option.seriesField;
- spec.stack = option.stack === true;
- return spec;
-}
export function getDimensions(info: DataInfo) {
const ordinalFields: string[] = [];
@@ -178,19 +21,6 @@ export function getDimensions(info: DataInfo) {
};
}
-export function CommonStandardDataCheck(data: StandardData) {
- data = array(data);
- if (data.length === 0) {
- return false;
- }
- // mvp 使用total data 不再使用totalData
- // const totalData = data.find(d => d.sourceKey === 'total');
- // if (totalData && totalData.values.length === 0) {
- // return false;
- // }
- return true;
-}
-
export function getSeriesLabelSpec(direction: 'horizontal' | 'vertical', visible = true) {
return {
visible,
diff --git a/packages/vstory/src/story/character/chart/temp/templates/line.ts b/packages/vstory/src/story/character/chart/temp/templates/line.ts
deleted file mode 100644
index 33579027..00000000
--- a/packages/vstory/src/story/character/chart/temp/templates/line.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import { TemplateChartType } from '../constant';
-import { CartesianSingleSeriesTemp } from './cartesian-single';
-import { getSeriesLabelSpec } from './common';
-
-export class LineTemp extends CartesianSingleSeriesTemp {
- static type: string = TemplateChartType.line;
- type: string = LineTemp.type;
- // 唯一系列类型
- seriesType = 'line';
- stack = false;
- // 是否消除维度轴的2测留白
- trimPadding = true;
-
- protected _getSeriesSpec() {
- return {
- direction: this.direction,
- type: 'line',
- stack: false,
- line: {
- style: {
- lineCap: 'butt'
- }
- },
- label: {
- visible: true,
- position: 'top',
- style: {
- lineHeight: '100%',
- fontSize: 16,
- fontWeight: 'bold'
- },
- overlap: true,
- smartInvert: true
- },
- seriesLabel: getSeriesLabelSpec(this.direction)
- };
- }
-}
diff --git a/packages/vstory/src/story/character/chart/temp/templates/pie.ts b/packages/vstory/src/story/character/chart/temp/templates/pie.ts
deleted file mode 100644
index baa7984b..00000000
--- a/packages/vstory/src/story/character/chart/temp/templates/pie.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { array } from '@visactor/vutils';
-import type { StandardData } from '../../data/interface';
-import type { DataInfo } from '../../data/interface';
-import { BaseTemp } from './base-temp';
-import { CommonStandardDataCheck, getCommonSpec } from './common';
-import { TemplateChartType } from '../constant';
-import { ChartDimensionField, ChartValueField } from '../../const';
-
-export function spec() {
- return {
- type: 'pie'
- };
-}
-
-export class PieTemp extends BaseTemp {
- static type: string = TemplateChartType.pie;
- type: string = PieTemp.type;
- checkDataEnable(data: StandardData, opt?: any): boolean {
- return CommonStandardDataCheck(data);
- }
- getSpec(data: StandardData, opt?: any) {
- const tempSpec = getCommonSpec() as any;
- tempSpec.series = [spec()];
- tempSpec.data = array(data);
- tempSpec.series[0].valueField = ChartValueField;
- tempSpec.series[0].categoryField = ChartDimensionField;
- tempSpec.series[0].dataId = tempSpec.data[0].id;
- tempSpec.series[0].seriesField = ChartDimensionField;
- tempSpec.series[0].id = `series-${tempSpec.data[0].id}`;
- return tempSpec;
- }
-}
diff --git a/packages/vstory/src/story/character/chart/temp/templates/polar-single.ts b/packages/vstory/src/story/character/chart/temp/templates/polar-single.ts
deleted file mode 100644
index 8d97d430..00000000
--- a/packages/vstory/src/story/character/chart/temp/templates/polar-single.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { IChartCharacterSpec } from '../../../dsl-interface';
-import type { StandardData } from '../../data/interface';
-import { BaseTemp } from './base-temp';
-import { getPolarCommonSpec, getPolarSpec } from './common';
-
-export abstract class PolarSingleSeriesTemp extends BaseTemp {
- // 唯一系列类型
- seriesType: string;
- defaultLegendVisible = false;
-
- constructor(characterSpec: IChartCharacterSpec) {
- super();
- }
-
- checkDataEnable(data: StandardData, opt?: any): boolean {
- return !!data; // CommonStandardDataCheck(data);
- }
- getSpec(data: StandardData, opt?: any) {
- const polarCommonSpec = getPolarCommonSpec() as any;
- if (polarCommonSpec.legends) {
- polarCommonSpec.legends.visible = this.defaultLegendVisible;
- }
-
- return getPolarSpec(this._getSeriesSpec.bind(this), polarCommonSpec, data, {
- categoryField: opt.character.specProcess.getCharacterSpec().options.categoryField,
- valueField: opt.character.specProcess.getCharacterSpec().options.valueField,
- seriesField: opt.character.specProcess.getCharacterSpec().options.seriesField
- });
- }
-
- protected abstract _getSeriesSpec(): any;
-}
diff --git a/packages/vstory/src/story/character/chart/temp/templates/radar.ts b/packages/vstory/src/story/character/chart/temp/templates/radar.ts
deleted file mode 100644
index 38f90ee5..00000000
--- a/packages/vstory/src/story/character/chart/temp/templates/radar.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import type { StandardData } from '../../data/interface';
-import { CommonStandardDataCheck, getCommonSpec } from './common';
-import { TemplateChartType } from '../constant';
-import { PolarSingleSeriesTemp } from './polar-single';
-
-export class RadarTemp extends PolarSingleSeriesTemp {
- static type: string = TemplateChartType.radar;
- type: string = RadarTemp.type;
- checkDataEnable(data: StandardData, opt?: any): boolean {
- return CommonStandardDataCheck(data);
- }
-
- protected _getSeriesSpec() {
- return {
- type: 'radar'
- };
- }
-}
diff --git a/packages/vstory/src/story/character/chart/temp/templates/rangeColumn.ts b/packages/vstory/src/story/character/chart/temp/templates/rangeColumn.ts
deleted file mode 100644
index 8f937812..00000000
--- a/packages/vstory/src/story/character/chart/temp/templates/rangeColumn.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import { TemplateChartType } from '../constant';
-import { CartesianSingleSeriesTemp } from './cartesian-single';
-import type { CharacterChart } from '../../character';
-
-export class RangeColumnTemp extends CartesianSingleSeriesTemp {
- static type: string = TemplateChartType.rangeColumn;
- type: string = RangeColumnTemp.type;
- // 唯一系列类型
- seriesType = 'rangeColumn';
- // 是否消除维度轴的2测留白
- trimPadding = true;
-
- protected _getSeriesSpec() {
- return {
- type: 'rangeColumn',
- stack: false,
- direction: this.direction
- };
- }
-
- standardizedSpec(spec: any, ctx: { character: CharacterChart }) {
- if (spec.series) {
- spec.series.forEach((seriesSpec: any) => {
- if (seriesSpec.minField && seriesSpec.maxField) {
- if (this.direction === 'vertical') {
- if (!seriesSpec.yField) {
- seriesSpec.yField = [seriesSpec.minField, seriesSpec.maxField];
- }
- } else {
- if (!seriesSpec.xField) {
- seriesSpec.xField = [seriesSpec.minField, seriesSpec.maxField];
- }
- }
- }
- });
- }
- }
-}
diff --git a/packages/vstory/src/story/character/chart/temp/templates/rose.ts b/packages/vstory/src/story/character/chart/temp/templates/rose.ts
deleted file mode 100644
index 2b50f889..00000000
--- a/packages/vstory/src/story/character/chart/temp/templates/rose.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { array } from '@visactor/vutils';
-import type { StandardData } from '../../data/interface';
-import type { DataInfo } from '../../data/interface';
-import { BaseTemp } from './base-temp';
-import { CommonStandardDataCheck, getCommonSpec } from './common';
-import { TemplateChartType } from '../constant';
-import { ChartDimensionField, ChartValueField } from '../../const';
-import { PolarSingleSeriesTemp } from './polar-single';
-
-export class RoseTemp extends PolarSingleSeriesTemp {
- static type: string = TemplateChartType.rose;
- type: string = RoseTemp.type;
- protected _getSeriesSpec() {
- return {
- type: 'rose'
- };
- }
-}
diff --git a/packages/vstory/src/story/character/chart/temp/templates/scatter.ts b/packages/vstory/src/story/character/chart/temp/templates/scatter.ts
deleted file mode 100644
index 9f038fa2..00000000
--- a/packages/vstory/src/story/character/chart/temp/templates/scatter.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { TemplateChartType } from '../constant';
-import { CartesianSingleSeriesTemp } from './cartesian-single';
-
-export class ScatterTemp extends CartesianSingleSeriesTemp {
- static type: string = TemplateChartType.scatter;
- type: string = ScatterTemp.type;
- // 唯一系列类型
- seriesType = 'scatter';
- // 是否消除维度轴的2测留白
- trimPadding = true;
-
- protected _getSeriesSpec() {
- return {
- type: 'scatter',
- stack: false,
- direction: this.direction
- };
- }
-}
diff --git a/packages/vstory/src/story/character/chart/temp/templates/sunburst.ts b/packages/vstory/src/story/character/chart/temp/templates/sunburst.ts
deleted file mode 100644
index a1bc4947..00000000
--- a/packages/vstory/src/story/character/chart/temp/templates/sunburst.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { array } from '@visactor/vutils';
-import type { StandardData } from '../../data/interface';
-import type { DataInfo } from '../../data/interface';
-import { BaseTemp } from './base-temp';
-import { CommonStandardDataCheck, getCommonSpec } from './common';
-import { TemplateChartType } from '../constant';
-import { ChartDimensionField, ChartValueField } from '../../const';
-
-export function spec() {
- return {
- type: 'sunburst'
- };
-}
-
-export class SunburstTemp extends BaseTemp {
- static type: string = TemplateChartType.sunburst;
- type: string = SunburstTemp.type;
- checkDataEnable(data: StandardData, opt?: any): boolean {
- return CommonStandardDataCheck(data);
- }
- getSpec(data: StandardData, opt?: any) {
- const tempSpec = getCommonSpec() as any;
- tempSpec.series = [spec()];
- tempSpec.data = array(data);
- tempSpec.series[0].valueField = ChartValueField;
- tempSpec.series[0].categoryField = ChartDimensionField;
- tempSpec.series[0].dataId = tempSpec.data[0].id;
- tempSpec.series[0].seriesField = ChartDimensionField;
- tempSpec.series[0].id = `series-${tempSpec.data[0].id}`;
- return tempSpec;
- }
-}
diff --git a/packages/vstory/src/story/character/chart/temp/templates/treemap.ts b/packages/vstory/src/story/character/chart/temp/templates/treemap.ts
deleted file mode 100644
index 22ff25e2..00000000
--- a/packages/vstory/src/story/character/chart/temp/templates/treemap.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { array } from '@visactor/vutils';
-import type { StandardData } from '../../data/interface';
-import type { DataInfo } from '../../data/interface';
-import { BaseTemp } from './base-temp';
-import { CommonStandardDataCheck, getCommonSpec } from './common';
-import { TemplateChartType } from '../constant';
-import { ChartDimensionField, ChartValueField } from '../../const';
-
-export function spec() {
- return {
- type: 'treemap'
- };
-}
-
-export class TreeMapTemp extends BaseTemp {
- static type: string = TemplateChartType.treemap;
- type: string = TreeMapTemp.type;
- checkDataEnable(data: StandardData, opt?: any): boolean {
- return CommonStandardDataCheck(data);
- }
- getSpec(data: StandardData, opt?: any) {
- const tempSpec = getCommonSpec() as any;
- tempSpec.series = [spec()];
- tempSpec.data = array(data);
- tempSpec.series[0].valueField = ChartValueField;
- tempSpec.series[0].categoryField = ChartDimensionField;
- tempSpec.series[0].dataId = tempSpec.data[0].id;
- tempSpec.series[0].seriesField = ChartDimensionField;
- tempSpec.series[0].id = `series-${tempSpec.data[0].id}`;
- return tempSpec;
- }
-}
diff --git a/packages/vstory/src/story/character/chart/temp/templates/vchart-temp.ts b/packages/vstory/src/story/character/chart/temp/templates/vchart-temp.ts
new file mode 100644
index 00000000..70c65385
--- /dev/null
+++ b/packages/vstory/src/story/character/chart/temp/templates/vchart-temp.ts
@@ -0,0 +1,15 @@
+import type { StandardData } from '../../data/interface';
+import { BaseTemp } from './base-temp';
+import { TemplateChartType } from '../constant';
+
+export class VChartTemp extends BaseTemp {
+ static type: string = TemplateChartType.vchart;
+ type: string = VChartTemp.type;
+ checkDataEnable(data: StandardData, opt?: any): boolean {
+ return true;
+ }
+ getSpec(data: StandardData, opt: any) {
+ // TODO 转换特定chart Spec到通用common spec
+ return opt.character.spec.options.spec as any;
+ }
+}
diff --git a/packages/vstory/src/story/character/chart/temp/templates/wordcloud.ts b/packages/vstory/src/story/character/chart/temp/templates/wordcloud.ts
deleted file mode 100644
index e3adaa7d..00000000
--- a/packages/vstory/src/story/character/chart/temp/templates/wordcloud.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { array } from '@visactor/vutils';
-import type { StandardData } from '../../data/interface';
-import type { DataInfo } from '../../data/interface';
-import { BaseTemp } from './base-temp';
-import { CommonStandardDataCheck, getCommonSpec } from './common';
-import { TemplateChartType } from '../constant';
-import { ChartDimensionField, ChartValueField } from '../../const';
-
-export function spec() {
- return {
- type: 'wordCloud'
- };
-}
-
-export class WordCloudTemp extends BaseTemp {
- static type: string = TemplateChartType.wordcloud;
- type: string = WordCloudTemp.type;
- checkDataEnable(data: StandardData, opt?: any): boolean {
- const check = CommonStandardDataCheck(data);
- return check;
- }
- getSpec(data: StandardData, opt?: any) {
- const tempSpec = getCommonSpec() as any;
- tempSpec.series = [spec()];
- tempSpec.data = array(data);
- tempSpec.series[0].valueField = ChartValueField;
- tempSpec.series[0].nameField = ChartDimensionField;
- tempSpec.series[0].dataId = tempSpec.data[0].id;
- tempSpec.series[0].seriesField = ChartDimensionField;
- tempSpec.series[0].id = `series-${tempSpec.data[0].id}`;
- return tempSpec;
- }
-}
diff --git a/packages/vstory/src/story/character/component/characters/character-image.ts b/packages/vstory/src/story/character/component/characters/character-image.ts
index afdc42e5..33b2c3ad 100644
--- a/packages/vstory/src/story/character/component/characters/character-image.ts
+++ b/packages/vstory/src/story/character/component/characters/character-image.ts
@@ -1,6 +1,6 @@
import type { Graphic } from '../graphic/graphic';
import { CharacterComponent } from '../character';
-import { StoryGraphicType } from '../../../../dsl/constant';
+import { StoryGraphicType } from '../../../../constants/character';
import { GraphicImage } from '../graphic/image';
export class CharacterComponentImage extends CharacterComponent {
diff --git a/packages/vstory/src/story/character/component/characters/character-line.ts b/packages/vstory/src/story/character/component/characters/character-line.ts
index f0290740..1815c957 100644
--- a/packages/vstory/src/story/character/component/characters/character-line.ts
+++ b/packages/vstory/src/story/character/component/characters/character-line.ts
@@ -1,7 +1,7 @@
import type { Graphic } from '../graphic/graphic';
import { GraphicLine } from '../graphic/line';
import { CharacterComponent } from '../character';
-import { StoryGraphicType } from '../../../../dsl/constant';
+import { StoryGraphicType } from '../../../../constants/character';
export class CharacterComponentLine extends CharacterComponent {
readonly graphicType: string = 'line';
diff --git a/packages/vstory/src/story/character/component/characters/character-rect.ts b/packages/vstory/src/story/character/component/characters/character-rect.ts
index 377bf5ea..558ecc06 100644
--- a/packages/vstory/src/story/character/component/characters/character-rect.ts
+++ b/packages/vstory/src/story/character/component/characters/character-rect.ts
@@ -1,7 +1,7 @@
import type { Graphic } from '../graphic/graphic';
import { GraphicRect } from '../graphic/rect';
import { CharacterComponent } from '../character';
-import { StoryGraphicType } from '../../../../dsl/constant';
+import { StoryGraphicType } from '../../../../constants/character';
export class CharacterComponentRect extends CharacterComponent {
readonly graphicType: string = 'rect';
diff --git a/packages/vstory/src/story/character/component/characters/character-richtext.ts b/packages/vstory/src/story/character/component/characters/character-richtext.ts
index 58e0f65e..a662d990 100644
--- a/packages/vstory/src/story/character/component/characters/character-richtext.ts
+++ b/packages/vstory/src/story/character/component/characters/character-richtext.ts
@@ -1,7 +1,7 @@
import type { Graphic } from '../graphic/graphic';
import { GraphicRichText } from '../graphic/richtext';
import { CharacterComponent } from '../character';
-import { StoryGraphicType } from '../../../../dsl/constant';
+import { StoryGraphicType } from '../../../../constants/character';
export class CharacterComponentRichText extends CharacterComponent {
readonly graphicType: string = 'richtext';
diff --git a/packages/vstory/src/story/character/component/characters/character-shape.ts b/packages/vstory/src/story/character/component/characters/character-shape.ts
index b89795bc..898d3433 100644
--- a/packages/vstory/src/story/character/component/characters/character-shape.ts
+++ b/packages/vstory/src/story/character/component/characters/character-shape.ts
@@ -1,6 +1,6 @@
import type { Graphic } from '../graphic/graphic';
import { CharacterComponent } from '../character';
-import { StoryGraphicType } from '../../../../dsl/constant';
+import { StoryGraphicType } from '../../../../constants/character';
import { GraphicSymbol } from '../graphic/symbol';
export class CharacterComponentShape extends CharacterComponent {
diff --git a/packages/vstory/src/story/character/component/characters/character-text.ts b/packages/vstory/src/story/character/component/characters/character-text.ts
index 70115468..b2495311 100644
--- a/packages/vstory/src/story/character/component/characters/character-text.ts
+++ b/packages/vstory/src/story/character/component/characters/character-text.ts
@@ -1,7 +1,7 @@
import type { Graphic } from '../graphic/graphic';
import { GraphicPureText } from '../graphic/text';
import { CharacterComponent } from '../character';
-import { StoryGraphicType } from '../../../../dsl/constant';
+import { StoryGraphicType } from '../../../../constants/character';
/**
* text component 没有关联 graphic,逻辑与 GraphicText 有所不同
diff --git a/packages/vstory/src/story/character/runtime-interface.ts b/packages/vstory/src/story/character/runtime-interface.ts
index 23f75de8..61409fe9 100644
--- a/packages/vstory/src/story/character/runtime-interface.ts
+++ b/packages/vstory/src/story/character/runtime-interface.ts
@@ -1,7 +1,7 @@
import type { IGroup } from '@visactor/vrender';
import type { IPointLike } from '@visactor/vutils';
import type { StoryCanvas } from '../canvas/canvas';
-import type { IStory, StoryEvent } from '../interface/runtime-interface';
+import type { IStory, IStoryCanvas, StoryEvent } from '../interface/runtime-interface';
import type { ICharacterSpec } from './dsl-interface';
export interface ICharacterPickInfo {
@@ -17,6 +17,7 @@ export interface ICharacter {
show: () => void;
hide: () => void;
getGraphicParent: () => IGroup;
+ graphic: IGroup;
tickTo: (t: number) => void;
checkEvent: (event: StoryEvent) => false | (ICharacterPickInfo & any);
@@ -28,7 +29,7 @@ export interface ICharacter {
export interface ICharacterInitOption {
story: IStory;
- canvas: StoryCanvas;
+ canvas: IStoryCanvas;
graphicParent: IGroup;
}
diff --git a/packages/vstory/src/story/index.ts b/packages/vstory/src/story/index.ts
index 3ac4c982..1f5bc701 100644
--- a/packages/vstory/src/story/index.ts
+++ b/packages/vstory/src/story/index.ts
@@ -1,28 +1,17 @@
import { CharacterComponentQipao } from './character/component/characters/character-qipao';
import { CharacterComponentRect } from './character/component/characters/character-rect';
import { StoryFactory } from './factory/factory';
-import { CharacterChart } from './character/chart/character';
import { ContainerModule, GraphicRender, container } from '@visactor/vrender';
import { CanvasPickerContribution } from '@visactor/vrender';
import { ChartRender, VChartRender } from './character/chart/graphic/vchart-graphic-render';
-import { BarChartCharacter } from './character/chart/characters/bar';
-import { LineChartCharacter } from './character/chart/characters/line';
-import { AreaChartCharacter } from './character/chart/characters/area';
-import { PieChartCharacter } from './character/chart/characters/pie';
-import { RoseChartCharacter } from './character/chart/characters/rose';
-import { RadarChartCharacter } from './character/chart/characters/radar';
-import { WordCloudCharacter } from './character/chart/characters/wordcloud';
-import { TreeMapChartCharacter } from './character/chart/characters/treemap';
-import { SunburstChartCharacter } from './character/chart/characters/sunburst';
-import { ScatterChartCharacter } from './character/chart/characters/scatter';
-import { RangeColumnChartCharacter } from './character/chart/characters/rangeColumn';
import { CharacterComponentText } from './character/component/characters/character-text';
import { CharacterComponentRichText } from './character/component/characters/character-richtext';
import { VChartPicker } from './character/chart/graphic/vchart-graphic-picker';
-import { StoryGraphicType } from '../dsl/constant';
+import { StoryGraphicType } from '../constants/character';
import { CharacterComponentLine } from './character/component/characters/character-line';
import { CharacterComponentImage } from './character/component/characters/character-image';
import { CharacterComponentShape } from './character/component/characters/character-shape';
+import { VChartCharacter } from './character/chart/characters/vchart';
const splitModule = new ContainerModule((bind: any) => {
// chart渲染器注入
@@ -39,18 +28,7 @@ export function registerCharacter() {
return;
}
_register = true;
- StoryFactory.registerCharacter(BarChartCharacter.type, BarChartCharacter);
- StoryFactory.registerCharacter(LineChartCharacter.type, CharacterChart);
- StoryFactory.registerCharacter(CharacterChart.type, CharacterChart);
- StoryFactory.registerCharacter(AreaChartCharacter.type, AreaChartCharacter);
- StoryFactory.registerCharacter(PieChartCharacter.type, PieChartCharacter);
- StoryFactory.registerCharacter(RoseChartCharacter.type, RoseChartCharacter);
- StoryFactory.registerCharacter(RadarChartCharacter.type, RadarChartCharacter);
- StoryFactory.registerCharacter(WordCloudCharacter.type, WordCloudCharacter);
- StoryFactory.registerCharacter(TreeMapChartCharacter.type, TreeMapChartCharacter);
- StoryFactory.registerCharacter(SunburstChartCharacter.type, SunburstChartCharacter);
- StoryFactory.registerCharacter(ScatterChartCharacter.type, ScatterChartCharacter);
- StoryFactory.registerCharacter(RangeColumnChartCharacter.type, RangeColumnChartCharacter);
+ StoryFactory.registerCharacter(VChartCharacter.type, VChartCharacter);
// StoryFactory.registerCharacter('BarChart', CharacterChart);
// StoryFactory.registerCharacter('CharacterChart', CharacterChart);
diff --git a/packages/vstory/src/story/interface/dsl-interface.ts b/packages/vstory/src/story/interface/dsl-interface.ts
index 9e3dc4db..5e216a24 100644
--- a/packages/vstory/src/story/interface/dsl-interface.ts
+++ b/packages/vstory/src/story/interface/dsl-interface.ts
@@ -2,9 +2,9 @@ import type { Action } from '../../dsl/types';
import type { ICharacterSpec } from '../character';
export interface IAction {
- startTime: number;
+ startTime?: number;
action: string;
- duration: number;
+ duration?: number;
payload?: Action['payload'];
}
diff --git a/packages/vstory/src/story/interface/player.ts b/packages/vstory/src/story/interface/player.ts
index af03d3c6..50fb1918 100644
--- a/packages/vstory/src/story/interface/player.ts
+++ b/packages/vstory/src/story/interface/player.ts
@@ -1,18 +1,17 @@
-import { ICharacter } from '../character';
-import { IActSpec } from './dsl-interface';
+import type { ICharacter } from '../character';
+import type { IActSpec } from './dsl-interface';
export interface IPlayer {
- tickTo(t: number): void;
- play(): void;
- encodeToVideo(millsecond: number, fps: number): Promise;
- pause(): void;
- release(): void;
- addAct(
+ tickTo: (t: number) => void;
+ play: () => void;
+ encodeToVideo: (millsecond: number, fps: number) => Promise;
+ pause: () => void;
+ release: () => void;
+ addAct: (
c: IActSpec,
characters: {
[key: string]: ICharacter;
}
- ): void;
- setCurrentAct(id: number | string): void;
- getCurrentAct(): number | string;
+ ) => void;
+ getCurrentAct: () => number | string;
}
diff --git a/packages/vstory/src/story/interface/runtime-interface.ts b/packages/vstory/src/story/interface/runtime-interface.ts
index dcd84edb..865dd6b0 100644
--- a/packages/vstory/src/story/interface/runtime-interface.ts
+++ b/packages/vstory/src/story/interface/runtime-interface.ts
@@ -1,4 +1,5 @@
-import type { IGraphic } from '@visactor/vrender';
+import type { IGraphic, IStage } from '@visactor/vrender';
+import type { ICharacter, ICharacterSpec } from '../character';
export interface IStoryInitOption {
dom: string | HTMLDivElement; // dom id
@@ -8,8 +9,27 @@ export interface IStoryInitOption {
};
}
+export interface IStoryCanvas {
+ getStage: () => IStage;
+ getCanvas: () => HTMLCanvasElement;
+ getEventDetail: (event: StoryEvent) => {
+ character: ICharacter;
+ characterInfo: undefined;
+ };
+ release: () => void;
+}
+
export interface IStory {
readonly id: string;
+ canvas: IStoryCanvas;
+ getCharacters: () => { [key: string]: ICharacter };
+ getCharactersById: (key: string) => ICharacter | null;
+}
+export interface ICharacterTree {
+ getCharacters: () => { [key: string]: ICharacter };
+ getCharactersById: (key: string) => ICharacter | null;
+ addCharacter: (spec: ICharacterSpec) => ICharacter;
+ initCharacters: (spec: ICharacterSpec[]) => void;
}
export type StoryEvent = Event & {
diff --git a/packages/vstory/src/story/player/index.ts b/packages/vstory/src/story/player/index.ts
index 680f6ac7..663799dc 100644
--- a/packages/vstory/src/story/player/index.ts
+++ b/packages/vstory/src/story/player/index.ts
@@ -1,216 +1,216 @@
-import { isNumber } from '@visactor/vutils';
-import type { StoryCanvas } from '../canvas/canvas';
-import type { IActSpec, IAction } from '../interface';
-import type { IPlayer } from '../interface/player';
-import { processorMap, ActionProcessor } from '../../dsl/story-processor';
-// import { Encoder } from './encode';
-import type { ICharacter } from '../character';
-
-export class Ticker {
- cb?: (delta: number) => void;
- rafIdx = 0;
- start(cb: (t: number) => void) {
- this.stop();
- this.cb = cb;
- this._tick(0);
- }
-
- _tick = (lt: number) => {
- const ct = Date.now();
- this.cb && this.cb(lt === 0 ? 0 : ct - lt);
- this.rafIdx = requestAnimationFrame(() => this._tick(ct));
- };
-
- stop() {
- this.rafIdx && cancelAnimationFrame(this.rafIdx);
- this.rafIdx = 0;
- }
-}
-
-type IChapterInstanceItem = {
- id: string;
- scenes: Array<{
- scene: {
- character: ICharacter;
- action: IAction;
- }[];
- delay: number;
- }>;
- characters: ICharacter[];
-};
-
-export class Player implements IPlayer {
- protected _canvas: StoryCanvas;
- protected _acts: IChapterInstanceItem[];
- protected _currAct: IChapterInstanceItem;
- protected _ticker: Ticker;
- protected _currTime: number;
- // protected _encoder: Encoder;
- protected _actionProcessor: ActionProcessor;
-
- constructor(c: StoryCanvas, options?: { scaleX?: number; scaleY?: number }) {
- this._canvas = c;
- this._acts = [];
- this._ticker = new Ticker();
- this._currTime = 0;
- c.getStage().defaultLayer.setAttributes({
- scaleX: options?.scaleX ?? 1,
- scaleY: options?.scaleY ?? 1
- });
- // this._encoder = new Encoder();
- this._actionProcessor = new ActionProcessor(processorMap);
- }
-
- addAct(
- c: IActSpec,
- characters: {
- [key: string]: ICharacter;
- }
- ): void {
- const scenes: IChapterInstanceItem['scenes'] = [];
- const characterSet: Set = new Set();
- c.scenes.forEach(item => {
- const scene: IChapterInstanceItem['scenes'][0] = { scene: [], delay: item.delay ?? 0 };
- item.actions.forEach(({ characterActions, characterId }) => {
- const _actions = characterActions.slice();
- _actions.sort((a, b) => a.startTime - b.startTime);
- _actions.forEach(action => {
- const character = characters[characterId];
- scene.scene.push({
- character,
- action: action
- });
- characterSet.add(character);
- });
- });
- scenes.push(scene);
- });
- this._acts.push({
- id: c.id,
- scenes: scenes,
- characters: Array.from(characterSet.values())
- });
- }
-
- setCurrentAct(id: number | string) {
- if (isNumber(id)) {
- this._currAct = this._acts[id];
- } else {
- this._currAct = this._acts.filter(item => item.id === id)[0];
- }
- }
-
- getCurrentAct() {
- return this._currAct?.id;
- }
-
- // 清除当前状态,一般用于回放操作
- reset() {
- this._currAct.characters.forEach(item => {
- item.reset();
- });
- }
-
- tickTo(t: number) {
- const lastTime = this._currTime;
- if (lastTime > t) {
- // 如果时间回退,那就重新走一遍
- this.reset();
- this._currTime = 0;
- this.tickTo(0);
- }
- const characterSet = new Set();
-
- let baseStartTime = 0;
- for (let i = 0; i < this._currAct.scenes.length; i++) {
- const scene = this._currAct.scenes[i];
- baseStartTime += scene.delay;
- if (baseStartTime <= t) {
- scene.scene.forEach(({ character, action }) => {
- const { startTime: st } = action;
- const startTime = st + baseStartTime;
- if (startTime > t) {
- return;
- }
- characterSet.add(character);
- // 之前没走过,现在走
- if (startTime > lastTime && startTime <= t) {
- const { type } = character.spec;
- this._actionProcessor.doAction(type, action.action, [character, {}, action]);
- }
- character.show();
- });
- }
- let sceneTime = 0;
- scene.scene.forEach(({ action }) => {
- const { startTime, duration } = action;
- sceneTime = Math.max(startTime + duration, startTime);
- });
- baseStartTime += sceneTime;
- // if (baseStartTime > t) {
- // break;
- // }
- }
-
- // roleSet.forEach(r => {
- // r.tickTo && r.tickTo(t);
- // });
-
- this._currTime = t;
- this._canvas.getStage().ticker.tickAt(t);
- this._canvas.getStage().render();
- }
-
- play(): void {
- if (!this._currAct) {
- return;
- }
- this._ticker.stop();
- this._currTime = 0;
- this.reset();
- this._ticker.start(t => {
- this.tickTo(this._currTime + t);
- });
- }
-
- async encodeToVideo(millsecond: number, fps: number): Promise {
- // // if (!this._currChapter) {
- // // return;
- // // }
- // const frameNum = (millsecond / 1000) * fps;
- // const deltaT = 1000 / fps;
- // this.tickTo(0);
- // const objUrl = await this._encoder.exportVideo(frameNum, fps, async i => {
- // const t = deltaT * i;
- // this.tickTo(t);
- // return new Promise((resolve, reject) => {
- // this._canvas
- // .getStage()
- // .window.getContext()
- // .canvas.nativeCanvas.toBlob((blob: any) => {
- // if (blob) {
- // resolve(blob);
- // } else {
- // // console.log('no blob');
- // reject('no blob');
- // }
- // }, `image/png`);
- // });
- // });
-
- // return objUrl;
- return null;
- }
-
- pause(): void {
- this._ticker.stop();
- }
-
- resume(): void {
- this._ticker._tick(this._currTime);
- }
-
- release(): void {
- return;
- }
-}
+// import { isNumber } from '@visactor/vutils';
+// import type { StoryCanvas } from '../canvas/canvas';
+// import type { IActSpec, IAction, IStoryCanvas } from '../interface';
+// import type { IPlayer } from '../../player/interface/player';
+// import { processorMap, ActionProcessor } from '../../dsl/story-processor';
+// // import { Encoder } from './encode';
+// import type { ICharacter } from '../character';
+
+// export class Ticker {
+// cb?: (delta: number) => void;
+// rafIdx = 0;
+// start(cb: (t: number) => void) {
+// this.stop();
+// this.cb = cb;
+// this._tick(0);
+// }
+
+// _tick = (lt: number) => {
+// const ct = Date.now();
+// this.cb && this.cb(lt === 0 ? 0 : ct - lt);
+// this.rafIdx = requestAnimationFrame(() => this._tick(ct));
+// };
+
+// stop() {
+// this.rafIdx && cancelAnimationFrame(this.rafIdx);
+// this.rafIdx = 0;
+// }
+// }
+
+// type IChapterInstanceItem = {
+// id: string;
+// scenes: Array<{
+// scene: {
+// character: ICharacter;
+// action: IAction;
+// }[];
+// delay: number;
+// }>;
+// characters: ICharacter[];
+// };
+
+// export class Player implements IPlayer {
+// protected _canvas: IStoryCanvas;
+// protected _acts: IChapterInstanceItem[];
+// protected _currAct: IChapterInstanceItem;
+// protected _ticker: Ticker;
+// protected _currTime: number;
+// // protected _encoder: Encoder;
+// protected _actionProcessor: ActionProcessor;
+
+// constructor(c: IStoryCanvas, options?: { scaleX?: number; scaleY?: number }) {
+// this._canvas = c;
+// this._acts = [];
+// this._ticker = new Ticker();
+// this._currTime = 0;
+// c.getStage().defaultLayer.setAttributes({
+// scaleX: options?.scaleX ?? 1,
+// scaleY: options?.scaleY ?? 1
+// });
+// // this._encoder = new Encoder();
+// this._actionProcessor = new ActionProcessor(processorMap);
+// }
+
+// addAct(
+// c: IActSpec,
+// characters: {
+// [key: string]: ICharacter;
+// }
+// ): void {
+// const scenes: IChapterInstanceItem['scenes'] = [];
+// const characterSet: Set = new Set();
+// c.scenes.forEach(item => {
+// const scene: IChapterInstanceItem['scenes'][0] = { scene: [], delay: item.delay ?? 0 };
+// item.actions.forEach(({ characterActions, characterId }) => {
+// const _actions = characterActions.slice();
+// _actions.sort((a, b) => a.startTime - b.startTime);
+// _actions.forEach(action => {
+// const character = characters[characterId];
+// scene.scene.push({
+// character,
+// action: action
+// });
+// characterSet.add(character);
+// });
+// });
+// scenes.push(scene);
+// });
+// this._acts.push({
+// id: c.id,
+// scenes: scenes,
+// characters: Array.from(characterSet.values())
+// });
+// }
+
+// setCurrentAct(id: number | string) {
+// if (isNumber(id)) {
+// this._currAct = this._acts[id];
+// } else {
+// this._currAct = this._acts.filter(item => item.id === id)[0];
+// }
+// }
+
+// getCurrentAct() {
+// return this._currAct?.id;
+// }
+
+// // 清除当前状态,一般用于回放操作
+// reset() {
+// this._currAct.characters.forEach(item => {
+// item.reset();
+// });
+// }
+
+// tickTo(t: number) {
+// const lastTime = this._currTime;
+// if (lastTime > t) {
+// // 如果时间回退,那就重新走一遍
+// this.reset();
+// this._currTime = 0;
+// this.tickTo(0);
+// }
+// const characterSet = new Set();
+
+// let baseStartTime = 0;
+// for (let i = 0; i < this._currAct.scenes.length; i++) {
+// const scene = this._currAct.scenes[i];
+// baseStartTime += scene.delay;
+// if (baseStartTime <= t) {
+// scene.scene.forEach(({ character, action }) => {
+// const { startTime: st } = action;
+// const startTime = st + baseStartTime;
+// if (startTime > t) {
+// return;
+// }
+// characterSet.add(character);
+// // 之前没走过,现在走
+// if (startTime > lastTime && startTime <= t) {
+// const { type } = character.spec;
+// this._actionProcessor.doAction(type, action.action, [character, {}, action]);
+// }
+// character.show();
+// });
+// }
+// let sceneTime = 0;
+// scene.scene.forEach(({ action }) => {
+// const { startTime, duration } = action;
+// sceneTime = Math.max(startTime + duration, startTime);
+// });
+// baseStartTime += sceneTime;
+// // if (baseStartTime > t) {
+// // break;
+// // }
+// }
+
+// // roleSet.forEach(r => {
+// // r.tickTo && r.tickTo(t);
+// // });
+
+// this._currTime = t;
+// this._canvas.getStage().ticker.tickAt(t);
+// this._canvas.getStage().render();
+// }
+
+// play(): void {
+// if (!this._currAct) {
+// return;
+// }
+// this._ticker.stop();
+// this._currTime = 0;
+// this.reset();
+// this._ticker.start(t => {
+// this.tickTo(this._currTime + t);
+// });
+// }
+
+// async encodeToVideo(millsecond: number, fps: number): Promise {
+// // // if (!this._currChapter) {
+// // // return;
+// // // }
+// // const frameNum = (millsecond / 1000) * fps;
+// // const deltaT = 1000 / fps;
+// // this.tickTo(0);
+// // const objUrl = await this._encoder.exportVideo(frameNum, fps, async i => {
+// // const t = deltaT * i;
+// // this.tickTo(t);
+// // return new Promise((resolve, reject) => {
+// // this._canvas
+// // .getStage()
+// // .window.getContext()
+// // .canvas.nativeCanvas.toBlob((blob: any) => {
+// // if (blob) {
+// // resolve(blob);
+// // } else {
+// // // console.log('no blob');
+// // reject('no blob');
+// // }
+// // }, `image/png`);
+// // });
+// // });
+
+// // return objUrl;
+// return null;
+// }
+
+// pause(): void {
+// this._ticker.stop();
+// }
+
+// resume(): void {
+// this._ticker._tick(this._currTime);
+// }
+
+// release(): void {
+// return;
+// }
+// }
diff --git a/packages/vstory/src/story/story.ts b/packages/vstory/src/story/story.ts
index b1c92938..797e0820 100644
--- a/packages/vstory/src/story/story.ts
+++ b/packages/vstory/src/story/story.ts
@@ -1,13 +1,14 @@
import type { ICharacterSpec } from './character/dsl-interface';
import { isString } from '@visactor/vutils';
-import type { IStory, IStoryInitOption } from './interface/runtime-interface';
+import type { ICharacterTree, IStory, IStoryCanvas, IStoryInitOption } from './interface/runtime-interface';
import type { ICharacter } from './character/runtime-interface';
import { StoryCanvas } from './canvas/canvas';
import type { IStorySpec, IActSpec } from './interface';
import { StoryFactory } from './factory/factory';
import { defaultTicker, defaultTimeline } from '@visactor/vrender';
-import type { IPlayer } from './interface/player';
-import { Player } from './player';
+import { CharacterTree } from './character-tree/character-tree';
+import type { IPlayer } from '../player/interface/player';
+import { Player } from '../player/player';
defaultTicker.remTimeline(defaultTimeline);
@@ -18,71 +19,55 @@ export class Story implements IStory {
readonly id: string;
- protected _canvas: StoryCanvas;
+ protected _canvas: IStoryCanvas;
+
+ protected _characterTree: ICharacterTree;
get canvas() {
return this._canvas;
}
- protected _characters: { [key: string]: ICharacter } = {};
-
constructor(spec: IStorySpec, option: IStoryInitOption) {
this.id = 'test-mvp_' + Story._id_++;
this._canvas = new StoryCanvas(
this,
isString(option.dom) ? (document.getElementById(option.dom) as HTMLDivElement) : option.dom
);
- this._player = new Player(this._canvas, option.playerOption);
+ this._player = new Player(this, option.playerOption);
+ this._characterTree = new CharacterTree(this);
if (spec) {
this.load(spec);
}
}
load(spec: IStorySpec) {
- spec.characters.forEach(e => {
- this._createCharacter(e);
- });
- // @ts-ignore
- spec.acts.forEach(e => {
- this._createAct(e);
- });
+ this._characterTree.initCharacters(spec.characters);
+ this._player.initActs(spec.acts);
}
getCharacters(): { [key: string]: ICharacter } {
- return this._characters;
+ return this._characterTree.getCharacters();
}
- private _createCharacter(spec: ICharacterSpec) {
- const option = { story: this, canvas: this._canvas, graphicParent: this._canvas.getStage().defaultLayer };
- if ((spec).id) {
- if (!this._characters[(spec).id]) {
- this._characters[(spec).id] = StoryFactory.createCharacter(spec, option);
- }
- return this._characters[(spec).id];
- }
- // else if ((spec).characterId) {
- // return this._characters[(spec).characterId];
- // }
- return null;
+ getCharactersById(key: string) {
+ return this._characterTree.getCharactersById(key);
}
- private _createAct(spec: IActSpec) {
- this._player.addAct(spec, this._characters);
- }
+ // private _createAct(spec: IActSpec) {
+ // this._player.addAct(spec, this._characters);
+ // }
- play(actIndex: string | number = 0) {
+ play(actIndexOrId: string | number = 0) {
// player 开始播放
- this._player.setCurrentAct(actIndex);
this._player.play();
}
pause() {
this._player.pause();
- return this._player.getCurrentAct();
+ return;
}
- async encodeToVideo(actIndex: number, millsecond: number, fps: number) {
- this._player.setCurrentAct(actIndex);
+ async encodeToVideo(actIndexOrId: number, millsecond: number, fps: number) {
return this._player.encodeToVideo(millsecond, fps);
}
diff --git a/packages/vstory/src/task.ts b/packages/vstory/src/task.ts
index f351df9c..e4eb6fe4 100644
--- a/packages/vstory/src/task.ts
+++ b/packages/vstory/src/task.ts
@@ -1,43 +1,43 @@
-import { IContext } from './interface/type';
+// import { IContext } from './interface/type';
-export type TaskCb = () => void;
+// export type TaskCb = () => void;
-export interface ITask {
- runCb: (cb: TaskCb) => void;
- run: (context?: Partial) => void;
- next: ITask | null;
- prev: ITask | null;
-}
+// export interface ITask {
+// runCb: (cb: TaskCb) => void;
+// run: (context?: Partial) => void;
+// next: ITask | null;
+// prev: ITask | null;
+// }
-export abstract class AbstractTask implements ITask {
- prev: ITask;
- next: ITask;
+// export abstract class AbstractTask implements ITask {
+// prev: ITask;
+// next: ITask;
- abstract runCb(cb: TaskCb): void;
- abstract run(context?: Partial): void;
-}
+// abstract runCb(cb: TaskCb): void;
+// abstract run(context?: Partial): void;
+// }
-export class TaskManager {
- protected _tail: ITask;
- protected _head: ITask;
+// export class TaskManager {
+// protected _tail: ITask;
+// protected _head: ITask;
- protected _context: Partial;
- setContext(context: Partial) {
- this._context = context;
- }
+// protected _context: Partial;
+// setContext(context: Partial) {
+// this._context = context;
+// }
- next(task: ITask) {
- if (!this._tail) {
- this._tail = task;
- this._head = task;
- task.run(this._context);
- } else {
- this._tail.next = task;
- task.prev = this._tail;
- this._tail.runCb(() => {
- task.run(this._context);
- });
- this._tail = task;
- }
- }
-}
+// next(task: ITask) {
+// if (!this._tail) {
+// this._tail = task;
+// this._head = task;
+// task.run(this._context);
+// } else {
+// this._tail.next = task;
+// task.prev = this._tail;
+// this._tail.runCb(() => {
+// task.run(this._context);
+// });
+// this._tail = task;
+// }
+// }
+// }
diff --git a/packages/vstory/src/template/base-template.ts b/packages/vstory/src/template/base-template.ts
deleted file mode 100644
index a78acd77..00000000
--- a/packages/vstory/src/template/base-template.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import type VChart from '@visactor/vchart';
-import type { IContext } from '../interface/type';
-import { IGraphic } from '@visactor/vrender';
-import { TaskManager } from '../task';
-import { forEachGraphicItem } from '../util/vrender-api';
-
-export abstract class Template {
- declare spec: Record;
- protected _chartInstance: VChart;
- vchartInstance() {
- return this._chartInstance;
- }
-
- // protected _graphicAnimationManager = new Map();
-
- constructor(spec: Record) {
- this.spec = spec;
- }
-
- protected abstract isValid(): boolean;
-
- protected abstract setUp(): Record;
-
- abstract render(context: Partial): void;
-
- onRenderEnd(context: Partial) {
- // const { stage } = context;
- // if (stage && this._chartInstance) {
- // forEachGraphicItem(stage as unknown as IGraphic, graphic => {
- // if (!this._graphicAnimationManager.get(graphic)) {
- // const manager = new TaskManager();
- // this._graphicAnimationManager.set(graphic, manager);
- // }
- // });
- // }
- }
-
- release() {
- this._chartInstance.release();
- this._chartInstance = null;
- // this._graphicAnimationManager.clear();
- // this._graphicAnimationManager = null;
- }
-}
diff --git a/packages/vstory/src/template/charts/simple-chart.ts b/packages/vstory/src/template/charts/simple-chart.ts
deleted file mode 100644
index 23abbb13..00000000
--- a/packages/vstory/src/template/charts/simple-chart.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import VChart, { IChartSpec } from '@visactor/vchart';
-import { IContext } from '../../interface/type';
-import { Template } from '../base-template';
-
-// TODO: 动态生成
-export const CHART_TYPES = ['line', 'bar'];
-
-export class Bar extends Template {
- protected isValid() {
- const { xField, yField, data } = this.spec;
- if (!xField || !yField) {
- throw new Error('Missing config: `xField`,`yField`');
- }
- if (!data) {
- throw new Error('Missing data');
- }
- return true;
- }
-
- protected setUp() {
- if (this.spec) {
- // TODO chart 会绘制整个background
- this.spec.background = 'rgba(0,0,0,0)';
- }
- return this.spec;
- }
-
- render(context: Partial = {}) {
- const spec = this.setUp();
- if (spec && context.dom) {
- this._chartInstance = new VChart(spec as IChartSpec, {
- dom: context.dom,
- stage: context.stage,
- renderCanvas: context.canvas
- });
- if (this._chartInstance) {
- this._chartInstance.renderSync();
- // this.onRenderEnd(context);
- }
- }
- }
-}
diff --git a/packages/vstory/src/template/ranking-bar/interface.ts b/packages/vstory/src/template/ranking-bar/interface.ts
deleted file mode 100644
index 82e19dde..00000000
--- a/packages/vstory/src/template/ranking-bar/interface.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import type { ILineGraphicAttribute, ITextGraphicAttribute } from '@visactor/vrender';
-
-export type IRankingBarData = any[];
-
-export interface IPlayConfig {
- interval?: number; // 单位毫秒
-}
-
-export interface IRankingBarSpec extends IPlayConfig {
- data: IRankingBarData;
-
- timeField: string;
- xField: string;
- yField: string;
-
- topN?: number;
-
- bar?: {
- padding?: number;
- cornerRadius?: number;
- };
-
- color?: Record;
-
- icon?: Record;
-
- iconPosition?: 'bar-end' | 'bar-start' | 'axis';
-
- iconShape?: 'circle' | 'rect';
-
- background?: string;
-
- label?: {
- visible?: boolean;
- style?: ITextGraphicAttribute;
- };
-
- nameLabel?: ITextGraphicAttribute & {
- visible?: boolean;
- position?: 'bar-end' | 'bar-start';
- style?: ITextGraphicAttribute;
- };
-
- timeLabel?: ITextGraphicAttribute;
-
- xAxis?: {
- label?: ITextGraphicAttribute;
- domainLine?: ILineGraphicAttribute;
- grid?: ILineGraphicAttribute;
- };
-
- yAxis?: {
- label?: ITextGraphicAttribute;
- domainLine?: ILineGraphicAttribute;
- grid?: ILineGraphicAttribute;
- };
-}
diff --git a/packages/vstory/src/template/ranking-bar/ranking-bar.ts b/packages/vstory/src/template/ranking-bar/ranking-bar.ts
deleted file mode 100644
index 7d5fe07b..00000000
--- a/packages/vstory/src/template/ranking-bar/ranking-bar.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import { IContext } from 'src/interface/type';
-import { IRankingBarSpec } from './interface';
-import { VChart } from '@visactor/vchart';
-import { specParser } from './spec-parser';
-import { Template } from '../base-template';
-
-export class RankingBar extends Template {
- declare spec: IRankingBarSpec;
-
- protected _chartInstance: VChart;
-
- protected _timeNodes: string[];
- protected _timeData: Map;
-
- constructor(spec: IRankingBarSpec) {
- super(spec);
- this.init();
- }
-
- protected init() {
- if (!this.isValid()) {
- return;
- }
- this._timeData = new Map();
- this._timeNodes = [];
- }
-
- protected isValid() {
- const { xField, yField, timeField, data } = this.spec;
- if (!xField || !yField || !timeField) {
- throw new Error('Missing config: `xField`,`yField`, `timeField`');
- }
- if (!data) {
- throw new Error('Missing data');
- }
- return true;
- }
-
- protected setUp() {
- const { vchartSpec } = specParser(this.spec);
- return vchartSpec;
- }
-
- render(context: Partial = {}) {
- const spec = this.setUp();
- if (spec && context.dom) {
- this._chartInstance = new VChart(spec, { dom: context.dom, stage: context.stage });
- if (this._chartInstance) {
- this._chartInstance.renderSync();
- this.onRenderEnd(context);
- }
- }
- }
-
- release() {
- super.release();
- this._timeData = null;
- this._timeNodes = null;
- }
-}
diff --git a/packages/vstory/src/template/ranking-bar/spec-parser.ts b/packages/vstory/src/template/ranking-bar/spec-parser.ts
deleted file mode 100644
index f745bd60..00000000
--- a/packages/vstory/src/template/ranking-bar/spec-parser.ts
+++ /dev/null
@@ -1,364 +0,0 @@
-import type { IRankingBarSpec } from 'src/template/ranking-bar/interface';
-import type { ICartesianAxisSpec, ICommonChartSpec, ILabelSpec } from '@visactor/vchart';
-import { isValid } from '@visactor/vutils';
-
-export function specParser(spec: IRankingBarSpec) {
- const { xField, yField, timeField, data, topN = 10, icon, interval: userInterval } = spec;
-
- // 数据处理
- const timeNodes = new Set();
- const timeData = new Map();
-
- data.sort((d1, d2) => Number(d2[xField]) - Number(d1[xField]));
-
- data.forEach(d => {
- const time = d[timeField];
- if (isValid(time)) {
- timeNodes.add(time);
- }
- if (!timeData.has(time)) {
- timeData.set(time, []);
- }
- const currentData = timeData.get(time);
- if (currentData.length < topN) {
- const _d = { ...d };
- if (icon && icon[_d[yField]]) {
- _d['icon'] = icon[_d[yField]];
- }
- currentData.push(_d);
- }
- });
-
- const interval = userInterval ? userInterval : 1000;
- const exchangeDuration = Math.min(interval, 500);
-
- // 配置处理
- const vchartSpec = templateSpec(
- spec,
- { timeNodes: Array.from(timeNodes).sort(), timeData },
- { interval, exchangeDuration }
- );
- console.log(vchartSpec);
- return { timeData, timeNodes, vchartSpec };
-}
-
-function templateSpec(
- { xField, yField, color, icon, iconPosition, iconShape, timeLabel, label, nameLabel, xAxis, yAxis }: IRankingBarSpec,
- data: { timeNodes: string[]; timeData: Map },
- { interval, exchangeDuration }: any
-): ICommonChartSpec {
- const { timeData, timeNodes } = data;
- const spec: ICommonChartSpec = {
- type: 'common',
- data: [
- {
- id: 'timeData',
- values: timeData.get(timeNodes[0])
- },
- {
- id: 'time',
- values: [{ time: timeNodes[0] }]
- }
- ],
- // @ts-ignore
- color: {
- specified: {
- ...color
- }
- },
- region: [{ clip: true }],
- series: [
- {
- type: 'bar',
- id: 'ranking-bar',
- dataId: 'timeData',
- direction: 'horizontal',
- yField,
- xField,
- seriesField: yField,
- extensionMark: [],
- label: labelSpec(label, { ...nameLabel, yField }, { interval, exchangeDuration }) as any
- }
- ],
- axes: axisSpec(xAxis, yAxis),
- player: {
- type: 'continuous',
- // visible: false,
- auto: true,
- loop: false,
- interval,
- // slider: { visible: false },
- // controller: { visible: false },
- specs: timeNodes.map(time => ({
- data: [
- { id: 'timeData', values: timeData.get(time) },
- { id: 'time', values: [{ time }] }
- ]
- }))
- },
- tooltip: { visible: false },
- customMark: [],
- animationAppear: false,
- animationUpdate: {
- bar: [
- {
- type: 'update',
- options: { excludeChannels: ['y'] },
- easing: 'linear',
- duration: interval
- },
- {
- channel: ['y'],
- easing: 'circInOut',
- duration: exchangeDuration
- }
- ],
- axis: {
- duration: interval,
- easing: 'linear'
- }
- },
- animationEnter: {
- bar: [
- {
- type: 'moveIn',
- duration: exchangeDuration,
- easing: 'cubicInOut',
- options: {
- direction: 'y',
- orient: 'negative',
- point: (datum: any, element: any, param: any, ctx: any) => {
- return {
- y: param.groupHeight + element.getBounds().height()
- };
- }
- }
- }
- ]
- },
- animationExit: {
- bar: [
- {
- type: 'moveOut',
- duration: exchangeDuration,
- easing: 'cubicInOut',
- options: {
- direction: 'y',
- orient: 'negative'
- }
- }
- ]
- }
- };
- if (!timeLabel || timeLabel.visible !== false) {
- spec.customMark.push(timeLabelSpec() as any);
- }
- if (icon) {
- const icon = iconSpec(iconPosition, iconShape, { interval, exchangeDuration });
- spec.series[0].extensionMark.push(icon as any);
- }
- return spec;
-}
-
-function labelSpec(
- label: IRankingBarSpec['label'] = {},
- nameLabel: IRankingBarSpec['nameLabel'] & { yField: string },
- { interval, exchangeDuration }: any
-) {
- const spec: ILabelSpec[] = [];
-
- if (label.visible !== false) {
- spec.push({
- visible: true,
- overlap: false,
- style: {
- // @ts-ignore
- fill: `rgb(64, 64, 64)`,
- ...label.style
- },
- smartInvert: {
- fillStrategy: label.style?.fill ? 'null' : undefined,
- strokeStrategy: label.style?.stroke ? 'null' : undefined
- },
- animationUpdate: [
- {
- duration: exchangeDuration,
- easing: 'cubicInOut',
- channel: ['y']
- },
- {
- options: { excludeChannels: ['y'] },
- easing: 'linear',
- duration: interval
- }
- ]
- });
- }
-
- if (nameLabel.visible) {
- spec.push({
- visible: true,
- overlap: false,
- // @ts-ignore
- style: {
- ...nameLabel.style
- },
- smartInvert: {
- fillStrategy: nameLabel.style?.fill ? 'null' : undefined,
- strokeStrategy: nameLabel.style?.stroke ? 'null' : undefined
- },
- position: nameLabel.position === 'bar-end' ? 'inside-right' : 'inside-left',
- formatter: `{${nameLabel.yField}}`,
- animationUpdate: customMarkUpdateAnimation(interval, exchangeDuration)
- });
- }
-
- return spec;
-}
-
-function axisSpec(xAxis: IRankingBarSpec['xAxis'] = {}, yAxis: IRankingBarSpec['yAxis'] = {}) {
- const leftAxis: ICartesianAxisSpec = {
- orient: 'left',
- type: 'band',
- inverse: true,
- // @ts-ignore
- label: { style: yAxis.label },
- domainLine: { style: yAxis.domainLine },
- // @ts-ignore
- grid: { style: yAxis.grid }
- };
- const bottomAxis: ICartesianAxisSpec = {
- orient: 'bottom',
- type: 'linear',
- nice: false,
- animation: true,
- // @ts-ignore
- label: { style: xAxis.label },
- domainLine: { style: xAxis.domainLine },
- // @ts-ignore
- grid: { style: xAxis.grid },
- // @ts-ignore
- innerOffset: { right: '10%' }
- };
-
- if (xAxis.label) {
- bottomAxis.label = xAxis.label;
- }
- return [leftAxis, bottomAxis];
-}
-
-function timeLabelSpec() {
- return {
- type: 'text',
- dataId: 'time',
- style: {
- textBaseline: 'bottom',
- fontSize: 200,
- textAlign: 'end',
- fontWeight: 600,
- text: (datum: any) => datum.time,
- x: (datum: any, ctx: any) => {
- return ctx.vchart.getChart().getCanvasRect()?.width - 50;
- },
- y: (datum: any, ctx: any) => {
- return ctx.vchart.getChart().getCanvasRect()?.height - 80;
- },
- fill: 'grey',
- fillOpacity: 0.5
- }
- };
-}
-
-function iconSpec(
- iconPosition: IRankingBarSpec['iconPosition'] = 'bar-end',
- iconShape: IRankingBarSpec['iconShape'] = 'circle',
- { interval, exchangeDuration }: any
-) {
- return {
- type: 'symbol',
- dataId: 'timeData',
- style: {
- symbolType: iconShape,
- stroke: 'white',
- lineWidth: 1,
- size: (data: any, ctx: any) => {
- const vchart = ctx.vchart;
- const series = vchart.getChart()?.getSeriesInIndex(0)[0];
- if (vchart && series) {
- const bandwidth = series.getYAxisHelper().getBandwidth(0) ?? 0;
- return Math.max(bandwidth - 4, 0);
- }
- },
- background: (data: any) => data.icon,
- // globalZIndex 有bug,会有动画闪烁和报错
- // globalZIndex: 1, // 否则会被 region 区域 clip
- x: (data: any, ctx: any) => {
- const vchart = ctx.vchart;
- const series = vchart.getChart()?.getSeriesInIndex(0)[0];
- if (vchart && series) {
- const bandwidth = series.getYAxisHelper().getBandwidth(0) ?? 0;
- if (iconPosition === 'bar-start') {
- return bandwidth / 2;
- } else if (iconPosition === 'axis') {
- return -bandwidth / 2;
- } else {
- return series.dataToPositionX(data) - bandwidth / 2;
- }
- }
- },
- y: (data: any, ctx: any) => {
- const vchart = ctx.vchart;
- const series = vchart.getChart()?.getSeriesInIndex(0)[0];
- if (vchart && series) {
- const bandwidth = series.getYAxisHelper().getBandwidth(0) ?? 0;
- return series.dataToPositionY(data) + bandwidth / 2;
- }
- },
- scaleY: iconShape === 'rect' ? 1.2 : 1
- },
- animationUpdate: customMarkUpdateAnimation(interval, exchangeDuration),
- animationEnter: [
- {
- type: 'moveIn',
- duration: exchangeDuration,
- easing: 'cubicInOut',
- options: {
- direction: 'y',
- orient: 'negative',
- point: (datum: any, element: any, param: any) => {
- return {
- y: param.groupHeight + element.getBounds().height()
- };
- }
- }
- }
- ],
- animationExit: [
- {
- type: 'moveOut',
- duration: exchangeDuration,
- easing: 'cubicInOut',
- options: {
- direction: 'y',
- orient: 'negative'
- }
- }
- ]
- };
-}
-
-function customMarkUpdateAnimation(duration: number, exchangeDuration: number) {
- return [
- {
- duration: exchangeDuration,
- easing: 'cubicInOut',
- channel: ['y']
- },
- {
- options: { excludeChannels: ['y'] },
- channel: ['x', 'x2', 'x1'],
- easing: 'linear',
- duration
- }
- ];
-}
diff --git a/packages/vstory/src/util/output.ts b/packages/vstory/src/util/output.ts
new file mode 100644
index 00000000..eb7b475c
--- /dev/null
+++ b/packages/vstory/src/util/output.ts
@@ -0,0 +1,11 @@
+const styles: Record = {
+ warn: 'color: orange;',
+ error: 'color: red;',
+ info: 'color: blue;'
+};
+
+// 定义输出函数
+export function logger(type: string, ...args: any) {
+ // eslint-disable-next-line no-console
+ console.log(`%c[${type.toUpperCase()}] ${args}`, styles[type]);
+}