Make narratives on map into a react component

This commit is contained in:
Franc Camps-Febrer
2018-12-19 11:02:16 +01:00
parent 47a01801af
commit 65a608088c
7 changed files with 166 additions and 250 deletions

View File

@@ -6,7 +6,7 @@ import * as selectors from '../selectors'
import MapLogic from '../js/map/map.js'
import MapSites from './MapSites.jsx';
import MapDefsMarkers from './MapDefsMarkers.jsx';
import MapNarratives from './MapNarratives.jsx';
class Map extends React.Component {
@@ -97,19 +97,11 @@ class Map extends React.Component {
map.keyboard.disable();
map.on("move", () => this.moveElements());
map.on("move", () => this.updateSVG());
this.setState({ map });
}
projectPoint(location) {
const latLng = new L.LatLng(location[0], location[1]);
return {
x: this.state.map.latLngToLayerPoint(latLng).x + this.state.mapTransformX,
y: this.state.map.latLngToLayerPoint(latLng).y + this.state.mapTransformY
};
}
getSVGBoundaries() {
const mapNode = d3.select('.leaflet-map-pane').node();
if (mapNode === null) return { transformX: 0, transformY: 0 };
@@ -152,10 +144,6 @@ class Map extends React.Component {
});*/
}
moveElements() {
this.updateSVG();
}
renderSites() {
if (this.state.isInitialized) {
return (
@@ -171,12 +159,32 @@ class Map extends React.Component {
return '';
}
renderNarratives() {
if (this.state.isInitialized) {
return (
<MapNarratives
svg={this.svg}
narratives={this.props.domain.narratives}
map={this.state.map}
mapTransformX={this.state.mapTransformX}
mapTransformY={this.state.mapTransformY}
narrative={this.props.app.narrative}
narrativeProps={this.props.ui.narratives}
onSelect={this.props.methods.onSelect}
onSelectNarrative={this.props.methods.onSelectNarrative}
/>
);
}
return '';
}
render() {
const classes = this.props.app.narrative ? 'map-wrapper narrative-mode' : 'map-wrapper';
return (
<div className={classes}>
<div id={this.props.mapId} />
{this.renderSites()}
{this.renderNarratives()}
</div>
);
}

View File

@@ -3,10 +3,10 @@ import React from 'react';
const MapDefsMarkers = ({}) => (
<defs>
<marker id="arrow" viewBox="0 0 6 6" refX="3" refY="3" markerWidth="6" markerHeight="6" orient="auto">
<path d="M0,3v-3l6,3l-6,3z" style="fill: red;"></path>
<path d="M0,3v-3l6,3l-6,3z" style={{ fill: 'red' }}></path>
</marker>
<marker id="arrow-off" viewBox="0 0 6 6" refX="3" refY="3" markerWidth="6" markerHeight="6" orient="auto">
<path d="M0,3v-3l6,3l-6,3z" style="fill: black; fill-opacity: 0.2;"></path>
<path d="M0,3v-3l6,3l-6,3z" style={{ fill: 'black', fillOpacity: 0.2 }}></path>
</marker>
</defs>
);

View File

@@ -0,0 +1,94 @@
import React from 'react';
import { Portal } from 'react-portal';
import MapDefsMarkers from './MapDefsMarkers.jsx';
class MapNarratives extends React.Component {
projectPoint(location) {
const latLng = new L.LatLng(location[0], location[1]);
return {
x: this.props.map.latLngToLayerPoint(latLng).x + this.props.mapTransformX,
y: this.props.map.latLngToLayerPoint(latLng).y + this.props.mapTransformY
};
}
getNarrativeStyle(narrativeId) {
const styleName = (narrativeId && narrativeId in this.props.narrativeProps)
? narrativeId
: 'default';
return this.props.narrativeProps[styleName];
}
getStrokeWidth(narrative, step) {
if (!step) return 0;
return this.getNarrativeStyle(narrative.id).strokeWidth;
}
getStrokeDashArray(narrative, step) {
if (!step) return 'none';
return (this.getNarrativeStyle(narrative.id).style === 'dotted') ? "2px 5px" : 'none';
}
getStroke(narrative, step) {
if (!step || this.props.narrative === null) return 'none';
return this.getNarrativeStyle(narrative.id).stroke;
}
getStrokeOpacity(narrative, step) {
if (this.props.narrative === null) return 0;
if (!step || narrative.id !== this.props.narrative.id) return 0.2;
return 1;
}
renderNarrativeStep(allSteps, step, idx, n) {
const { x, y } = this.projectPoint([step.latitude, step.longitude]);
const step2 = allSteps[idx + 1];
const p2 = this.projectPoint([step2.latitude, step2.longitude]);
return (
<line
className="narrative-step"
x1={x}
x2={p2.x}
y1={y}
y2={p2.y}
markerStart="none"
markerEnd="url(#arrow)"
midMarker="url(#arrow)"
onClick={() => this.props.onSelectNarrative(n)}
style={{
strokeWidth: this.getStrokeWidth(n, step),
strokeDasharray: this.getStrokeDashArray(n, step),
strokeOpacity: this.getStrokeOpacity(n, step),
stroke: this.getStroke(n, step)
}}
>
</line>
);
}
renderNarrative(n) {
const steps = n.steps.slice(0, n.steps.length - 1);
return (
<g id={`narrative-${n.id.replace(/ /g,"_")}`} className="narrative">
{steps.map((s, idx) => this.renderNarrativeStep(n.steps, s, idx, n))}
</g>
)
}
render() {
if (this.props.narrative === null) return (<div />);
/*<MapDefsMarkers />*/
return (
<Portal node={this.props.svg.node()}>
{this.props.narratives.map(n => this.renderNarrative(n))}
</Portal>
);
}
}
export default MapNarratives;