100pah opened a new issue #11906: About serializable `option` (JSONable `option`) URL: https://github.com/apache/incubator-echarts/issues/11906 ## Potential Scenarios There might some scenarios requiring serializable `option`. **If there are other scenarios, add them in thsi part.** ### (A) Some kind of online chart generating system Some online systems enable users to make chart via "drag and drop" componets and assemble snippets to `echarts option`. This system need to take care about security issues (like XSS) so user defiend code snippets might be forbiden. But those code snippets are necessary in some cases to suffice some elaborate requirements. So those system might only provide some predefined code snippet, rather than let user to write code online and `eval`. ### (B) Run cross runtime enrionment Check these example below: #### pyecharts https://github.com/pyecharts/pyecharts It seems transpile callbacks to JavaScript code and assemble them to the final JavaScript `option`. See https://pyecharts.readthedocs.io/zh/latest/zh-cn/advanced/#javascript #### Flutter-echarts Seams also by `eval`. https://github.com/entronad/flutter_echarts/blob/master/example/lib/main.dart#L129 #### Baidu Smart App Currently the dynamic lib echarts requires run code cross runtime. But I think that is not a case becuase this solution is temporarily. After the implementation of Canvas refactored, this issue will not exists. Callback can be used at that time. ## Candidate solutions ### Provide an DSL (Domain-Specific Language) to write callback But, emm... currently @100pah still be worried about using DSL, because the defects below: + The cost of learning for user. More powerful, more cost. + Difficult to debug. + Might increase the size of the package a log. + Compared to the original JS callback, the capability probably need to be reduced. It's not easy to trade-off between the capabilities and complexity. But when users need to use callback, they probably have met some elaborate requirement. It might be depressed if take time to learnt the DSL but finally found the feature can not be satisfied. + Not easy to ensure compatibiliy if meet bugs or new requirements. A relatively simple solution is introduce string pattern language (like [etpl](https://github.com/ecomfe/etpl)) in callback. But it suitable for the callback that returns string (like `label.formatter`) but not sure it is suitable enough to be used on other callback if they returns `number`/`object`. ### Add pipe Like Ovilia mentioned in #11878. That is not a overall solution but devoted to some common cases. It probably helps but now meets some confliction and compatibility issues. ### Make a bridge between runtimes I think the target goal is "make `option` seriablizable or event JSONable", but it's not necessary to instroduce new language to callback. New language also needs to be compiled (evaluated) at runtime. So it is essentially the same as JavaScript with `eval`. Probably we can write every callback still in JavaScript or in other Languages that users familiar with, and mount them in some places. And give the "name/path" in `option` to tell echarst where to find the callback. For example: ```js // A serializable `option`: var option = { series: [{ type: 'line', label: { formatterHandler: 'xxx.yyy.myLabelFormatter' } }, { type: 'custom', renderItemHandler: 'xxx.yyy.myRenderItem' }] }; ``` And then, the handlers can be implemented eithere in JavaScript or in other existing languages. For example, run the handlers in the same runtime: ```js function myLabelFormatter() { ... } function myRenderItem() { ... } echarts.registerExternalHandler('xxx.yyy.myLabelFormatter', myLabelFormatter); echarts.registerExternalHandler('xxx.yyy.myRenderItem', myRenderItem); ``` And if users need the handlers serializable, users are responsible for `eval` them according to their security requirement. For example, final developer write the code: ```js var myRenderItemCode = ` return function (params, api) { return { type: 'circle', shape: {cx: api.get(0), cy: api.get(1), r: 20}, style: {fill: 'red'} }; }; ` ``` And the platform is responsible for `eval` them: ```js function compileAndRegister(handlerName, userCode) { // Prevent userCode from visit global variables. var mask = []; for (var key in window) { mask.push(key + ' = null'); } mask = 'var ' + mask.join(',') + ';'; // Use strict mode to prevent userCode create variable // on global or visit global via `this`. var body = '"use strict"; ' + mask + ' ' + userCode; var handler = (new Function (userCode))(); echarts.registerExternalHandler(handlerName, handler); } ``` And if possible, platform developers can make some transpiler that enable users to write the callbacks in some other language and then transpiled to JavaScript, and then call `registerExternalHandler`. Notice, if business code need to be run on a different runtime environment from echarts, in most cases, we have to run callbacks on "echarts runtime" rather than "business runtime". Becuase in most cases the callbacks need to be "sync" rather than "async". If the communication between runtimes can not be "sync", that would be impossible. <!-- This issue is generated by echarts-issue-helper. DO NOT REMOVE --> <!-- This issue is in English. DO NOT REMOVE -->
---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: [email protected] With regards, Apache Git Services --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
