1

Wirecloud 使用 iframe 来呈现小部件的 html。这似乎给一些需要引用内部定义的高级 svg 功能带来了问题(另请参阅此讨论)。

生成 svg 的 js 代码在单页应用程序或 django 视图中运行良好。没有错误消息。

整个代码太大,无法在此处发布,但关键的相关元素是:

    var canvas = document.getElementById("canvas");
    var svgns = "http://www.w3.org/2000/svg";
    var svg = document.createElementNS(svgns, 'svg');

然后是一个典型的定义(例如渐变):

    var defs = document.createElementNS(svgns, "defs"); 
    var linearGradient = document.createElementNS(svgns, "linearGradient");

最后是定义的使用

    arc.setAttribute('style', "fill:url(about:srcdoc#linearGradient);");

它是在创建 svg 对象时未正确链接到的引用(此处为#linearGradient)(检查创建的图形时,填充属性为空)

通常在 svg 中,您只需使用 url(#reference)。已尝试将“about:blank”和“about:srcdoc”作为SO其他地方建议的解决方法,但不知何故它们似乎不起作用(chrome / firefox)

这似乎是 svg / iframe 的问题(不是特定于wirecloud),但我没有尝试在wirecloud 之外的iframe 中渲染svg 来确认这一点。

如果没有解决方法,这将限制可以使用 javascript 以编程方式在 Wirecloud 小部件中呈现的 svg 图形类型。也许嵌入 svg 的其他一些方法会起作用(从服务器获取它),但它不是交互式小部件的最佳设计,或者可能是 iframe替代方案:-)

4

1 回答 1

1

WireCloud 的所有架构都是基于iframes 的。这些元素用于提供每个小部件和操作符之间的隔离,目前无法禁用。此外,提议的替代方案(webcomponents)还不够成熟,无法成为真正的替代方案:(。

无论如何,WireCloud 没有使用该srcdoc属性,因此您在小部件内渲染 SVG 图像的问题不应该与链接的问题有关。问题似乎与<base>元素的使用有关(由 WireCloud 注入到小部件的 HTML 中)。有关更多详细信息,请参阅此答案。我们已经创建了一张票,用于分析是否可以删除该<base>元素,但现在,您必须使用绝对 URL。例如:

var baseUrl = window.location.origin + window.location.pathname + window.location.search;

arc.setAttribute("fill", "url(" + baseUrl + "#MyGradient)");

这是我的“SVG 示例小部件”的完整代码:

var baseUrl = window.location.origin + window.location.pathname + window.location.search;

var svgns = "http://www.w3.org/2000/svg";
var svg = document.createElementNS(svgns, 'svg');
document.body.appendChild(svg);

var defs = document.createElementNS(svgns, "defs");
var linearGradient = document.createElementNS(svgns, "linearGradient");
linearGradient.setAttribute("id", "MyGradient");
defs.appendChild(linearGradient);
svg.appendChild(defs);

var stop = document.createElementNS(svgns, "stop");
stop.setAttribute("offset", "5%");
stop.setAttribute("stop-color", "green");
linearGradient.appendChild(stop);

stop = document.createElementNS(svgns, "stop");
stop.setAttribute("offset", "95%");
stop.setAttribute("stop-color", "gold");
linearGradient.appendChild(stop);

var rect = document.createElementNS(svgns, "rect");
rect.setAttribute("x", "10");
rect.setAttribute("y", "10");
rect.setAttribute("width", "100");
rect.setAttribute("height", "100");
rect.setAttribute("fill", "url(" + baseUrl + "#MyGradient)");
于 2016-04-22T06:52:24.533 回答