如何更新 d3 中圆环图的 innerRadius 和 outterRadius?

How to update the innerRadius and the outterRadius of a donut chart in d3?

我正在尝试使用滑块更改圆环图的 innerRadius 和 outterRadius。

这是 JSFiddle link:https://jsfiddle.net/SashimiEthan/woetyLg3/3/

<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="bootstrap.css">
<link href='http://fonts.googleapis.com/css?family=Lato' rel='stylesheet' type='text/css' />
<link rel="stylesheet" type="text/css" href="style.css">
<script src="d3.min.js"></script>
<script scr="color.min.js"></script>
<script scr="d3.slider.js"></script>
</head>
<body>
<div class="content">
  <div class="wrapper" id="wheel"></div>    
</div>
<script>

  var width = 300;
  r = width / 2,
  labelr = r + 20
  outerRadius = 150,
  innerRadius = outerRadius - 30;
  ; // radius for label anchor

  var mySvg = d3.select("#wheel").append("svg")
      .attr("width", 500)
      .attr("height", 500);

  var myGroup = mySvg.append("g")
      .attr("transform", "translate(200,200)" );

  var arc = d3.svg.arc()
                .innerRadius(innerRadius)
                .outerRadius(outerRadius);

  var arc1 = d3.svg.arc()
                .innerRadius(innerRadius-30)
                .outerRadius(outerRadius-30);

  var numberOfSegments = 12;
  var radians;
  var degrees;

  // function render (arc) {
    radians = (Math.PI * 2) / numberOfSegments;
    degrees = 360 / numberOfSegments;

    arc.startAngle(function (d,i) { return radians * i } );
    arc.endAngle(function (d,i) { return radians * (i + 1) });

    var g = myGroup.selectAll("g").data(d3.range(numberOfSegments));

    g.enter().append("g").attr("class", "arc");        

    g.append("path")
      .attr("class", "seg")
      .attr("d", arc)
      .attr("fill", function(d,i) {
        return "hsl(" + (i * degrees) + ",100%,50%)";
      });

    g.append('text').attr("transform", function(d,i) {
      var c = arc.centroid(d,i),
          x = c[0],
          y = c[1],

          // pythagorean theorem for hypotenuse
          h = Math.sqrt(x*x + y*y);
          console.log(c);
          return "translate(" + (x/h * labelr) +  ',' +(y/h * labelr) +         ")"; 
      })
      .attr("dy", ".35em")
      .attr("dx", "-0.9em")
      .attr("text-anchor", function(d) {
          // are we past the center?
          return (d.endAngle + d.startAngle)/2 > Math.PI ?
              "end" : "start";
        })
      .text(function(d,i) {
              return i * degrees + "°";
            });

    g.exit().remove();      
  // }

  // render(arc);

  var margin = {top: 10, right: 50, bottom: 10, left: 50},
  width = 300 - margin.left - margin.right, //controller
  height = 50 - margin.bottom - margin.top; //controller
  startingValue1 = 1;

  var x = d3.scale.linear()
      .domain([0, 1])
      .range([0, width])
      .clamp(true);

  var brush1 = d3.svg.brush()
      .x(x)
      .extent([0, 0]) //brush length
      .on("brush", brushed1);

  var svg = d3.select("body").append("svg") //controller area
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
      .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); //move controller

  svg.append("text").text("Saturation")

  var axis  = svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height / 2 + ")")
      .call(d3.svg.axis()
        .scale(x)
        .orient("bottom")
        .tickValues([0, 0.5, 1])
        .tickSize(0)
        .tickPadding(10))
      .select(".domain")
      .select(function() { return this.parentNode.appendChild(this.cloneNode(true)); })
      .attr("class", "halo");

  var slider = svg.append("g")
      .attr("class", "slider")
      .call(brush1);

  slider.selectAll(".extent,.resize")
      .remove();

  slider.select(".background")
      .attr("height", height);

  var handle = slider.append("g")
      .attr("class", "handle")

  handle.append("circle")
      .attr("class","ctl")
      .attr("transform", "translate(0," + height / 2 + ")")
      .attr("r", 8);

  handle.append('text')
  .text(startingValue1)
  .attr("transform", "translate(" + (-5) + " ,0)");

  slider
      .call(brush1.event)
      .call(brush1.extent([1, 1]))
      .call(brush1.event);

  function brushed1() {
    var value = brush1.extent()[0];
    if (d3.event.sourceEvent) {
      handle.select('text');
      value = x.invert(d3.mouse(this)[0]);
      brush1.extent([value, value]);
    }

    handle.attr("transform", "translate(" + x(value) + ",0)");
    var format = d3.format(".1f");
    handle.select('text').text(format(value))

    var newarc = d3.svg.arc()
                .innerRadius(innerRadius-30)
                .outerRadius(outerRadius-30);
    d3.selectAll(".seg").attr("d",newarc);
    d3.selectAll(".seg").style("fill",function(d,i) {
      return d3.hsl(i * degrees, value, 0.5)
      });
  }

</script>

(对不起,代码很乱。我是 d3 的新手)所以我得到了饱和度调整部分的工作,但是半径调整部分

var newarc = d3.svg.arc()
                .innerRadius(innerRadius-30)
                .outerRadius(outerRadius-30);
    d3.selectAll(".seg").attr("d",newarc)

总是给我错误:属性 d="……" 的值无效

T^T

移动滑块后定义newarc时,需要包含startAngleendAngle属性,方法与第一次定义[=14时相同=].

这就是您需要做的所有事情:

var newarc = d3.svg.arc()
      .innerRadius(innerRadius - (30 * value))
      .outerRadius(outerRadius)
      .startAngle(function(d, i) {
          return radians * i
      })
      .endAngle(function(d, i) {
          return radians * (i + 1)
      });

  d3.selectAll(".seg").attr("d", newarc);

请注意,为了更清楚地说明移动滑块时发生的情况,我将 innerRadius 值设置为取决于滑块的 value

在此处查看有效的 fiddle:http://jsfiddle.net/henbox/vxq9o2a8/1/