-
-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #224 from hackforla/restructure_application
#153 Create bare containers to establish general layout
- Loading branch information
Showing
29 changed files
with
244 additions
and
875 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,83 +1,22 @@ | ||
import React, { Component } from 'react'; | ||
import axios from 'axios'; | ||
|
||
import { getDataResources } from './Util/DataService'; | ||
import { REQUESTS, COUNCILS } from './components/common/CONSTANTS'; | ||
import React, { useEffect } from 'react'; | ||
import { connect } from 'react-redux'; | ||
|
||
import Header from './components/main/header/Header'; | ||
import Body from './components/main/body/Body'; | ||
import Footer from './components/main/footer/Footer'; | ||
|
||
class App extends Component { | ||
constructor() { | ||
super(); | ||
|
||
this.state = { | ||
data: [], | ||
year: '2015', | ||
startMonth: '1', | ||
endMonth: '12', | ||
request: REQUESTS[0], | ||
showMarkers: false, | ||
showMarkersDropdown: true, | ||
}; | ||
} | ||
|
||
componentDidMount() { | ||
this.fetchData(); | ||
} | ||
|
||
updateState = (key, value, cb = () => null) => { | ||
this.setState({ [key]: value }, () => { | ||
this.fetchData(); // This is only for the dropdown component to fetch data on change | ||
cb(); | ||
}); | ||
} | ||
|
||
toggleShowMarkers = () => { | ||
const { showMarkers } = this.state; | ||
this.setState({ showMarkers: !showMarkers }); | ||
} | ||
|
||
fetchData = () => { | ||
const dataUrl = this.buildDataUrl(); | ||
|
||
axios.get(dataUrl) | ||
.then(({ data }) => { | ||
this.setState({ data }); | ||
}) | ||
.catch((error) => { | ||
console.error(error); | ||
}); | ||
} | ||
|
||
buildDataUrl = () => { | ||
const { | ||
startMonth, endMonth, year, request, | ||
} = this.state; | ||
const dataResources = getDataResources(); | ||
return `https://data.lacity.org/resource/${dataResources[year]}.json?$select=location,zipcode,address,requesttype,status,ncname,streetname,housenumber&$where=date_extract_m(CreatedDate)+between+${startMonth}+and+${endMonth}+and+requesttype='${request}'`; | ||
} | ||
|
||
render() { | ||
const { data, showMarkers, showMarkersDropdown } = this.state; | ||
|
||
return ( | ||
<div className="main"> | ||
<Header | ||
updateState={this.updateState} | ||
toggleShowMarkers={this.toggleShowMarkers} | ||
showMarkers={showMarkers} | ||
showMarkersDropdown={showMarkersDropdown} | ||
/> | ||
<Body | ||
data={data} | ||
showMarkers={showMarkers} | ||
/> | ||
<Footer /> | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
export default App; | ||
const App = () => { | ||
useEffect(() => { | ||
// fetch data on load?? | ||
}, []); | ||
|
||
return ( | ||
<div className="main"> | ||
<Header /> | ||
<Body /> | ||
<Footer /> | ||
</div> | ||
); | ||
}; | ||
|
||
export default connect(null, null)(App); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,95 +1,97 @@ | ||
import DataFrame from 'dataframe-js'; | ||
|
||
const dataResources = { | ||
2019:"pvft-t768", | ||
2018:"h65r-yf5i", | ||
2017:"d4vt-q4t5", | ||
2016:"ndkd-k878", | ||
2015:"ms7h-a45h" | ||
} | ||
2019: 'pvft-t768', | ||
2018: 'h65r-yf5i', | ||
2017: 'd4vt-q4t5', | ||
2016: 'ndkd-k878', | ||
2015: 'ms7h-a45h', | ||
}; | ||
|
||
export function getDataResources() { | ||
return dataResources; | ||
} | ||
|
||
export function getColorMap(discrete){ | ||
if(discrete){ | ||
export function getColorMap(discrete) { | ||
if (discrete) { | ||
return [ | ||
{title: "Dead Animal Removal", color:"#3b69a6"}, | ||
{title: "Other",color:"#0dd311"}, | ||
{title: "Homeless Encampment",color:"#c1614e"}, | ||
{title: "Single Streetlight Issue",color:"#304bb5"}, | ||
{title: "Electronic Waste",color:"#41a84b"}, | ||
{title: "Feedback",color:"#c2f961"}, | ||
{title: "Graffiti Removal",color:"#4d6173"}, | ||
{title: "Multiple Streetlight Issue",color:"#9f2826"}, | ||
{title: "Metal/Household Appliances",color:"#306088"}, | ||
{title: "Illegal Dumping Pickup",color:"#b6d4df"}, | ||
{title: "Bulky Items",color:"#7f2a10"}, | ||
{title: "Report Water Waste",color:"#f7a6ce"} | ||
]; | ||
} else { | ||
return { | ||
"Dead Animal Removal":"#3b69a6", | ||
"Other":"#0dd311", | ||
"Homeless Encampment":"#c1614e", | ||
"Single Streetlight Issue":"#304bb5", | ||
"Electronic Waste":"#41a84b", | ||
"Feedback":"#c2f961", | ||
"Graffiti Removal":"#4d6173", | ||
"Multiple Streetlight Issue":"#9f2826", | ||
"Metal/Household Appliances":"#306088", | ||
"Illegal Dumping Pickup":"#b6d4df", | ||
"Bulky Items":"#7f2a10", | ||
"Report Water Waste":"#f7a6ce" | ||
}; | ||
{ title: 'Dead Animal Removal', color: '#3b69a6' }, | ||
{ title: 'Other', color: '#0dd311' }, | ||
{ title: 'Homeless Encampment', color: '#c1614e' }, | ||
{ title: 'Single Streetlight Issue', color: '#304bb5' }, | ||
{ title: 'Electronic Waste', color: '#41a84b' }, | ||
{ title: 'Feedback', color: '#c2f961' }, | ||
{ title: 'Graffiti Removal', color: '#4d6173' }, | ||
{ title: 'Multiple Streetlight Issue', color: '#9f2826' }, | ||
{ title: 'Metal/Household Appliances', color: '#306088' }, | ||
{ title: 'Illegal Dumping Pickup', color: '#b6d4df' }, | ||
{ title: 'Bulky Items', color: '#7f2a10' }, | ||
{ title: 'Report Water Waste', color: '#f7a6ce' }, | ||
]; | ||
} | ||
return { | ||
'Dead Animal Removal': '#3b69a6', | ||
Other: '#0dd311', | ||
'Homeless Encampment': '#c1614e', | ||
'Single Streetlight Issue': '#304bb5', | ||
'Electronic Waste': '#41a84b', | ||
Feedback: '#c2f961', | ||
'Graffiti Removal': '#4d6173', | ||
'Multiple Streetlight Issue': '#9f2826', | ||
'Metal/Household Appliances': '#306088', | ||
'Illegal Dumping Pickup': '#b6d4df', | ||
'Bulky Items': '#7f2a10', | ||
'Report Water Waste': '#f7a6ce', | ||
}; | ||
} | ||
|
||
export function getBroadCallVolume(year, startMonth=0, endMonth=13, onBroadDataReady){ | ||
let treemap_data = {"title": "Broad 311 Calls Map", "color": "#FFFFFF", "children": []}; | ||
const start = Math.min(startMonth, endMonth) | ||
const end = Math.max(startMonth, endMonth) | ||
export function getBroadCallVolume(year, startMonth = 0, endMonth = 13, onBroadDataReady) { | ||
const treemap_data = { title: 'Broad 311 Calls Map', color: '#FFFFFF', children: [] }; | ||
const start = Math.min(startMonth, endMonth); | ||
const end = Math.max(startMonth, endMonth); | ||
|
||
DataFrame.fromJSON(`https://data.lacity.org/resource/${dataResources[year]}.json?$select=count(*)+AS+CallVolume,NCName,RequestType&$where=date_extract_m(CreatedDate)+between+${start}+and+${end}&$group=NCName,RequestType&$order=CallVolume DESC`) | ||
.then(df => { | ||
df.show(); | ||
.then((df) => { | ||
df.show(); | ||
|
||
const totalCounts = df.groupBy("ncname").aggregate(group => group.stat.sum("callvolume")).rename("aggregation", "callvolume"); | ||
let biggestProblems = {}; | ||
df.toCollection().forEach(row => { | ||
const rhs = parseInt(row.callvolume); | ||
const lhs = parseInt(biggestProblems[row.ncname]); | ||
if(!lhs){ | ||
biggestProblems[row.ncname] = rhs; | ||
biggestProblems[`${row.ncname}_biggestproblem`] = row.requesttype; | ||
} | ||
else if (lhs < rhs){ | ||
biggestProblems[row.ncname] = rhs; | ||
biggestProblems[`${row.ncname}_biggestproblem`] = row.requesttype; | ||
} | ||
const totalCounts = df.groupBy('ncname').aggregate((group) => group.stat.sum('callvolume')).rename('aggregation', 'callvolume'); | ||
const biggestProblems = {}; | ||
df.toCollection().forEach((row) => { | ||
const rhs = parseInt(row.callvolume, 10); | ||
const lhs = parseInt(biggestProblems[row.ncname], 10); | ||
if (!lhs) { | ||
biggestProblems[row.ncname] = rhs; | ||
biggestProblems[`${row.ncname}_biggestproblem`] = row.requesttype; | ||
} else if (lhs < rhs) { | ||
biggestProblems[row.ncname] = rhs; | ||
biggestProblems[`${row.ncname}_biggestproblem`] = row.requesttype; | ||
} | ||
}); | ||
const colorMap = getColorMap(false); | ||
totalCounts.toCollection().forEach((row) => { | ||
const biggestProblem = biggestProblems[`${row.ncname}_biggestproblem`]; | ||
const data_point = { | ||
title: row.ncname, | ||
color: colorMap[biggestProblem], | ||
size: row.callvolume, | ||
}; | ||
treemap_data.children.push(data_point); | ||
}); | ||
onBroadDataReady(treemap_data); | ||
}); | ||
const colorMap = getColorMap(false); | ||
totalCounts.toCollection().forEach(row => { | ||
const biggestProblem = biggestProblems[`${row.ncname}_biggestproblem`]; | ||
const data_point = {"title": row.ncname, "color": colorMap[biggestProblem] , "size": row.callvolume}; | ||
treemap_data["children"].push(data_point); | ||
}) | ||
onBroadDataReady(treemap_data); | ||
}); | ||
} | ||
|
||
export function getZoomedCallVolume(ncName, year, startMonth=0, endMonth=13, onZoomedDataReady){ | ||
let treemap_data = {"title": "Zoomed 311 Calls Map", "color": "#FFFFFF", "children": []}; | ||
const start = Math.min(startMonth, endMonth) | ||
const end = Math.max(startMonth, endMonth) | ||
export function getZoomedCallVolume(ncName, year, startMonth = 0, endMonth = 13, onZoomedDataReady) { | ||
const treemap_data = { title: 'Zoomed 311 Calls Map', color: '#FFFFFF', children: [] }; | ||
const start = Math.min(startMonth, endMonth); | ||
const end = Math.max(startMonth, endMonth); | ||
|
||
DataFrame.fromJSON(`https://data.lacity.org/resource/${dataResources[year]}.json?$select=count(*)+AS+CallVolume,NCName,RequestType&$where=NCName+=+'${ncName}'+and+date_extract_m(CreatedDate)+between+${start}+and+${end}&$group=NCName,RequestType&$order=CallVolume DESC`).then(df => { | ||
DataFrame.fromJSON(`https://data.lacity.org/resource/${dataResources[year]}.json?$select=count(*)+AS+CallVolume,NCName,RequestType&$where=NCName+=+'${ncName}'+and+date_extract_m(CreatedDate)+between+${start}+and+${end}&$group=NCName,RequestType&$order=CallVolume DESC`).then((df) => { | ||
const colorMap = getColorMap(false); | ||
df.toCollection().forEach(row => { | ||
const data_point = {"title": row.requesttype, "color": colorMap[row.requesttype] , "size": row.callvolume}; | ||
treemap_data["children"].push(data_point); | ||
}) | ||
df.toCollection().forEach((row) => { | ||
const data_point = { title: row.requesttype, color: colorMap[row.requesttype], size: row.callvolume }; | ||
treemap_data.children.push(data_point); | ||
}); | ||
onZoomedDataReady(treemap_data); | ||
}); | ||
} |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.