import Ember from 'ember'; import Util from 'ui/utils/util'; import ThrottledResize from 'ui/mixins/throttled-resize'; import { activeIcon } from 'ui/models/service'; import C from 'ui/utils/constants'; export default Ember.View.extend(ThrottledResize,{ classNames: ['environment-graph'], graphZoom: null, graphInner: null, graphOuter: null, graphRender: null, graph: null, didInsertElement: function() { this._super(); var elem = $('
').appendTo('BODY'); this.set('graphElem', elem[0]); Ember.run.later(this,'initGraph',100); }, click: function(evt) { if ($(evt.target).hasClass('icon-x')) { this.styleSvg(); } }, onResize: function() { $('#environment-svg').css('top', $('MAIN').position().top + 55 + 'px'); $('#environment-svg').css('bottom', $('FOOTER').outerHeight() + 'px'); if ( this.get('graph') ) { this.renderGraph(); } }, initGraph: function() { var outer = d3.select("#environment-svg svg"); // SVG must be lowercase! This is case sensitive in not-Chrome var inner = outer.select("g"); var zoom = d3.behavior.zoom().on("zoom", function() { inner.attr("transform", "translate(" + d3.event.translate + ")" + "scale(" + d3.event.scale + ")"); }); outer.call(zoom); var g = new dagreD3.graphlib.Graph().setGraph({ rankdir: "TB", nodesep: 50, ranksep: 50, marginx: 30, marginy: 30 }); var render = new dagreD3.render(); this.setProperties({ graphZoom: zoom, graphOuter: outer, graphInner: inner, graphRender: render, graph: g }); this.updateGraph(); $(outer[0]).on('click', (event) => { if ( this._state === 'destroying' ) { return; } var fo = $(event.target).closest('foreignObject'); if ( fo ) { if ( this.get('currentFO') ) { this.get('currentFO').find('>div').removeClass('highlighted'); this.set('prevFO', this.get('currentFO')); this.set('currentFO', fo); fo.find('>div').addClass('highlighted'); } else { this.set('currentFO', fo); fo.find('>div').addClass('highlighted'); } var serviceId = $('span[data-service]', fo).data('service'); if ( serviceId ) { this.showService(serviceId); return; } } this.showService(null); this.setProperties({ currentFO: null, prevFO: null, }); }); }, styleSvg: function(height='100%') { $('#environment-svg svg').css('height', height); }, showService: function(id) { let svgHeight; if ( id ) { svgHeight = $('#environment-svg').height() - 260; // svg minus the height of info service-addtl-info.scss this.styleSvg(`${svgHeight}px`); if (!this.get('context.showServiceInfo')) { this.zoomAndScale(1.5); } this.set('context.showServiceInfo', true); this.set('context.selectedService', this.get('context.stack.services').findBy('id', id)); } else { svgHeight = $('#environment-svg').height() - 0; // svg minus the height of info service-addtl-info.scss this.styleSvg(svgHeight); if (this.get('context.showServiceInfo')) { this.zoomAndScale(2); } this.set('context.showServiceInfo', null); } }, crosslinkServices: function() { // Add services that are cross-linked from another environment var out = []; var unremovedServices = this.get('context.stack.services').filter(function(service) { return C.REMOVEDISH_STATES.indexOf(service.get('state')) === -1; }); unremovedServices.forEach((service) => { var externals = (service.get('consumedServicesWithNames')||[]).filter((linked) => { return linked.get('service.environmentId') !== this.get('context.stack.id'); }).map((linked) => { return linked.get('service'); }); out.pushObjects(externals); }); return out; }.property('context.stack.services.@each.consumedServicesUpdated'), updateGraph: function() { var g = this.get('graph'); var services = this.get('context.stack.services'); var unremovedServices = services.filter(function(service) { return ['removed','purging','purged'].indexOf(service.get('state')) === -1; }); var unexpectedNodes = g.nodes(); var unexpectedEdges = g.edges(); var expectedServices = unremovedServices.slice(); expectedServices.pushObjects(this.get('crosslinkServices')); expectedServices.forEach((service) => { var serviceId = service.get('id'); var instances = service.get('instances.length')||'No'; var color = service.get('stateColor').replace('text-',''); var isCrossLink = service.get('environmentId') !== this.get('context.stack.id'); var envName = ''; if ( isCrossLink ) { envName = service.get('displayEnvironment') + '/'; } var html = `