Replies: 4 comments 4 replies
-
|
Beta Was this translation helpful? Give feedback.
-
现在支持 render(options){
this.mark(options);
// ...
} |
Beta Was this translation helpful? Give feedback.
-
目前通过 主要考虑下面两种情况:
chart.interval().encode('x', 'a');
chart.options({
type: 'view',
children: [{ type: 'interval', encode: { x: 'b' } }],
});
const options = chart.options();
// 结果1:直接覆盖
expect(options.children[0].encode.x).toBe('b');
// 结果2:合并
expect(options.children[0].encode.x).toBe('a');
chart.options({
type: 'view',
children: [{ type: 'interval', encode: { x: 'b' } }],
});
// 是否要支持以下的写法?
// 如何支持以下的写法?
chart.getNodeByType('interval').encode('x', 'a');
const options = chart.options();
expect(options.children[0].encode.x).toBe('a'); 下面提出一种实现上面问题的方法。 解决思路就是把 chart 类比成浏览器的 document 对象,options 是 innerHTML,chart node 树就是实例化的 DMO 树。所以在调用 下面是伪代码。 export class Chart {
options(options) {
const oldOptions = optionsOf(this); // 获得当前 options
if (arguments.length === 0) return oldOptions;
const newOptions = deepMix(oldOptions, options); // 得到最新的 options
updateRoot(this.root, newOptions); // 根据新的 options 去获得更新 chart node
return this;
}
render() {
render(optionsOf(this));
}
} 上面最关键的函数就是
第一个问题一个思路就是:同一层级的的节点在没有 id 的情况下,根据 index 匹配。 chart.interval();
chart.options({
type: 'view',
children: [
{ type: 'interval', encode: { x: 'b' } },
{ type: 'interval', encode: { x: 'a' } },
],
});
const options = chart.options();
expect(options.children[0].encode.x).toBe('b'); 第二个问题是:如果类型相同,更新配置;如果节点不同,删除旧的节点,然后增加新的节点。 第三个问题的问题在于对自定义 Mark 的处理。对于内置的 Mark 都用对应的 node 类,但是自定义 Mark 是没有过的。解决办法就是自定义 Mark 的就对应 node 基类,只能通过 function ctorFromType(type) {
// 正对高阶 Mark
if(typeof type === 'function') return Mark;
// 内置 Mark
const builtins = {
interval: Interval,
line: Line,
// ...
};
return builtins[type] || Node;
}
function createNode(type, options) {
const Ctor = ctorFromType(type);
return new Ctor(options);
} // 自定义节点
registerNode('grid', Grid);
chart.options({
type: 'grid',
id: 'grid'
});
const node = chart.getNodeById('grid');
// 只能通过 attr 去设置数据性,没有 encode 这些方法。
node.attr('cols', 2).attr('rows', 3); 这里说面一下,为什么要这么复杂去更新 tree 而不是生成 tree,比如如下: this.root = parse(options); 主要是因为要保持之前的引用,如果是直接更新 tree,就会出现以下的问题。 const interval = chart.interval();
chart.options({
type:'view',
children: [{type:'interval'}]
})
// 这行代码不会去更新 options
// 因为这个 interval 已经被新的 interval 替代了
interval.encode('x', 'a');
const options = chart.options();
expect(options.children[0].encode.x).toBeUndefined(); // 这里还是 undefined |
Beta Was this translation helpful? Give feedback.
-
close: #5074 |
Beta Was this translation helpful? Give feedback.
-
Chart API 渲染 Spec
让 Chart API 可以直接渲染 Spec,这个能力在 321 不会在文档透出,但是可以作为内部或者外部生态建设的机制。期望在 5.1.0,也就是正式版本的后的第一个版本发布。
开始使用
函数签名
实现建议
参考
__tests__/plots/api/chart-hom-mark.ts
增加多个图表测试新增 API,同时在参考__tests__/integration/api-chart-hom-mark.spec.ts
增加对应集成测试文件。设计参考
Beta Was this translation helpful? Give feedback.
All reactions