4 * Copyright 2016 RIFT.IO Inc
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 import React from 'react';
21 import DashboardCard from '../dashboard_card/dashboard_card.jsx';
23 export default class TopologyL2Graph extends React.Component {
26 this.data = props.data;
29 this.network_coding = {}
30 this.nodeEvent = props.nodeEvent || null;
35 this.force = d3.layout.force()
36 .size([this.props.width, this.props.height])
39 .on("tick", this.tick.bind(this));
41 this.drag = this.force.drag()
42 .on("dragstart", function(d) {
43 handler.dragstart(d, handler);
47 componentWillUnmount() {
48 d3.select('svg').remove();
50 componentWillReceiveProps(props) {
52 // NOTE: We may need to revisit how D3 accesses DOM elements
53 this.svg = d3.select(document.querySelector('#topologyL2')).append("svg")
54 .attr("width", this.props.width)
55 .attr("height", this.props.height)
56 .classed("topology", true);
59 if (props.data.links.length > 0) {
60 this.network_coding = this.create_group_coding(props.data.network_ids.sort());
61 this.update(props.data);
65 create_group_coding(group_ids) {
66 var group_coding = {};
67 group_ids.forEach(function(element, index, array) {
68 group_coding[element] = index+1;
72 getNetworkCoding(network_id) {
73 var group = this.network_coding[network_id];
74 if (group != undefined) {
82 // Hack to prevent multiple legends being displayed
83 this.svg.selectAll(".legend").remove();
87 var item_count = (graph.network_ids) ? graph.network_ids.length : 0;
97 pos.height += item_count * pos.item_height;
98 var legend_translate = "translate("+pos.anchorX+","+pos.anchorY+")";
100 var legend = svg.append("g")
101 .attr("class", "legend")
102 .attr("transform", legend_translate);
104 var legend_box = (showBox) ? legend.append("rect")
107 .attr("height", pos.height)
108 .attr("width", pos.width)
109 .style("stroke", "black")
110 .style("fill", "none") : null;
112 legend.append("text")
115 .text("Network color mapping:");
117 legend.selectAll("g").data(graph.network_ids)
120 .each(function(d, i) {
121 var colors = ["green", "orange", "red" ];
122 var g = d3.select(this);
123 var group_number = i+1;
124 g.attr('class', "node-group-" + group_number);
127 .attr("cx", pos.items_x + 3)
128 .attr("cy", pos.items_y + i * pos.item_height)
132 .attr("x", pos.items_x + 25)
133 .attr("y", pos.items_y + (i * pos.item_height + 4))
148 this.link = svg.selectAll(".link")
150 .enter().append("line")
151 .attr("class", "link");
153 this.gnodes = svg.selectAll('g.gnode')
157 .classed('gnode', true)
158 .attr('data-network', function(d) { return d.network; })
159 .attr('class', function(d) {
160 return d3.select(this).attr('class') + ' node-group-'+ handler.getNetworkCoding(d.network);
163 this.node = this.gnodes.append("circle")
164 .attr("class", "node")
165 .attr("r", this.props.radius)
166 .on("dblclick", function(d) {
167 handler.dblclick(d, handler)
170 .on('click', function(d) {
171 handler.click.call(this, d, handler)
173 var labels = this.gnodes.append("text")
174 .attr("text-anchor", "middle")
175 .attr("fill", "black")
176 .attr("font-size", "12")
178 .text(function(d) { return d.name; });
179 this.drawLegend(graph);
183 this.link.attr("x1", function(d) { return d.source.x; })
184 .attr("y1", function(d) { return d.source.y; })
185 .attr("x2", function(d) { return d.target.x; })
186 .attr("y2", function(d) { return d.target.y; });
188 this.gnodes.attr("transform", function(d) {
189 return 'translate(' + [d.x, d.y] + ')';
195 console.log("TopologyL2Graph.click called");
196 // 'This' is the svg circle element
197 var gnode = d3.select(this.parentNode);
199 topo.svg.selectAll("text").transition()
200 .duration(topo.props.nodeText.transitionTime)
201 .attr("font-size", topo.props.nodeText.size)
202 .attr("fill", topo.props.nodeText.color)
204 // Set focus node text properties
205 d3.select(this.parentNode).selectAll('text').transition()
206 .duration(topo.props.nodeText.transitionTime)
207 .attr("font-size", topo.props.nodeText.focus.size)
208 .attr("fill", topo.props.nodeText.focus.color);
210 // Perform detail view
211 topo.selectedID = d.id;
212 if (topo.nodeEvent) {
213 topo.nodeEvent(d.id);
215 // set record view as listener
219 this.d3.select(this).classed("fixed", d.fixed = false);
223 //d3.select(this).classed("fixed", d.fixed = true);
227 return ( <DashboardCard showHeader={true} title="Topology L2 Graph">
228 <div id="topologyL2"></div>
233 TopologyL2Graph.defaultProps = {