diff --git a/src/components/Map.jsx b/src/components/Map.jsx
index b565d1a..9b2fc7a 100644
--- a/src/components/Map.jsx
+++ b/src/components/Map.jsx
@@ -6,6 +6,7 @@ import * as selectors from '../selectors'
import MapLogic from '../js/map/map.js'
import MapSites from './MapSites.jsx';
+import MapEvents from './MapEvents.jsx';
import MapNarratives from './MapNarratives.jsx';
class Map extends React.Component {
@@ -49,15 +50,15 @@ class Map extends React.Component {
});
this.mapLogic = new MapLogic(this.state.map, this.svg, this.g, this.props.app, this.props.ui, this.props.methods)
- this.mapLogic.update(this.props.domain, this.props.app)
+ this.mapLogic.update(this.props.app)
this.setState({ isInitialized: true })
}
}
componentWillReceiveProps(nextProps) {
- if (hash(nextProps) !== hash(this.props)) {
- this.mapLogic.update(nextProps.domain, nextProps.app)
+ if (hash(nextProps.app) !== hash(this.props.app)) {
+ this.mapLogic.update(nextProps.app)
}
}
@@ -121,10 +122,10 @@ class Map extends React.Component {
}
updateSVG() {
- const boundingClient = d3.select(`#${this.props.mapId}`).node().getBoundingClientRect();
+ //const boundingClient = d3.select(`#${this.props.mapId}`).node().getBoundingClientRect();
- let WIDTH = boundingClient.width;
- let HEIGHT = boundingClient.height;
+ //let WIDTH = boundingClient.width;
+ //let HEIGHT = boundingClient.height;
// Offset with leaflet map transform boundaries
const { transformX, transformY } = this.getSVGBoundaries();
@@ -136,12 +137,7 @@ class Map extends React.Component {
/*this.svg.attr('width', WIDTH)
.attr('height', HEIGHT)
- .attr('style', `left: ${-transformX}px; top: ${-transformY}px`);
-
- this.g.selectAll('.location').attr('transform', (d) => {
- const newPoint = projectPoint([+d.latitude, +d.longitude]);
- return `translate(${newPoint.x},${newPoint.y})`;
- });*/
+ .attr('style', `left: ${-transformX}px; top: ${-transformY}px`);*/
}
renderSites() {
@@ -178,12 +174,32 @@ class Map extends React.Component {
return '';
}
+ renderEvents() {
+ if (this.state.isInitialized) {
+ return (
+
+ );
+ }
+ return '';
+ }
+
+
render() {
const classes = this.props.app.narrative ? 'map-wrapper narrative-mode' : 'map-wrapper';
return (
{this.renderSites()}
+ {this.renderEvents()}
{this.renderNarratives()}
);
diff --git a/src/components/MapEvents.jsx b/src/components/MapEvents.jsx
new file mode 100644
index 0000000..edfd68b
--- /dev/null
+++ b/src/components/MapEvents.jsx
@@ -0,0 +1,76 @@
+import React from 'react';
+import { Portal } from 'react-portal';
+
+class MapEvents 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
+ };
+ }
+
+ getLocationEventsDistribution(location) {
+ const eventCount = {};
+ const categories = this.props.categories;
+
+ categories.forEach(cat => {
+ eventCount[cat.category] = 0
+ });
+
+ location.events.forEach((event) => {;
+ eventCount[event.category] += 1;
+ });
+
+ let i = 0;
+ const events = [];
+
+ while (i < categories.length) {
+ let _eventsCount = eventCount[categories[i].category];
+ for (let j = i + 1; j < categories.length; j++) {
+ _eventsCount += eventCount[categories[j].category];
+ }
+ events.push(_eventsCount);
+ i++;
+ }
+ return events;
+ }
+
+ renderCategory(counts, events) {
+ return (
+ this.props.onSelect(events)}
+ >
+
+ );
+ }
+
+ renderLocation(location) {
+ const { x, y } = this.projectPoint([location.latitude, location.longitude]);
+ const eventsCounts = this.getLocationEventsDistribution(location);
+
+ return (
+
+ {eventsCounts.map(eventsCount => this.renderCategory(eventsCount, location.events))}
+
+ )
+ }
+
+ render() {
+
+ return (
+
+ {this.props.locations.map(loc => this.renderLocation(loc))}
+
+ );
+ }
+}
+
+export default MapEvents;
\ No newline at end of file
diff --git a/src/js/map/map.js b/src/js/map/map.js
index adc16be..2fcf7a7 100644
--- a/src/js/map/map.js
+++ b/src/js/map/map.js
@@ -7,31 +7,14 @@ import 'leaflet-polylinedecorator';
export default function(lMap, svg, g, newApp, ui, methods) {
- const domain = {
- locations: [],
- narratives: [],
- categories: [],
- }
const app = {
selected: [],
highlighted: null,
- narrative: null,
- views: Object.assign({}, newApp.views),
}
- const getCategoryColor = methods.getCategoryColor;
-
// Icons for markPoint flags (a yellow ring around a location)
const eventCircleMarkers = {};
- function projectPoint(location) {
- const latLng = new L.LatLng(location[0], location[1]);
- return {
- x: lMap.latLngToLayerPoint(latLng).x + getSVGBoundaries().transformX,
- y: lMap.latLngToLayerPoint(latLng).y + getSVGBoundaries().transformY
- };
- }
-
function getSVGBoundaries() {
const mapNode = d3.select('.leaflet-map-pane').node();
if (mapNode === null) return { transformX: 0, transformY: 0 };
@@ -62,25 +45,10 @@ export default function(lMap, svg, g, newApp, ui, methods) {
svg.attr('width', WIDTH)
.attr('height', HEIGHT)
.attr('style', `left: ${-transformX}px; top: ${-transformY}px`);
-
- g.selectAll('.location').attr('transform', (d) => {
- const newPoint = projectPoint([+d.latitude, +d.longitude]);
- return `translate(${newPoint.x},${newPoint.y})`;
- });
}
lMap.on("zoomend viewreset moveend", updateSVG);
- /**
- * Returns latitud / longitude
- * @param {Object} eventPoint: data for an evenPoint - time, loc, tags, etc
- */
- function getEventLocation(eventPoint) {
- return {
- latitude: +eventPoint.location.latitude,
- longitude: +eventPoint.location.longitude,
- };
- }
/*
* INTERACTIVE FUNCTIONS
@@ -130,136 +98,22 @@ export default function(lMap, svg, g, newApp, ui, methods) {
}
}
}
-
- /*
- * RENDERING FUNCTIONS
- */
-
- function getLocationEventsDistribution(location) {
- const eventCount = {};
- const categories = domain.categories;
-
- categories.forEach(cat => {
- eventCount[cat.category] = 0
- });
-
- location.events.forEach((event) => {;
- eventCount[event.category] += 1;
- });
-
- let i = 0;
- const events = [];
-
- while (i < categories.length) {
- let _eventsCount = eventCount[categories[i].category];
- for (let j = i + 1; j < categories.length; j++) {
- _eventsCount += eventCount[categories[j].category];
- }
- events.push(_eventsCount);
- i++;
- }
- return events;
- }
-
- /**
- * Clears existing event layer
- * Renders all events as markers
- * Adds eventlayer to map
- */
- function renderEvents() {
- const locationsDom = g.selectAll('.location')
- .data(domain.locations, d => d.id)
-
- locationsDom
- .exit()
- .remove();
-
- locationsDom
- .enter().append('g')
- .attr('class', 'location')
- .attr('transform', (d) => {
- const newPoint = projectPoint([+d.latitude, +d.longitude]);
- return `translate(${newPoint.x},${newPoint.y})`;
- })
- .on('click', (location) => {
- methods.onSelect(location.events);
- });
-
- const eventsDom = g.selectAll('.location')
- .selectAll('.location-event-marker')
- .data((d, i) => getLocationEventsDistribution(domain.locations[i]))
-
- eventsDom
- .exit()
- .attr('r', 0)
- .remove();
-
- eventsDom
- .transition()
- .duration(500)
- .attr('r', d => (d) ? Math.sqrt(16 * d) + 3 : 0);
-
- eventsDom
- .enter().append('circle')
- .attr('class', 'location-event-marker')
- .style('fill', (d, i) => getCategoryColor(domain.categories[i].category))
- .transition()
- .duration(500)
- .attr('r', d => (d) ? Math.sqrt(16 * d) + 3 : 0);
-
- eventsDom.selectAll('.location-event-marker')
- .style('fill-opacity', '0.1 !important');
- }
-
- const getCoords = (d) => {
- d.LatLng = new L.LatLng(+d.latitude, +d.longitude);
- return {
- x: lMap.latLngToLayerPoint(d.LatLng).x,
- y: lMap.latLngToLayerPoint(d.LatLng).y
- }
- }
-
-
-
- function getMarker (d) {
- if (!d || app.narrative === null) return 'none';
- if (d.id === app.narrative.id) return 'url(#arrow)';
- return 'url(#arrow-off)';
- }
-
/**
* Updates displayable data on the map: events, coevents and paths
- * @param {Object} domain: object of arrays of events, coevs, attacks, paths, sites
*/
- function update(newDomain, newApp) {
+ function update(newApp) {
updateSVG();
- const isNewDomain = (hash(domain) !== hash(newDomain));
const isNewAppProps = (hash(app) !== hash(newApp));
- if (isNewDomain) {
- domain.locations = newDomain.locations;
- domain.categories = newDomain.categories;
- }
-
if (isNewAppProps) {
- app.views = newApp.views;
app.selected = newApp.selected;
app.highlighted = newApp.highlighted;
- app.mapAnchor = newApp.mapAnchor;
- app.narrative = newApp.narrative;
}
- if (isNewDomain || isNewAppProps) renderDomain();
if (isNewAppProps) renderSelectedAndHighlight();
}
- /**
- * Renders events on the map: takes data, and enters, updates and exits
- */
- function renderDomain () {
- renderEvents();
- }
function renderSelectedAndHighlight () {
renderSelected();
renderHighlighted();