选择圆弧上的区域

Select a region over an arc

本文关键字:区域 选择      更新时间:2023-09-26

我正试图通过单击圆弧并拖动来进行选择。下面的例子显示了一个非常相似的概念,但选择是从一个随机位置开始的,相反,我想从深蓝色弧线上的一个位置开始,方法是单击鼠标并四处拖动。http://jsfiddle.net/bno009s5/

var dataset = {
  apples: [532, 284],
};
var degree = Math.PI / 180;
var width = 460,
  height = 300,
  radius = Math.min(width, height) / 2;
var color = d3.scale.category20();
var pie = d3.layout.pie().startAngle(-90 * degree).endAngle(90 * degree)
  .sort(null);
var arc = d3.svg.arc()
  .innerRadius(50)
  .outerRadius(100);
var svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height)
  .append("g")
  .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var path = svg.selectAll("path")
  .data(pie(dataset.apples))
  .enter().append("path")
  .attr("fill", function(d, i) {
    return color(i);
  })
  .attr("d", arc)
  .each(function(d) {
    this._current = d;
  }); // store the initial values;
window.setInterval(dummyData, 2000);
// Store the displayed angles in _current.
// Then, interpolate from _current to the new angles.
// During the transition, _current is updated in-place by d3.interpolate.
function arcTween(a) {
  var i = d3.interpolate(this._current, a);
  this._current = i(0);
  return function(t) {
    return arc(i(t));
  };
}
function dummyData() {
  var num = Math.floor(Math.random() * 100);
  var key = Math.floor(Math.random() * dataset.apples.length);
  dataset.apples[key] = num;
  draw();
};
function draw() {
  svg.selectAll("path")
    .data(pie(dataset.apples))
    .transition()
    .attrTween("d", arcTween);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.0.4/d3.min.js"></script>

这是一个jsfiddle,蓝色线条可见。您可以在圆内部和外部单击,也可以尝试在两个端点下方单击。

绿色圆圈只是为了美观(即:用最喜欢的宠物图片代替:-)已测试可在IE9、最新Chrome和FF中工作(2014年10月)。

编辑:添加了拖动功能。下面的代码是原来的小提琴。

var s = Snap(400,400);
var circleX = 100, circleY = 100, circleRadius = 57; 
var stroke_width = 20;
var blueCircle = s.circle(circleX, circleY, circleRadius);
var hcp = Math.Pi*circleRadius; // half circle perimeter = 179.0
//Arc Path
var d='M 43,100 A 57,57 0 0 1 43,100';
var arcPath = s.path(d);
arcPath.attr({
    fill: "none",
    stroke: "red",
    "stroke-width": stroke_width
});
// Line Path
var L1 = s.path("M "+circleX+" "+circleY +"L 0 0");
blueCircle.attr({
    fill: "none",
    stroke: "skyblue",
    "stroke-width": stroke_width,
    "stroke-dasharray": "0,179,179"
});
var c1 = s.circle(0,0,5).attr({ fill: "none",stroke: "green" });
function OnMouseDown(evt) {
    var mouseY = Math.min(evt.clientY,100); // limit mouseY to 100
   
    L1.attr({ d: "M "+circleX+" "+circleY +"L "+evt.clientX+" "+mouseY });
    var totalLength = L1.getTotalLength();
    if (totalLength < circleRadius) { // smaller, extend line
        var ratio = circleRadius/totalLength;
        var x_len = evt.clientX + (evt.clientX - circleX)*ratio;
        var y_len = mouseY + (mouseY - circleY)*ratio;
        L1.attr({ d: "M "+circleX+" "+circleY +"L "+x_len+" "+y_len });
    } 
    var PAL = L1.getPointAtLength(circleRadius);
    c1.attr({ cx: PAL.x , cy: PAL.y });
    draw_arc(PAL.x,PAL.y);
}
function draw_arc(endX,endY) { // Draw SVG arc
    // point starts on left at 43,100, 
    // Arc Box height is 57,57 (radius)
    // Ends at (endX,endY)
   
    var newArc ='M 43,100 A 57,57 0 0 1 '+endX+','+endY;
    arcPath.attr({ 'd': newArc });
}
document.onmousedown = OnMouseDown;
<script src='//cdnjs.cloudflare.com/ajax/libs/snap.svg/0.3.0/snap.svg-min.js'></script>