--- /dev/null
+
+/*
+ *
+ * Copyright 2016 RIFT.IO Inc
+ *
+ * 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.
+ *
+ */
+/**
+ * Created by onvelocity on 8/24/15.
+ */
+'use strict';
+
+import _ from 'lodash'
+import d3 from 'd3'
+import math from './math'
+import ClassNames from 'classnames'
+import ColorGroups from '../ColorGroups'
+import DescriptorModel from './../model/DescriptorModel'
+import DescriptorModelFactory from './../model/DescriptorModelFactory'
+import DescriptorGraphSelection from './DescriptorGraphSelection'
+import DescriptorGraphEdgeBuilder from './DescriptorGraphPathBuilder'
+import CatalogItemsActions from '../../actions/CatalogItemsActions'
+import DescriptorGraphGrid from './DescriptorGraphGrid'
+import SelectionManager from './../SelectionManager'
+import GraphConnectionPointNumber from './GraphConnectionPointNumber'
+import RelationsAndNetworksLayout from './layouts/RelationsAndNetworksLayout'
+
+const defaults = {
+ width: 1000,
+ height: 500,
+ padding: 10,
+ snapTo: 15,
+ zoom: 100,
+ connectionPointSize: 135
+};
+
+export default class DescriptorGraph {
+
+ constructor(element, props) {
+
+ this.element = element;
+ this.props = Object.assign({}, props, defaults);
+ this.layouts = [RelationsAndNetworksLayout];
+ this.containers = [];
+ this.showMoreInfo = false;
+ this.scale = 1;
+
+ if (!element) {
+ throw new ReferenceError('An HTML DOM element is required to render DescriptorGraph.');
+ }
+
+ this.svg = d3.select(element).append('svg')
+ .attr('class', 'DescriptorGraph')
+ .attr('width', this.props.width)
+ .attr('height', this.props.height)
+ .attr('data-offset-parent', true);
+
+ this.g = this.svg.append('g')
+ .attr('class', 'viewport');
+
+ // set the scale of everything
+ this.zoom(this.props.zoom || defaults.zoom);
+
+ this.defs = this.svg.append('defs');
+ this.grid = this.g.append('g').classed('grid', true);
+ this.paths = this.g.append('g').classed('paths', true);
+ this.connectorsGroup = this.g.append('g').classed('connectors', true);
+ this.containersGroup = this.g.append('g').classed('containers', true);
+ this.cpNumbers = this.g.append('g').classed('connection-point-numbers', true);
+ this.forwardingGraphPaths = this.g.append('g').classed('forwarding-graph-paths', true);
+ this.selectionOutlineGroup = this.g.append('g').attr('data-outline-indicator', true);
+
+ this.defs.append('marker')
+ .attr({
+ id: 'relation-marker-end',
+ 'markerWidth': 30,
+ 'markerHeight': 30,
+ 'orient': '0',
+ //markerUnits: 'userSpaceOnUse'
+ viewBox: '-15 -15 30 30'
+ })
+ .append('path')
+ .attr({
+ d: d3.svg.symbol().type('circle'),
+ 'class': 'relation-marker-end'
+ });
+
+ this.update();
+
+ }
+
+ zoom(zoom) {
+ const scale = zoom / 100;
+ if (this.scale !== scale) {
+ this.scale = scale;
+ const transform = 'scale(' + this.scale + ')';
+ requestAnimationFrame(() => {
+ this.g.attr('transform', transform);
+ });
+ }
+ }
+
+ get containerPositionMap() {
+ if (this.containers[0].uiState.containerPositionMap) {
+ return this.containers[0].uiState.containerPositionMap;
+ } else {
+ return this.containers[0].uiState.containerPositionMap = {};
+ }
+ }
+
+ lookupSavedContainerPosition(container) {
+ return this.containerPositionMap[container.key];
+ }
+
+ saveContainerPosition(container) {
+ this.containerPositionMap[container.key] = container.position.value();
+ }
+
+ update() {
+
+ const graph = this;
+
+ const filterContainers = d => (graph.showMoreInfo ? true : d.type !== 'vdu');
+ const containers = this.containers.filter(filterContainers);
+ const layouts = graph.layouts.map(layoutFactory => layoutFactory.bind(this)());
+
+ function runLayout(i) {
+ const layout = layouts[i];
+ if (layout) {
+ layout.addContainers(containers);
+ layout.render(graph, runLayout.bind(null, i + 1));
+ }
+ }
+ runLayout(0);
+
+ const selection = new DescriptorGraphSelection(graph);
+ selection.addContainers(containers);
+ selection.render();
+
+ const edgeBuilder = new DescriptorGraphEdgeBuilder(graph);
+ edgeBuilder.addContainers(containers);
+ edgeBuilder.render();
+
+ const grid = new DescriptorGraphGrid(graph, {size: defaults.snapTo, padding: defaults.padding});
+ grid.render();
+
+ }
+
+ destroy() {
+ if (this.svg) {
+ this.svg.remove();
+ delete this.svg;
+ }
+ }
+
+}