如何用d3.shape创建半圆,从晚上9点开始到早上6点结束

时间:2017-12-11 14:23:49

标签: javascript reactjs d3.js react-native

我正在尝试使用d3.shape.arc创建一个圆圈并对原生艺术作出反应

让我们说圆圈潜到12,所以我希望圆圈从9开始到6结束(从晚上9点到早上6点)

这是我的代码:

const _circle = d3.shape.arc()
    .outerRadius(radius)
    .padAngle(0)
    .startAngle(5)
    .endAngle(3)
    .innerRadius(radius);

圆圈从5开始直到4,我需要它向左移动(如时钟)

circle

1 个答案:

答案 0 :(得分:3)

以这种方式定义您的比例:

var scaleHours = d3.scaleLinear()
  .domain([0, 12])
  .range([0, 2 * Math.PI]);

当您指定arc时,您应该以这种方式定义startAngle

.startAngle(scaleHours(start))

对于.endAngle,您应该检查您的开始时间是否超过结束时间(超过6个),您应该将12添加到结束时间值:

function specifyArc(start, end) {
  return d3.arc()
    .startAngle(scaleHours(start))
    .endAngle(scaleHours(end + (start > end ? 12 : 0)))
    .innerRadius(0)
    .outerRadius(radius - 10);
}

检查下面的演示(注意日志):

var radius = 90;

var svg = d3.select('body')
  .append('svg')
	.attr('width', radius * 2)
  .attr('height', radius * 2)
  .append('g')
  .attr('transform', 'translate(' + radius + ', ' + radius + ')');

var scaleHours = d3.scaleLinear()
  .domain([0, 12])
  .range([0, 2 * Math.PI]);
  
var hoursScale = d3.scaleLinear()
	.range([0,330])
	.domain([0,11]);

var ticks = svg.selectAll('.second-tick')
  .data(d3.range(0, 12));
  
ticks.enter()
  .append('line')
  .attr('class', 'second-tick')
  .merge(ticks)
  .attr('x1', 0)
  .attr('x2', 0)
  .attr('y1', radius)
  .attr('y2', radius - 10)
  .attr('transform', function(d) {
    return 'rotate(' + hoursScale(d) + ')';
  });
 

function specifyArc(start, end) {
	return d3.arc()
    .startAngle(scaleHours(start))
    .endAngle(scaleHours(end + (start > end ? 12 : 0)))
    .innerRadius(0)
    .outerRadius(radius - 10);
}

var count = 0;

var timeframes = [
	{ start: 9, end: 6 },
  { start: 6, end: 9 },
];

setInterval(() => {
	var currentTimeFrame = timeframes[count%2];
  
  console.clear();
  console.log('start: ', currentTimeFrame.start, 'end: ', currentTimeFrame.end);
  
	var arc = specifyArc(currentTimeFrame.start, currentTimeFrame.end);
  count++;
  
  svg.select('.arc').remove();
  
  svg.append("path")
  	.attr('class', 'arc')
  	.attr("d", arc)
    .style("fill", 'red');
}, 2500);
.second-tick{
	stroke-width:3;
	fill:#000;
  stroke:#000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.12.0/d3.min.js"></script>