我正在尝试创建一个包含svg元素作为范围的比例。例如。线性连续刻度,范围包含半径为0到100的圆,也可以查询这些圆。这样做的目的是将比例尺传递给图例制造商,后者使用d3比例尺的良好属性来构建图例。
我可以创建在浏览器的页面检查器中看到的圈子,但是在重要的地方不会显示出来。这是为什么?如果append()接受dom元素,为什么不显示?
let canvas = d3.select("body").append("svg")
.attr("width", 800)
.attr("height", 200);
let domFun = function(scale, range) {
scale.range(range);
return function(d) {
let template = document.createElement("template");
template.innerHTML = scale(d);
let dom = template.content.childNodes[0];
return dom;
}
};
let cScale = domFun(d3.scaleLinear(), ["<circle r = 0>", "<circle r = 100>"]);
let data = [0.2, 0.3, 0.6, 1];
canvas.selectAll("circle").data(data).enter()
.append(d => cScale(d))
.attr("cy", 100)
.attr("cx", (d, i) => (i + 0.5) * 200)
.attr("fill", "red");
在此感谢您的任何帮助/输入。
答案 0 :(得分:0)
为什么要使用秤来构造一些标签,并使用函数从另一个标签内部提取它?
只需使用比例尺计算半径,圆便可见
let canvas = d3.select("body").append("svg")
.attr("width", 800)
.attr("height", 200);
let cScale = d3.scaleLinear().range([0, 100]);
let data = [0.2, 0.3, 0.6, 1];
canvas.selectAll("circle").data(data).enter()
.append("circle")
.attr("r", d => cScale(d))
.attr("cy", 100)
.attr("cx", (d, i) => (i + 0.5) * 200)
.attr("fill", "red");
修改
可以使用Object interpolator来代替使用字符串插值器和构造DOM元素。这样还可以插入颜色。
let canvas = d3.select("body").append("svg")
.attr("width", 800)
.attr("height", 200);
let icScale = d3.scaleLinear().range([{r:10, fill:"red", cx:100}, {r:100, fill:"yellow", cx:700, cy:100, shape:"circle"}]);
let data = icScale.ticks(5);
let shape = icScale(data[0]).shape;
canvas.selectAll(shape).data(data).enter()
.append(shape)
.attrs(d => icScale(d));
您需要添加
<script src="https://d3js.org/d3-selection-multi.v1.min.js"></script>
将其移至HTML页面以使用.attrs()
。
仅第二个对象需要具有shape
属性,并且由于此处cy
不变,因此它仅需要位于第二个对象中。
如果您需要保留秤返回的对象,请注意必须进行复制。
答案 1 :(得分:0)
虽然其他答案是典型的D3处理此类任务的方法,但是您可以进行一次修改使其工作。
创建元素时,需要指定SVG名称空间。可能看起来像:
return function(d) {
let template = document.createElementNS(d3.namespaces.svg, "svg")
template.innerHTML = scale(d);
let dom = template.firstChild;
return dom;
}
总看起来像这样:
let svg = d3.select("body").append("svg")
.attr("width", 800)
.attr("height", 200);
let domFun = function(scale, range) {
scale.range(range);
return function(d) {
let template = document.createElementNS(d3.namespaces.svg, "svg")
template.innerHTML = scale(d);
let dom = template.firstChild;
return dom;
}
};
let cScale = domFun(d3.scaleLinear(), ["<circle r = 0>", "<circle r = 100>"]);
let data = [0.2, 0.3, 0.6, 1];
svg.selectAll("circle").data(data).enter()
.append(d => cScale(d))
.attr("cy", 100)
.attr("cx", (d, i) => (i + 0.5) * 200)
.attr("fill", "red");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>