lucifer
lucifer

Reputation: 2327

How to call d3.json() outside of d3

I have a requirement that i need to refresh the d3 api which is generated through json.But i can not use location.reload() i.e i can not refresh the full page.i have a click button here that will only refresh the svg but not the ful page.Is it possible???I think that calling d3.json from outside the script will solve the problem.Can anyone help me in that??

    <script>


        var w = 1200, h = 900, radius = d3.scale.log().domain([0,312000 ])
        .range([ "10", "50" ]);

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

        vis.append("marker")
        .attr("id", "arrowhead")
        .attr("refX", 6 + 6) /*must be smarter way to calculate shift*/
        .attr("refY", 2)
        .attr("markerWidth", 6)
        .attr("markerHeight", 4)
        .attr("orient", "auto")
        .append("path")
        .attr("d", "M 0,0 V 4 L6,2 Z"); //this is actual shape for arrowhead

        d3.json("LinkServlet", function(data,error) {
            var force = self.force = d3.layout.force().nodes(data.nodes).links(
            data.links).linkDistance(function(d) {
                return (d.distance * 10);
            })
            //.friction(0.5)
            .charge(-250).size([ w, h ]).start();

            var link = vis.selectAll("line.link").data(data.links).enter().append(
            "svg:line").attr("class", function(d) {
                return "link" + d.value + "";
            }).attr("x1", function(d) {
                return d.source.x;
            }).attr("y1", function(d) {
                return d.source.y;
            }).attr("x2", function(d) {
                return d.target.x;
            }).attr("y2", function(d) {
                return d.target.y;
            }).attr("marker-end", function(d) {
                if (d.value == 10 || d.value==1) {
                    return "url(#arrowhead)"
                } else {
                    return " "

           }
                ;
            });

            function openLink() {
                return function(d) {
                    var url = "";
                    if (d.slug != "") {
                        url = d.slug
                    } else if(d.type == 2) {
                        url = "clients/" + d.slug
                    } else if(d.type == 3) {
                        url = "agencies/" + d.slug
                    }
                    window.open("//" + url)
                }
            }

            var node = vis.selectAll("g.node").data(data.nodes).enter().append(
            "svg:g").attr("class", "node").call(force.drag);


            // size of the nodes are given here
            node.append("circle").attr("class", function(d) {
                return "node type" + d.type
            }).attr("r", function(d) {
                if (d.entity == "description") {
                    return 20
                } else if(d.entity=="big"){
                    return 25
                }else if(d.entity=="small"){
                    return 15
                }else if(d.entity=="company"){
                    return 25
                }else if(d.entity=="manager"){
                    return 30
                }else if(d.entity=="ceo"){
                    return 35
                }else{
                    return 18
                }
            })


            node.append("text").attr("class", function(d) {
                return "nodetext title_" + d.name
            }).attr("dx", 0).attr("dy", ".35em").style("font-size", "10px").attr(
            "text-anchor", "middle").style("fill", "black").text(
            function(d) {                
                return d.name                
            });

            node.on("mouseover", function(d) {
                if (d.entity == "description") {
                    d3.select(this).select('text').transition().duration(300).text(
                    function(d) {
                        return d.name;
                    }).style("font-size", "15px")

                } else if (d.entity == "employee") {
                    var asdf = d3.select(this);
                    asdf.select('text').remove();

                    asdf.append("text").text(function(d) {
                        return d.prefix + ' ' + d.fst_name
                    }).attr("class", "nodetext").attr("dx", 0).attr("dy", ".35em")
                    .style("font-size", "5px")
                    .attr("text-anchor", "middle").style("fill", "white")
                    .transition().duration(300).style("font-size", "12px");

                    asdf.append("text").text(function(d) {
                        return d.snd_name
                    }).attr("class", "nodetext").attr("transform",
                    "translate(0, 12)").attr("dx", 0).attr("dy", ".35em")
                    .style("font-size", "5px")
                    .attr("text-anchor", "middle").style("fill", "white")
                    .transition().duration(300).style("font-size", "12px");
                } else {
                    d3.select(this).select('text').transition().duration(300)
                    .style("font-size", "15px")
                }

                if (d.entity == "company") {
                    d3.select(this).select('image').attr("width", "100px").attr("x",
                    "-46px").attr("y", "-36.5px").attr("xlink:href",
                    function(d) {
                        return d.name
                    });
                }

                if (d.entity == "company") {

                    d3.select(this).select('circle').transition().duration(300)
                    .attr("r", 28)

                } else if (d.entity == "employee") {
                    d3.select(this).select('circle').transition().duration(300)
                    .attr("r", 15)
                }
            });

            node.on("mouseout", function(d) {
                if (d.entity == "company") {
                    d3.select(this).select('text').transition().duration(300).text(
                    function(d) {
                        return d.name;
                    }).style("font-size", "10px")
                } else if (d.entity == "employee") {
                    ///////////////////////////
                    // CHANGE
                    ///////////////////////////

                    d3.select(this).selectAll('text').remove();

                    //d3.select(this).select('text')
                    d3.select(this).append('text').text(function(d) {
                        return d.name;
                    }).style("font-size", "14px").attr("dx", 0).attr("dy", ".35em")
                    .attr("text-anchor", "middle").style("fill", "white")
                    .attr("class", "nodetext").transition().duration(300)
                    .style("font-size", "10px")

                } else {
                    d3.select(this).select('text').transition().duration(300)
                    .style("font-size", "10px")
                }

                if (d.entity == "company") {
                    d3.select(this).select('image').attr("width", "70px").attr("x",
                    "-36px").attr("y", "-36px").attr("xlink:href",
                    function(d) {
                        return d.img_hrefD
                    });
                }

                if (d.entity == "company" || d.entity == "employee") {

                    d3.select(this).select('circle').transition().duration(300)
                    .attr("r", 18)
                }

            });

            node.on("mouseover", fade(.4, "red")).on("mouseout", fade(1));

            var linkedByIndex = {};
            data.links.forEach(function(d) {
                linkedByIndex[d.source.index + "," + d.target.index] = 1;
            });

            function isConnected(a, b) {
                return linkedByIndex[a.index + "," + b.index]
                    || linkedByIndex[b.index + "," + a.index]
                    || a.index == b.index;
            }

            force.on("tick", function() {
                link.attr("x1", function(d) {
                    return d.source.x;
                }).attr("y1", function(d) {
                    return d.source.y;
                }).attr("x2", function(d) {
                    return d.target.x;
                }).attr("y2", function(d) {
                    return d.target.y;
                });

                node.attr("transform", function(d) {
                    return "translate(" + d.x + "," + d.y + ")";
                });
            });


            function getConnected(cn, d, level) {
                node.each(function(o) {
                    if(isConnected(d, o) && cn.indexOf(o) == -1) {
                        cn.push(o);
                        if(level > 0) getConnected(cn, o, level-1);
                    };
                });

                return cn;
            }





            function fade(opacity,color) {
                return function(d) {

                    node.style("stroke-opacity", function(o) {
                        thisOpacity = isConnected(d, o) ? 1 : opacity;
                        this.setAttribute('fill-opacity', thisOpacity);
                        return thisOpacity;
                    });

                    link.style("stroke-opacity", function(o) {
                        return o.source === d || o.target === d ? 1 : opacity;
                    })

                    .style("stroke", function(o) {
                        return o.source === d || o.target === d ? color : "#000" ;
                    });
                };

            }
        });
    </script>

sample data here

{"nodes":[{"name":"9748108991","type":1,"slug":"","entity":"company"},{"name":"offnet","type":2,"slug":"","entity":"employee"},{"name":"onnet","type":2,"slug":"","entity":"employee"}],"links":[{"source":0,"target":1,"value":1,"distance":10},{"source":0,"target":2,"value":1,"distance":10}]}

Upvotes: 2

Views: 1105

Answers (2)

Andreas
Andreas

Reputation: 1160

I realized that what you want to do is to just reload all the data so here is what I 've done in this fiddle

  • I have put the d3.json in another function so that I can call it whenever I want to.

Now whenever I want other data:

  • I use d3.select('svg').remove(); in order to remove the original svg
  • I call the function that includes the d3.json to visualise the new data

EDIT

For doing it in intervals you can use set timeout as per my example fiddle here: Your function the function that includes the d3.json code can recursively call it self in this manner:

 T =setTimeout(function(){
    d3.select('svg').remove();
    testing(["http://csmonk.com/data1.php","http://csmonk.com/data2.php"], ++count);
 },2000);

to clarify in your case you will do:

    var T;// (globally)

in your <myd3jsonfunctionhere> function add:

    T =setTimeout(function() {
         d3.select('svg').remove();<myd3jsonfunctionhere>;
         },<myintervalhereinms>);

More efficient(Best choice in my opinion):

 window.setInterval(function(){d3.select('svg').remove();<yourd3.jsonfunctionhere>},<intervalinmilliseconds>);

Fiddle

for the last example your code should be something like:

</script>
    var w = 1200, h = 900, radius = d3.scale.log().domain([0,312000 ])
    .range([ "10", "50" ]);
function loadNewData(){
    var vis = d3.select("body").append("svg:svg").attr("width", w).attr(
    "height", h);

    vis.append("marker")
    .attr("id", "arrowhead")
    .attr("refX", 6 + 6) /*must be smarter way to calculate shift*/
    .attr("refY", 2)
    .attr("markerWidth", 6)
    .attr("markerHeight", 4)
    .attr("orient", "auto")
    .append("path")
    .attr("d", "M 0,0 V 4 L6,2 Z"); //this is actual shape for arrowhead

    d3.json("LinkServlet", function(data,error) {
        var force = self.force = d3.layout.force().nodes(data.nodes).links(
        data.links).linkDistance(function(d) {
            return (d.distance * 10);
        })
        //.friction(0.5)
        .charge(-250).size([ w, h ]).start();

        var link = vis.selectAll("line.link").data(data.links).enter().append(
        "svg:line").attr("class", function(d) {
            return "link" + d.value + "";
        }).attr("x1", function(d) {
            return d.source.x;
        }).attr("y1", function(d) {
            return d.source.y;
        }).attr("x2", function(d) {
            return d.target.x;
        }).attr("y2", function(d) {
            return d.target.y;
        }).attr("marker-end", function(d) {
            if (d.value == 10 || d.value==1) {
                return "url(#arrowhead)"
            } else {
                return " "

       }
            ;
        });

        function openLink() {
            return function(d) {
                var url = "";
                if (d.slug != "") {
                    url = d.slug
                } else if(d.type == 2) {
                    url = "clients/" + d.slug
                } else if(d.type == 3) {
                    url = "agencies/" + d.slug
                }
                window.open("//" + url)
            }
        }

        var node = vis.selectAll("g.node").data(data.nodes).enter().append(
        "svg:g").attr("class", "node").call(force.drag);


        // size of the nodes are given here
        node.append("circle").attr("class", function(d) {
            return "node type" + d.type
        }).attr("r", function(d) {
            if (d.entity == "description") {
                return 20
            } else if(d.entity=="big"){
                return 25
            }else if(d.entity=="small"){
                return 15
            }else if(d.entity=="company"){
                return 25
            }else if(d.entity=="manager"){
                return 30
            }else if(d.entity=="ceo"){
                return 35
            }else{
                return 18
            }
        })


        node.append("text").attr("class", function(d) {
            return "nodetext title_" + d.name
        }).attr("dx", 0).attr("dy", ".35em").style("font-size", "10px").attr(
        "text-anchor", "middle").style("fill", "black").text(
        function(d) {                
            return d.name                
        });

        node.on("mouseover", function(d) {
            if (d.entity == "description") {
                d3.select(this).select('text').transition().duration(300).text(
                function(d) {
                    return d.name;
                }).style("font-size", "15px")

            } else if (d.entity == "employee") {
                var asdf = d3.select(this);
                asdf.select('text').remove();

                asdf.append("text").text(function(d) {
                    return d.prefix + ' ' + d.fst_name
                }).attr("class", "nodetext").attr("dx", 0).attr("dy", ".35em")
                .style("font-size", "5px")
                .attr("text-anchor", "middle").style("fill", "white")
                .transition().duration(300).style("font-size", "12px");

                asdf.append("text").text(function(d) {
                    return d.snd_name
                }).attr("class", "nodetext").attr("transform",
                "translate(0, 12)").attr("dx", 0).attr("dy", ".35em")
                .style("font-size", "5px")
                .attr("text-anchor", "middle").style("fill", "white")
                .transition().duration(300).style("font-size", "12px");
            } else {
                d3.select(this).select('text').transition().duration(300)
                .style("font-size", "15px")
            }

            if (d.entity == "company") {
                d3.select(this).select('image').attr("width", "100px").attr("x",
                "-46px").attr("y", "-36.5px").attr("xlink:href",
                function(d) {
                    return d.name
                });
            }

            if (d.entity == "company") {

                d3.select(this).select('circle').transition().duration(300)
                .attr("r", 28)

            } else if (d.entity == "employee") {
                d3.select(this).select('circle').transition().duration(300)
                .attr("r", 15)
            }
        });

        node.on("mouseout", function(d) {
            if (d.entity == "company") {
                d3.select(this).select('text').transition().duration(300).text(
                function(d) {
                    return d.name;
                }).style("font-size", "10px")
            } else if (d.entity == "employee") {
                ///////////////////////////
                // CHANGE
                ///////////////////////////

                d3.select(this).selectAll('text').remove();

                //d3.select(this).select('text')
                d3.select(this).append('text').text(function(d) {
                    return d.name;
                }).style("font-size", "14px").attr("dx", 0).attr("dy", ".35em")
                .attr("text-anchor", "middle").style("fill", "white")
                .attr("class", "nodetext").transition().duration(300)
                .style("font-size", "10px")

            } else {
                d3.select(this).select('text').transition().duration(300)
                .style("font-size", "10px")
            }

            if (d.entity == "company") {
                d3.select(this).select('image').attr("width", "70px").attr("x",
                "-36px").attr("y", "-36px").attr("xlink:href",
                function(d) {
                    return d.img_hrefD
                });
            }

            if (d.entity == "company" || d.entity == "employee") {

                d3.select(this).select('circle').transition().duration(300)
                .attr("r", 18)
            }

        });

        node.on("mouseover", fade(.4, "red")).on("mouseout", fade(1));

        var linkedByIndex = {};
        data.links.forEach(function(d) {
            linkedByIndex[d.source.index + "," + d.target.index] = 1;
        });

        function isConnected(a, b) {
            return linkedByIndex[a.index + "," + b.index]
                || linkedByIndex[b.index + "," + a.index]
                || a.index == b.index;
        }

        force.on("tick", function() {
            link.attr("x1", function(d) {
                return d.source.x;
            }).attr("y1", function(d) {
                return d.source.y;
            }).attr("x2", function(d) {
                return d.target.x;
            }).attr("y2", function(d) {
                return d.target.y;
            });

            node.attr("transform", function(d) {
                return "translate(" + d.x + "," + d.y + ")";
            });
        });


        function getConnected(cn, d, level) {
            node.each(function(o) {
                if(isConnected(d, o) && cn.indexOf(o) == -1) {
                    cn.push(o);
                    if(level > 0) getConnected(cn, o, level-1);
                };
            });

            return cn;
        }





        function fade(opacity,color) {
            return function(d) {

                node.style("stroke-opacity", function(o) {
                    thisOpacity = isConnected(d, o) ? 1 : opacity;
                    this.setAttribute('fill-opacity', thisOpacity);
                    return thisOpacity;
                });

                link.style("stroke-opacity", function(o) {
                    return o.source === d || o.target === d ? 1 : opacity;
                })

                .style("stroke", function(o) {
                    return o.source === d || o.target === d ? color : "#000" ;
                });
            };

        }
    });
 }
 loadNewData();
 window.setInterval(function(){d3.select('svg').remove();loadNewData()},5000);
</script>

Upvotes: 2

Andreas
Andreas

Reputation: 1160

The button could trigger some JavaScript without refreshing the page if you want to filter your data you can take a look into crossfilter or use a library that leverages it like dc.js

Upvotes: 0

Related Questions