Skip to content

Commit

Permalink
//** Reactify app/visualizer
Browse files Browse the repository at this point in the history
  • Loading branch information
braxex committed Jan 17, 2018
1 parent 3330a16 commit be479de
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 136 deletions.
87 changes: 6 additions & 81 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,22 @@ import 'react-tippy/dist/tippy.css';
import * as d3 from 'd3';
import * as d3sc from 'd3-scale-chromatic';
import { Tooltip } from 'react-tippy';
import {Visualizer, passFiles} from './Visualizer.js';
import Visualizer from './Visualizer.js';
import {LPRCheckbox, NICheckbox, Modal} from './Reusables.js';
import {lprStatics, niStatics, noteStatics} from './Statics.js';
import Legend from './Legend.js';
import Card from './Card.js';
import {flags} from './flags.js';


let playing, dataFlags;
let yearSpan = [2005,2016];
let playing;
export let lprScale = d3.scaleThreshold()
.domain([0.05,0.1,0.25,0.75,1.5,4,7.5])
.range(d3sc.schemePuBuGn[9].slice(1));
export let niScale = d3.scaleThreshold()
.domain([0.01,0.1,0.25,.5,1,2.5,5])
.range(d3sc.schemeYlGnBu[9].slice(1));
export let map;
export let datums = {};
let immigrationData = {};


class App extends Component {
Expand Down Expand Up @@ -206,7 +204,7 @@ class App extends Component {
}
}

slideHandler(firstTime) { //BUG3
slideHandler(firstTime) {
if (firstTime) {
this.setState.bind(this)({
isPlaying: true
Expand Down Expand Up @@ -236,89 +234,16 @@ class App extends Component {
}
}


d3.json('./map_geo.json', (err,geofile) => {
if (err) {
console.log(err)
} else {
map = geofile;
for (let i=yearSpan[0]; i <= yearSpan[1]; i = i + 1) {
datums['lpr' + i] = makeMyData(i, 'lpr');
datums['ni' + i] = makeMyData(i, 'ni');
}
}
})

function combinator(world, dataset, flags, year, radioset) {
if (radioset === 'lpr') {
dataset.forEach(function(d) {
d.immediateRelative = +d.immediateRelative;
d.familySponsored = +d.familySponsored;
d.employmentBased = +d.employmentBased;
d.refugeeAsylee = +d.refugeeAsylee;
d.diversityLottery = +d.diversityLottery;
d.adoptedOrphans = +d.adoptedOrphans;
d.otherLPR = +d.otherLPR;
d.total = +d.total;
})
}
if (radioset === 'ni') {
dataset.forEach(function(d) {
d.temporaryVisitor = +d.temporaryVisitor;
d.studentExchange = +d.studentExchange;
d.temporaryWorker = +d.temporaryWorker;
d.diplomatRep = +d.diplomatRep;
d.otherNI = +d.otherNI;
d.total = +d.total;
})
}
dataFlags = dataset.map(data => ({...data, href: flags.find(
flag => flag[0] === data.ISO)[2] }))
datums[radioset+year] = world.features.map(f => ({
type: 'Feature',
id: f.properties.iso_a3,
name: f.properties.name_long,
formalName: f.properties.formal_en,
population: f.properties.pop_est,
geometry: f.geometry,
immigrationData: dataFlags.find(dataFlag =>
dataFlag.ISO === f.properties.iso_a3)
})
)/*.filter(x => x.immigrationData !== undefined)*/
.sort((a,b) => {
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
return 0;
});
if (year === 2005 && radioset === 'lpr') { //**only the first
passFiles(datums,map);
}
if (year === 2016 && radioset === 'ni') { //**and the last
passFiles(datums,map);
}
}

function makeMyData(year, radioset) {
/*loads new dataset and prepares for manipulation*/
d3.csv(("./"+radioset+year+".csv"), function(err, csvData) {
if (err) {
console.log(err)
} else {
combinator(map,csvData,flags,year,radioset);
}
});
}

App.defaultProps = {
lprItems: lprStatics,
niItems: niStatics,
noteItems: noteStatics,
yearBounds: yearSpan,
yearBounds: [2005,2016],
lprThresholds: lprScale.domain(),
lprColors: lprScale.range(),
niThresholds: niScale.domain(),
niColors: niScale.range(),
datums
immigrationData
}

export default App;
4 changes: 2 additions & 2 deletions src/Reusables.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ export class Modal extends Component {
<div className="colossus">From her beacon-hand<br/>
Glows world-wide welcome…<br/>
“Give me your tired, your poor,<br/>
Your huddled masses yearning to breathe free<br/>
Send these, the homeless, tempest-tost to me”
Your huddled masses yearning to breathe free,<br/>
Send these, the homeless, tempest-tost to me.
</div>
<div className="image-credit">image:
<a href="https://goo.gl/Wt4S3r" alt=""
Expand Down
2 changes: 0 additions & 2 deletions src/Statics.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import React, { Component } from 'react';

export let lprStatics = [
{
name: "immediateRelative",
Expand Down
172 changes: 121 additions & 51 deletions src/Visualizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,135 @@ import './Visualizer.css';
import * as d3 from 'd3';
import * as d3geoproj from 'd3-geo-projection';
import {initialFill, fillChoropleth} from './formulas.js';
import {flags} from './flags.js';

//Variable Declarations
let worldMap, svg, g, geoPath, projection, sumSelected, tempdat;
let svg, g, geoPath, projection, sumSelected;
let width, height = 0;
let immigrationData = {};
export let csvData;
export let subtotalKeys = ['immediateRelative','familySponsored','employmentBased','refugeeAsylee','diversityLottery','otherLPR']; //**
export let whichSet;
export let whichYear;

export function passFiles(datums, map) { //**
tempdat = datums;
worldMap = map;
class Visualizer extends Component {

shouldComponentUpdate() {
return false;
}

componentDidMount() {
const self = this;
loadData();
csvData = immigrationData[(this.props.radioDataset).toLowerCase()+this.props.dataYear];
readData(csvData);
calcSelectedTotal(csvData);
initialFill(g,geoPath,'LPR',sumSelected,csvData,self.props.saveAppState,self.props.map);
}

componentWillReceiveProps(nextProps,svg,g,geoPath) {
//determine which data to display
csvData = immigrationData[(nextProps.radioDataset).toLowerCase()+nextProps.dataYear];

whichYear = nextProps.dataYear; //** passes to Card.js
whichSet = nextProps.radioDataset; //**passes to Card.js

getSubtotalKeys(nextProps);
readData(csvData);
calcSelectedTotal(csvData);

//restyle choropleth paths
d3.select('#d3-mount-point').selectAll('path')
.data(csvData)
.attr('fill', function(d) {return fillChoropleth(d, nextProps.radioDataset,sumSelected)})
}

render() {
return (
<div id="d3-mount-point" ref={(elem) => { this.div = elem; }} />
);
}
}

function loadData() {
const self = this;
const immigrationData = {};

d3.json('./map_geo.json', (err,map) => {
if (err) {
console.log(err)
} else {
const combinerProgress = {
filesLeft: (self.props.yearBounds[1] - self.props.yearBounds[0])*2
};

this.setState({map})
initializeD3(map);

for (let i=self.props.yearBounds[0]; i <= self.props.yearBounds[1]; i++) {
immigrationData['lpr' + i] = makeMyData(i, 'lpr', combinerProgress, map);
immigrationData['ni' + i] = makeMyData(i, 'ni', combinerProgress, map);
}
}
});

function makeMyData(year, radioset, combinerProgress, map) {
/*loads new dataset and prepares for manipulation*/
d3.csv(("./"+radioset+year+".csv"), function(err, csvData) {
if (err) {
console.log(err)
} else {
combinator(map,csvData,flags,year,radioset);
combinerProgress.filesLeft -= 1;
if (combinerProgress.filesLeft === 0) {
self.setState({immigrationData});
}
}
});
}

function combinator(world, dataset, flags, year, radioset) {
if (radioset === 'lpr') {
dataset.forEach(function(d) {
d.immediateRelative = +d.immediateRelative;
d.familySponsored = +d.familySponsored;
d.employmentBased = +d.employmentBased;
d.refugeeAsylee = +d.refugeeAsylee;
d.diversityLottery = +d.diversityLottery;
d.adoptedOrphans = +d.adoptedOrphans;
d.otherLPR = +d.otherLPR;
d.total = +d.total;
})
}
if (radioset === 'ni') {
dataset.forEach(function(d) {
d.temporaryVisitor = +d.temporaryVisitor;
d.studentExchange = +d.studentExchange;
d.temporaryWorker = +d.temporaryWorker;
d.diplomatRep = +d.diplomatRep;
d.otherNI = +d.otherNI;
d.total = +d.total;
})
}
let dataFlags = dataset.map(data => ({...data, href: flags.find(
flag => flag[0] === data.ISO)[2] }))
immigrationData[radioset+year] = world.features.map(f => ({
type: 'Feature',
id: f.properties.iso_a3,
name: f.properties.name_long,
formalName: f.properties.formal_en,
population: f.properties.pop_est,
geometry: f.geometry,
immigrationData: dataFlags.find(dataFlag =>
dataFlag.ISO === f.properties.iso_a3)
})
)/*.filter(x => x.immigrationData !== undefined)*/
.sort((a,b) => {
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
return 0;
});
}
}

function initializeD3(worldMap) {
Expand Down Expand Up @@ -47,53 +164,6 @@ function initializeD3(worldMap) {
.projection(projection);
}

export class Visualizer extends Component {

shouldComponentUpdate() {
return false;
}

componentDidMount() {
const self = this;
function checkForData() { //**
if (tempdat === undefined) {
} else {
clearInterval(checkInterval)
//determine which data to display
csvData = tempdat[(self.props.radioDataset).toLowerCase()+self.props.dataYear];
readData(csvData);
calcSelectedTotal(csvData);
initializeD3(worldMap);
initialFill(g,geoPath,'LPR',sumSelected,csvData,self.props.saveAppState,worldMap);
}
}
var checkInterval = setInterval(checkForData,250);
}

componentWillReceiveProps(nextProps,svg,g,geoPath) {
//determine which data to display
csvData = tempdat[(nextProps.radioDataset).toLowerCase()+nextProps.dataYear];

whichYear = nextProps.dataYear;
whichSet = nextProps.radioDataset;

getSubtotalKeys(nextProps);
readData(csvData);
calcSelectedTotal(csvData);

//restyle choropleth paths
d3.select('#d3-mount-point').selectAll('path')
.data(csvData)
.attr('fill', function(d) {return fillChoropleth(d, nextProps.radioDataset,sumSelected)})
}

render() {
return (
<div id="d3-mount-point" ref={(elem) => { this.div = elem; }} />
);
}
}

function getSubtotalKeys(nextProps) {
subtotalKeys = Object.keys(nextProps[nextProps.radioDataset])
.filter(key => nextProps[nextProps.radioDataset][key].checkedStatus === true);
Expand Down

0 comments on commit be479de

Please sign in to comment.