【问题标题】:Fix broken display of SVG using ipywidgets DOMWidget in Jupyter Notebook在 Jupyter Notebook 中使用 ipywidgets DOMWidget 修复 SVG 的损坏显示
【发布时间】:2019-11-01 16:40:20
【问题描述】:

总结

请参阅this example notebook,它没有按预期工作。笔记本中的第三个单元应该显示一个 SVG 窗口,其中包含一个简单的绿色框。示例输出显示在单元格 4* 中。

详情

运行笔记本后,当我将鼠标悬停在控制台中的元素上时,会显示一个工具提示弹出窗口。由于这个弹出窗口,我相信肯定会创建 SVG 容器和框(这是一个 PATH 元素),它们只是没有被显示。弹出窗口说它们以 0x0 的大小呈现。

我怎样才能让它按预期工作,以便 SVG 窗口的内容显示在输出单元格(单元格 #3)中?

代码

为方便起见,这里是逐个单元格的代码。

单元#1

import ipywidgets.widgets as widgets
from traitlets import Unicode


class Test(widgets.DOMWidget):
    _view_name = Unicode('TestView').tag(sync=True)
    _view_module = Unicode('test').tag(sync=True)
    _view_module_version = Unicode('0.1.0').tag(sync=True)

单元#2

%%javascript

require.undef('test');

define('test', ["@jupyter-widgets/base"], function(widgets) {
    var TestView = widgets.DOMWidgetView.extend({

        render: function() {
            TestView.__super__.render.apply(this, arguments);
            var svg = document.createElement('svg');
            svg.innerHTML = '<path fill-rule="evenodd" fill="#66cc99" stroke="#555555" stroke-width="2.0" opacity="0.6" d="M 0.0,0.0 L 50.0,0.0 L 50.0,50.0 L 0.0,50.0 L 0.0,0.0 z" />';
            this.el.appendChild(svg);
            console.log(svg);  // when you hover over this line in the console, you can see the SVG has been created...
        },
    });

    return {
        TestView : TestView,
    };

});

#3 单元格

Test()  # this cell should output a green box

单元格 #4:示例输出

%%html
<svg>
<path fill-rule="evenodd" fill="#66cc99" stroke="#555555" stroke-width="2.0" opacity="0.6" d="M 0.0,0.0 L 50.0,0.0 L 50.0,50.0 L 0.0,50.0 L 0.0,0.0 z" />
</svg>

* 注意:克隆并运行 notebook 以在底部显示预期的输出。

【问题讨论】:

    标签: javascript python svg jupyter-notebook ipywidgets


    【解决方案1】:

    想通了:由于我不明白的原因,您必须使用 document.createElementNS() 函数来添加 SVG,而不是 document.createElement()。您还必须使用svg.setAttributeNS() 而不是svg.setAttribute()

    Here's a fixed version 的笔记本。代码:

    %%javascript
    
    require.undef('test');
    
    define('test', ["@jupyter-widgets/base"], function(widgets) {
        var TestView = widgets.DOMWidgetView.extend({
    
            render: function() {
                TestView.__super__.render.apply(this, arguments);
                var xmlns = "http://www.w3.org/2000/svg";
                var svg = document.createElementNS(xmlns, "svg");
                svg.setAttributeNS(null, "viewBox", "0 0 100 100");
                svg.innerHTML = '<path fill-rule="evenodd" fill="#66cc99" stroke="#555555" stroke-width="2.0" opacity="0.6" d="M 0.0,0.0 L 50.0,0.0 L 50.0,50.0 L 0.0,50.0 L 0.0,0.0 z" />';
                this.el.appendChild(svg);
                console.log(svg);  // when you hover over this line in the console, you can see the SVG has been created...
            },
        });
    
        return {
            TestView : TestView,
        };
    
    });
    

    【讨论】:

    • 啊,这是一个非常好的发现。当您在 jupyter-widgets 存储库上发布问题时,我使用了您的代码,但我无法弄清楚出了什么问题(主要是因为我对 SVG 一无所知)。
    • @PascalBugnion 是的,我不知道杰克关于 javascript 或 SVG,这是一个愚蠢的陷阱。天哪。
    • @PascalBugnion 和now I'm trying to figure out 如何将 SVG 附加到主干视图。我发现每一次关于如何做到这一点的讨论似乎都已经有好几年了。
    猜你喜欢
    • 1970-01-01
    • 2017-10-04
    • 1970-01-01
    • 2022-12-01
    • 2019-01-07
    • 2021-02-06
    • 1970-01-01
    • 2016-07-20
    • 2016-05-01
    相关资源
    最近更新 更多