简体   繁体   English

在 Svelte 中渲染使用 d3.js 创建的 div 节点?

[英]Rendering a div node created with d3.js in svelte?

I created a table in d3.js and return it as a div.node() and I am trying to render it in svelte.我在 d3.js 中创建了一个表,并将其作为div.node()返回,我正在尝试将其渲染为苗条。 It's created with fetched data so I wrap it inside an sveltes asynchronous await syntax:它是用获取的数据创建的,所以我将它包装在一个 sveltes 异步等待语法中:

<div>
    {#await fetched}
    <p>...waiting</p>
    {:then result}
        {@html result}
    {/await}
</div>

where fetched is the result of the following:其中 fetched 是以下结果:

function getData() 
    {
        return fetch("path").then(d => tabulate(d.json(), ['col', 'col2']));
    }
    let fetched = getData();

However, what is returned on the page is [object HTMLDivElement] instead of the actual table.但是,页面上返回的是[object HTMLDivElement]而不是实际的表格。 The docs say it needs to be standalone HTML, I rendered it in a file and it worked.文档说它需要是独立的 HTML,我将它呈现在一个文件中并且它可以工作。 Should I create the element first in svelte and then select it instead?我应该先在 svelte 中创建元素,然后再创建 select 它吗? It works if I select a pre-existing div.如果我 select 是一个预先存在的 div,它就可以工作。

The accompanying d3.js function full credit to jfreels :随附的 d3.js function 完全归功于jfreels

    function tabulate(data, columns) {
        const div = d3.create("div")
        
        let table = div.append('table')
        let thead = table.append('thead')
        let tbody = table.append('tbody');

        // append the header row
        thead.append('tr')
        .selectAll('th')
        .data(columns).enter()
        .append('th')
            .text(function (column) { return column; });

        // create a row for each object in the data
        let rows = tbody.selectAll('tr')
        .data(data)
        .enter()
        .append('tr');

        // create a cell in each row for each column
        let cells = rows.selectAll('td')
        .data(function (row) {
            return columns.map(function (column) {
            return {column: column, value: row[column]};
            });
        })
        .enter()
        .append('td')
            .text(function (d) { return d.value; });

        return div.node();
}

The object is a DOM element, not HTML; object 是 DOM 元素,而不是 HTML; but since it is already a fully functional element, it is not necessary to write it as HTML and make the browser re-parse it.但是由于它已经是一个功能齐全的元素,所以没有必要将它写成 HTML 并让浏览器重新解析它。 As Corrl noted, that would also cause all event listeners to be lost.正如 Corrl 所指出的,这也会导致所有事件侦听器丢失。

You can easily attach the node using eg an action :您可以使用例如操作轻松附加节点:

const append = (node, child) => node.append(child);
<div>
    {#await fetched}
        <p>...waiting</p>
    {:then result}
        <div use:append={result} />
    {/await}
</div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM