将子颜色添加到子路径作为父路径 - d3js

时间:2014-05-27 11:20:11

标签: d3.js colors charts

如何将相同颜色添加到子路径作为父路径 - d3js 例如 : 如果我有一个红色的父路径,那么它的孩子必须是渐变红色到白色,以使每个孩子和一个孩子之间有所不同。父

<script>

var margin = {top: 350, right: 400, bottom: 350, left: 400},
    radius = Math.min(margin.top, margin.right, margin.bottom, margin.left) - 10;

var x = d3.scale.linear()
    .range([0, 2 * Math.PI]);

var y = d3.scale.linear()
    .range([0, radius]);

var hue = d3.scale.category10();

var luminance = d3.scale.sqrt()
    .domain([0, 1e6])
    .clamp(true)
    .range([90, 20]);

var svg = d3.select("#chart").append("svg")
    .attr("width", '100%')
    .attr("height", '100%')
    .attr('viewBox','0 0 '+Math.min(margin.left + margin.right, margin.top + margin.bottom)+' '+Math.min(margin.left + margin.right, margin.top + margin.bottom))
    .attr('preserveAspectRatio','xMinYMin')
    .append("g")
        .attr("id", "container")
    .attr("transform", "translate(" + Math.min(margin.left + margin.right, margin.top + margin.bottom) / 2 + "," + Math.min(margin.left + margin.right, margin.top + margin.bottom) / 2 + ")");

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

var arc = d3.svg.arc()
    .startAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x))); })
    .endAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx))); })
    // lw 3'erna al y(d.y) we 2smnaha 3la 2 he3'er al radius le al first level 
    .innerRadius(function(d) { return Math.max(0, y(d.y)); })
    .outerRadius(function(d) { return Math.max(0, y(d.y + d.dy)); });


d3.json("expanses.json", function(error, root) {

  // Compute the initial layout on the entire tree to sum sizes.
  // Also compute the full name and fill color for each node,
  // and stash the children so they can be restored as we descend.
  partition
      .value(function(d) { return d.size; })
      .nodes(root)
      .forEach(function(d) {
        d._children = d.children;
        d.sum = d.value;
        d.fill = fill(d);
      });

  // Now redefine the value function to use the previously-computed sum.
  partition
      .children(function(d, depth) { return depth < 3 ? d._children : null; })
      .value(function(d) { return d.sum; });




  var g = svg.selectAll("g").selectAll("radialGradient").append("radialGradient")
      .data(partition.nodes(root))
      .enter().append("g");

  var path = g.append("path")
    .attr("d", arc)
    .style("fill", colour)
    .on("click", click)    
    .on("mouseover", function(d) {
        tooltip.show([d3.event.clientX,d3.event.clientY],'<div>'+d.name+'</div><div>'+d.value+'</div>')
    })
    .on('mouseout',function(){
            tooltip.cleanup()
    })   
    .each(stash);

    // Define the legeneds
    var legend = d3.select("#legend").append("svg")
      .attr("class", "legend")
      .attr("width", radius)
      .attr("height", radius)
      .selectAll("g")
      .data(partition.nodes(root))
      .enter().append("g")
      .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });

    legend.append("rect")
      .attr("width", 18)
      .attr("height", 18)
      .style("fill", colour)
      .on("click", click);

    legend.append("text")
      .attr("x", 24)
      .attr("y", 9)
      .attr("dy", ".35em")
      .text(function(d) { return d.name; });

    // Define Labels on the arcs
    var text = g.append("text")
    .attr("dy", ".35em") // vertical-align
    .attr("transform", function(d) { return "rotate(" + computeTextRotation(d) + ")"; })
    .attr("x", function(d) { return y(d.y); })
    .attr("dx", "6") // margin
    .attr("display", 'block')
    .text(function(d) {
    return d.name;
    })
    .on("click", click);

    // Append a new white circle instead of the root circle ... I made this just to control the style
    var center = svg.append("circle")
      .attr("r", radius / 4)
      .style("fill", "white")
      .on("click", click);

    center.append("title")
      center.datum(root);  

    function fill(d) {
      var p = d;
      while (p.depth > 1) p = p.parent;
      var c = d3.lab(hue(p.name));
      c.l = luminance(d.sum);
      return c;
    }
  function click(d) {
    // fade out all text elements
    text.transition().attr("opacity", 0);

    path.transition()
      .duration(500)
      .attrTween("d", arcTween(d))
      .each("end", function(e, i) {
          // check if the animated element's data e lies within the visible angle span given in d
          if (e.x >= d.x && e.x < (d.x + d.dx)) {
            // get a selection of the associated text element
            var arcText = d3.select(this.parentNode).select("text");
            // fade in the text element and recalculate positions
            arcText.transition().duration(250)
              .attr("opacity", 1)
              .attr("transform", function() { return "rotate(" + computeTextRotation(e) + ")" })
              .attr("x", function(d) { return y(d.y); });
          }
      });
  }
});

d3.select(self.frameElement).style("height", margin.top + margin.bottom + "px");

// Interpolate the scales!
function arcTween(d) {
  var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
      yd = d3.interpolate(y.domain(), [d.y, 1]),
      yr = d3.interpolate(y.range(), [d.y* radius]);
  return function(d, i) {
    return i
        ? function(t) { return arc(d); }
        : function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t)); return arc(d); };
  };
}

function computeTextRotation(d) {
  return (x(d.x + d.dx / 2) - Math.PI / 2) / Math.PI * 180;
}

// Stash the old values for transition.
function stash(d) {
  d.x0 = d.x;
  d.dx0 = d.dx;
}

function colour(d) {
  if (d.children) {
    // There is a maximum of two children!
    var colours = d.children.map(colour),
        a = d3.hsl(colours[0]),
        b = d3.hsl(colours[0]);
    // L*a*b* might be better here...
    return d3.hsl((a.h + b.h) / 2, a.s * 1, a.l / 1);
  }
  return d.colour || "#fff";
}

function updateArc(d) {
  return {depth: d.depth, x: d.x, dx: d.dx};
}
/*****
 * A no frills tooltip implementation.
 *****/

(function() {

  var tooltip = window.tooltip = {}

  tooltip.show = function(pos, content, gravity, dist, parentContainer, classes) {

    var container = d3.select('chart').selectAll('.tooltip').data([1])

        container.enter().append('div').attr('class', 'tooltip ' + (classes ? classes : 'xy-tooltip'))

        container.html(content)

    gravity = gravity || 'n'
    dist = dist || 20

    var body = document.getElementsByTagName('body')[0]

    var height = parseInt(container[0][0].offsetHeight)
      , width = parseInt(container[0][0].offsetWidth)
      , windowWidth = window.innerWidth
      , windowHeight = window.innerHeight
      , scrollTop = body.scrollTop
      , scrollLeft = body.scrollLeft
      , left = 0
      , top = 0


    switch (gravity) {
      case 'e':
        left = pos[0] - width - dist
        top = pos[1] - (height / 2)
        if (left < scrollLeft) left = pos[0] + dist
        if (top < scrollTop) top = scrollTop + 5
        if (top + height > scrollTop + windowHeight) top = scrollTop - height - 5
        break
      case 'w':
        left = pos[0] + dist
        top = pos[1] - (height / 2)
        if (left + width > windowWidth) left = pos[0] - width - dist
        if (top < scrollTop) top = scrollTop + 5
        if (top + height > scrollTop + windowHeight) top = scrollTop - height - 5
        break
      case 's':
        left = pos[0] - (width / 2)
        top = pos[1] + dist
        if (left < scrollLeft) left = scrollLeft + 5
        if (left + width > windowWidth) left = windowWidth - width - 5
        if (top + height > scrollTop + windowHeight) top = pos[1] - height - dist
        break
      case 'n':
        left = pos[0] - (width / 2)
        top = pos[1] - height - dist
        if (left < scrollLeft) left = scrollLeft + 5
        if (left + width > windowWidth) left = windowWidth - width - 5
        if (scrollTop > top) top = pos[1] + 20
        break
    }


    container.style('left', left+'px')
    container.style('top', top+'px')

    return container
  }

  tooltip.cleanup = function() {
      // Find the tooltips, mark them for removal by this class (so other tooltip functions won't find it)
      var tooltips = d3.selectAll('.tooltip').attr('class','tooltip-pending-removal').transition().duration(250).style('opacity',0).remove()
      var textMiddleClean = d3.selectAll('.textMiddle').transition().duration(250).style('opacity',0).remove()

  }
})()

</script>

这是我的JS代码,现在我使用名为color的内部JSON对象包含&#34; rgb&#34;

0 个答案:

没有答案