在以下示例中,有人可以帮我理解如何在路径上渲染标记吗?
var size = {width: 500, height: 180},
svg = d3.select("body").append("svg").attr(size),
markers = Marker(svg, "red");
var circles = svg.append("ellipse").datum({})
.attr({
class: "circle",
'cx': size.width / 2,
'cy': size.height / 2,
'ry': 50,
'rx': 100,
"fill": "steelblue"
}),
shadePath = svg.append("path")
.attr({
class: "arrow",
d: d3.svg.line()([[100,50], [400,150]]),
stroke: "red"
}).style({
"marker-start": markers.start,
"marker-end": markers.end
});
function Marker(svg, color){
var id = "filter-marker", defs = svg.selectAll("defs").data([id]),
idS = id + "-start", idE = id + "-end";
defs.enter().append("defs");
var markers = defs.selectAll("#"+id).data([
{
attr: {id: idS, viewBox: "0 0 7 7",
markerWidth: "7", markerHeight: "7",
refX: "4", refY: "4",orient: "auto"},
symbol: {
type: "rect",
attr: {x: "1", y: "1", width: "5", height: "5", style: "stroke: none; fill: " + color + ";"}
}
},
{
attr: {id: idE, viewBox: "0 0 13 13",
markerWidth: "13", markerHeight: "13",
refX: "2", refY: "7", orient: "auto"},
symbol: {
type: "path",
attr:{d: "M2,2 L2,13 L8,7 L2,2", style: "stroke: none; fill: " + color + ";"}
}
}
]);
markers.enter().append("marker")
.each(function(d){
return d3.select(this).attr(d.attr)
});
var marker = markers.selectAll(".symbol").data(function(d){return [d.symbol]});
marker.enter().append(function(d) {
return document.createElement(d.type)
})
.each(function(d){
return d3.select(this).attr(d.attr)
});
return {
start: ["url(#", idS, ")"].join(""),
end: ["url(#", idE, ")"].join("")
}
};
body{margin:0; position: relative}
svg{outline:solid 1px #ccc;
overflow: visible;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tinycolor/1.1.2/tinycolor.min.js"></script>
例如,如果我手动编辑chrome devtools中的标记元素,并删除viewBox属性,则会渲染标记。然后,如果我从代码中删除viewBox属性并再次尝试,则仍然不会渲染标记。然后,如果我手动添加viewBox,标记将呈现。
我尝试在计时器回调中添加标记,以防它是时间问题但没有变化。
呈现的HTML看起来像这样......
<svg width="500" height="180">
<defs>
<marker id="filter-marker-start" viewBox="0 0 7 7" markerWidth="7"
markerHeight="7" refX="4" refY="4"
orient="auto">
<rect x="1" y="1" width="5" height="5"
style="stroke: none; fill: red;"></rect>
</marker>
<marker id="filter-marker-end" viewBox="0 0 13 13" markerWidth="13"
markerHeight="13" refX="2" refY="7"
orient="auto">
<path d="M2,2 L2,13 L8,7 L2,2" style="stroke: none; fill: red;"></path>
</marker>
</defs>
<ellipse class="circle" cx="250" cy="90" ry="50" rx="100" fill="steelblue"></ellipse>
<path class="arrow" d="M100,50L400,150" stroke="red"
style="marker-start: url(#filter-marker-start); marker-end: url(#filter-marker-end);">
</path>
</svg>
答案 0 :(得分:2)
您无法使用document.createElement创建SVG元素,您必须使用document.createElementNS并提供SVG名称空间。
我确定如果你使用Chrome的devtools检查rect和path元素,它会告诉你元素是html元素(在html命名空间中)而不是SVG元素。
我已经纠正了以下示例:
var size = {width: 500, height: 180},
svg = d3.select("body").append("svg").attr(size),
markers = Marker(svg, "red");
var circles = svg.append("ellipse").datum({})
.attr({
class: "circle",
'cx': size.width / 2,
'cy': size.height / 2,
'ry': 50,
'rx': 100,
"fill": "steelblue"
}),
shadePath = svg.append("path")
.attr({
class: "arrow",
d: d3.svg.line()([[100,50], [400,150]]),
stroke: "red"
}).style({
"marker-start": markers.start,
"marker-end": markers.end
});
function Marker(svg, color){
var id = "filter-marker", defs = svg.selectAll("defs").data([id]),
idS = id + "-start", idE = id + "-end";
defs.enter().append("defs");
var markers = defs.selectAll("#"+id).data([
{
attr: {id: idS, viewBox: "0 0 7 7",
markerWidth: "7", markerHeight: "7",
refX: "4", refY: "4",orient: "auto"},
symbol: {
type: "rect",
attr: {x: "1", y: "1", width: "5", height: "5", style: "stroke: none; fill: " + color + ";"}
}
},
{
attr: {id: idE, viewBox: "0 0 13 13",
markerWidth: "13", markerHeight: "13",
refX: "2", refY: "7", orient: "auto"},
symbol: {
type: "path",
attr:{d: "M2,2 L2,13 L8,7 L2,2", style: "stroke: none; fill: " + color + ";"}
}
}
]);
markers.enter().append("marker")
.each(function(d){
return d3.select(this).attr(d.attr)
});
var marker = markers.selectAll(".symbol").data(function(d){return [d.symbol]});
marker.enter().append(function(d) {
return document.createElementNS("http://www.w3.org/2000/svg", d.type)
})
.each(function(d){
return d3.select(this).attr(d.attr)
});
return {
start: ["url(#", idS, ")"].join(""),
end: ["url(#", idE, ")"].join("")
}
};
&#13;
body{margin:0; position: relative}
svg{outline:solid 1px #ccc;
overflow: visible;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tinycolor/1.1.2/tinycolor.min.js"></script>
&#13;