/** * Copyright (c) 2006-2013, JGraph Ltd * * Google maps (Adding a Custom Overlay) * * This example demonstrates using * a graph container as a Google Maps overlay. */ import React from 'react'; import mxEvent from '../mxgraph/util/mxEvent'; import mxGraph from '../mxgraph/view/mxGraph'; import mxRubberband from '../mxgraph/handler/mxRubberband'; HTML_TEMPLATE = `
` // Keeps the font sizes independent of the scale mxCellRenderer.prototype.getTextScale = function(state) { return 1; }; // This example creates a custom overlay called mxGraphOverlay, containing // a mxGraph container. // Set the custom overlay object's prototype to a new instance // of OverlayView. In effect, this will subclass the overlay class. // Note that we set the prototype to an instance, rather than the // parent class itself, because we do not wish to modify the parent class. var overlay; mxGraphOverlay.prototype = new google.maps.OverlayView(); // Initialize the map and the custom overlay. function initialize() { let mapOptions = { zoom: 4, center: new google.maps.LatLng(34, -96), mapTypeId: google.maps.MapTypeId.ROADMAP, styles: [ {featureType: "road", stylers: [{visibility: "off"}]}, {"elementType": "labels", "stylers": [{"visibility": "off" }]} ], }; let map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions); let swBound = new google.maps.LatLng(18, -126); let neBound = new google.maps.LatLng(50, -65); let bounds = new google.maps.LatLngBounds(swBound, neBound); // The custom mxGraphOverlay object contains the graph, // the bounds of the graph, and a reference to the map. overlay = new mxGraphOverlay(bounds, map); } function mxGraphOverlay(bounds, map) { // Initialize all properties. this.bounds_ = bounds; this.map_ = map; // Define a property to hold the graph's div. We'll // actually create this div upon receipt of the onAdd() // method so we'll leave it null for now. this.div_ = null; // Explicitly call setMap on this overlay. this.setMap(map); } /** * onAdd is called when the map's panes are ready and the overlay has been * added to the map. */ mxGraphOverlay.prototype.onAdd = function() { let div = document.createElement('div'); div.style.borderStyle = 'none'; div.style.borderWidth = '0px'; div.style.overflow = 'visible'; div.style.position = 'absolute'; // Allows labels to be rendered outside the container Client.NO_FO = true; // Creates the graph inside the given container let graph = new mxGraph(div); graph.setHtmlLabels(true); graph.view.setTranslate(4, 4); // Sets default vertex style let style = {}; style.shape = mxConstants.SHAPE_ELLIPSE; style.perimiter = mxPerimeter.EllipsePerimeter; style.fillColor = '#8CCDF5'; style.strokeColor = '#1B78C8'; style.fontColor = '#000000'; style.opacity = '50'; style.fontSize = '16'; graph.getStylesheet().putDefaultVertexStyle(style); // Gets label from custom user object graph.convertValueToString = function(cell) { return (cell.value != null && cell.value.label != null) ? cell.value.label : mxGraph.prototype.convertValueToString.apply(this, arguments); }; // Implements level of detail graph.isCellVisible = function(cell) { return (cell.value != null && cell.value.minScale != null) ? cell.value.minScale <= this.view.scale : mxGraph.prototype.isCellVisible.apply(this, arguments); }; // Enables rubberband selection new mxRubberband(graph); // Gets the default parent for inserting new cells. This // is normally the first child of the root (ie. layer 0). let parent = graph.getDefaultParent(); // Adds cells to the model in a single step graph.getDataModel().beginUpdate(); try { var n1 = graph.insertVertex(parent, null, {label:'Seattle'}, 23, 23, 10, 10); var n2 = graph.insertVertex(parent, null, {label:'Sunnyvale'}, 25.76, 148.4, 10, 10); var n3 = graph.insertVertex(parent, null, {label:'Los Angeles'}, 59.8, 185.25, 10, 10); var n4 = graph.insertVertex(parent, null, {label:'Denver'}, 179.39, 121.25, 10, 10); var n5 = graph.insertVertex(parent, null, {label:'Kansas'}, 273.30, 128.63, 10, 10); var n6 = graph.insertVertex(parent, null, {label:'Houston'}, 266.36, 230.7, 10, 10); var n7 = graph.insertVertex(parent, null, {label:'Chicago'}, 336, 95.67, 10, 10); var n8 = graph.insertVertex(parent, null, {label:'Indianapolis'}, 349.38, 120.85, 10, 10); var n9 = graph.insertVertex(parent, null, {label:'Atlanta'}, 365.23, 188.51, 10, 10); var n10 = graph.insertVertex(parent, null, {label:'New York'}, 458.83, 109.61, 10, 10); var n11 = graph.insertVertex(parent, null, {label:'Washington'}, 432.93, 129.52, 10, 10); // This node and its connections are only visible for zoom 200% and above var n12 = graph.insertVertex(parent, null, {label:'Columbus', minScale:2}, 380, 120, 10, 10); let estyle = 'strokeWidth=2;endArrow=none;labelBackgroundColor=white;'; let e = [ graph.insertEdge(parent, null, '', n1, n2, estyle), graph.insertEdge(parent, null, '', n2, n3, estyle), graph.insertEdge(parent, null, '', n1, n4, estyle), graph.insertEdge(parent, null, '', n2, n4, estyle), graph.insertEdge(parent, null, '', n3, n6, estyle), graph.insertEdge(parent, null, '', n4, n5, estyle), graph.insertEdge(parent, null, '', n5, n6, estyle), graph.insertEdge(parent, null, '', n5, n8, estyle), graph.insertEdge(parent, null, '', n6, n9, estyle), graph.insertEdge(parent, null, '', n8, n7, estyle), graph.insertEdge(parent, null, '', n7, n10, estyle), graph.insertEdge(parent, null, '', n9, n11, estyle), graph.insertEdge(parent, null, '', n10, n11, estyle), graph.insertEdge(parent, null, '', n8, n9, estyle), graph.insertEdge(parent, null, '', n8, n12, estyle), graph.insertEdge(parent, null, '', n12, n11, estyle), ]; } finally { // Updates the display graph.getDataModel().endUpdate(); } // Writes some random numbers on the connections window.setInterval(function() { graph.getDataModel().beginUpdate(); try { for (let i = 0; i < e.length; i++) { let rnd = Math.random(); graph.getDataModel().setValue(e[i], Math.round(rnd * 100)); } } finally { graph.getDataModel().endUpdate(); } }, 1000); this.graph_ = graph; this.div_ = div; // Add the element to the "overlayLayer" pane. let panes = this.getPanes(); panes.overlayLayer.appendChild(div); }; mxGraphOverlay.prototype.draw = function() { // We use the south-west and north-east // coordinates of the overlay to peg it to the correct position and size. // To do this, we need to retrieve the projection from the overlay. let overlayProjection = this.getProjection(); // Retrieve the south-west and north-east coordinates of this overlay // in LatLngs and convert them to pixel coordinates. // We'll use these coordinates to resize the div. let sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest()); let ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast()); // Resize the graph's div to fit the indicated dimensions. let div = this.div_; div.style.left = sw.x + 'px'; div.style.top = ne.y + 'px'; let w = (ne.x - sw.x); let h = (sw.y - ne.y); div.style.width = w + 'px'; div.style.height = h + 'px'; // Sets the scale of the graph based on reference width this.graph_.view.setScale(w / 550); }; // The onRemove() method will be called automatically from the API if // we ever set the overlay's map property to 'null'. mxGraphOverlay.prototype.onRemove = function() { this.div_.parentNode.removeChild(this.div_); this.div_ = null; }; google.maps.event.addDomListener(window, 'load', initialize);