score:2

Accepted answer

for creating this sub value indicator, you just need to set an arc generator who accepts the percentage value you want to set (here named subindicator), with a padding in the outer and inner radiuses...

arc2 = d3.svg.arc()
    .outerradius(radius - chartinset + 10)
    .innerradius(radius - chartinset - barwidth - 10)
    .startangle(perctorad(subindicator))
    .endangle(perctorad(subindicator));

... and use it to append the new path:

chart.append('path')
    .attr('d', arc2)
    .style("stroke", "black")
    .style("stroke-width", "2px");

pay attention to the fact that, given the way the author of the original code set their functions, the zero in the gauge is equivalent to 75%. therefore, you have to set the percentage value accordingly. for instance, positioning the sub value indicator at 55%:

subindicator = totalpercent + (55 / 200);

here is a demo (using 55% for the sub value indicator):

(function () {
  var needle, arc, arcendrad, arcstartrad, barwidth, chart, chartinset, degtorad, el, endpadrad, height, i, margin, needle, numsections, padrad, perctodeg, perctorad, percent, radius, ref, sectionindx, sectionperc, startpadrad, svg, totalpercent, width, subindicator;

  percent = .65;

  barwidth = 60;

  numsections = 3;

  // / 2 for half circle
  sectionperc = [0.1, 0.25, 0.15];

  padrad = 0;

  chartinset = 10;

  // start at 270deg
  totalpercent = .75;
  
  subindicator = totalpercent + (55/200)

  el = d3.select('.chart-gauge');

  margin = {
    top: 20,
    right: 20,
    bottom: 30,
    left: 20 };


  width = el[0][0].offsetwidth - margin.left - margin.right;

  height = width;

  radius = math.min(width, height) / 2;

  perctodeg = function (perc) {
    return perc * 360;
  };

  perctorad = function (perc) {
    return degtorad(perctodeg(perc));
  };

  degtorad = function (deg) {
    return deg * math.pi / 180;
  };

  svg = el.append('svg').attr('width', width + margin.left + margin.right).attr('height', height + margin.top + margin.bottom);

  chart = svg.append('g').attr('transform', `translate(${(width + margin.left) / 2}, ${(height + margin.top) / 2})`);

  // build gauge bg
  for (sectionindx = i = 1, ref = numsections; 1 <= ref ? i <= ref : i >= ref; sectionindx = 1 <= ref ? ++i : --i) {
    arcstartrad = perctorad(totalpercent);
    arcendrad = arcstartrad + perctorad(sectionperc[sectionindx-1]);
    totalpercent += sectionperc[sectionindx-1];
    startpadrad = 0;
    endpadrad = 0;
    arc = d3.svg.arc().outerradius(radius - chartinset).innerradius(radius - chartinset - barwidth).startangle(arcstartrad + startpadrad).endangle(arcendrad - endpadrad);
    chart.append('path').attr('class', `arc chart-color${sectionindx}`).attr('d', arc);
  }
  
  arc2 = d3.svg.arc().outerradius(radius - chartinset + 10).innerradius(radius - chartinset - barwidth - 10).startangle(perctorad(subindicator)).endangle(perctorad(subindicator));
    chart.append('path').attr('d', arc2).style("stroke", "black").style("stroke-width", "2px");

  needle = class needle {
    constructor(len, radius1) {
      this.len = len;
      this.radius = radius1;
    }

    drawon(el, perc) {
      el.append('circle').attr('class', 'needle-center').attr('cx', 0).attr('cy', 0).attr('r', this.radius);
      return el.append('path').attr('class', 'needle').attr('d', this.mkcmd(perc));
    }

    animateon(el, perc) {
      var self;
      self = this;
      return el.transition().delay(500).ease('elastic').duration(3000).selectall('.needle').tween('progress', function () {
        return function (percentofpercent) {
          var progress;
          progress = percentofpercent * perc;
          return d3.select(this).attr('d', self.mkcmd(progress));
        };
      });
    }

    mkcmd(perc) {
      var centerx, centery, leftx, lefty, rightx, righty, thetarad, topx, topy;
      thetarad = perctorad(perc / 2); // half circle
      centerx = 0;
      centery = 0;
      topx = centerx - this.len * math.cos(thetarad);
      topy = centery - this.len * math.sin(thetarad);
      leftx = centerx - this.radius * math.cos(thetarad - math.pi / 2);
      lefty = centery - this.radius * math.sin(thetarad - math.pi / 2);
      rightx = centerx - this.radius * math.cos(thetarad + math.pi / 2);
      righty = centery - this.radius * math.sin(thetarad + math.pi / 2);
      return `m ${leftx} ${lefty} l ${topx} ${topy} l ${rightx} ${righty}`;
    }};



  needle = new needle(140, 15);

  needle.drawon(chart, 0);

  needle.animateon(chart, percent);

}).call(this);

//# sourceurl=coffeescript
.chart-gauge {
  width: 400px;
  margin: 10px auto;
}

.chart-color1 {
  fill: #d82724;
}

.chart-color2 {
  fill: #fcbf02;
}

.chart-color3 {
  fill: #92d14f;
}

.needle,
.needle-center {
  fill: #464a4f;
}

.prose {
  text-align: center;
  font-family: sans-serif;
  color: #ababab;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<div class="chart-gauge"></div>

use the same approach for appending the sub value indicator text.


Related Query

More Query from same tag