问题描述
我一直在使用mithril.js构建框架,并希望添加this script,该框架将交互式树绘制到我网站上的组件中。
到目前为止,我只是将JS代码放在script
标记内的应用程序中,并且我知道通常情况下,生成的DOM对象是通过调用svg.node()
获得的。但是我知道我无法从对象的view
方法返回该值,而是需要返回m(...)
形式的值。我尝试查看this one之类的资源,但是找不到解决我问题的方法。 是否存在将D3 SVG图形合并到mihtril.js中的已知方法?
如果您想查看我现在拥有的代码:
export default class TreeModal extends Modal {
content() {
var treeData = ... // some data
... // Other code; irrelevant to this question
var svg = d3.select("body").append("svg")
.attr("width",width + margin.right + margin.left)
.attr("height",height + margin.top + margin.bottom).append("g")
.attr("transform","translate(" + margin.left + "," + margin.top + ")");
// Some other code adding more functionality
// At this point,svg contains the SVG object which I wish to display
return svg.node(); // Raises ILLEgal CONSTRUCTOR error; how to adapt this for Mithril.js?
}
}
提前感谢所有帮助!
更新:Modal
似乎对我的问题至关重要,因为我使用的API实际上要求我在以下任何子类中实现content()
方法Modal
。我看着Modal.js
,相关的位是:
export default class Modal {
view() {
return (
<div>
...
{this.content()}
...
</div>
)
}
}
理想情况下,该解决方案不必覆盖view()
的{{1}}方法,而只需在Modal
中包含对content()
的更改。
解决方法
在不知道基本Modal类的实现或文档的情况下,很难编写正确的代码。要解决您提到的API,我们可以在内容中呈现一个带有随机ID的div,稍后将其放入DOM树中后再用于查找它。然后将SVG注入该div中,然后像往常一样使用D3。我不确定D3是否需要清理,但是可以在onremove
中完成,如果有必要,请再次确保致电父母onremove
。
我在content
中使用JSX,但是无法测试其格式。
export default class TreeModal extends Modal {
constructor() {
// @TODO: Not sure what Modal's constructor looks like.
super();
// Create a random DOM id we share between content()
//and oncreate().
this.svgContainerId = 'svg_container_' +
Math.floor(Math.random()*1000000000) + 1;
}
oncreate(vnode) {
// @TODO: Check if Modal implements this method or not.
// super.oncreate(vnode);
var treeData = {} // some data
... // Other code; irrelevant to this question
// USE our predefined id to lookup the div rendered in content
// and inject our SVG into that container.
var svg = d3.select(document.getElementById(this.svgContainerId)).append("svg")
.attr("width",width + margin.right + margin.left)
.attr("height",height + margin.top + margin.bottom).append("g")
.attr("transform","translate(" + margin.left + "," + margin.top + ")");
// Some other code adding more functionality
}
content() {
// render a plain DIV with our predefined id that never changes.
// this JSX is untested
return (<div id="{this.svgContainerId}"/>);
}
}