From 345a1f2be29b355d078b06e1ef026b791669a4f9 Mon Sep 17 00:00:00 2001 From: Franc Camps-Febrer Date: Sat, 22 Dec 2018 10:43:12 +0100 Subject: [PATCH] Add reactified event markers to timeline --- src/components/Timeline.jsx | 2 + src/components/TimelineMarkers.jsx | 27 ++++++++++ src/js/timeline/timeline.js | 83 +++--------------------------- 3 files changed, 37 insertions(+), 75 deletions(-) create mode 100644 src/components/TimelineMarkers.jsx diff --git a/src/components/Timeline.jsx b/src/components/Timeline.jsx index 015ee6e..fb8e713 100644 --- a/src/components/Timeline.jsx +++ b/src/components/Timeline.jsx @@ -10,6 +10,7 @@ import TimelineHandles from './TimelineHandles.jsx'; import TimelineZoomControls from './TimelineZoomControls.jsx'; import TimelineLogic from '../js/timeline/timeline.js'; import TimelineLabels from './TimelineLabels.jsx'; +import TimelineMarkers from './TimelineMarkers.jsx' class Timeline extends React.Component { constructor(props) { @@ -83,6 +84,7 @@ class Timeline extends React.Component { { this.onMoveTime(dir) }} /> { this.onApplyZoom(zoom); }} /> + this.timeline.getEventX(e)} getEventY={(e) => this.timeline.getEventY(e)} /> ); } diff --git a/src/components/TimelineMarkers.jsx b/src/components/TimelineMarkers.jsx new file mode 100644 index 0000000..54de8f1 --- /dev/null +++ b/src/components/TimelineMarkers.jsx @@ -0,0 +1,27 @@ +import React from 'react'; + +class TimelineMarkers extends React.Component { + + renderMarker(event) { + return ( + + + ) + } + + render () { + return ( + + {this.props.selected.map(event => this.renderMarker(event))} + + ); + } +} + +export default TimelineMarkers; \ No newline at end of file diff --git a/src/js/timeline/timeline.js b/src/js/timeline/timeline.js index 91c8709..bd317e8 100644 --- a/src/js/timeline/timeline.js +++ b/src/js/timeline/timeline.js @@ -4,14 +4,9 @@ Allows brushing and selecting periods of time in it TODO: is it possible to express this idiomatically as React? */ -import { - areEqual, - parseDate, - formatterWithYear -} from '../utilities'; +import { parseDate } from '../utilities'; import hash from 'object-hash'; import esLocale from '../data/es-MX.json'; -import copy from '../data/copy.json'; export default function(svg, newApp, ui, methods) { d3.timeFormatDefaultLocale(esLocale); @@ -23,18 +18,12 @@ export default function(svg, newApp, ui, methods) { } const app = { timerange: newApp.timerange, - selected: [], - language: newApp.language, + selected: [] } // Dimension of the client const WIDTH_CONTROLS = 100; - const HEIGHT = 140; - const boundingClient = d3.select(`#${ui.dom.timeline}`).node().getBoundingClientRect(); - let WIDTH = boundingClient.width - WIDTH_CONTROLS; - - // Highlight events with a larger white ring marker - const markerRadius = 15; + let WIDTH = getCurrentWidth() - WIDTH_CONTROLS; // NB: is it possible to do this with SCSS? // A: Maybe, although we are using it programmatically here for now @@ -85,7 +74,6 @@ export default function(svg, newApp, ui, methods) { dom.body = dom.svg.append("g").attr("clip-path", "url(#clip)"); dom.events = dom.body.append('g'); - dom.markers = dom.body.append('g'); /* @@ -131,7 +119,6 @@ export default function(svg, newApp, ui, methods) { if (d3.select(`#${ui.dom.timeline}`).node() !== null) { WIDTH = getCurrentWidth() - WIDTH_CONTROLS; - dom.svg.attr('width', WIDTH); scale.x.range([margin.left, WIDTH]); axis.y.tickSize(WIDTH - margin.left); dom.axis.y.attr('transform', `translate(${WIDTH}, 0)`) @@ -140,16 +127,7 @@ export default function(svg, newApp, ui, methods) { }); } addResizeListener(); - - - /** - * Return which color event circle should be based on incident type - * @param {object} eventPoint data object - */ - function getEventPointFillColor(eventPoint) { - return methods.getCategoryColor(eventPoint.category); - } - + /** * Given an event, get all the filtered events that happen simultaneously @@ -185,17 +163,6 @@ export default function(svg, newApp, ui, methods) { return (scale.x.domain()[1].getTime() - scale.x.domain()[0].getTime()) / 60000; } - - /* - * Given a number of minutes, calculate the width based on current scale.x - * @param {number} minutes: number of minutes - */ - function getWidthOfTime(minutes) { - const allMins = getTimeScaleExtent(); - return (minutes * WIDTH) / allMins; - } - - /** * Apply zoom level to timeline * @param {object} zoom: zoom level from zoomLevels @@ -286,39 +253,6 @@ export default function(svg, newApp, ui, methods) { .classed('mouseover', false); } - - /** - * It automatically sets brush timeline to a domain set by the params - */ - function updateTimeRange() { - scale.x.domain(app.timerange); - axis.x0.scale(scale.x); - axis.x1.scale(scale.x); - } - - /** - * Makes a circular ring mark in all selected events - * @param {object} eventPoint: object with eventPoint data (time, loc, tags) - */ - function renderHighlight() { - const markers = dom.markers - .selectAll('circle') - .data(app.selected); - - markers - .enter() - .append('circle') - .attr('class', 'timeline-marker') - .merge(markers) - .attr('cy', eventPoint => getEventY(eventPoint)) - .attr('cx', eventPoint => getEventX(eventPoint)) - .attr('r', 10) - .style('opacity', .9); - - markers.exit().remove(); - } - - /** * Return event circles of different groups */ @@ -342,10 +276,8 @@ export default function(svg, newApp, ui, methods) { .attr('class', 'event') .attr('cx', eventPoint => getEventX(eventPoint)) .attr('cy', eventPoint => getEventY(eventPoint)) - .style('fill', eventPoint => getEventPointFillColor(eventPoint)) - .on('click', eventPoint => { - return methods.onSelect(getAllEventsAtOnce(eventPoint)) - }) + .style('fill', eventPoint => methods.getCategoryColor(eventPoint.category)) + .on('click', eventPoint => methods.onSelect(getAllEventsAtOnce(eventPoint))) .on('mouseover', handleMouseOver) .on('mouseout', handleMouseOut) .transition() @@ -432,10 +364,11 @@ export default function(svg, newApp, ui, methods) { updateAxis(); renderAxis(); renderEvents(); - renderHighlight(); } return { + getEventX, + getEventY, applyZoom, moveTime, update,