Feature/reduce bundle size (#234) (#36)

Co-authored-by: Juan Camilo González <j.gonzalezj@uniandes.edu.co>
Co-authored-by: msramalho <19508417+msramalho@users.noreply.github.com>
This commit is contained in:
Lachlan Kermode
2022-04-08 05:20:16 -04:00
committed by GitHub
parent 250c43a301
commit 1c08ed9378
7 changed files with 583 additions and 423 deletions

View File

@@ -9,7 +9,7 @@ module.exports = {
MAPBOX_TOKEN:
"pk.eyJ1IjoiYmVsbGluZ2NhdC1tYXBib3giLCJhIjoiY2tleW0wbWliMDA1cTJ5bzdkbTRraHgwZSJ9.GJQkjPzj8554VhR5SPsfJg",
// MEDIA_EXT: "/api/media",
DATE_FMT: "MM/DD/YYYY",
DATE_FMT: "M/D/YYYY",
TIME_FMT: "HH:mm",
store: {

900
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -31,7 +31,8 @@
"camelcase": "^6.1.0",
"case-sensitive-paths-webpack-plugin": "2.3.0",
"css-loader": "4.3.0",
"d3": "^5.7.0",
"d3": "^7.4.2",
"dayjs": "^1.11.0",
"dotenv": "8.2.0",
"dotenv-expand": "5.1.0",
"eslint": "^7.11.0",
@@ -59,7 +60,6 @@
"lint-staged": "^10.5.3",
"marked": "^0.7.0",
"mini-css-extract-plugin": "0.11.3",
"moment": "^2.26.0",
"object-hash": "^1.3.0",
"optimize-css-assets-webpack-plugin": "5.0.4",
"pnp-webpack-plugin": "1.6.4",

View File

@@ -1,8 +1,12 @@
import moment from "moment";
import customParseFormat from "dayjs/plugin/customParseFormat";
import dayjs from "dayjs";
import hash from "object-hash";
import { timeFormatDefaultLocale } from "d3";
import { ASSOCIATION_MODES, POLYGON_CLIP_PATH } from "./constants";
dayjs.extend(customParseFormat);
let { DATE_FMT, TIME_FMT } = process.env;
if (!DATE_FMT) DATE_FMT = "MM/DD/YYYY";
if (!TIME_FMT) TIME_FMT = "HH:mm";
@@ -16,7 +20,7 @@ export function getPathLeaf(path) {
export function calcDatetime(date, time) {
if (!time) time = "00:00";
const dt = moment(`${date} ${time}`, `${DATE_FMT} ${TIME_FMT}`);
const dt = dayjs(`${date} ${time}`, `${DATE_FMT} ${TIME_FMT}`);
return dt.toDate();
}
@@ -499,15 +503,14 @@ export function makeNiceDate(datetime) {
/**
* Sets the default locale for d3 to format dates in each available language.
* @param {Object} d3 - An instance of D3
*/
export function setD3Locale(d3) {
export function setD3Locale() {
const languages = {
"es-MX": require("./data/es-MX.json"),
};
if (language !== "es-US" && languages[language]) {
d3.timeFormatDefaultLocale(languages[language]);
timeFormatDefaultLocale(languages[language]);
}
}

View File

@@ -1,9 +1,9 @@
import React from "react";
import * as d3 from "d3";
import { axisBottom, timeFormat, select } from "d3";
import { setD3Locale } from "../../common/utilities";
const TEXT_HEIGHT = 15;
setD3Locale(d3);
setD3Locale();
class TimelineAxis extends React.Component {
constructor() {
super();
@@ -33,30 +33,28 @@ class TimelineAxis extends React.Component {
const { marginTop, contentHeight } = this.props.dims;
if (this.props.scaleX) {
this.x0 = d3
.axisBottom(this.props.scaleX)
this.x0 = axisBottom(this.props.scaleX)
.ticks(this.props.ticks)
.tickPadding(0)
.tickSize(contentHeight - TEXT_HEIGHT - marginTop)
.tickFormat(d3.timeFormat(fstFmt));
.tickFormat(timeFormat(fstFmt));
this.x1 = d3
.axisBottom(this.props.scaleX)
this.x1 = axisBottom(this.props.scaleX)
.ticks(this.props.ticks)
.tickPadding(marginTop)
.tickSize(0)
.tickFormat(d3.timeFormat(sndFmt));
.tickFormat(timeFormat(sndFmt));
if (!this.state.isInitialized) this.setState({ isInitialized: true });
}
if (this.state.isInitialized) {
d3.select(this.xAxis0Ref.current)
select(this.xAxis0Ref.current)
.transition()
.duration(this.props.transitionDuration)
.call(this.x0);
d3.select(this.xAxis1Ref.current)
select(this.xAxis1Ref.current)
.transition()
.duration(this.props.transitionDuration)
.call(this.x1);

View File

@@ -1,5 +1,5 @@
import React from "react";
import * as d3 from "d3";
import { drag as d3Drag, select } from "d3";
class TimelineCategories extends React.Component {
constructor(props) {
@@ -12,13 +12,12 @@ class TimelineCategories extends React.Component {
componentDidUpdate() {
if (!this.state.isInitialized) {
const drag = d3
.drag()
const drag = d3Drag()
.on("start", this.props.onDragStart)
.on("drag", this.props.onDrag)
.on("end", this.props.onDragEnd);
d3.select(this.grabRef.current).call(drag);
select(this.grabRef.current).call(drag);
this.setState({ isInitialized: true });
}

View File

@@ -1,7 +1,7 @@
import React from "react";
import { bindActionCreators } from "redux";
import { connect } from "react-redux";
import * as d3 from "d3";
import { scaleTime, timeMinute, timeSecond } from "d3";
import hash from "object-hash";
import { setLoading, setNotLoading, updateTicks } from "../../actions";
@@ -26,6 +26,9 @@ class Timeline extends React.Component {
this.getY = this.getY.bind(this);
this.onApplyZoom = this.onApplyZoom.bind(this);
this.onSelect = this.onSelect.bind(this);
this.onDragStart = this.onDragStart.bind(this);
this.onDrag = this.onDrag.bind(this);
this.onDragEnd = this.onDragEnd.bind(this);
this.svgRef = React.createRef();
this.state = {
isFolded:
@@ -90,8 +93,7 @@ class Timeline extends React.Component {
}
makeScaleX() {
return d3
.scaleTime()
return scaleTime()
.domain(this.state.timerange)
.range([
this.state.dims.marginLeft,
@@ -170,19 +172,19 @@ class Timeline extends React.Component {
*/
onMoveTime(direction) {
const extent = this.getTimeScaleExtent();
const newCentralTime = d3.timeMinute.offset(
const newCentralTime = timeMinute.offset(
this.state.scaleX.domain()[0],
extent
);
// if forward
let domain0 = newCentralTime;
let domainF = d3.timeMinute.offset(newCentralTime, extent);
let domainF = timeMinute.offset(newCentralTime, extent);
// if backwards
if (direction === "backwards") {
domain0 = d3.timeMinute.offset(newCentralTime, -(2 * extent));
domainF = d3.timeMinute.offset(newCentralTime, -extent);
domain0 = timeMinute.offset(newCentralTime, -(2 * extent));
domainF = timeMinute.offset(newCentralTime, -extent);
}
this.props.methods.onUpdateTimerange([domain0, domainF]);
@@ -192,8 +194,8 @@ class Timeline extends React.Component {
onCenterTime(newCentralTime) {
const extent = this.getTimeScaleExtent();
const domain0 = d3.timeMinute.offset(newCentralTime, -extent / 2);
const domainF = d3.timeMinute.offset(newCentralTime, +extent / 2);
const domain0 = timeMinute.offset(newCentralTime, -extent / 2);
const domainF = timeMinute.offset(newCentralTime, +extent / 2);
this.setState({ timerange: [domain0, domainF] }, () => {
this.props.methods.onUpdateTimerange(this.state.timerange);
@@ -215,14 +217,14 @@ class Timeline extends React.Component {
*/
onApplyZoom(zoom) {
const extent = this.getTimeScaleExtent();
const newCentralTime = d3.timeMinute.offset(
const newCentralTime = timeMinute.offset(
this.state.scaleX.domain()[0],
extent / 2
);
const { rangeLimits } = this.props.timeline;
let newDomain0 = d3.timeMinute.offset(newCentralTime, -zoom.duration / 2);
let newDomainF = d3.timeMinute.offset(newCentralTime, zoom.duration / 2);
let newDomain0 = timeMinute.offset(newCentralTime, -zoom.duration / 2);
let newDomainF = timeMinute.offset(newCentralTime, zoom.duration / 2);
if (rangeLimits) {
// If the store contains absolute time limits,
@@ -232,11 +234,11 @@ class Timeline extends React.Component {
if (newDomain0 < minDate) {
newDomain0 = minDate;
newDomainF = d3.timeMinute.offset(newDomain0, zoom.duration);
newDomainF = timeMinute.offset(newDomain0, zoom.duration);
}
if (newDomainF > maxDate) {
newDomainF = maxDate;
newDomain0 = d3.timeMinute.offset(newDomainF, -zoom.duration);
newDomain0 = timeMinute.offset(newDomainF, -zoom.duration);
}
}
@@ -258,11 +260,11 @@ class Timeline extends React.Component {
/*
* Setup drag behavior
*/
onDragStart() {
d3.event.sourceEvent.stopPropagation();
onDragStart(event) {
event.sourceEvent.stopPropagation();
this.setState(
{
dragPos0: d3.event.x,
dragPos0: event.x,
},
() => {
this.toggleTransition(false);
@@ -273,14 +275,14 @@ class Timeline extends React.Component {
/*
* Drag and update
*/
onDrag() {
onDrag(event) {
const drag0 = this.state.scaleX.invert(this.state.dragPos0).getTime();
const dragNow = this.state.scaleX.invert(d3.event.x).getTime();
const dragNow = this.state.scaleX.invert(event.x).getTime();
const timeShift = (drag0 - dragNow) / 1000;
const { range, rangeLimits } = this.props.timeline;
let newDomain0 = d3.timeSecond.offset(range[0], timeShift);
let newDomainF = d3.timeSecond.offset(range[1], timeShift);
const { range, rangeLimits } = this.props.app.timeline;
let newDomain0 = timeSecond.offset(range[0], timeShift);
let newDomainF = timeSecond.offset(range[1], timeShift);
if (rangeLimits) {
// If the store contains absolute time limits,
@@ -352,8 +354,8 @@ class Timeline extends React.Component {
const timeframe = Math.floor(
this.props.features.ZOOM_TO_TIMEFRAME_ON_TIMELINE_CLICK / 2
);
const start = d3.timeMinute.offset(event.datetime, -timeframe);
const end = d3.timeMinute.offset(event.datetime, timeframe);
const start = timeMinute.offset(event.datetime, -timeframe);
const end = timeMinute.offset(event.datetime, timeframe);
this.props.actions.updateTicks(1);
this.props.methods.onUpdateTimerange([start, end]);
}
@@ -416,15 +418,9 @@ class Timeline extends React.Component {
getCategoryY={(category) =>
this.getY({ category, project: null })
}
onDragStart={() => {
this.onDragStart();
}}
onDrag={() => {
this.onDrag();
}}
onDragEnd={() => {
this.onDragEnd();
}}
onDragStart={this.onDragStart}
onDrag={this.onDrag}
onDragEnd={this.onDragEnd}
categories={categories}
features={this.props.features}
fallbackLabel={