簡體   English   中英

如何在 D3.js 中強制氣泡的重力

[英]How to force the gravity of bubbles in D3.js

在下面的代碼中,我需要讓數值最高的氣泡浮動到屏幕左側,但是我對 D3.js 沒有深入的了解,也找不到辦法做到這一點。

我的代碼

<script type="text/javascript">

     dataset = {
        "children": [{"Name":"Olives","Count":10},
            {"Name":"Tea","Count":8},
            {"Name":"Mashed Potatoes","Count":6},
            {"Name":"Boiled Potatoes","Count":5},
            {"Name":"Milk","Count":4},
            {"Name":"Chicken Salad","Count":4},
            {"Name":"Vanilla Ice Cream","Count":2},
            {"Name":"Cocoa","Count":7}];

    var diameter = 600;
    var color = d3.scaleOrdinal(d3.schemeCategory20);

    var bubble = d3.pack(dataset)
        .size([diameter, diameter])
        .padding(1.5);

    var svg = d3.select("body")
        .append("svg")
        .attr("width", diameter)
        .attr("height", diameter)
        .attr("class", "bubble");

    var nodes = d3.hierarchy(dataset)
        .sum(function(d) { return d.Count; });

    var node = svg.selectAll(".node")
        .data(bubble(nodes).descendants())
        .enter()
        .filter(function(d){
            return  !d.children
        })
        .append("g")
        .attr("class", "node")
        .attr("transform", function(d) {
            return "translate(" + d.x + "," + d.y + ")";
        });

    node.append("title")
        .text(function(d) {
            return d.Name + ": " + d.Count;
        });

    node.append("circle")
        .attr("r", function(d) {
            return d.r;
        })
        .style("fill", function(d,i) {
            return color(i);
        });

    node.append("text")
        .attr("dy", ".2em")
        .style("text-anchor", "middle")
        .text(function(d) {
            return d.data.Name.substring(0, d.r / 3);
        })
        .attr("font-family", "sans-serif")
        .attr("font-size", function(d){
            return d.r/5;
        })
        .attr("fill", "white");

    node.append("text")
        .attr("dy", "1.3em")
        .style("text-anchor", "middle")
        .text(function(d) {
            return d.data.Count;
        })
        .attr("font-family",  "Gill Sans", "Gill Sans MT")
        .attr("font-size", function(d){
            return d.r/5;
        })
        .attr("fill", "white");

    d3.select(self.frameElement)
        .style("height", diameter + "px");

</script>

在 JS Fiddle 中編輯

代碼產生這個結果

我需要數值最高的氣泡在左邊,如下圖所示。

我可以使用 D3.js 的什么屬性或功能來根據需要控制氣泡的嚴重程度? 謝謝!

d3.pack 中沒有專門用於此的功能。 d3.force 允許您根據數據的值指定 x 和 y 位置,並可以實現您正在尋找的結果。

力模擬有一個基於數據計數的 .x 和 .y 函數,然后為了避免重疊,.collide 函數根據它們的半徑(加上 3px 的小填充)調整圓的位置。

 var simulation = d3.forceSimulation(nodes)
        .force("forceX", d3.forceX().strength(.051).x(d => xScale(d.Count)))
        .force("forceY", d3.forceY().strength(.051).y(d => yScale(d.Count)))
        .force('collision', d3.forceCollide().radius(d => rScale(d.Count) + 3))

 dataset = { "children": [{"Name":"Olives","Count":10}, {"Name":"Tea","Count":8}, {"Name":"Mashed Potatoes","Count":6}, {"Name":"Boiled Potatoes","Count":5}, {"Name":"Milk","Count":4}, {"Name":"Chicken Salad","Count":4}, {"Name":"Vanilla Ice Cream","Count":2}, {"Name":"Cocoa","Count":7}] } let nodes = dataset.children var width = 600; var height = 600; var margin = 50 var color = d3.scaleOrdinal(d3.schemeCategory20); let extentCount = d3.extent(nodes, d => d.Count) let maxRadius = 100 let yScale = d3.scaleLinear() .domain(extentCount) .range([height - maxRadius, maxRadius]) let xScale = d3.scaleLinear() .domain(extentCount) .range([(width - maxRadius), maxRadius]) let rScale = d3.scaleSqrt() .domain(extentCount) .range([5, maxRadius]) var svg = d3.select("body") .append("svg") .attr("width", width + margin + margin) .attr("height", height + margin + margin) .attr("class", "bubble"); var g = svg.append("g") .attr("transform", "translate(" + margin + "," + margin + ")") var simulation = d3.forceSimulation(nodes) .force("forceX", d3.forceX().strength(.051).x(d => xScale(d.Count))) .force("forceY", d3.forceY().strength(.051).y(d => yScale(d.Count))) .force('collision', d3.forceCollide().radius(d => rScale(d.Count) + 3)) .on("tick", function(d){ node .attr("cx", function(d){ return dx; }) .attr("cy", function(d){ return dy; }) }) .stop() for (var i = 0; i < 120; i++) { simulation.tick() } var node = g.selectAll(".node") .data(nodes) .enter() .append("g") .attr("class", "node") .attr("transform", function(d) { return "translate(" + dx + "," + dy + ")"; }); node.append("title") .text(function(d) { return d.Name + ": " + d.Count; }); node.append("circle") .attr("r", d => rScale(d.Count)) .style("fill", function(d,i) { return color(i); }); node.append("text") .attr("dy", ".2em") .style("text-anchor", "middle") .text(function(d) { return d.Name.substring(0, rScale(d.Count) / 3); }) .attr("font-family", "sans-serif") .attr("font-size", function(d){ return rScale(d.Count)/5; }) .attr("fill", "white"); node.append("text") .attr("dy", "1.3em") .style("text-anchor", "middle") .text(function(d) { return d.Count; }) .attr("font-family", "Gill Sans", "Gill Sans MT") .attr("font-size", function(d){ return dr/5; }) .attr("fill", "white");
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM