/** * * HeatTop JS Framework * Dependencies: jQuery 1.7.1 or later, d3 v3 or later * Date: June 2013 * Description: JS Framework that subclasses the D3 Force Directed Graph library to create * Heat-specific objects and relationships with the purpose of displaying * Stacks, Resources, and related Properties in a Resource Topology Graph. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ var container = "#heat_resource_topology"; if ($(container).length){ var width = $(container).width(), height = 500, stack_id = $("#stack_id").data("stack_id"), ajax_url = '/project/stacks/get_d3_data/'+stack_id+'/', graph = $("#d3_data").data("d3_data"), force = d3.layout.force() .nodes(graph.nodes) .links([]) .gravity(0.1) .charge(-2000) .linkDistance(100) .size([width, height]) .on("tick",tick), svg = d3.select(container).append("svg") .attr("width", width) .attr("height", height), node = svg.selectAll(".node"), link = svg.selectAll(".link"), needs_update = false, nodes = force.nodes(), links = force.links(); build_links(); update(); function update(){ node = node.data(nodes, function(d){return d.name}); link = link.data(links); var nodeEnter = node.enter().append("g") .attr("class", "node") .attr("node_name", function(d){ return d.name }) .attr("node_id", function(d){ return d.instance }) .call(force.drag); nodeEnter.append("image") .attr("xlink:href", function(d) { return d.image; }) .attr("id", function(d){return "image_"+ d.name}) .attr("x", function(d) { return d.image_x; }) .attr("y", function(d) { return d.image_y; }) .attr("width", function(d) { return d.image_size; }) .attr("height", function(d) { return d.image_size; }); node.exit().remove(); link.enter().insert("svg:line", "g.node") .attr("class", "link") .style("stroke-width", function(d) { return Math.sqrt(d.value); }); link.exit().remove(); //Setup click action for all nodes node.on("mouseover", function(d) { $("#info_box").html(d.info_box); current_info = d.name; }); node.on("mouseout", function(d) { $("#info_box").html(''); }); force.start(); } function tick() { 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 + ")"; }); } //Load initial Stack box $("#stack_box").html(graph.stack.info_box); //On Page load, set Action In Progress var in_progress = false; set_in_progress(graph.stack, node); //If status is In Progress, start AJAX polling var poll_time = 0; if (in_progress == true){poll_time = 3000;} else {poll_time = 30000;} ajax_poll(poll_time); function set_in_progress(stack, nodes) { if (stack.in_progress == true){in_progress = true;} for (var i=0;i