【发布时间】:2019-01-29 16:13:52
【问题描述】:
我正在尝试在 D3 中开发一个自定义形状,但我有点不懂 Javascript,我不确定 D3-Shapes 库在后台做什么。
特别是,我不确定symbol.js 中的default 函数在做什么或如何使用它。从我所知道的一点点 JS 来看,它似乎是在描述一个原型或可能是一个类。据说可以使用symbol.type 类/函数注册其他形状,但我不确定我应该如何调用它,例如var symbol = symbol("SYMBOL").type(SYMBOL) 或可能是 var SYMBOL = symbol().type(SYMBOL) 或其他一些组合。 Issue 23 讨论了形状库如何从原始实现发生变化,我认为这否定了SO: answer。我还搜索了D3-Symbol-Extra 以寻找线索,但没有骰子。
到目前为止,我有一个超椭圆的以下形状定义,它与 D3 形状库中的符号定义相匹配,例如circle、diamond等
var superellipse = {
draw : function (context, size) {
var w = size;
var h = size;
var n = 2/4;
context.moveTo(w/2*Math.sign(Math.cos( 0/9*2*Math.PI))*Math.pow(Math.abs(Math.cos( 0/9*2*Math.PI)), n), h/2*Math.sign(Math.sin( 0/9*2*Math.PI))*Math.pow(Math.abs(Math.sin( 0/9*2*Math.PI)), n));
context.lineTo(w/2*Math.sign(Math.cos( 1/9*2*Math.PI))*Math.pow(Math.abs(Math.cos( 1/9*2*Math.PI)), n), h/2*Math.sign(Math.sin( 1/9*2*Math.PI))*Math.pow(Math.abs(Math.sin( 1/9*2*Math.PI)), n));
context.lineTo(w/2*Math.sign(Math.cos( 2/9*2*Math.PI))*Math.pow(Math.abs(Math.cos( 2/9*2*Math.PI)), n), h/2*Math.sign(Math.sin( 2/9*2*Math.PI))*Math.pow(Math.abs(Math.sin( 2/9*2*Math.PI)), n));
context.lineTo(w/2*Math.sign(Math.cos( 3/9*2*Math.PI))*Math.pow(Math.abs(Math.cos( 3/9*2*Math.PI)), n), h/2*Math.sign(Math.sin( 3/9*2*Math.PI))*Math.pow(Math.abs(Math.sin( 3/9*2*Math.PI)), n));
context.lineTo(w/2*Math.sign(Math.cos( 4/9*2*Math.PI))*Math.pow(Math.abs(Math.cos( 4/9*2*Math.PI)), n), h/2*Math.sign(Math.sin( 4/9*2*Math.PI))*Math.pow(Math.abs(Math.sin( 4/9*2*Math.PI)), n));
context.lineTo(w/2*Math.sign(Math.cos( 5/9*2*Math.PI))*Math.pow(Math.abs(Math.cos( 5/9*2*Math.PI)), n), h/2*Math.sign(Math.sin( 5/9*2*Math.PI))*Math.pow(Math.abs(Math.sin( 5/9*2*Math.PI)), n));
context.lineTo(w/2*Math.sign(Math.cos( 6/9*2*Math.PI))*Math.pow(Math.abs(Math.cos( 6/9*2*Math.PI)), n), h/2*Math.sign(Math.sin( 6/9*2*Math.PI))*Math.pow(Math.abs(Math.sin( 6/9*2*Math.PI)), n));
context.lineTo(w/2*Math.sign(Math.cos( 7/9*2*Math.PI))*Math.pow(Math.abs(Math.cos( 7/9*2*Math.PI)), n), h/2*Math.sign(Math.sin( 7/9*2*Math.PI))*Math.pow(Math.abs(Math.sin( 7/9*2*Math.PI)), n));
context.lineTo(w/2*Math.sign(Math.cos( 8/9*2*Math.PI))*Math.pow(Math.abs(Math.cos( 8/9*2*Math.PI)), n), h/2*Math.sign(Math.sin( 8/9*2*Math.PI))*Math.pow(Math.abs(Math.sin( 8/9*2*Math.PI)), n));
context.lineTo(w/2*Math.sign(Math.cos( 9/9*2*Math.PI))*Math.pow(Math.abs(Math.cos( 9/9*2*Math.PI)), n), h/2*Math.sign(Math.sin( 9/9*2*Math.PI))*Math.pow(Math.abs(Math.sin( 9/9*2*Math.PI)), n));
context.closePath();
}
};
我可以根据默认大小绘制要绘制的形状,但是我无法通过设置r 属性来调整圆形的尺寸;在这种情况下,通过设置 n、h 和 w 属性。
var svg = d3.select("svg")
.attr("width", 500)
.attr("height", 500);
function visualize(json) {
var nodes = svg.selectAll("g nodetext")
.data(json.nodes);
var entryPoint = nodes.enter()
.append("g")
.attr("class", "node")
.attr("transform", function(d) {
return "translate(" + d.x + ",80)"
});
// var ellipse = entryPoint.append("circle")
// .attr("r", 50);
var nodeShape = entryPoint.append("path")
.attr("d", d3.symbol().type(superellipse))
.style("stroke", "gray")
.attr("fill", "pink")
// .n(function(d) {return d.n;})
.attr("w", function(d) {
return d.w;
})
.attr("h", function(d) {
return d.h;
});
var nodeText = entryPoint.append("text")
.text(function(d) {
return d.text;
})
.attr({
"text-anchor": "middle"
});
};
明确地说,我按如下方式调用它:
var superellipse = {
draw: function(context, size) {
var w = size;
var h = size;
var n = 2 / 4;
context.moveTo(w / 2 * Math.sign(Math.cos(0 / 9 * 2 * Math.PI)) * Math.pow(Math.abs(Math.cos(0 / 9 * 2 * Math.PI)), n), h / 2 * Math.sign(Math.sin(0 / 9 * 2 * Math.PI)) * Math.pow(Math.abs(Math.sin(0 / 9 * 2 * Math.PI)), n));
context.lineTo(w / 2 * Math.sign(Math.cos(1 / 9 * 2 * Math.PI)) * Math.pow(Math.abs(Math.cos(1 / 9 * 2 * Math.PI)), n), h / 2 * Math.sign(Math.sin(1 / 9 * 2 * Math.PI)) * Math.pow(Math.abs(Math.sin(1 / 9 * 2 * Math.PI)), n));
context.lineTo(w / 2 * Math.sign(Math.cos(2 / 9 * 2 * Math.PI)) * Math.pow(Math.abs(Math.cos(2 / 9 * 2 * Math.PI)), n), h / 2 * Math.sign(Math.sin(2 / 9 * 2 * Math.PI)) * Math.pow(Math.abs(Math.sin(2 / 9 * 2 * Math.PI)), n));
context.lineTo(w / 2 * Math.sign(Math.cos(3 / 9 * 2 * Math.PI)) * Math.pow(Math.abs(Math.cos(3 / 9 * 2 * Math.PI)), n), h / 2 * Math.sign(Math.sin(3 / 9 * 2 * Math.PI)) * Math.pow(Math.abs(Math.sin(3 / 9 * 2 * Math.PI)), n));
context.lineTo(w / 2 * Math.sign(Math.cos(4 / 9 * 2 * Math.PI)) * Math.pow(Math.abs(Math.cos(4 / 9 * 2 * Math.PI)), n), h / 2 * Math.sign(Math.sin(4 / 9 * 2 * Math.PI)) * Math.pow(Math.abs(Math.sin(4 / 9 * 2 * Math.PI)), n));
context.lineTo(w / 2 * Math.sign(Math.cos(5 / 9 * 2 * Math.PI)) * Math.pow(Math.abs(Math.cos(5 / 9 * 2 * Math.PI)), n), h / 2 * Math.sign(Math.sin(5 / 9 * 2 * Math.PI)) * Math.pow(Math.abs(Math.sin(5 / 9 * 2 * Math.PI)), n));
context.lineTo(w / 2 * Math.sign(Math.cos(6 / 9 * 2 * Math.PI)) * Math.pow(Math.abs(Math.cos(6 / 9 * 2 * Math.PI)), n), h / 2 * Math.sign(Math.sin(6 / 9 * 2 * Math.PI)) * Math.pow(Math.abs(Math.sin(6 / 9 * 2 * Math.PI)), n));
context.lineTo(w / 2 * Math.sign(Math.cos(7 / 9 * 2 * Math.PI)) * Math.pow(Math.abs(Math.cos(7 / 9 * 2 * Math.PI)), n), h / 2 * Math.sign(Math.sin(7 / 9 * 2 * Math.PI)) * Math.pow(Math.abs(Math.sin(7 / 9 * 2 * Math.PI)), n));
context.lineTo(w / 2 * Math.sign(Math.cos(8 / 9 * 2 * Math.PI)) * Math.pow(Math.abs(Math.cos(8 / 9 * 2 * Math.PI)), n), h / 2 * Math.sign(Math.sin(8 / 9 * 2 * Math.PI)) * Math.pow(Math.abs(Math.sin(8 / 9 * 2 * Math.PI)), n));
context.lineTo(w / 2 * Math.sign(Math.cos(9 / 9 * 2 * Math.PI)) * Math.pow(Math.abs(Math.cos(9 / 9 * 2 * Math.PI)), n), h / 2 * Math.sign(Math.sin(9 / 9 * 2 * Math.PI)) * Math.pow(Math.abs(Math.sin(9 / 9 * 2 * Math.PI)), n));
context.closePath();
}
};
var svg = d3.select("svg")
.attr("width", 500)
.attr("height", 500);
function visualize(json) {
var nodes = svg.selectAll("g nodetext")
.data(json.nodes);
var entryPoint = nodes.enter()
.append("g")
.attr("class", "node")
.attr("transform", function(d) {
return "translate(" + d.x + ",80)"
});
// var ellipse = entryPoint.append("circle")
// .attr("r", 50);
var nodeShape = entryPoint.append("path")
.attr("d", d3.symbol().type(superellipse))
.style("stroke", "gray")
.attr("fill", "pink")
// .n(function(d) {return d.n;})
.attr("w", function(d) {
return d.w;
})
.attr("h", function(d) {
return d.h;
});
var nodeText = entryPoint.append("text")
.text(function(d) {
return d.text;
})
.attr({
"text-anchor": "middle"
});
}
var json = {
"nodes": [{
"text": "test A",
"x": 100,
"y": 100,
"w": 200,
"n": 0.5,
"h": 200,
"color": "red"
},
{
"text": "test B",
"x": 200,
"y": 200,
"w": 200,
"n": 3,
"h": 100,
"color": "red"
},
]
};
visualize(json);
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg></svg>
【问题讨论】:
标签: javascript d3.js svg html5-canvas