Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
136 views
in Technique[技术] by (71.8m points)

javascript - Doughnut pie hybrid d3 version 4

I have an old doughnut hybrid pie chart/bubble chart combo working on d3v3.

enter image description here

//doughnut bubble chart v3 https://jsfiddle.net/ajevh5wf/

var $this = $('body');

var w = 300,
  h = 300;
var radius = Math.min(w, h) / 2;

var svg = d3.select($this[0])
  .append("svg")
  .attr("width", w)
  .attr("height", h)
  .append("g")

svg.append("g")
  .attr("class", "slices");
svg.append("g")
  .attr("class", "placeholders");


var pie = d3.layout.pie()
  .sort(null)
  .value(function(d) {
    return d.value;
  });

var arc = d3.svg.arc()
  .outerRadius(radius * 0.85)
  .innerRadius(radius * 0.83);

var arc2 = d3.svg.arc()
  .outerRadius(radius - 10)
  .innerRadius(0);

var outerArc = d3.svg.arc()
  .innerRadius(radius * 0.9)
  .outerRadius(radius * 0.9);

svg.attr("transform", "translate(" + w / 2 + "," + h / 2 + ")");


function colores_google(n) {
  var colores_g = ["#f7b363", "#448875", "#c12f39", "#2b2d39", "#f8dd2f"];
  return colores_g[n % colores_g.length];
}


var data = [{
  "group": "<5",
  "value": 1000,
  "children": [{
    "group": "<5",
    "label": "Mel",
    "value": 1000,
    "totalGroupValue": 1000
  }]
}, {
  "group": "5-13",
  "value": 1000,
  "children": [{
    "group": "5-13",
    "label": "Erica",
    "value": 1000,
    "totalGroupValue": 1000
  }]
}, {
  "group": "14-17",
  "value": 2000,
  "children": [{
    "group": "14-17",
    "label": "Jessica",
    "value": 1500,
    "totalGroupValue": 2000
  }, {
    "group": "14-17",
    "label": "Jill",
    "value": 500,
    "totalGroupValue": 2000
  }]
}, {
  "group": "18-24",
  "value": 1300,
  "children": [{
    "group": "18-24",
    "label": "Jerry",
    "value": 500,
    "totalGroupValue": 1300
  }, {
    "group": "18-24",
    "label": "Ben",
    "value": 500,
    "totalGroupValue": 1300
  }, {
    "group": "18-24",
    "label": "Billy",
    "value": 150,
    "totalGroupValue": 1300
  }, {
    "group": "18-24",
    "label": "Billy2",
    "value": 150,
    "totalGroupValue": 1300
  }]
}, {
  "group": "25-44",
  "value": 1000,
  "children": [{
    "group": "25-44",
    "label": "Kelly",
    "value": 1000,
    "totalGroupValue": 1000
  }]
}];

$.each(data, function(index, value) {
  value["groupid"] = index;
  $.each(value.children, function(i, v) {
    v["groupid"] = index;
  });
});

//slices
var slice = svg.select(".slices").selectAll("path.slice")
  .data(pie(data));

slice.enter()
  .insert("path")
  .style("fill", function(d) {
    return colores_google(d.data.groupid);
  })
  .attr("class", "slice");

slice
  .transition().duration(1000)
  .attrTween("d", function(d) {
    this._current = this._current || d;
    var interpolate = d3.interpolate(this._current, d);
    this._current = interpolate(0);
    return function(t) {
      return arc(interpolate(t));
    };
  })

slice.exit()
  .remove();
//slices


//placeholder bubbles
var placeholders = svg.select(".placeholders").selectAll("g.placeholder")
  .data(pie(data));

placeholders.enter()
  .insert("g")
  .attr("class", function(d, i) {
    return "placeholder place" + i;
  });

placeholders
  .transition().duration(1000)
  .attr("transform", function(d) {
    return "translate(" + arc2.centroid(d) + ")";
  })

placeholders.exit()
  .remove();
//placeholder bubbles


//bubbles
function bubbledata(data) {
  //loop through data -- and MERGE children
  var childs = [];
  $.each(data, function(index, value) {
    childs.push(value.children);
  });

  return $.extend(true, {}, {
    "children": data
  }); // return deep clone
}


function setBubbleChart(width, index, data) {

  //_create bubble
  var diameter = width / 2; //take half/width

  var bubs = svg.select(".place" + index).append("g")
    .attr("class", "bubs");

  bubs.attr("transform", "translate(" + -diameter / 2 + "," + -diameter / 2 + ")");

  var bubble = d3.layout.pack()
    .size([diameter, diameter])
    .value(function(d) {
      return d.value;
    })
    .padding(3);

  //_create bubble
  var data = bubbledata(data);

  var nodes = bubble.nodes(data)
    .filter(function(d) {
      return !d.children;
    }); // filter out the outer bubble


  var bubbles = bubs.selectAll('circle')
    .data(nodes);

  bubbles.enter()
    .insert("circle")
    .attr('transform', function(d) {
      return 'translate(' + d.x + ',' + d.y + ')';
    })
    .attr('r', function(d) {
      return d.r;
    })
    .style("fill", function(d) {
      return colores_google(d.groupid);
    });

  bubbles = bubbles.transition()
    .transition()
    .duration(250)
    .attr('transform', function(d) {
      return 'translate(' + d.x + ',' + d.y + ')';
    })
    .attr('r', function(d) {
      return d.r;
    })
    .ease('sine');

}

//loop through data and for EACH children array paint dots.
$.each(data, function(index, value) {
  setBubbleChart(100, index, value.children);
});
//custom bubble chart
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
question from:https://stackoverflow.com/questions/65870599/doughnut-pie-hybrid-d3-version-4

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Many things have changed from v3 to v4, like d3.pack() instead of d3.layout.pack(), and having to import the "ease" module and reference d3.easeSin instead of 'sine'. Once you take care of all these little differences, your code works: https://jsfiddle.net/dc6eugtn/1

Here's the relevant section of changes:

function setBubbleChart(width, index, data) {

  var diameter = width / 2; //take half/width

  var bubs = doughnutbubble.select(".place" + index).append("g")
    .attr("class", "bubs");

  bubs.attr("transform", "translate(" + -diameter / 2 + "," + -diameter / 2 + ")");

  var data = bubbledata(data);
  var bubble = d3.pack(data)
    .size([diameter, diameter])
    .padding(3);

  var nodes = d3.hierarchy(data).sum(d => d.value);

  var bubbles = bubs.selectAll('circle')
    .data(bubble(nodes).descendants());
  bubbles.enter()
    .filter(d => !d.children)
    .insert("circle")
    .attr('transform', function(d) {
      return 'translate(' + d.x + ',' + d.y + ')';
    })
    .attr('r', d => d.r)
    .style("fill", function(d) {
      return colores_google(d.data.groupid);
    });

  bubbles = bubbles.transition()
    .transition()
    .duration(250)
    .attr('transform', function(d) {
      return 'translate(' + d.x + ',' + d.y + ')';
    })
    .attr('r', d => d.r)
    .ease(d3.easeSin);
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...