diff options
| author | Georgios Andreadis <g.andreadis@student.tudelft.nl> | 2017-09-22 08:48:38 +0200 |
|---|---|---|
| committer | Georgios Andreadis <g.andreadis@student.tudelft.nl> | 2017-09-23 10:06:06 +0200 |
| commit | 3bf073f46e74667df4d2be9488a9f8f44ac84421 (patch) | |
| tree | 75731c952d6965cf5075b03f504193936348780f | |
| parent | d6455f1c9e57934b76ce95b3fb204072300a1991 (diff) | |
Make timeline clickable
| -rw-r--r-- | src/actions/simulation/tick.js | 27 | ||||
| -rw-r--r-- | src/components/sidebars/topology/rack/BackToRoomComponent.js | 2 | ||||
| -rw-r--r-- | src/components/sidebars/topology/rack/RackSidebarComponent.js | 2 | ||||
| -rw-r--r-- | src/components/sidebars/topology/rack/RackSidebarComponent.sass | 3 | ||||
| -rw-r--r-- | src/components/sidebars/topology/room/BackToBuildingComponent.js | 2 | ||||
| -rw-r--r-- | src/components/sidebars/topology/room/RoomSidebarComponent.js | 2 | ||||
| -rw-r--r-- | src/components/timeline/TimelineComponent.js | 10 | ||||
| -rw-r--r-- | src/components/timeline/TimelineControlsComponent.js | 56 | ||||
| -rw-r--r-- | src/containers/timeline/TimelineContainer.js | 2 | ||||
| -rw-r--r-- | src/containers/timeline/TimelineControlsContainer.js | 10 | ||||
| -rw-r--r-- | src/store/middlewares/viewport-adjustment.js | 18 | ||||
| -rw-r--r-- | src/util/timeline.js | 19 |
12 files changed, 109 insertions, 44 deletions
diff --git a/src/actions/simulation/tick.js b/src/actions/simulation/tick.js index 68f226d7..06066662 100644 --- a/src/actions/simulation/tick.js +++ b/src/actions/simulation/tick.js @@ -1,3 +1,6 @@ +import {getDatacenterIdOfTick} from "../../util/timeline"; +import {setCurrentDatacenter} from "../topology/building"; + export const GO_TO_TICK = "GO_TO_TICK"; export const SET_LAST_SIMULATED_TICK = "SET_LAST_SIMULATED_TICK"; @@ -9,9 +12,27 @@ export function incrementTick() { } export function goToTick(tick) { - return { - type: GO_TO_TICK, - tick + return (dispatch, getState) => { + const state = getState(); + + let sections = []; + if (state.currentExperimentId !== -1) { + const sectionIds = state.objects.path[state.objects.experiment[state.currentExperimentId].pathId].sectionIds; + + if (sectionIds) { + sections = sectionIds.map(sectionId => state.objects.section[sectionId]); + } + } + + const newDatacenterId = getDatacenterIdOfTick(tick, sections); + if (state.currentDatacenterId !== newDatacenterId) { + dispatch(setCurrentDatacenter(newDatacenterId)); + } + + dispatch({ + type: GO_TO_TICK, + tick + }); } } diff --git a/src/components/sidebars/topology/rack/BackToRoomComponent.js b/src/components/sidebars/topology/rack/BackToRoomComponent.js index 9bb719a3..252e95b7 100644 --- a/src/components/sidebars/topology/rack/BackToRoomComponent.js +++ b/src/components/sidebars/topology/rack/BackToRoomComponent.js @@ -1,7 +1,7 @@ import React from "react"; const BackToRoomComponent = ({onClick}) => ( - <div className="btn btn-secondary btn-block" onClick={onClick}> + <div className="btn btn-secondary btn-block mb-2" onClick={onClick}> Back to room </div> ); diff --git a/src/components/sidebars/topology/rack/RackSidebarComponent.js b/src/components/sidebars/topology/rack/RackSidebarComponent.js index 398b3c13..6a36972f 100644 --- a/src/components/sidebars/topology/rack/RackSidebarComponent.js +++ b/src/components/sidebars/topology/rack/RackSidebarComponent.js @@ -10,7 +10,7 @@ import "./RackSidebarComponent.css"; const RackSidebarComponent = ({inSimulation, rackId}) => { return ( <div className="rack-sidebar-container flex-column"> - <div style={{flex: 0}}> + <div className="rack-sidebar-header-container"> <RackNameContainer/> <BackToRoomContainer/> {inSimulation ? diff --git a/src/components/sidebars/topology/rack/RackSidebarComponent.sass b/src/components/sidebars/topology/rack/RackSidebarComponent.sass index 192929cf..822804bc 100644 --- a/src/components/sidebars/topology/rack/RackSidebarComponent.sass +++ b/src/components/sidebars/topology/rack/RackSidebarComponent.sass @@ -3,6 +3,9 @@ height: 100% max-height: 100% +.rack-sidebar-header-container + flex: 0 + .machine-list-container flex: 1 overflow-y: scroll diff --git a/src/components/sidebars/topology/room/BackToBuildingComponent.js b/src/components/sidebars/topology/room/BackToBuildingComponent.js index 12dc15dd..85d2adcd 100644 --- a/src/components/sidebars/topology/room/BackToBuildingComponent.js +++ b/src/components/sidebars/topology/room/BackToBuildingComponent.js @@ -1,7 +1,7 @@ import React from "react"; const BackToBuildingComponent = ({onClick}) => ( - <div className="btn btn-secondary btn-block" onClick={onClick}> + <div className="btn btn-secondary btn-block mb-2" onClick={onClick}> Back to building </div> ); diff --git a/src/components/sidebars/topology/room/RoomSidebarComponent.js b/src/components/sidebars/topology/room/RoomSidebarComponent.js index 04df4372..fb3c3296 100644 --- a/src/components/sidebars/topology/room/RoomSidebarComponent.js +++ b/src/components/sidebars/topology/room/RoomSidebarComponent.js @@ -16,8 +16,8 @@ const RoomSidebarComponent = ({roomId, roomType, inSimulation}) => { return ( <div> <RoomNameContainer/> - <BackToBuildingContainer/> <RoomTypeContainer/> + <BackToBuildingContainer/> {inSimulation ? <div> <LoadBarContainer objectType="room" objectId={roomId}/> diff --git a/src/components/timeline/TimelineComponent.js b/src/components/timeline/TimelineComponent.js index b400a378..119c396b 100644 --- a/src/components/timeline/TimelineComponent.js +++ b/src/components/timeline/TimelineComponent.js @@ -11,15 +11,9 @@ class TimelineComponent extends React.Component { } if (this.props.currentTick < this.props.lastSimulatedTick) { - for (let i in this.props.sections.reverse()) { - if (this.props.currentTick + 1 >= this.props.sections[i].startTick) { - if (this.props.currentDatacenterId !== this.props.sections[i].datacenterId) { - this.props.setCurrentDatacenter(this.props.sections[i].datacenterId); - } - break; - } - } this.props.incrementTick(); + } else { + this.props.pauseSimulation(); } }, 1000); } diff --git a/src/components/timeline/TimelineControlsComponent.js b/src/components/timeline/TimelineControlsComponent.js index 2e093583..bd98afc3 100644 --- a/src/components/timeline/TimelineControlsComponent.js +++ b/src/components/timeline/TimelineControlsComponent.js @@ -1,33 +1,39 @@ import React from "react"; import PlayButtonContainer from "../../containers/timeline/PlayButtonContainer"; +import {convertTickToPercentage} from "../../util/timeline"; -function getXPercentage(tick, maxTick) { - if (maxTick === 0) { - return "0%"; - } else if (tick > maxTick) { - return ((maxTick / (maxTick + 1)) * 100) + "%"; +class TimelineControlsComponent extends React.Component { + onTimelineClick(e) { + const percentage = e.nativeEvent.offsetX / this.timeline.clientWidth; + const tick = Math.floor(percentage * (this.props.lastSimulatedTick + 1)); + this.props.goToTick(tick); } - return ((tick / (maxTick + 1)) * 100) + "%"; -} - -const TimelineControlsComponent = ({currentTick, lastSimulatedTick, sectionTicks}) => ( - <div className="timeline-controls"> - <PlayButtonContainer/> - <div className="timeline"> - <div - className="time-marker" - style={{left: getXPercentage(currentTick, lastSimulatedTick)}} - /> - {sectionTicks.map(sectionTick => ( + render() { + return ( + <div className="timeline-controls"> + <PlayButtonContainer/> <div - key={sectionTick} - className="section-marker" - style={{left: getXPercentage(sectionTick, lastSimulatedTick)}} - /> - ))} - </div> - </div> -); + className="timeline" + ref={timeline => this.timeline = timeline} + onClick={this.onTimelineClick.bind(this)} + > + <div + className="time-marker" + style={{left: convertTickToPercentage(this.props.currentTick, this.props.lastSimulatedTick)}} + /> + {this.props.sectionTicks.map(sectionTick => ( + <div + key={sectionTick} + className="section-marker" + style={{left: convertTickToPercentage(sectionTick, this.props.lastSimulatedTick)}} + title="Topology changes at this tick" + /> + ))} + </div> + </div> + ); + } +} export default TimelineControlsComponent; diff --git a/src/containers/timeline/TimelineContainer.js b/src/containers/timeline/TimelineContainer.js index 32756b6d..d52d5477 100644 --- a/src/containers/timeline/TimelineContainer.js +++ b/src/containers/timeline/TimelineContainer.js @@ -1,4 +1,5 @@ import {connect} from "react-redux"; +import {pauseSimulation} from "../../actions/simulation/playback"; import {incrementTick} from "../../actions/simulation/tick"; import {setCurrentDatacenter} from "../../actions/topology/building"; import TimelineComponent from "../../components/timeline/TimelineComponent"; @@ -25,6 +26,7 @@ const mapStateToProps = state => { const mapDispatchToProps = dispatch => { return { incrementTick: () => dispatch(incrementTick()), + pauseSimulation: () => dispatch(pauseSimulation()), setCurrentDatacenter: id => dispatch(setCurrentDatacenter(id)) }; }; diff --git a/src/containers/timeline/TimelineControlsContainer.js b/src/containers/timeline/TimelineControlsContainer.js index 16d44052..e7f27fbf 100644 --- a/src/containers/timeline/TimelineControlsContainer.js +++ b/src/containers/timeline/TimelineControlsContainer.js @@ -1,4 +1,5 @@ import {connect} from "react-redux"; +import {goToTick} from "../../actions/simulation/tick"; import TimelineControlsComponent from "../../components/timeline/TimelineControlsComponent"; const mapStateToProps = state => { @@ -19,8 +20,15 @@ const mapStateToProps = state => { }; }; +const mapDispatchToProps = dispatch => { + return { + goToTick: (tick) => dispatch(goToTick(tick)), + }; +}; + const TimelineControlsContainer = connect( - mapStateToProps + mapStateToProps, + mapDispatchToProps )(TimelineControlsComponent); export default TimelineControlsContainer; diff --git a/src/store/middlewares/viewport-adjustment.js b/src/store/middlewares/viewport-adjustment.js index 75ad6a2f..e5500d5e 100644 --- a/src/store/middlewares/viewport-adjustment.js +++ b/src/store/middlewares/viewport-adjustment.js @@ -1,4 +1,5 @@ import {SET_MAP_DIMENSIONS, setMapPosition, setMapScale} from "../../actions/map"; +import {SET_CURRENT_DATACENTER} from "../../actions/topology/building"; import { MAP_MAX_SCALE, MAP_MIN_SCALE, @@ -10,12 +11,23 @@ import {calculateRoomListBounds} from "../../util/tile-calculations"; export const viewportAdjustmentMiddleware = store => next => action => { const state = store.getState(); - if (action.type === SET_MAP_DIMENSIONS && state.currentDatacenterId !== -1) { - const roomIds = state.objects.datacenter[state.currentDatacenterId].roomIds; + + let datacenterId = -1; + let mapDimensions = {}; + if (action.type === SET_CURRENT_DATACENTER && action.datacenterId !== -1) { + datacenterId = action.datacenterId; + mapDimensions = state.map.dimensions; + } else if (action.type === SET_MAP_DIMENSIONS && state.currentDatacenterId !== -1) { + datacenterId = state.currentDatacenterId; + mapDimensions = {width: action.width, height: action.height}; + } + + if (datacenterId !== -1) { + const roomIds = state.objects.datacenter[datacenterId].roomIds; const rooms = roomIds.map(id => Object.assign({}, state.objects.room[id])); rooms.forEach(room => room.tiles = room.tileIds.map(tileId => state.objects.tile[tileId])); - const viewportParams = calculateParametersToZoomInOnRooms(rooms, action.width, action.height); + const viewportParams = calculateParametersToZoomInOnRooms(rooms, mapDimensions.width, mapDimensions.height); store.dispatch(setMapPosition(viewportParams.newX, viewportParams.newY)); store.dispatch(setMapScale(viewportParams.newScale)); } diff --git a/src/util/timeline.js b/src/util/timeline.js new file mode 100644 index 00000000..c6828ad7 --- /dev/null +++ b/src/util/timeline.js @@ -0,0 +1,19 @@ +export function convertTickToPercentage(tick, maxTick) { + if (maxTick === 0) { + return "0%"; + } else if (tick > maxTick) { + return ((maxTick / (maxTick + 1)) * 100) + "%"; + } + + return ((tick / (maxTick + 1)) * 100) + "%"; +} + +export function getDatacenterIdOfTick(tick, sections) { + for (let i in sections.reverse()) { + if (tick >= sections[i].startTick) { + return sections[i].datacenterId; + } + } + + return -1; +} |
