D3仪表图工具提示

时间:2019-06-11 09:49:05

标签: javascript html d3.js visualization

https://codepen.io/venugopals/pen/LKYQvo

上面的链接是我尝试在工具提示(黑色)上实现目标和值的代码的代码。由于我是js和D3图表的新手,所以我无法解决问题。请帮助我整理一下。当我尝试实现工具提示(var tip)时,呈现图表的过程就停止了。

在JS中,

(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, dataset, doi, tip, name;    
  percent = .65;
  name = "Sales :";
  barWidth = 50;    
  numSections = 3;    
  // / 2 for HALF circle
  sectionPerc = [0.1, 0.25, 0.15];    
  padRad = 0;    
  chartInset = 10;    
  // start at 270deg
  totalPercent = .75;      
  subIndicator = totalPercent + (35/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;
  };
  doi = function(subi) {
    return subIndicator;
  };
  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 + 0).innerRadius(radius - chartInset - barWidth - 0).startAngle(percToRad(subIndicator)).endAngle(percToRad(subIndicator));
    chart.append('path').attr('d', arc2).style("stroke", "black").style("stroke-width", "5px");
  dataset = [{
    metric: name,
    value: percent
  }]
 texts = svg.selectAll("text")
    .data(dataset)
    .enter();

  texts.append("text")
    .text(function() {
      return dataset[0].metric;
    })
    .attr('id', "Name")
    .attr('transform', "translate(" + ((width + margin.left) / 3.0) + ", " + ((height + margin.top) / 1.6) + ")")
    .attr("font-size", 25)
    .style("fill", "#000000");


  texts.append("text")
    .text(function() {
      return dataset[0].value * 100 + "C";
    })
    .attr('id', "Value")
    .attr('transform', "translate(" + ((width + margin.left) / 1.8) + ", " + ((height + margin.top) / 1.6) + ")")
    .attr("font-size", 25)   
    .style("fill", "#000000");

  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, 07);

  needle.drawOn(chart, 0);

  needle.animateOn(chart, percent);

}).call(this);

我只添加了一些我尝试过的JS代码。 预先感谢。

0 个答案:

没有答案