如何将 D3 svg 元素合并到 mithril.js?
How to incorporate D3 svg elements into mithril.js?
我一直在使用 mithril.js 的框架,并希望添加 this script 将交互式树绘制到我网站上的组件中。
到目前为止,我只是将script
标签内的JS代码放入我的应用程序中,我知道通常生成的DOM对象是通过调用svg.node()
获得的。但是我知道我不能从我的对象的 view
方法中 return,而是需要 return 某种形式的 m(...)
。我尝试查看 之类的来源,但无法在其中找到解决我的问题的方法。 是否有将 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>
)
}
}
理想情况下,解决方案不必重写 Modal
的 view()
方法,而只包含对 TreeModal
中 content()
的更改。
如果不了解基本模态的实现或文档,就很难编写正确的代码 class。要解决您提到的 API,我们可以在内容中呈现一个带有随机 ID 的 div,我们稍后在将其放入 DOM 树后使用它来查找它。然后将 SVG 注入 div 并像往常一样使用 D3。我不确定 D3 是否需要清理,但这将在 onremove
中完成,如有必要,请再次确保调用 parents 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}"/>);
}
}
我一直在使用 mithril.js 的框架,并希望添加 this script 将交互式树绘制到我网站上的组件中。
到目前为止,我只是将script
标签内的JS代码放入我的应用程序中,我知道通常生成的DOM对象是通过调用svg.node()
获得的。但是我知道我不能从我的对象的 view
方法中 return,而是需要 return 某种形式的 m(...)
。我尝试查看
如果你想看看我现在的代码:
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>
)
}
}
理想情况下,解决方案不必重写 Modal
的 view()
方法,而只包含对 TreeModal
中 content()
的更改。
如果不了解基本模态的实现或文档,就很难编写正确的代码 class。要解决您提到的 API,我们可以在内容中呈现一个带有随机 ID 的 div,我们稍后在将其放入 DOM 树后使用它来查找它。然后将 SVG 注入 div 并像往常一样使用 D3。我不确定 D3 是否需要清理,但这将在 onremove
中完成,如有必要,请再次确保调用 parents 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}"/>);
}
}