Wirecloud使用iframe呈现小部件的html。这似乎为一些需要引用内部定义的高级svg功能带来了问题(另请参阅this discussion)。
生成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)(当检查创建的图形时,fill属性为null)
通常在svg中你只需使用url(#reference)。已尝试将“about:blank”和“about:srcdoc”作为workarounds按照其他地方的建议尝试,但不知何故它们似乎不起作用(chrome / firefox)
这似乎是svg / iframe的问题(不是特定于wirecloud)但我没有尝试在wirecloud外的iframe中渲染svg以确认这一点。
如果没有解决方法,这将限制可以使用javascript以编程方式在wirecloud小部件中呈现的svg图形的类型。也许嵌入svg的其他一些方法可以工作(从服务器获取它),但它不是交互式小部件的最佳设计,或者可能是iframe alternative :-)
答案 0 :(得分:1)
WireCloud的所有架构都基于iframe
。这些元素用于在每个小部件和操作符之间提供隔离,并且当前不能被禁用。此外,建议的替代方案(webcomponents)还不够成熟,无法成为真正的替代方案:(。
无论如何,WireCloud并没有使用srcdoc
属性,因此在窗口小部件中呈现SVG图像的问题不应与链接的问题相关。这个问题似乎与使用<base>
元素(由WireCloud注入到小部件的HTML中)有关。有关详细信息,请参阅此answer。我们创建了一个ticket来分析我们是否可以删除<base>
元素,但是现在,您必须使用绝对网址。 E.g:
var baseUrl = window.location.origin + window.location.pathname + window.location.search;
arc.setAttribute("fill", "url(" + baseUrl + "#MyGradient)");
这是我的&#34; SVG示例小部件的完整代码&#34;:
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)");