summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGeorgios Andreadis <g.andreadis@student.tudelft.nl>2017-09-21 19:15:08 +0200
committerGeorgios Andreadis <g.andreadis@student.tudelft.nl>2017-09-23 10:06:05 +0200
commitd2fe45aaa1b265c0caad7e83b16f6f2adbcd4c27 (patch)
treea6332d2335f4c769bc38f3eebfb916a2a816337d /src
parent4272111ce7da4293bff7d11cf08e172651e7b3b1 (diff)
Add tool panel to lower left map corner
Diffstat (limited to 'src')
-rw-r--r--src/components/map/MapConstants.js1
-rw-r--r--src/components/map/MapStageComponent.js7
-rw-r--r--src/components/map/controls/ExportCanvasComponent.js13
-rw-r--r--src/components/map/controls/ScaleIndicatorComponent.js14
-rw-r--r--src/components/map/controls/ScaleIndicatorComponent.sass9
-rw-r--r--src/components/map/controls/ToolPanelComponent.js13
-rw-r--r--src/components/map/controls/ToolPanelComponent.sass5
-rw-r--r--src/components/map/controls/ZoomControlComponent.js31
-rw-r--r--src/containers/map/controls/ScaleIndicatorContainer.js14
-rw-r--r--src/containers/map/controls/ZoomControlContainer.js22
-rw-r--r--src/index.sass3
-rw-r--r--src/pages/App.js4
12 files changed, 136 insertions, 0 deletions
diff --git a/src/components/map/MapConstants.js b/src/components/map/MapConstants.js
index 524dd1ae..a0166d15 100644
--- a/src/components/map/MapConstants.js
+++ b/src/components/map/MapConstants.js
@@ -1,5 +1,6 @@
export const MAP_SIZE = 50;
export const TILE_SIZE_IN_PIXELS = 100;
+export const TILE_SIZE_IN_METERS = 0.5;
export const MAP_SIZE_IN_PIXELS = MAP_SIZE * TILE_SIZE_IN_PIXELS;
export const OBJECT_MARGIN_IN_PIXELS = TILE_SIZE_IN_PIXELS / 5;
diff --git a/src/components/map/MapStageComponent.js b/src/components/map/MapStageComponent.js
index 62d8687c..d3c75da0 100644
--- a/src/components/map/MapStageComponent.js
+++ b/src/components/map/MapStageComponent.js
@@ -34,6 +34,13 @@ class MapStageComponent extends React.Component {
componentDidMount() {
window.addEventListener("resize", this.updateDimensions);
window.addEventListener("wheel", this.updateScale);
+
+ window["exportCanvasToImage"] = () => {
+ const canvasData = this.stage.getStage().toDataURL();
+ const newWindow = window.open('about:blank', 'OpenDC Canvas Export');
+ newWindow.document.write("<img src='" + canvasData + "' alt='Canvas Image Export'/>");
+ newWindow.document.title = "OpenDC Canvas Export";
+ }
}
componentWillUnmount() {
diff --git a/src/components/map/controls/ExportCanvasComponent.js b/src/components/map/controls/ExportCanvasComponent.js
new file mode 100644
index 00000000..2f044ffe
--- /dev/null
+++ b/src/components/map/controls/ExportCanvasComponent.js
@@ -0,0 +1,13 @@
+import React from "react";
+
+const ExportCanvasComponent = () => (
+ <button
+ className="btn btn-success btn-circle btn-sm"
+ title="Export Canvas to PNG Image"
+ onClick={() => window["exportCanvasToImage"]()}
+ >
+ <span className="fa fa-camera"/>
+ </button>
+);
+
+export default ExportCanvasComponent;
diff --git a/src/components/map/controls/ScaleIndicatorComponent.js b/src/components/map/controls/ScaleIndicatorComponent.js
new file mode 100644
index 00000000..fd9483b5
--- /dev/null
+++ b/src/components/map/controls/ScaleIndicatorComponent.js
@@ -0,0 +1,14 @@
+import React from "react";
+import {TILE_SIZE_IN_METERS, TILE_SIZE_IN_PIXELS} from "../MapConstants";
+import "./ScaleIndicatorComponent.css";
+
+const ScaleIndicatorComponent = ({scale}) => (
+ <div
+ className="scale-indicator"
+ style={{width: TILE_SIZE_IN_PIXELS * scale}}
+ >
+ {TILE_SIZE_IN_METERS}m
+ </div>
+);
+
+export default ScaleIndicatorComponent;
diff --git a/src/components/map/controls/ScaleIndicatorComponent.sass b/src/components/map/controls/ScaleIndicatorComponent.sass
new file mode 100644
index 00000000..f2d2b55b
--- /dev/null
+++ b/src/components/map/controls/ScaleIndicatorComponent.sass
@@ -0,0 +1,9 @@
+.scale-indicator
+ position: absolute
+ right: 10px
+ bottom: 10px
+ z-index: 50
+
+ border: solid 2px #212529
+ border-top: none
+ border-left: none
diff --git a/src/components/map/controls/ToolPanelComponent.js b/src/components/map/controls/ToolPanelComponent.js
new file mode 100644
index 00000000..19e9f0d9
--- /dev/null
+++ b/src/components/map/controls/ToolPanelComponent.js
@@ -0,0 +1,13 @@
+import React from "react";
+import ZoomControlContainer from "../../../containers/map/controls/ZoomControlContainer";
+import ExportCanvasComponent from "./ExportCanvasComponent";
+import "./ToolPanelComponent.css";
+
+const ToolPanelComponent = () => (
+ <div className="tool-panel">
+ <ZoomControlContainer/>
+ <ExportCanvasComponent/>
+ </div>
+);
+
+export default ToolPanelComponent;
diff --git a/src/components/map/controls/ToolPanelComponent.sass b/src/components/map/controls/ToolPanelComponent.sass
new file mode 100644
index 00000000..996712b3
--- /dev/null
+++ b/src/components/map/controls/ToolPanelComponent.sass
@@ -0,0 +1,5 @@
+.tool-panel
+ position: absolute
+ left: 10px
+ bottom: 10px
+ z-index: 50
diff --git a/src/components/map/controls/ZoomControlComponent.js b/src/components/map/controls/ZoomControlComponent.js
new file mode 100644
index 00000000..c5628d16
--- /dev/null
+++ b/src/components/map/controls/ZoomControlComponent.js
@@ -0,0 +1,31 @@
+import React from "react";
+import {MAP_MAX_SCALE, MAP_MIN_SCALE, MAP_SCALE_PER_EVENT} from "../MapConstants";
+
+const ZoomControlComponent = ({mapScale, setMapScale}) => {
+ const zoom = (out) => {
+ const newScale = out ? mapScale / MAP_SCALE_PER_EVENT : mapScale * MAP_SCALE_PER_EVENT;
+ const boundedScale = Math.min(Math.max(MAP_MIN_SCALE, newScale), MAP_MAX_SCALE);
+ setMapScale(boundedScale);
+ };
+
+ return (
+ <span>
+ <button
+ className="btn btn-default btn-circle btn-sm mr-1"
+ title="Zoom in"
+ onClick={() => zoom(false)}
+ >
+ <span className="fa fa-plus"/>
+ </button>
+ <button
+ className="btn btn-default btn-circle btn-sm mr-1"
+ title="Zoom out"
+ onClick={() => zoom(true)}
+ >
+ <span className="fa fa-minus"/>
+ </button>
+ </span>
+ );
+};
+
+export default ZoomControlComponent;
diff --git a/src/containers/map/controls/ScaleIndicatorContainer.js b/src/containers/map/controls/ScaleIndicatorContainer.js
new file mode 100644
index 00000000..06cc96f5
--- /dev/null
+++ b/src/containers/map/controls/ScaleIndicatorContainer.js
@@ -0,0 +1,14 @@
+import {connect} from "react-redux";
+import ScaleIndicatorComponent from "../../../components/map/controls/ScaleIndicatorComponent";
+
+const mapStateToProps = state => {
+ return {
+ scale: state.map.scale,
+ };
+};
+
+const ScaleIndicatorContainer = connect(
+ mapStateToProps
+)(ScaleIndicatorComponent);
+
+export default ScaleIndicatorContainer;
diff --git a/src/containers/map/controls/ZoomControlContainer.js b/src/containers/map/controls/ZoomControlContainer.js
new file mode 100644
index 00000000..280ede4f
--- /dev/null
+++ b/src/containers/map/controls/ZoomControlContainer.js
@@ -0,0 +1,22 @@
+import {connect} from "react-redux";
+import {setMapScale} from "../../../actions/map";
+import ZoomControlComponent from "../../../components/map/controls/ZoomControlComponent";
+
+const mapStateToProps = state => {
+ return {
+ mapScale: state.map.scale,
+ };
+};
+
+const mapDispatchToProps = dispatch => {
+ return {
+ setMapScale: scale => dispatch(setMapScale(scale)),
+ };
+};
+
+const ZoomControlContainer = connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(ZoomControlComponent);
+
+export default ZoomControlContainer;
diff --git a/src/index.sass b/src/index.sass
index 09be977d..248987ab 100644
--- a/src/index.sass
+++ b/src/index.sass
@@ -32,5 +32,8 @@ html, body, #root
.btn, .list-group-item-action
+clickable
+.btn-circle
+ +border-radius(50%)
+
a, a:hover
text-decoration: none
diff --git a/src/pages/App.js b/src/pages/App.js
index 26ded58c..8e74bfa5 100644
--- a/src/pages/App.js
+++ b/src/pages/App.js
@@ -5,9 +5,11 @@ import {ShortcutManager} from "react-shortcuts";
import {openExperimentSucceeded} from "../actions/experiments";
import {openSimulationSucceeded} from "../actions/simulations";
import {resetCurrentDatacenter} from "../actions/topology/building";
+import ToolPanelComponent from "../components/map/controls/ToolPanelComponent";
import LoadingScreen from "../components/map/LoadingScreen";
import AppNavbar from "../components/navigation/AppNavbar";
import SimulationSidebarComponent from "../components/sidebars/simulation/SimulationSidebarComponent";
+import ScaleIndicatorContainer from "../containers/map/controls/ScaleIndicatorContainer";
import MapStage from "../containers/map/MapStage";
import DeleteMachineModal from "../containers/modals/DeleteMachineModal";
import DeleteRackModal from "../containers/modals/DeleteRackModal";
@@ -55,6 +57,8 @@ class AppComponent extends React.Component {
</div> :
<div className="full-height">
<MapStage/>
+ <ScaleIndicatorContainer/>
+ <ToolPanelComponent/>
<TopologySidebar/>
{this.props.inSimulation ?
<TimelineContainer/> :