gpt4 book ai didi

javascript - D3 : Spiral plot

转载 作者:行者123 更新时间:2023-11-29 10:33:42 24 4
gpt4 key购买 nike

有人可以帮助我使用 d3.js 实现类似于下面的螺旋图吗?

enter image description here

到目前为止,我刚刚获得了基本的螺旋图(一个简单的图),但无法根据图像中显示的时间线将条形图附加到图中。我正在尝试一些事情(如果您看到注释代码)。

这是我的 fiddle ,以及我的代码:

      var width = 400,
height = 430,
axes = 12,
tick_axis = 9,
start = 0,
end = 2.25;

var theta = function(r) {
return 2 * Math.PI * r;
};

var angle = d3.scale.linear()
.domain([0, axes]).range([0, 360])

var r = d3.min([width, height]) / 2 - 40;
var r2 = r;

var radius = d3.scale.linear()
.domain([start, end])
.range([0, r]);

var svg = d3.select("#chart").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + (height / 2 + 8) + ")");

var points = d3.range(start, end + 0.001, (end - start) / 1000);

var spiral = d3.svg.line.radial()
.interpolate("cardinal")
.angle(theta)
.radius(radius);

var path = svg.selectAll(".spiral")
.data([points])
.enter().append("path")
.attr("class", "spiral")
.attr("d", spiral)


var z = d3.scale.category20();

var circles = svg.selectAll('.circle')
.data(points);

/* circles.enter().append('circle')
.attr('r', 5)
.attr('transform', function(d) { return 'translate(' + d + ')'})
.style('fill', function(d) { return z(d); });

*/

var circle = svg.append("circle")
.attr("r", 13)
.attr("transform", "translate(" + points[0] + ")");

var movingCircle = circle.transition().duration(4000)
.attrTween('transform', translateAlongPath(path.node()))
// .attr('cx', function(d) { return radius(d) * Math.cos(theta(d))})
// .attr('cy', function(d) { return radius(d) * Math.sin(theta(d))})


function translateAlongPath(path) {
var l = path.getTotalLength();
return function(d, i, a) {
return function(t) {

var p = path.getPointAtLength(t * l);
//console.log(p)
return "translate(" + p.x + "," + p.y + ")";
};
};
}

function pathXY(path) {
var l = path.getTotalLength();
var start = 0;

/* for(i=start; i<l; i++) {
var point = path.getPointAtLength(i);
svg.append('rect').transition().duration(400).attr('transform', 'translate(' + point.x +','+point.y+')')
.attr('width', 10).attr('height', 30).style('fill', z);
}*/
}
pathXY(path.node());

/*var test = translateAlongPath(path.node())()();
//console.log(test)
var bars = svg.selectAll('.bar')
.data(points).enter().append('rect').transition().duration(2000)
// .attrTween('transform', translateAlongPath(path.node()))
.attr('class', 'bar')
.attr('width', 10)
.attr('height', 20)
.style('fill', function(d) { return z(d)});
*/
var rect = svg.append('rect').attr('width', 10).attr('height', 10);
rect.transition().duration(3400)
.attrTween('transform', translateAlongPath(path.node()));

最好能有几个类似的例子(即螺旋时间线图)。

谢谢。

最佳答案

很高兴您回来并更新了您的问题,因为这是一个有趣的问题。这是一个正在运行的最小实现。我已经评论好了,所以如果您有任何问题,请告诉我...

<!DOCTYPE html>
<html>

<head>
<script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.js"></script>
</head>

<body>
<div id="chart"></div>
<script>
var width = 500,
height = 500,
start = 0,
end = 2.25,
numSpirals = 4;

var theta = function(r) {
return numSpirals * Math.PI * r;
};

var r = d3.min([width, height]) / 2 - 40;

var radius = d3.scaleLinear()
.domain([start, end])
.range([40, r]);

var svg = d3.select("#chart").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

// create the spiral, borrowed from http://bl.ocks.org/syntagmatic/3543186
var points = d3.range(start, end + 0.001, (end - start) / 1000);

var spiral = d3.radialLine()
.curve(d3.curveCardinal)
.angle(theta)
.radius(radius);

var path = svg.append("path")
.datum(points)
.attr("id", "spiral")
.attr("d", spiral)
.style("fill", "none")
.style("stroke", "steelblue");

// fudge some data, 2 years of data starting today
var spiralLength = path.node().getTotalLength(),
N = 730,
barWidth = (spiralLength / N) - 1;
var someData = [];
for (var i = 0; i < N; i++) {
var currentDate = new Date();
currentDate.setDate(currentDate.getDate() + i);
someData.push({
date: currentDate,
value: Math.random()
});
}

// here's our time scale that'll run along the spiral
var timeScale = d3.scaleTime()
.domain(d3.extent(someData, function(d){
return d.date;
}))
.range([0, spiralLength]);

// yScale for the bar height
var yScale = d3.scaleLinear()
.domain([0, d3.max(someData, function(d){
return d.value;
})])
.range([0, (r / numSpirals) - 30]);

// append our rects
svg.selectAll("rect")
.data(someData)
.enter()
.append("rect")
.attr("x", function(d,i){

// placement calculations
var linePer = timeScale(d.date),
posOnLine = path.node().getPointAtLength(linePer),
angleOnLine = path.node().getPointAtLength(linePer - barWidth);

d.linePer = linePer; // % distance are on the spiral
d.x = posOnLine.x; // x postion on the spiral
d.y = posOnLine.y; // y position on the spiral

d.a = (Math.atan2(angleOnLine.y, angleOnLine.x) * 180 / Math.PI) - 90; //angle at the spiral position

return d.x;
})
.attr("y", function(d){
return d.y;
})
.attr("width", function(d){
return barWidth;
})
.attr("height", function(d){
return yScale(d.value);
})
.style("fill", "steelblue")
.style("stroke", "none")
.attr("transform", function(d){
return "rotate(" + d.a + "," + d.x + "," + d.y + ")"; // rotate the bar
});

// add date labels
var tF = d3.timeFormat("%b %Y"),
firstInMonth = {};
svg.selectAll("text")
.data(someData)
.enter()
.append("text")
.attr("dy", 10)
.style("text-anchor", "start")
.style("font", "10px arial")
.append("textPath")
// only add for the first of each month
.filter(function(d){
var sd = tF(d.date);
if (!firstInMonth[sd]){
firstInMonth[sd] = 1;
return true;
}
return false;
})
.text(function(d){
return tF(d.date);
})
// place text along spiral
.attr("xlink:href", "#spiral")
.style("fill", "grey")
.attr("startOffset", function(d){
return ((d.linePer / spiralLength) * 100) + "%";
})

</script>
</body>

</html>

关于javascript - D3 : Spiral plot,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40533749/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com