Skip to content
Snippets Groups Projects
Commit d9cc2bf1 authored by Esko Ikkala's avatar Esko Ikkala
Browse files

Open marker popup from result table, reorganize state passing

parent 1bfb5dd2
No related branches found
No related tags found
No related merge requests found
export const UPDATE_QUERY = 'UPDATE_QUERY';
export const TOGGLE_DATASET = 'TOGGLE_DATASET';
export const BOUNCE_MARKER = 'BOUNCE_MARKER';
export const OPEN_MARKER_POPUP = 'OPEN_MARKER_POPUP';
export const START_SPINNER = 'START_SPINNER';
export const FETCH_SUGGESTIONS = 'FETCH_SUGGESTIONS';
export const FETCH_SUGGESTIONS_FAILED = 'FETCH_SUGGESTIONS_FAILED';
......@@ -35,6 +36,11 @@ export const bounceMarker = (uri) => ({
uri
});
export const openMarkerPopup = (uri) => ({
type: OPEN_MARKER_POPUP,
uri
});
export const startSpinner = () => ({
type: START_SPINNER,
});
......
......@@ -130,6 +130,7 @@ class VirtualizedTable extends React.PureComponent {
if (typeof rowData.lat !== 'undefined' || typeof rowData.long !== 'undefined') {
marker = (
<IconButton
onMouseOver={handleMarkerHover(rowData.s)}
onClick={handleMarkerClick(rowData.s)}
aria-label="Marker"
>
......@@ -145,6 +146,10 @@ class VirtualizedTable extends React.PureComponent {
};
const handleMarkerClick = value => () => {
this.props.openMarkerPopup(value);
};
const handleMarkerHover = value => () => {
this.props.bounceMarker(value);
};
......@@ -324,7 +329,8 @@ VirtualizedTable.propTypes = {
clearSuggestions: PropTypes.func.isRequired,
fetchResults: PropTypes.func.isRequired,
clearResults: PropTypes.func.isRequired,
bounceMarker: PropTypes.func.isRequired
bounceMarker: PropTypes.func.isRequired,
openMarkerPopup: PropTypes.func.isRequired
};
export default withStyles(styles)(VirtualizedTable);
......@@ -138,6 +138,8 @@ class LeafletMap extends React.Component {
position: 'bottomleft'
}).addTo(this.map);
L.Marker.setBouncingOptions({ exclusive: true });
// map.on('fullscreenchange', function () {
// if (map.isFullscreen()) {
// console.log('entered fullscreen');
......@@ -146,12 +148,9 @@ class LeafletMap extends React.Component {
// }
// });
//this.createOpacitySlider();
}
componentDidUpdate({ results, mapMode, geoJSONKey, bouncingMarker }) {
componentDidUpdate({ results, mapMode, geoJSONKey, bouncingMarkerKey, openPopupMarkerKey }) {
// check if results data or mapMode have changed
if (this.props.results !== results || this.props.mapMode !== mapMode) {
if (this.props.mapMode === 'cluster') {
......@@ -161,8 +160,12 @@ class LeafletMap extends React.Component {
}
}
if (this.props.bouncingMarker !== bouncingMarker) {
this.markers[this.props.bouncingMarker].bounce(5);
if (this.props.bouncingMarkerKey !== bouncingMarkerKey) {
this.markers[this.props.bouncingMarker].bounce(3);
}
if (this.props.openPopupMarkerKey !== openPopupMarkerKey) {
this.markers[this.props.openPopupMarker].openPopup();
}
// check if geoJSON has updated
......@@ -206,9 +209,6 @@ class LeafletMap extends React.Component {
} else {
const latLng = [+lat, +long];
const marker = L.marker(latLng, {icon: icon})
.on('click', function() {
this.toggleBouncing();
})
.bindPopup(this.createPopUpContent(result));
return marker;
}
......@@ -249,7 +249,7 @@ class LeafletMap extends React.Component {
createOpacitySlider() {
L.Control.OpacitySlider = L.Control.extend({
onAdd: function(map) {
onAdd: function() {
const slider = L.DomUtil.create('input', 'opacity-slider');
slider.type = 'range';
slider.min = 0;
......@@ -277,7 +277,10 @@ LeafletMap.propTypes = {
geoJSON: PropTypes.array,
geoJSONKey: PropTypes.number.isRequired,
getGeoJSON: PropTypes.func.isRequired,
bouncingMarker: PropTypes.string.isRequired
bouncingMarker: PropTypes.string.isRequired,
bouncingMarkerKey: PropTypes.number.isRequired,
openPopupMarker: PropTypes.string.isRequired,
openPopupMarkerKey: PropTypes.number.isRequired
};
export default LeafletMap;
......@@ -30,6 +30,7 @@ import {
updateResultsFilter,
sortResults,
bounceMarker,
openMarkerPopup,
} from '../actions';
const styles = theme => ({
......@@ -124,7 +125,7 @@ const styles = theme => ({
});
let MapApp = (props) => {
const { classes, mapMode, resultFormat, browser } = props;
const { classes, options, browser, search, map, results, resultValues } = props;
//error,
let oneColumnView = browser.lessThan.extraLarge;
......@@ -134,13 +135,13 @@ let MapApp = (props) => {
// console.log('mapMode', mapMode)
let table = '';
if ((oneColumnView && resultFormat === 'table') || (!oneColumnView)) {
if ((oneColumnView && options.resultFormat === 'table') || (!oneColumnView)) {
table = (
<div className={oneColumnView ? classes.resultTableOneColumn : classes.resultTable}>
<VirtualizedTable
list={Immutable.List(props.results)}
resultValues={props.resultValues}
search={props.search}
list={Immutable.List(results)}
resultValues={resultValues}
search={search}
sortResults={props.sortResults}
updateResultsFilter={props.updateResultsFilter}
updateQuery={props.updateQuery}
......@@ -149,15 +150,16 @@ let MapApp = (props) => {
fetchSuggestions={props.fetchSuggestions}
clearSuggestions={props.clearSuggestions}
bounceMarker={props.bounceMarker}
openMarkerPopup={props.openMarkerPopup}
/>
</div>
);
}
let map = '';
if ((oneColumnView && resultFormat === 'map') || (!oneColumnView)) {
if (mapMode === 'heatmap') {
map = (
let mapElement = '';
if ((oneColumnView && options.resultFormat === 'map') || (!oneColumnView)) {
if (options.mapMode === 'heatmap') {
mapElement = (
<GMap
results={props.results}
googleMapURL="https://maps.googleapis.com/maps/api/js?key=AIzaSyCKWw5FjhwLsfp_l2gjVAifPkT3cxGXhA4&v=3.exp&libraries=geometry,drawing,places,visualization"
......@@ -167,14 +169,17 @@ let MapApp = (props) => {
/>
);
} else {
map = (
mapElement = (
<LeafletMap
results={props.results}
mapMode={props.mapMode}
geoJSON={props.geoJSON}
geoJSONKey={props.geoJSONKey}
mapMode={options.mapMode}
geoJSON={map.geoJSON}
geoJSONKey={map.geoJSONKey}
getGeoJSON={props.getGeoJSON}
bouncingMarker={props.bouncingMarker}
bouncingMarker={map.bouncingMarker}
bouncingMarkerKey={map.bouncingMarkerKey}
openPopupMarker={map.openPopupMarker}
openPopupMarkerKey={map.openPopupMarkerKey}
// sliderValue={100}
/>
);
......@@ -182,7 +187,7 @@ let MapApp = (props) => {
}
let statistics = '';
if ((oneColumnView && resultFormat === 'statistics') || (!oneColumnView)) {
if ((oneColumnView && options.resultFormat === 'statistics') || (!oneColumnView)) {
statistics = (
<div className={oneColumnView ? classes.statisticsOneColumn : classes.statistics}>
<Pie data={props.results} groupBy={props.search.groupBy} query={props.search.query} />
......@@ -192,7 +197,7 @@ let MapApp = (props) => {
let mainResultsView = '';
if (oneColumnView) {
switch(props.resultFormat) {
switch(options.resultFormat) {
case 'table': {
mainResultsView = table;
break;
......@@ -220,13 +225,13 @@ let MapApp = (props) => {
<div className={classes.root}>
<div className={classes.appFrame}>
<TopBar
results={props.results}
results={results}
oneColumnView={oneColumnView}
mapMode={props.mapMode}
resultFormat={props.resultFormat}
mapMode={options.mapMode}
resultFormat={options.resultFormat}
updateMapMode={props.updateMapMode}
updateResultFormat={props.updateResultFormat}
datasets={props.search.datasets}
datasets={search.datasets}
toggleDataset={props.toggleDataset}
/>
<div className={classes.mainContainer}>
......@@ -234,7 +239,7 @@ let MapApp = (props) => {
{!oneColumnView &&
<div className={classes.rightColumn}>
<div className={classes.map}>
{map}
{mapElement}
</div>
{statistics}
</div>
......@@ -254,16 +259,12 @@ let MapApp = (props) => {
const mapStateToProps = (state) => {
return {
options: state.options,
browser: state.browser,
search: state.search,
map: state.map,
results: getVisibleResults(state.search),
resultValues: getVisibleValues(state.search),
mapMode: state.options.mapMode,
error: state.error,
geoJSON: state.map.geoJSON,
geoJSONKey: state.map.geoJSONKey,
bouncingMarker: state.map.bouncingMarker,
resultFormat: state.options.resultFormat,
browser: state.browser
};
};
......@@ -279,14 +280,22 @@ const mapDispatchToProps = ({
updateResultFormat,
updateMapMode,
updateResultsFilter,
bounceMarker
bounceMarker,
openMarkerPopup,
});
MapApp.propTypes = {
classes: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
//error: PropTypes.object.isRequired,
browser: PropTypes.object.isRequired,
options: PropTypes.object.isRequired,
search: PropTypes.object.isRequired,
error: PropTypes.object.isRequired,
map: PropTypes.object.isRequired,
results: PropTypes.array,
resultValues: PropTypes.object,
updateQuery: PropTypes.func.isRequired,
toggleDataset: PropTypes.func.isRequired,
fetchSuggestions: PropTypes.func.isRequired,
......@@ -294,19 +303,12 @@ MapApp.propTypes = {
fetchResults: PropTypes.func.isRequired,
clearResults: PropTypes.func.isRequired,
sortResults: PropTypes.func.isRequired,
geoJSON: PropTypes.array.isRequired,
geoJSONKey: PropTypes.number.isRequired,
getGeoJSON: PropTypes.func.isRequired,
bounceMarker: PropTypes.func.isRequired,
openMarkerPopup: PropTypes.func.isRequired,
updateResultFormat: PropTypes.func.isRequired,
updateMapMode: PropTypes.func.isRequired,
resultFormat: PropTypes.string.isRequired,
mapMode: PropTypes.string.isRequired,
results: PropTypes.array,
resultValues: PropTypes.object,
updateResultsFilter: PropTypes.func.isRequired,
browser: PropTypes.object.isRequired,
bouncingMarker: PropTypes.string.isRequired
};
export default compose(
......
import {
UPDATE_GEOJSON,
BOUNCE_MARKER,
OPEN_MARKER_POPUP,
} from '../actions';
export const INITIAL_STATE = {
......@@ -9,7 +10,10 @@ export const INITIAL_STATE = {
'features': []
}],
geoJSONKey: 0,
bouncingMarker: ''
bouncingMarker: '',
bouncingMarkerKey: 0,
openPopupMarker: '',
openPopupMarkerKey: 0,
};
const map = (state = INITIAL_STATE, action) => {
......@@ -23,7 +27,14 @@ const map = (state = INITIAL_STATE, action) => {
case BOUNCE_MARKER:
return {
...state,
bouncingMarker: action.uri
bouncingMarker: action.uri,
bouncingMarkerKey: state.bouncingMarkerKey + 1
};
case OPEN_MARKER_POPUP:
return {
...state,
openPopupMarker: action.uri,
openPopupMarkerKey: state.openPopupMarkerKey + 1
};
default:
return state;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment