2015-11-18 1 views
0

J'ai créé un graphique à bulles d3.js. Je veux que l'info-bulle soit toujours positionnée en haut à droite sur la bordure du cercle, partout où le curseur est déplacé dans le cercle.Positionnement de l'info-bulle dans le graphique à bulles

Voici comment j'ai créé l'info-bulle.

 new Ext.ToolTip({ 
     title: desc, 
     radius:circle[0][i].__data__.radius, 
     anchor: 'left', 
     autoHide: false, 
     showDelay:0, 
     trackMouse: false, 
     anchorToTarget: false, 
     ttype:"ltype"+i, 
     target: circle[0][i], 
     listeners:{ 
      move:function(a,b,c){ 
        var currentType = this.ttype; 
       items.push(this); 
       for(var i=0;i<items.length;i++){ 
        if(items[i].ttype!=currentType){ 
         if(items[i].isVisible()){ 
          items[i].hide(); 
         } 
        } 
       } 

       } 
     } 

    }); 

Comment puis-je le faire? Voici mon fiddle

Répondre

1

Il existe une solution possible si vous utilisez des événements de survol de la souris.

var data = { 
 
    name: "layout", 
 
    children: [{ 
 
    name: "AxisLayout", 
 
    size: 6725 
 
    }, { 
 
    name: "BundledEdgeRouter", 
 
    size: 3727 
 
    }, { 
 
    name: "CircleLayout", 
 
    size: 9317 
 
    }, { 
 
    name: "CirclePackingLayout", 
 
    "size": 12003 
 
    }, { 
 
    name: "DendrogramLayout", 
 
    "size": 4853 
 
    }, { 
 
    name: "ForceDirectedLayout", 
 
    "size": 8411 
 
    }, { 
 
    name: "IcicleTreeLayout", 
 
    "size": 4864 
 
    }, { 
 
    name: "IndentedTreeLayout", 
 
    "size": 3174 
 
    }, { 
 
    name: "Layout", 
 
    "size": 7881 
 
    }, { 
 
    name: "NodeLinkTreeLayout", 
 
    "size": 12870 
 
    }, { 
 
    name: "PieLayout", 
 
    "size": 2728 
 
    }, { 
 
    name: "RadialTreeLayout", 
 
    "size": 12348 
 
    }, { 
 
    name: "RandomLayout", 
 
    "size": 870 
 
    }, { 
 
    name: "StackedAreaLayout", 
 
    "size": 9121 
 
    }, { 
 
    name: "TreeMapLayout", 
 
    "size": 9191 
 
    }] 
 
}; 
 

 
var margin = { 
 
    top: 0, 
 
    right: 0, 
 
    bottom: 0, 
 
    left: 0 
 
    }, 
 
    width = 400 - margin.left - margin.right, 
 
    height = 400 - margin.top - margin.bottom; 
 

 
var n = data.children.length, 
 
    m = 1, 
 
    padding = 6, 
 
    radius = d3.scale.sqrt().range([0, 12]), 
 
    color = d3.scale.category10().domain(d3.range(m)), 
 
    x = d3.scale.ordinal().domain(d3.range(m)).rangePoints([0, width], 1); 
 

 
var nodes = d3.range(n).map(function() { 
 
    var i = Math.floor(Math.random() * m), //color 
 
    v = (i + 1)/m * -Math.log(Math.random()); //value 
 
    return { 
 
    radius: radius(v), 
 
    color: color(i), 
 
    cx: x(i), 
 
    cy: height/2, 
 
    }; 
 

 
}); 
 

 
nodes.forEach(function(item, index) { 
 
    item.radius = data.children[index].size/300; 
 
}); 
 

 
var force = d3.layout.force() 
 
    .nodes(nodes) 
 
    .size([width, height]) 
 
    .gravity(0) 
 
    .charge(0) 
 
    .on("tick", tick) 
 
    .start(); 
 

 
var drag = force.drag() 
 
    .on("drag", dragmove); 
 

 
function dragmove(d) { 
 
    var euclideanDistance = Math.sqrt(Math.pow((d.px - 198), 2) + Math.pow((d.py - 198), 2)); 
 

 
    if (euclideanDistance > 198 - d.radius) { 
 
    d.px = d.px - 198; 
 
    d.py = d.py - 198; 
 

 
    var radians = Math.atan2(d.py, d.px); 
 

 
    d.px = Math.cos(radians) * (198 - d.radius) + 198; 
 
    d.py = Math.sin(radians) * (198 - d.radius) + 198; 
 
    } 
 
} 
 

 
var svg = d3.select("#chart").append("svg") 
 
    .attr("width", width + margin.left + margin.right) 
 
    .attr("height", height + margin.top + margin.bottom) 
 
    .append("g") 
 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 
 

 
var circle = svg.selectAll("circle") 
 
    .data(nodes) 
 
    .enter().append("circle") 
 
    .attr("r", function(d) { 
 
    return d.radius; 
 
    }) 
 
    .style("fill", function(d, i) { 
 
    return "green"; 
 
    }) 
 
    .call(drag); 
 

 
var tip = Ext.create('Ext.tip.ToolTip', { 
 
    title: 'test', 
 
    width: 150, 
 
    height: 40, 
 
    radius: 5, 
 
    hidden: true, 
 
    anchor: 'left', 
 
    autoHide: false, 
 
    trackMouse: true, 
 
    anchorToTarget: false 
 
}); 
 

 
circle.on('mouseover', function(d, i) { 
 
    tip.setTitle("radius: " + d.radius); 
 
    tip.showAt([d.x - d.radius, d.y - d.radius]); 
 
}); 
 

 
function tick(e) { 
 
    circle.each(gravity(.2 * e.alpha)) 
 
    .each(collide(.5)) 
 
    .attr("cx", function(d) { 
 
     return d.x; 
 
    }) 
 
    .attr("cy", function(d) { 
 
     return d.y; 
 
    }); 
 
} 
 

 
// Move nodes toward cluster focus. 
 
function gravity(alpha) { 
 
    return function(d) { 
 
    d.y += (d.cy - d.y) * alpha; 
 
    d.x += (d.cx - d.x) * alpha; 
 
    }; 
 
} 
 

 
// Resolve collisions between nodes. 
 
function collide(alpha) { 
 
    var quadtree = d3.geom.quadtree(nodes); 
 
    return function(d) { 
 
    var r = d.radius + radius.domain()[1] + padding, 
 
     nx1 = d.x - r, 
 
     nx2 = d.x + r, 
 
     ny1 = d.y - r, 
 
     ny2 = d.y + r; 
 
    quadtree.visit(function(quad, x1, y1, x2, y2) { 
 
     if (quad.point && (quad.point !== d)) { 
 
     var x = d.x - quad.point.x, 
 
      y = d.y - quad.point.y, 
 
      l = Math.sqrt(x * x + y * y), 
 
      r = d.radius + quad.point.radius + (d.color !== quad.point.color) * padding; 
 
     if (l < r) { 
 
      l = (l - r)/l * alpha; 
 
      d.x -= x *= l; 
 
      d.y -= y *= l; 
 
      quad.point.x += x; 
 
      quad.point.y += y; 
 
     } 
 
     } 
 
     return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1; 
 
    }); 
 
    }; 
 
}
svg { 
 
    /*border: 1px solid black;*/ 
 
    border-radius: 50%; 
 
    background: lightgray; 
 
} 
 
circle { 
 
    stroke: #fff; 
 
}
<link href="http://dev.sencha.com/deploy/ext-4.1.0-gpl/resources/css/ext-all.css" rel="stylesheet"/> 
 
<script src="http://cdn.sencha.com/ext/gpl/4.1.1/ext-all.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 
<p id='chart'>