D3.js を使用して、太陽系のデータ視覚化を作成しました。そうしているうちに、円要素の x、y 位置と、円要素または曲線パス要素の半径を設定するときに奇妙な矛盾に気付きました。惑星を配置するには、次のようにします。
planetEnter.append("circle")
.attr("r", function (d) {
return planetScale(d.radius); })
.attr("class", "body")
.attr("fill", "url(#gradePlanet)")
.attr("filter", "url(#glowPlanet)")
.attr("transform", function (d) {
// Position of planet in relation to the sun at (0,0)
// x and y are linear scales
return "translate(" + x(d.orbital_radius) + ", " + y(0) + "), scale(.05)"; });
軌道線を作成するには、次のようにします。
var orbital_arc = d3.svg.arc()
.startAngle(0)
.endAngle(6.28318531) // 360 degrees
.innerRadius(function (d) {
return x(d.orbital_radius); })
.outerRadius(function (d) {
return x(d.orbital_radius); });
これが機能し、円弧の半径が惑星の位置と一致すると考えるかもしれませんが、そうではありません。半径ははるかに大きくなります。これを補うために、試行錯誤の末に次の魔法の数字を見つけました。
var orbital_arc = d3.svg.arc()
.startAngle(0)
.endAngle(6.28318531) // 360 degrees
.innerRadius(function (d) {
return x(d.orbital_radius) - 470; }) // Magic number.
.outerRadius(function (d) {
return x(d.orbital_radius) - 470; }); // Magic number.
その数はすべての軌道線で一貫して機能しますが、その理由はわかりません。パス要素だけでなく、円の半径も大きくなります:
planetEnter.append("circle")
.attr("r", function (d) {
return x(d.orbital_radius); })
.attr("class", "body")
.attr("transform", function (d) {
return "translate(" + x(0) + ", " + y(0) + ")"; });
これをデモするjsfiddlesは次のとおりです(より良いビューが必要な場合は、パンとズームしてください):
では、なぜこのマジック ナンバーが必要なのでしょうか。