Skip to content

Instantly share code, notes, and snippets.

@BadCoder1337
Forked from ZJONSSON/force_labels.js
Last active May 18, 2023 09:06
Show Gist options
  • Select an option

  • Save BadCoder1337/7f2cdc379d8c69debf8a2e6695515ede to your computer and use it in GitHub Desktop.

Select an option

Save BadCoder1337/7f2cdc379d8c69debf8a2e6695515ede to your computer and use it in GitHub Desktop.

Revisions

  1. BadCoder1337 revised this gist May 18, 2023. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -103,11 +103,11 @@
    }

    function correlate() {
    var corr = d3.select("#corr").property("value")
    var corr = 1
    d3.select("#corr-label").text("Correlation: "+d3.format("%")(corr))

    data.forEach(function(d) { d.x = x_mean+(d.z1*x_std),
    d.y = y_mean+y_std*(corr*d.z1+d.z2*Math.sqrt(1-Math.pow(corr,2)))})
    data.forEach(function(d) { d.x = x_mean+d.z1*x_std,
    d.y = y_mean+y_std*d.z1})
    refresh()
    }

  2. BadCoder1337 revised this gist May 18, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@
    <html>
    <head>
    <script src="https://d3js.org/d3.v2.js"></script>
    <script type="text/javascript" src="https://gist.githubusercontent.com/BadCoder1337/7f2cdc379d8c69debf8a2e6695515ede/raw/d3ad413323d6a1564bcb1c086fc5c8cfc9c2bd16/force_labels.js"></script>
    <script type="text/javascript" src="force_labels.js"></script>
    <style>
    .anchor { fill:blue}
    .labelbox { fill:black;opacity:0.8}
  3. BadCoder1337 revised this gist May 18, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@
    <html>
    <head>
    <script src="https://d3js.org/d3.v2.js"></script>
    <script type="text/javascript" src="force_labels.js"></script>
    <script type="text/javascript" src="https://gist.githubusercontent.com/BadCoder1337/7f2cdc379d8c69debf8a2e6695515ede/raw/d3ad413323d6a1564bcb1c086fc5c8cfc9c2bd16/force_labels.js"></script>
    <style>
    .anchor { fill:blue}
    .labelbox { fill:black;opacity:0.8}
  4. BadCoder1337 revised this gist May 18, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    <!DOCTYPE html>
    <html>
    <head>
    <script src="http://d3js.org/d3.v2.js"></script>
    <script src="https://d3js.org/d3.v2.js"></script>
    <script type="text/javascript" src="force_labels.js"></script>
    <style>
    .anchor { fill:blue}
  5. @ZJONSSON ZJONSSON revised this gist Nov 6, 2014. 1 changed file with 0 additions and 0 deletions.
    Binary file added thumbnail.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
  6. @ZJONSSON ZJONSSON revised this gist Oct 17, 2013. 2 changed files with 58 additions and 1 deletion.
    57 changes: 57 additions & 0 deletions force_labels.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,57 @@
    (function() {
    d3.force_labels = function force_labels() {
    var labels = d3.layout.force();

    // Update the position of the anchor based on the center of bounding box
    function updateAnchor() {
    if (!labels.selection) return;
    labels.selection.each(function(d) {
    var bbox = this.getBBox(),
    x = bbox.x + bbox.width / 2,
    y = bbox.y + bbox.height / 2;

    d.anchorPos.x = x;
    d.anchorPos.y = y;

    // If a label position does not exist, set it to be the anchor position
    if (d.labelPos.x == null) {
    d.labelPos.x = x;
    d.labelPos.y = y;
    }
    });
    }

    //The anchor position should be updated on each tick
    labels.on("tick.labels", updateAnchor);

    // This updates all nodes/links - retaining any previous labelPos on updated nodes
    labels.update = function(selection) {
    labels.selection = selection;
    var nodes = [], links = [];
    selection[0].forEach(function(d) {
    if(d && d.__data__) {
    var data = d.__data__;

    if (!d.labelPos) d.labelPos = {fixed: false};
    if (!d.anchorPos) d.anchorPos = {fixed: true};

    // Place position objects in __data__ to make them available through
    // d.labelPos/d.anchorPos for different elements
    data.labelPos = d.labelPos;
    data.anchorPos = d.anchorPos;

    links.push({target: d.anchorPos, source: d.labelPos});
    nodes.push(d.anchorPos);
    nodes.push(d.labelPos);
    }
    });
    labels
    .stop()
    .nodes(nodes)
    .links(links);
    updateAnchor();
    labels.start();
    };
    return labels;
    };
    })();
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@
    <html>
    <head>
    <script src="http://d3js.org/d3.v2.js"></script>
    <script type="text/javascript" src="https://raw.github.com/ZJONSSON/d3-plugins/master/force_labels/force_labels.js"></script>
    <script type="text/javascript" src="force_labels.js"></script>
    <style>
    .anchor { fill:blue}
    .labelbox { fill:black;opacity:0.8}
  7. @ZJONSSON ZJONSSON revised this gist Aug 23, 2012. 1 changed file with 0 additions and 64 deletions.
    64 changes: 0 additions & 64 deletions d3.z.labels.js
    Original file line number Diff line number Diff line change
    @@ -1,64 +0,0 @@
    /*
    D3 force labels v 0.1
    Generates an automatic positioning for labels, using the force layout
    Function .update should be called on the selection of anchors
    Anchor positions are determiend by svg bounding boxes and stored separately in anchorPos x,y
    After update, the label positions are found in __data__.labelPos
    ziggy.jonsson.nyc@gmail.com
    */


    if (typeof d3.z != "object") d3.z = {};
    (function(){
    d3.z.labels = function() {
    var label = d3.layout.force()
    ,margin=-1

    // Update the position of the anchor based on the center of bounding box
    function updateAnchor() {
    if (!label.selection) return
    label.selection.each(function(d) {
    var bbox = this.getBBox(),
    x=bbox.x+bbox.width/2,
    y=bbox.y+bbox.height/2
    d.anchorPos.x=x
    d.anchorPos.y=y

    // If a label position does not exist, set it to be the anchor position
    if (d.labelPos.x==null) {
    d.labelPos.x=x
    d.labelPos.y=y
    }
    })
    }

    //The anchor position should be updated on each tick
    label.on("tick.labels",updateAnchor)

    // This updates all nodes/links - retaining any previous labelPos on updated nodes
    label.update = function(selection) {
    label.selection = selection
    var nodes=[],links=[];
    selection[0].forEach(function(d) {

    if(d && d.__data__) {
    var data = d.__data__
    if (!d.labelPos) d.labelPos = {fixed:false}
    if (!d.anchorPos) d.anchorPos = {fixed:true}

    // Place position objects in __data__ to make them available through d.labelPos/d.anchorPos for different elements
    data.labelPos = d.labelPos
    data.anchorPos = d.anchorPos

    links.push({target:d.anchorPos,source:d.labelPos})
    nodes.push(d.anchorPos)
    nodes.push(d.labelPos)
    }
    })
    label.stop().nodes(nodes).links(links)
    updateAnchor()
    label.start()
    }
    return label
    }
    })()
  8. @ZJONSSON ZJONSSON revised this gist Aug 23, 2012. 1 changed file with 3 additions and 5 deletions.
    8 changes: 3 additions & 5 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,8 @@
    <!DOCTYPE html>
    <html>
    <head>
    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.geom.js"></script>
    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.layout.js"></script>
    <script type="text/javascript" src="d3.z.labels.js"></script>
    <script src="http://d3js.org/d3.v2.js"></script>
    <script type="text/javascript" src="https://raw.github.com/ZJONSSON/d3-plugins/master/force_labels/force_labels.js"></script>
    <style>
    .anchor { fill:blue}
    .labelbox { fill:black;opacity:0.8}
    @@ -87,7 +85,7 @@


    // Initialize the label-forces
    labelForce = d3.z.labels()
    labelForce = d3.force_labels()
    .linkDistance(0.0)
    .gravity(0)
    .nodes([]).links([])
  9. @ZJONSSON ZJONSSON revised this gist Jul 11, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -9,7 +9,7 @@
    .anchor { fill:blue}
    .labelbox { fill:black;opacity:0.8}
    .labeltext { fill:white;font-weight:bold;text-anchor:middle;font-size:16;font-family: serif}
    .link { stroke:gray;stroke-width:0.2}
    .link { stroke:gray;stroke-width:0.35}
    </style>
    </head>

  10. @ZJONSSON ZJONSSON revised this gist Jul 11, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -9,7 +9,7 @@
    .anchor { fill:blue}
    .labelbox { fill:black;opacity:0.8}
    .labeltext { fill:white;font-weight:bold;text-anchor:middle;font-size:16;font-family: serif}
    .link { stroke:gray;opacity:0.4;stroke-width:0.2}
    .link { stroke:gray;stroke-width:0.2}
    </style>
    </head>

  11. @ZJONSSON ZJONSSON revised this gist Jul 11, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -9,7 +9,7 @@
    .anchor { fill:blue}
    .labelbox { fill:black;opacity:0.8}
    .labeltext { fill:white;font-weight:bold;text-anchor:middle;font-size:16;font-family: serif}
    .link { stroke:gray;opacity:0.8;stroke-width:0.2}
    .link { stroke:gray;opacity:0.4;stroke-width:0.2}
    </style>
    </head>

  12. @ZJONSSON ZJONSSON revised this gist Jan 28, 2012. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions d3.z.labels.js
    Original file line number Diff line number Diff line change
    @@ -9,7 +9,7 @@ ziggy.jonsson.nyc@gmail.com


    if (typeof d3.z != "object") d3.z = {};
    (
    (function(){
    d3.z.labels = function() {
    var label = d3.layout.force()
    ,margin=-1
    @@ -61,4 +61,4 @@ d3.z.labels = function() {
    }
    return label
    }
    )()
    })()
  13. @ZJONSSON ZJONSSON revised this gist Jan 27, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -100,7 +100,7 @@
    function randomize(count) {
    z1=d3.random.normal()
    z2=d3.random.normal()
    data=data.concat(d3.range(count || 10).map(function(d,i) { return {z1:z1(),z2:z2(),num:data.length+i}}))
    data=data.concat(d3.range(count || 100).map(function(d,i) { return {z1:z1(),z2:z2(),num:data.length+i}}))
    correlate()
    }

  14. @ZJONSSON ZJONSSON created this gist Jan 27, 2012.
    64 changes: 64 additions & 0 deletions d3.z.labels.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,64 @@
    /*
    D3 force labels v 0.1
    Generates an automatic positioning for labels, using the force layout
    Function .update should be called on the selection of anchors
    Anchor positions are determiend by svg bounding boxes and stored separately in anchorPos x,y
    After update, the label positions are found in __data__.labelPos
    ziggy.jonsson.nyc@gmail.com
    */


    if (typeof d3.z != "object") d3.z = {};
    (
    d3.z.labels = function() {
    var label = d3.layout.force()
    ,margin=-1

    // Update the position of the anchor based on the center of bounding box
    function updateAnchor() {
    if (!label.selection) return
    label.selection.each(function(d) {
    var bbox = this.getBBox(),
    x=bbox.x+bbox.width/2,
    y=bbox.y+bbox.height/2
    d.anchorPos.x=x
    d.anchorPos.y=y

    // If a label position does not exist, set it to be the anchor position
    if (d.labelPos.x==null) {
    d.labelPos.x=x
    d.labelPos.y=y
    }
    })
    }

    //The anchor position should be updated on each tick
    label.on("tick.labels",updateAnchor)

    // This updates all nodes/links - retaining any previous labelPos on updated nodes
    label.update = function(selection) {
    label.selection = selection
    var nodes=[],links=[];
    selection[0].forEach(function(d) {

    if(d && d.__data__) {
    var data = d.__data__
    if (!d.labelPos) d.labelPos = {fixed:false}
    if (!d.anchorPos) d.anchorPos = {fixed:true}

    // Place position objects in __data__ to make them available through d.labelPos/d.anchorPos for different elements
    data.labelPos = d.labelPos
    data.anchorPos = d.anchorPos

    links.push({target:d.anchorPos,source:d.labelPos})
    nodes.push(d.anchorPos)
    nodes.push(d.labelPos)
    }
    })
    label.stop().nodes(nodes).links(links)
    updateAnchor()
    label.start()
    }
    return label
    }
    )()
    134 changes: 134 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,134 @@
    <!DOCTYPE html>
    <html>
    <head>
    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.geom.js"></script>
    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.layout.js"></script>
    <script type="text/javascript" src="d3.z.labels.js"></script>
    <style>
    .anchor { fill:blue}
    .labelbox { fill:black;opacity:0.8}
    .labeltext { fill:white;font-weight:bold;text-anchor:middle;font-size:16;font-family: serif}
    .link { stroke:gray;opacity:0.8;stroke-width:0.2}
    </style>
    </head>

    <body>
    <div style="width:150px;float:left">
    <span id="corr-label">Correlation: </span><br>
    <input type="range" min="-1.0" max="1.0" value="0.0" id="corr" step="0.01"/>
    </div>
    <div style="width:150px;float:left">
    <span id="charge-label">Label charge: </span><br>
    <input type="range" min="0" max="100" value="60.0" id="charge" step="1"/>
    </div>
    <button type="button" id="addone">Add one measurement</button>
    <button type="button" id="randomize20">Replace with 20</button>
    <button type="button" id="randomize50">Replace with 50</button>
    <button type="button" id="randomize100">Replace with 100</button>

    <script type="text/javascript">
    var w=960,h=500,
    x_mean = w/2,
    x_std = w/10,
    y_mean = h/2,
    y_std = h/10,
    labelBox,link,
    data=[];


    var svg=d3.select("body")
    .append("svg:svg")
    .attr("height",h)
    .attr("width",w)

    function refresh() {
    // plot the data as usual
    anchors = svg.selectAll(".anchor").data(data,function(d,i) { return i})
    anchors.exit().attr("class","exit").transition().duration(1000).style("opacity",0).remove()
    anchors.enter().append("circle").attr("class","anchor").attr("r",4).attr("cx",function(d) { return d.x}).attr("cy",function(d) { return h-d.y})
    anchors.transition()
    .delay(function(d,i) { return i*10})
    .duration(1500)
    .attr("cx",function(d) { return d.x})
    .attr("cy",function(d) { return h-d.y})


    // Now for the labels
    anchors.call(labelForce.update) // This is the only function call needed, the rest is just drawing the labels

    labels = svg.selectAll(".labels").data(data,function(d,i) { return i})
    labels.exit().attr("class","exit").transition().delay(0).duration(500).style("opacity",0).remove()

    // Draw the labelbox, caption and the link
    newLabels = labels.enter().append("g").attr("class","labels")

    newLabelBox = newLabels.append("g").attr("class","labelbox")
    newLabelBox.append("circle").attr("r",11)
    newLabelBox.append("text").attr("class","labeltext").attr("y",6)
    newLabels.append("line").attr("class","link")

    labelBox = svg.selectAll(".labels").selectAll(".labelbox")
    links = svg.selectAll(".link")
    labelBox.selectAll("text").text(function(d) { return d.num})

    }

    function redrawLabels() {
    labelBox
    .attr("transform",function(d) { return "translate("+d.labelPos.x+" "+d.labelPos.y+")"})

    links
    .attr("x1",function(d) { return d.anchorPos.x})
    .attr("y1",function(d) { return d.anchorPos.y})
    .attr("x2",function(d) { return d.labelPos.x})
    .attr("y2",function(d) { return d.labelPos.y})
    }


    // Initialize the label-forces
    labelForce = d3.z.labels()
    .linkDistance(0.0)
    .gravity(0)
    .nodes([]).links([])
    .charge(-60)
    .on("tick",redrawLabels)



    // and now for the data functionality
    function randomize(count) {
    z1=d3.random.normal()
    z2=d3.random.normal()
    data=data.concat(d3.range(count || 10).map(function(d,i) { return {z1:z1(),z2:z2(),num:data.length+i}}))
    correlate()
    }

    function correlate() {
    var corr = d3.select("#corr").property("value")
    d3.select("#corr-label").text("Correlation: "+d3.format("%")(corr))

    data.forEach(function(d) { d.x = x_mean+(d.z1*x_std),
    d.y = y_mean+y_std*(corr*d.z1+d.z2*Math.sqrt(1-Math.pow(corr,2)))})
    refresh()
    }

    // and finally hook up the controls

    d3.select("#randomize20").on("click",function() { data=[];randomize(20)})
    d3.select("#randomize50").on("click",function() { data=[];randomize(50)})
    d3.select("#randomize100").on("click",function() { data=[];randomize(100)})
    d3.select("#addone").on("click",function() { randomize(1)})
    d3.select("#corr")
    .on("change",function() { d3.select("#corr-label").text("Correlation: "+d3.format("%")(this.value))})
    .on("mouseup",correlate)
    d3.select("#charge")
    .on("change",function() {
    d3.select("#charge-label").text("Label charge: "+d3.format("f")(this.value))
    labelForce.charge(-this.value).start()
    })

    randomize()
    </script>
    </body>
    </html>