如何在雷达图表中添加多个可拖动区域

时间:2015-08-12 21:19:21

标签: javascript jquery

我是javascript和英语的新手,抱歉英语不好。

我使用此demo代码创建了雷达图表 现在我想在同一个图表中添加另一个区域,使用按钮,我无法做到这一点。

请帮帮我。



$("#btn").click(function(){
  // here i want to add another set of daata
  });
$("#btn").click(function(){
		d = [
	     {axis: "axisA", value: 2, order:0}, 
	     {axis: "axisB", value: 8, order:1},
	     {axis: "axisC", value: 4, order:2},
	     {axis: "axisD", value: 6, order:3}
	];

	RadarChart.draw("#chart", d);
	})
	
var RadarChart = {draw: function(id, d, options){
    var cfg = {
radius: 6, w: 600,h: 600,
      factor: 1,

      factorLegend: .85,
      levels: 3,

      maxValue: 0,
      radians: 2 * Math.PI,
      opacityArea: 0.5,
      color: d3.scale.category10()
    };
    if('undefined' !== typeof options){
      for(var i in options){
        if('undefined' !== typeof options[i]){
          cfg[i] = options[i];
        }
      }
    }
 cfg.maxValue = Math.max(cfg.maxValue, d3.max(d.map(function(o){return o.value}))); 
    var allAxis = (d.map(function(i, j){return i.axis}));
    var total = allAxis.length;

    var radius = cfg.factor*Math.min(cfg.w/2, cfg.h/2);


d3.select(id).select("svg").remove();
var g = d3.select(id).append("svg").attr("width", cfg.w).attr("height", cfg.h).append("g");

var tooltip;

drawFrame();
var maxAxisValues = []; 
drawAxis();
var dataValues = [];
reCalculatePoints();

var areagg = initPolygon();
drawPoly();

drawnode();


function drawFrame(){
  for(var j=0; j<cfg.levels; j++){
    var levelFactor = cfg.factor*radius*((j+1)/cfg.levels);
    g.selectAll(".levels").data(allAxis).enter().append("svg:line")
     .attr("x1", function(d, i){return levelFactor*(1-cfg.factor*Math.sin(i*cfg.radians/total));})
     .attr("y1", function(d, i){return levelFactor*(1-cfg.factor*Math.cos(i*cfg.radians/total));})
     .attr("x2", function(d, i){return levelFactor*(1-cfg.factor*Math.sin((i+1)*cfg.radians/total));})
     .attr("y2", function(d, i){return levelFactor*(1-cfg.factor*Math.cos((i+1)*cfg.radians/total));})
     .attr("class", "line").style("stroke", "grey").style("stroke-width", "0.5px").attr("transform", "translate(" + (cfg.w/2-levelFactor) + ", " + (cfg.h/2-levelFactor) + ")");;
  }
}


function drawAxis(){
  var axis = g.selectAll(".axis").data(allAxis).enter().append("g").attr("class", "axis");

  axis.append("line")
      .attr("x1", cfg.w/2)
      .attr("y1", cfg.h/2)
      .attr("x2", function(j, i){
        maxAxisValues[i] = {x:cfg.w/2*(1-cfg.factor*Math.sin(i*cfg.radians/total)), y:0};
        return maxAxisValues[i].x;
      })
      .attr("y2", function(j, i){
        maxAxisValues[i].y = cfg.h/2*(1-cfg.factor*Math.cos(i*cfg.radians/total));
        return maxAxisValues[i].y;
      })
      .attr("class", "line").style("stroke", "grey").style("stroke-width", "1px");

  axis.append("text").attr("class", "legend")
      .text(function(d){return d}).style("font-family", "sans-serif").style("font-size", "10px").attr("transform", function(d, i){return "translate(0, -10)";})
      .attr("x", function(d, i){return cfg.w/2*(1-cfg.factorLegend*Math.sin(i*cfg.radians/total))-20*Math.sin(i*cfg.radians/total);})
      .attr("y", function(d, i){return cfg.h/2*(1-Math.cos(i*cfg.radians/total))+20*Math.cos(i*cfg.radians/total);});
}

function reCalculatePoints(){
  g.selectAll(".nodes")
    .data(d, function(j, i){
      dataValues[i] =
      [
        cfg.w/2*(1-(parseFloat(Math.max(j.value, 0))/cfg.maxValue)*cfg.factor*Math.sin(i*cfg.radians/total)),
        cfg.h/2*(1-(parseFloat(Math.max(j.value, 0))/cfg.maxValue)*cfg.factor*Math.cos(i*cfg.radians/total)),
      ];
    });
  dataValues[d[0].length] = dataValues[0];
}

function initPolygon(){
  return g.selectAll("area").data([dataValues])
            .enter()
            .append("polygon")
            .attr("class", "radar-chart-serie0")
            .style("stroke-width", "2px")
            .style("stroke", cfg.color(0))
            .on('mouseover', function (d){
              z = "polygon."+d3.select(this).attr("class");
              g.selectAll("polygon").transition(200).style("fill-opacity", 0.1); 
              g.selectAll(z).transition(200).style("fill-opacity", 0.7);
            })
            .on('mouseout', function(){
              g.selectAll("polygon").transition(200).style("fill-opacity", cfg.opacityArea);
            })
            .style("fill", function(j, i){return cfg.color(0);})
            .style("fill-opacity", cfg.opacityArea);
}

function drawPoly(){
  areagg.attr("points",function(de) {
      var str="";
      for(var pti=0;pti<de.length;pti++){
        str=str+de[pti][0]+","+de[pti][1]+" ";
      }            
      return str;
    });
}

function drawnode(){    
  g.selectAll(".nodes")
    .data(d).enter()
    .append("svg:circle").attr("class", "radar-chart-serie0")
    .attr('r', cfg.radius)
    .attr("alt", function(j){return Math.max(j.value, 0);})
    .attr("cx", function(j, i){
      return cfg.w/2*(1-(Math.max(j.value, 0)/cfg.maxValue)*cfg.factor*Math.sin(i*cfg.radians/total));
    })
    .attr("cy", function(j, i){
      return cfg.h/2*(1-(Math.max(j.value, 0)/cfg.maxValue)*cfg.factor*Math.cos(i*cfg.radians/total));
    })
    .attr("data-id", function(j){return j.axis;})
    .style("fill", cfg.color(0)).style("fill-opacity", 0.9)
    .on('mouseover', function (d){
                newX =  parseFloat(d3.select(this).attr('cx')) - 10;
                newY =  parseFloat(d3.select(this).attr('cy')) - 5;
                tooltip.attr('x', newX).attr('y', newY).text(d.value).transition(200).style('opacity', 1);
                z = "polygon."+d3.select(this).attr("class");
                g.selectAll("polygon").transition(200).style("fill-opacity", 0.1);
                g.selectAll(z).transition(200).style("fill-opacity", 0.7);
              })
    .on('mouseout', function(){
                tooltip.transition(200).style('opacity', 0);
                g.selectAll("polygon").transition(200).style("fill-opacity", cfg.opacityArea);
              })
    .call(d3.behavior.drag().on("drag", move))      // for drag & drop
    .append("svg:title")
    .text(function(j){return Math.max(j.value, 0)});
}

//Tooltip
tooltip = g.append('text').style('opacity', 0).style('font-family', 'sans-serif').style('font-size', 13);


function move(dobj, i){
  this.parentNode.appendChild(this);
  var dragTarget = d3.select(this);

  var oldData = dragTarget.data()[0];

  var oldX = parseFloat(dragTarget.attr("cx")) - 300;
  var oldY = 300 - parseFloat(dragTarget.attr("cy"));
  var newY = 0, newX = 0, newValue = 0;
  var maxX = maxAxisValues[i].x - 300;
  var maxY = 300 - maxAxisValues[i].y;

  if(oldX == 0) {
    newY = oldY - d3.event.dy;

    if(Math.abs(newY) > Math.abs(maxY)) {
      newY = maxY;
    }
    newValue = (newY/oldY) * oldData.value;
  }
  else
  {
    var slope = oldY / oldX;   
    newX = d3.event.dx + parseFloat(dragTarget.attr("cx")) - 300;

    if(Math.abs(newX) > Math.abs(maxX)) {
      newX = maxX;
    }
    newY = newX * slope;

    var ratio = newX / oldX; 
    newValue = ratio * oldData.value;
  }

  dragTarget
      .attr("cx", function(){return newX + 300 ;})
      .attr("cy", function(){return 300 - newY;});

  d[oldData.order].value=newValue;
  reCalculatePoints();
  drawPoly();
}}};
&#13;
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
    <script src="http://d3js.org/d3.v3.min.js"></script>

<button id="btn">Click to add</button>
<button id="btnB">Click to add Another area</button>
   <div id="chart" >

</div>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

<!DOCTYPE html>
<html>
    <body>
    <script src="http://code.jquery.com/jquery-1.10.2.js"></script>
    <script src="http://d3js.org/d3.v3.min.js"></script>

    <button id="btn">Click to add</button>
    <button id="btnB">Click to add Another area</button>
    <div id="chart"></div>
    <script>
        d = [
                 {axis: "axisA", value: 2, order:0}, 
                 {axis: "axisB", value: 8, order:1},
                 {axis: "axisC", value: 4, order:2},
                 {axis: "axisD", value: 6, order:3}
            ];

        var RadarChart = {draw: function(id, d, options){
            var cfg = {
        radius: 6, w: 600,h: 600,
              factor: 1,

              factorLegend: .85,
              levels: 3,

              maxValue: 0,
              radians: 2 * Math.PI,
              opacityArea: 0.5,
              color: d3.scale.category10()
            };
            if('undefined' !== typeof options){
              for(var i in options){
                if('undefined' !== typeof options[i]){
                  cfg[i] = options[i];
                }
              }
            }
         cfg.maxValue = Math.max(cfg.maxValue, d3.max(d.map(function(o){return o.value}))); 
            var allAxis = (d.map(function(i, j){return i.axis}));
            var total = allAxis.length;

            var radius = cfg.factor*Math.min(cfg.w/2, cfg.h/2);


        d3.select(id).select("svg").remove();
        var g = d3.select(id).append("svg").attr("width", cfg.w).attr("height", cfg.h).append("g");

        var tooltip;

        drawFrame();
        var maxAxisValues = []; 
        drawAxis();
        var dataValues = [];
        reCalculatePoints();

        var areagg = initPolygon();
        drawPoly();

        drawnode();


        function drawFrame(){
          for(var j=0; j<cfg.levels; j++){
            var levelFactor = cfg.factor*radius*((j+1)/cfg.levels);
            g.selectAll(".levels").data(allAxis).enter().append("svg:line")
             .attr("x1", function(d, i){return levelFactor*(1-cfg.factor*Math.sin(i*cfg.radians/total));})
             .attr("y1", function(d, i){return levelFactor*(1-cfg.factor*Math.cos(i*cfg.radians/total));})
             .attr("x2", function(d, i){return levelFactor*(1-cfg.factor*Math.sin((i+1)*cfg.radians/total));})
             .attr("y2", function(d, i){return levelFactor*(1-cfg.factor*Math.cos((i+1)*cfg.radians/total));})
             .attr("class", "line").style("stroke", "grey").style("stroke-width", "0.5px").attr("transform", "translate(" + (cfg.w/2-levelFactor) + ", " + (cfg.h/2-levelFactor) + ")");;
          }
        }


        function drawAxis(){
          var axis = g.selectAll(".axis").data(allAxis).enter().append("g").attr("class", "axis");

          axis.append("line")
              .attr("x1", cfg.w/2)
              .attr("y1", cfg.h/2)
              .attr("x2", function(j, i){
                maxAxisValues[i] = {x:cfg.w/2*(1-cfg.factor*Math.sin(i*cfg.radians/total)), y:0};
                return maxAxisValues[i].x;
              })
              .attr("y2", function(j, i){
                maxAxisValues[i].y = cfg.h/2*(1-cfg.factor*Math.cos(i*cfg.radians/total));
                return maxAxisValues[i].y;
              })
              .attr("class", "line").style("stroke", "grey").style("stroke-width", "1px");

          axis.append("text").attr("class", "legend")
              .text(function(d){return d}).style("font-family", "sans-serif").style("font-size", "10px").attr("transform", function(d, i){return "translate(0, -10)";})
              .attr("x", function(d, i){return cfg.w/2*(1-cfg.factorLegend*Math.sin(i*cfg.radians/total))-20*Math.sin(i*cfg.radians/total);})
              .attr("y", function(d, i){return cfg.h/2*(1-Math.cos(i*cfg.radians/total))+20*Math.cos(i*cfg.radians/total);});
        }

        function reCalculatePoints(){
          g.selectAll(".nodes")
            .data(d, function(j, i){
              dataValues[i] =
              [
                cfg.w/2*(1-(parseFloat(Math.max(j.value, 0))/cfg.maxValue)*cfg.factor*Math.sin(i*cfg.radians/total)),
                cfg.h/2*(1-(parseFloat(Math.max(j.value, 0))/cfg.maxValue)*cfg.factor*Math.cos(i*cfg.radians/total)),
              ];
            });
          dataValues[d[0].length] = dataValues[0];
        }

        function initPolygon(){
          return g.selectAll("area").data([dataValues])
                    .enter()
                    .append("polygon")
                    .attr("class", "radar-chart-serie0")
                    .style("stroke-width", "2px")
                    .style("stroke", cfg.color(0))
                    .on('mouseover', function (d){
                      z = "polygon."+d3.select(this).attr("class");
                      g.selectAll("polygon").transition(200).style("fill-opacity", 0.1); 
                      g.selectAll(z).transition(200).style("fill-opacity", 0.7);
                    })
                    .on('mouseout', function(){
                      g.selectAll("polygon").transition(200).style("fill-opacity", cfg.opacityArea);
                    })
                    .style("fill", function(j, i){return cfg.color(0);})
                    .style("fill-opacity", cfg.opacityArea);
        }

        function drawPoly(){
          areagg.attr("points",function(de) {
              var str="";
              for(var pti=0;pti<de.length;pti++){
                str=str+de[pti][0]+","+de[pti][1]+" ";
              }            
              return str;
            });
        }

        function drawnode(){    
          g.selectAll(".nodes")
            .data(d).enter()
            .append("svg:circle").attr("class", "radar-chart-serie0")
            .attr('r', cfg.radius)
            .attr("alt", function(j){return Math.max(j.value, 0);})
            .attr("cx", function(j, i){
              return cfg.w/2*(1-(Math.max(j.value, 0)/cfg.maxValue)*cfg.factor*Math.sin(i*cfg.radians/total));
            })
            .attr("cy", function(j, i){
              return cfg.h/2*(1-(Math.max(j.value, 0)/cfg.maxValue)*cfg.factor*Math.cos(i*cfg.radians/total));
            })
            .attr("data-id", function(j){return j.axis;})
            .style("fill", cfg.color(0)).style("fill-opacity", 0.9)
            .on('mouseover', function (d){
                        newX =  parseFloat(d3.select(this).attr('cx')) - 10;
                        newY =  parseFloat(d3.select(this).attr('cy')) - 5;
                        tooltip.attr('x', newX).attr('y', newY).text(d.value).transition(200).style('opacity', 1);
                        z = "polygon."+d3.select(this).attr("class");
                        g.selectAll("polygon").transition(200).style("fill-opacity", 0.1);
                        g.selectAll(z).transition(200).style("fill-opacity", 0.7);
                      })
            .on('mouseout', function(){
                        tooltip.transition(200).style('opacity', 0);
                        g.selectAll("polygon").transition(200).style("fill-opacity", cfg.opacityArea);
                      })
            .call(d3.behavior.drag().on("drag", move))      // for drag & drop
            .append("svg:title")
            .text(function(j){return Math.max(j.value, 0)});
        }

        //Tooltip
        tooltip = g.append('text').style('opacity', 0).style('font-family', 'sans-serif').style('font-size', 13);


        function move(dobj, i){
          this.parentNode.appendChild(this);
          var dragTarget = d3.select(this);

          var oldData = dragTarget.data()[0];

          var oldX = parseFloat(dragTarget.attr("cx")) - 300;
          var oldY = 300 - parseFloat(dragTarget.attr("cy"));
          var newY = 0, newX = 0, newValue = 0;
          var maxX = maxAxisValues[i].x - 300;
          var maxY = 300 - maxAxisValues[i].y;

          if(oldX == 0) {
            newY = oldY - d3.event.dy;

            if(Math.abs(newY) > Math.abs(maxY)) {
              newY = maxY;
            }
            newValue = (newY/oldY) * oldData.value;
          }
          else
          {
            var slope = oldY / oldX;   
            newX = d3.event.dx + parseFloat(dragTarget.attr("cx")) - 300;

            if(Math.abs(newX) > Math.abs(maxX)) {
              newX = maxX;
            }
            newY = newX * slope;

            var ratio = newX / oldX; 
            newValue = ratio * oldData.value;
          }

          dragTarget
              .attr("cx", function(){return newX + 300 ;})
              .attr("cy", function(){return 300 - newY;});

          d[oldData.order].value=newValue;
          reCalculatePoints();
          drawPoly();
        }}};

        $("#btnB").click(function(){
          d.push({axis: "axisA", value: 1, order:4}, {axis: "axisB", value: 3, order:5}, {axis: "axisC", value: 5, order:6}, {axis: "axisD", value: 7, order:7})
          RadarChart.draw("#chart", d);
          });
        $("#btn").click(function(){
            RadarChart.draw("#chart", d);
        });
        </script> 
    </body>
<html>