From 5e5cb85a25ee35dbed03beddbf26a98122b64914 Mon Sep 17 00:00:00 2001 From: Conrad S Date: Wed, 15 Mar 2017 14:34:28 -0400 Subject: [PATCH 01/16] First test --- src/components/TurkHit/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/TurkHit/index.js b/src/components/TurkHit/index.js index 7ce0d776..126e3056 100644 --- a/src/components/TurkHit/index.js +++ b/src/components/TurkHit/index.js @@ -1,4 +1,5 @@ import React, { PropTypes, Component } from 'react'; +import Polygon from 'react-polygon'; import defaultForm from './defaultForm'; import './styles.css'; import turkHitPropTypes from '../../containers/Dimensions/propTypes'; @@ -168,6 +169,7 @@ class TurkHit extends Component { } mainContent = (
+ {currStatus.createBtn && this.renderCreateHitButton()}
-- GitLab From 4becac20847a08adb718ecf77e37592ccffff8dd Mon Sep 17 00:00:00 2001 From: Conrad S Date: Wed, 15 Mar 2017 14:35:06 -0400 Subject: [PATCH 02/16] Add polygon req --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index f0a5c583..0512af51 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "bpl": "git+https://7f8bbb4b0a383ad905fee5b0f7cbc0c22533b556:x-oauth-basic@github.com/Blocp/bpl.git", "react": "^15.3.2", "react-dom": "^15.3.2", + "react-polygon": "^0.1.0", "react-redux": "^4.4.5", "react-router": "^3.0.0", "react-router-redux": "^4.0.7", -- GitLab From a993fc365648bc779a12065363bff1aa2a99abe3 Mon Sep 17 00:00:00 2001 From: Conrad S Date: Wed, 15 Mar 2017 15:35:35 -0400 Subject: [PATCH 03/16] Graph the points --- src/components/TurkHit/features.js | 9 +++++++++ src/components/TurkHit/index.js | 23 +++++++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 src/components/TurkHit/features.js diff --git a/src/components/TurkHit/features.js b/src/components/TurkHit/features.js new file mode 100644 index 00000000..aa8c5b83 --- /dev/null +++ b/src/components/TurkHit/features.js @@ -0,0 +1,9 @@ +const featuresDict = { + 1: 'Door', + 2: 'Window', + 3: 'Building Point', + 4: 'Roof Point', + +}; + +export default featuresDict; diff --git a/src/components/TurkHit/index.js b/src/components/TurkHit/index.js index 126e3056..32ebdf3e 100644 --- a/src/components/TurkHit/index.js +++ b/src/components/TurkHit/index.js @@ -1,7 +1,8 @@ import React, { PropTypes, Component } from 'react'; -import Polygon from 'react-polygon'; +import { ScatterChart, XAxis, YAxis, CartesianGrid, Tooltip, Legend, Scatter } from 'recharts'; import defaultForm from './defaultForm'; import './styles.css'; +import featuresDict from './features'; import turkHitPropTypes from '../../containers/Dimensions/propTypes'; import documentsPropType from '../../containers/Documents/propTypes'; import turkStatus from './turkStatus'; @@ -167,9 +168,27 @@ class TurkHit extends Component { ); } + const data = curHit.dimensions.points.reduce((acc, val) => { + if (featuresDict[val.feature] === 'Building Point') { + acc.push({ x: val.latitude, y: val.longitude }); + } + return acc; + }, []); + console.log(data); mainContent = (
- + + + + + + + + {currStatus.createBtn && this.renderCreateHitButton()}
-- GitLab From cafa66ff01e20ed46d6298ab43c031e662261a68 Mon Sep 17 00:00:00 2001 From: Conrad S Date: Thu, 16 Mar 2017 16:15:36 -0400 Subject: [PATCH 04/16] Explore 3d graphics packages --- src/components/TurkHit/index.js | 180 ++++++++++++++++++++++--- src/containers/Dimensions/propTypes.js | 38 ++++++ 2 files changed, 202 insertions(+), 16 deletions(-) diff --git a/src/components/TurkHit/index.js b/src/components/TurkHit/index.js index 32ebdf3e..8a6b399f 100644 --- a/src/components/TurkHit/index.js +++ b/src/components/TurkHit/index.js @@ -1,5 +1,5 @@ import React, { PropTypes, Component } from 'react'; -import { ScatterChart, XAxis, YAxis, CartesianGrid, Tooltip, Legend, Scatter } from 'recharts'; +import 'highcharts-3d'; import defaultForm from './defaultForm'; import './styles.css'; import featuresDict from './features'; @@ -7,6 +7,12 @@ import turkHitPropTypes from '../../containers/Dimensions/propTypes'; import documentsPropType from '../../containers/Documents/propTypes'; import turkStatus from './turkStatus'; +const Highcharts = require('highcharts'); +const ReactHighcharts = require('react-highcharts'); +require('highcharts-3d')(ReactHighcharts.Highcharts); +/* eslint-disable */ +//import { ScatterChart, ZAxis, XAxis, YAxis, CartesianGrid, Tooltip, Legend, Scatter } from 'recharts'; + class TurkHit extends Component { constructor(props) { @@ -14,6 +20,15 @@ class TurkHit extends Component { // TODO not being used this.state = { + displayChart: false, + chart: null, + chartDrag: { + posX: null, + posY: null, + alpha: null, + beta: null, + sensitivity: 5, + }, error: false, }; } @@ -31,6 +46,10 @@ class TurkHit extends Component { hitDecision(hit, approve, responseMessage); } + toggleDisplayChart = () => { + this.setState({ displayChart: !this.state.displayChart }); + } + renderDefinitions = () => (

Mechanical Turk

@@ -131,6 +150,142 @@ class TurkHit extends Component { }) ) + renderChartToggleButton = () => ( +
+ +
+ ) + + renderChart = (building_points, roof_points) => { + let chartDiv = (
); + if (this.state.displayChart) { +// chart = ( +// +// +// +// +// +// +// +// +// +// ); + + // Set up the chart + chartDiv =
; + + Highcharts.getOptions().colors = Highcharts.getOptions().colors.map((color) => ( + { + radialGradient: { + cx: 0.4, + cy: 0.3, + r: 0.5 + }, + stops: [ + [0, color], + [1, Highcharts.Color(color).brighten(-0.2).get('rgb')] + ] + } + )); + const chart = new Highcharts.Chart({ + chart: { + renderTo: 'chart-container', + margin: 100, + type: 'scatter', + options3d: { + enabled: true, + alpha: 10, + beta: 30, + depth: 250, + viewDistance: 5, + fitToPlot: false, + frame: { + bottom: { size: 1, color: 'rgba(0,0,0,0.02)' }, + back: { size: 1, color: 'rgba(0,0,0,0.04)' }, + side: { size: 1, color: 'rgba(0,0,0,0.06)' } + } + } + }, + title: { + text: 'Draggable box' + }, + subtitle: { + text: 'Click and drag the plot area to rotate in space' + }, + plotOptions: { + scatter: { + lineWidth: 2, + width: 10, + height: 10, + depth: 10 + } + }, + yAxis: { + title: 'height' + }, + xAxis: { + gridLineWidth: 1 + }, + zAxis: { + showFirstLabel: false + }, + legend: { + enabled: false + }, + series: [ + { + name: 'Building Points', + colorByPoint: false, + data: building_points, + }, + { + name: 'Roof Points', + colorByPoint: false, + data: roof_points, + } + ] + }); + // this.setState({ chart }); + console.log(chart); + chart.container.onmousedown = (event) => { + this.setState({ + chartDrag: { + ...this.state.chartDrag, + posX: event.pageX, + posY: event.pageY, + alpha: chart.options.chart.options3d.alpha, + beta: chart.options.chart.options3d.beta, + } + }); + console.log(event); + }; + chart.container.onmousedrag = (event) => { + const { beta, alpha, posX, posY, sensitivity } = this.state.chartDrag; + + const newBeta = beta + (posX - event.pageX) / sensitivity; + chart.options.chart.options3d.beta = newBeta; + + const newAlpha = alpha + (event.pageY - posY) / sensitivity; + chart.options.chart.options3d.alpha = newAlpha; + + this.chart.redraw(false); + }; + } + + + return chartDiv; + + } + render() { const { hit } = this.props; const status = hit.status; @@ -169,26 +324,17 @@ class TurkHit extends Component { ); } const data = curHit.dimensions.points.reduce((acc, val) => { + const point = [val.latitude, val.corresponding_height, val.longitude] + if (featuresDict[val.feature] === 'Building Point') { - acc.push({ x: val.latitude, y: val.longitude }); + acc.building_points.push(point); + } else { + acc.roof_points.push(point); } return acc; - }, []); - console.log(data); + }, {building_points: [], roof_points: []}); mainContent = (
- - - - - - - - {currStatus.createBtn && this.renderCreateHitButton()}
@@ -203,6 +349,8 @@ class TurkHit extends Component {
{currStatus.downloadLink && this.renderDownloadLink(curHit.csv_document_key)} {currStatus.fileActions && this.renderHitActions(curHit)} + {data && this.renderChartToggleButton()} + {this.renderChart(data.building_points, data.roof_points)}
diff --git a/src/containers/Dimensions/propTypes.js b/src/containers/Dimensions/propTypes.js index d0d0b824..c942a4d9 100644 --- a/src/containers/Dimensions/propTypes.js +++ b/src/containers/Dimensions/propTypes.js @@ -2,12 +2,50 @@ import { PropTypes } from 'react'; const { shape, arrayOf, string, number, bool, oneOfType, instanceOf } = PropTypes; +export const buildingDimensionsProps = shape({ + area: number, + perimeter: number, + ground_elevation: number, + number_floors: number, + hit_id: number, + building_id: number, + id: number, +}); + +export const pointsProps = shape({ + latitude: number, + longitude: number, + elevation: number, + adjacent: bool, + feature: number, + hit_id: number, + building_id: number, + id: number, +}); + +export const windowsDoorsProps = shape({ + height: number, + width: number, + quantity: number, + orientation: number, + direction: number, + feature: number, + hit_id: number, + building_id: number, + id: number, +}); + export const hitDataProps = shape({ status_id: number, amazon_hit_id: string, building_id: number, csv_document_key: string, db_id: number, + dimensions: shape({ + building_dimensions: buildingDimensionsProps, + points: arrayOf(pointsProps), + windows_doors: arrayOf(windowsDoorsProps), + }), hit_date: string, requester_name: string, shapefile_document_key: string, -- GitLab From b2539ec36b695a6ca1bf5447c2aec5494a55f0c8 Mon Sep 17 00:00:00 2001 From: Conrad S Date: Thu, 16 Mar 2017 17:50:26 -0400 Subject: [PATCH 05/16] Add 3D chart with highchart --- package.json | 5 +- src/components/TurkHit/index.js | 225 +++++++++++++++++--------------- 2 files changed, 125 insertions(+), 105 deletions(-) diff --git a/package.json b/package.json index 0512af51..15bb46c2 100644 --- a/package.json +++ b/package.json @@ -55,12 +55,15 @@ }, "dependencies": { "bpl": "git+https://7f8bbb4b0a383ad905fee5b0f7cbc0c22533b556:x-oauth-basic@github.com/Blocp/bpl.git", + "highcharts": "^5.0.9", + "highcharts-3d": "^0.1.2", "react": "^15.3.2", "react-dom": "^15.3.2", - "react-polygon": "^0.1.0", + "react-highcharts": "^11.5.0", "react-redux": "^4.4.5", "react-router": "^3.0.0", "react-router-redux": "^4.0.7", + "recharts": "^0.21.2", "redux": "^3.6.0", "redux-saga": "^0.14.2", "whatwg-fetch": "^1.0.0" diff --git a/src/components/TurkHit/index.js b/src/components/TurkHit/index.js index 8a6b399f..767d22d1 100644 --- a/src/components/TurkHit/index.js +++ b/src/components/TurkHit/index.js @@ -1,5 +1,4 @@ import React, { PropTypes, Component } from 'react'; -import 'highcharts-3d'; import defaultForm from './defaultForm'; import './styles.css'; import featuresDict from './features'; @@ -23,6 +22,7 @@ class TurkHit extends Component { displayChart: false, chart: null, chartDrag: { + dragging: false, posX: null, posY: null, alpha: null, @@ -33,6 +33,13 @@ class TurkHit extends Component { }; } + componentDidUpdate() { + // Resize the chart + if (this.state.chart) { + this.state.chart.reflow(); + } + } + handleHitDecision = (hit, approve) => { const { hitDecision } = this.props; let responseMessage = null; @@ -46,7 +53,114 @@ class TurkHit extends Component { hitDecision(hit, approve, responseMessage); } - toggleDisplayChart = () => { + toggleDisplayChart = (building_points, roof_points) => { + if (!this.state.chart) { + Highcharts.getOptions().colors = Highcharts.getOptions().colors.map((color) => ( + { + radialGradient: { + cx: 0.4, + cy: 0.3, + r: 0.5 + }, + stops: [ + [0, color], + [1, Highcharts.Color(color).brighten(-0.2).get('rgb')] + ] + } + )); + const chart = new Highcharts.Chart({ + chart: { + renderTo: 'chart-container', + margin: 100, + type: 'scatter', + options3d: { + enabled: true, + alpha: 10, + beta: 30, + depth: 250, + viewDistance: 5, + fitToPlot: false, + frame: { + bottom: { size: 1, color: 'rgba(0,0,0,0.02)' }, + back: { size: 1, color: 'rgba(0,0,0,0.04)' }, + side: { size: 1, color: 'rgba(0,0,0,0.06)' } + } + }, + }, + title: { + text: 'Draggable box' + }, + subtitle: { + text: 'Click and drag the plot area to rotate in space' + }, + plotOptions: { + scatter: { + lineWidth: 2, + width: 10, + height: 10, + depth: 10 + } + }, + yAxis: { + title: 'height' + }, + xAxis: { + gridLineWidth: 1 + }, + zAxis: { + showFirstLabel: false + }, + legend: { + enabled: false + }, + series: [ + { + name: 'Building Points', + colorByPoint: false, + data: building_points, + }, + { + name: 'Roof Points', + colorByPoint: false, + data: roof_points, + } + ] + }); + this.setState({ chart }); + + chart.container.onmousedown = (event) => { + this.setState({ + chartDrag: { + ...this.state.chartDrag, + dragging: true, + posX: event.pageX, + posY: event.pageY, + alpha: this.state.chart.options.chart.options3d.alpha, + beta: this.state.chart.options.chart.options3d.beta, + } + }); + }; + chart.container.onmousemove = (event) => { + const { dragging, beta, alpha, posX, posY, sensitivity } = this.state.chartDrag; + if (dragging) { + const newBeta = beta + (posX - event.pageX) / sensitivity; + this.state.chart.options.chart.options3d.beta = newBeta; + + const newAlpha = alpha + (event.pageY - posY) / sensitivity; + this.state.chart.options.chart.options3d.alpha = newAlpha; + + this.state.chart.redraw(false); + } + }; + chart.container.onmouseup = (event) => { + this.setState({ + chartDrag: { + ...this.state.chartDrag, + dragging: false, + } + }) + }; + } this.setState({ displayChart: !this.state.displayChart }); } @@ -150,18 +264,18 @@ class TurkHit extends Component { }) ) - renderChartToggleButton = () => ( + renderChartToggleButton = (data) => (
) - renderChart = (building_points, roof_points) => { + renderChart = () => { let chartDiv = (
); if (this.state.displayChart) { // chart = ( @@ -182,103 +296,6 @@ class TurkHit extends Component { // Set up the chart chartDiv =
; - - Highcharts.getOptions().colors = Highcharts.getOptions().colors.map((color) => ( - { - radialGradient: { - cx: 0.4, - cy: 0.3, - r: 0.5 - }, - stops: [ - [0, color], - [1, Highcharts.Color(color).brighten(-0.2).get('rgb')] - ] - } - )); - const chart = new Highcharts.Chart({ - chart: { - renderTo: 'chart-container', - margin: 100, - type: 'scatter', - options3d: { - enabled: true, - alpha: 10, - beta: 30, - depth: 250, - viewDistance: 5, - fitToPlot: false, - frame: { - bottom: { size: 1, color: 'rgba(0,0,0,0.02)' }, - back: { size: 1, color: 'rgba(0,0,0,0.04)' }, - side: { size: 1, color: 'rgba(0,0,0,0.06)' } - } - } - }, - title: { - text: 'Draggable box' - }, - subtitle: { - text: 'Click and drag the plot area to rotate in space' - }, - plotOptions: { - scatter: { - lineWidth: 2, - width: 10, - height: 10, - depth: 10 - } - }, - yAxis: { - title: 'height' - }, - xAxis: { - gridLineWidth: 1 - }, - zAxis: { - showFirstLabel: false - }, - legend: { - enabled: false - }, - series: [ - { - name: 'Building Points', - colorByPoint: false, - data: building_points, - }, - { - name: 'Roof Points', - colorByPoint: false, - data: roof_points, - } - ] - }); - // this.setState({ chart }); - console.log(chart); - chart.container.onmousedown = (event) => { - this.setState({ - chartDrag: { - ...this.state.chartDrag, - posX: event.pageX, - posY: event.pageY, - alpha: chart.options.chart.options3d.alpha, - beta: chart.options.chart.options3d.beta, - } - }); - console.log(event); - }; - chart.container.onmousedrag = (event) => { - const { beta, alpha, posX, posY, sensitivity } = this.state.chartDrag; - - const newBeta = beta + (posX - event.pageX) / sensitivity; - chart.options.chart.options3d.beta = newBeta; - - const newAlpha = alpha + (event.pageY - posY) / sensitivity; - chart.options.chart.options3d.alpha = newAlpha; - - this.chart.redraw(false); - }; } @@ -349,8 +366,8 @@ class TurkHit extends Component {
{currStatus.downloadLink && this.renderDownloadLink(curHit.csv_document_key)} {currStatus.fileActions && this.renderHitActions(curHit)} - {data && this.renderChartToggleButton()} - {this.renderChart(data.building_points, data.roof_points)} + {data && this.renderChartToggleButton(data)} + {this.renderChart()}
-- GitLab From 22328bf042cdd101b8d407a5ba86faf22a7794c9 Mon Sep 17 00:00:00 2001 From: Conrad S Date: Mon, 20 Mar 2017 14:42:26 -0400 Subject: [PATCH 06/16] Remove print and console --- src/components/TurkHit/index.js | 4 ++-- src/components/Utilities/index.js | 18 +++++++----------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/components/TurkHit/index.js b/src/components/TurkHit/index.js index 2ff937ed..1dabdbc2 100644 --- a/src/components/TurkHit/index.js +++ b/src/components/TurkHit/index.js @@ -201,13 +201,13 @@ class TurkHit extends Component { ); } - return (); + return (); } renderCreateHitButton = () => { const { createHitConfirmation, address, building_id } = this.props; return ( -
+
@@ -276,23 +295,6 @@ class TurkHit extends Component { renderChart = () => { let chartDiv = (
); if (this.state.displayChart) { -// chart = ( -// -// -// -// -// -// -// -// -// -// ); - - // Set up the chart chartDiv =
; } @@ -338,16 +340,6 @@ class TurkHit extends Component {
); } - const data = curHit.dimensions.points.reduce((acc, val) => { - const point = [val.latitude, val.corresponding_height, val.longitude] - - if (featuresDict[val.feature] === 'Building Point') { - acc.building_points.push(point); - } else { - acc.roof_points.push(point); - } - return acc; - }, {building_points: [], roof_points: []}); mainContent = (
{currStatus.createBtn && this.renderCreateHitButton()} @@ -364,7 +356,7 @@ class TurkHit extends Component {
{currStatus.downloadLink && this.renderDownloadLink(curHit.csv_document_key)} {currStatus.fileActions && this.renderHitActions(curHit)} - {data && this.renderChartToggleButton(data)} + {this.state.chart && this.renderChartToggleButton()} {this.renderChart()}
-- GitLab From a65dee06f74145bc6956eda209904cc9a74e6b65 Mon Sep 17 00:00:00 2001 From: Conrad S Date: Tue, 21 Mar 2017 12:33:57 -0400 Subject: [PATCH 08/16] Eslint changes --- src/components/TurkHit/index.js | 83 ++++++++++++++++----------------- 1 file changed, 41 insertions(+), 42 deletions(-) diff --git a/src/components/TurkHit/index.js b/src/components/TurkHit/index.js index b8b2e76b..f2d1ed31 100644 --- a/src/components/TurkHit/index.js +++ b/src/components/TurkHit/index.js @@ -9,9 +9,6 @@ import turkStatus from './turkStatus'; const Highcharts = require('highcharts'); const ReactHighcharts = require('react-highcharts'); require('highcharts-3d')(ReactHighcharts.Highcharts); -/* eslint-disable */ -//import { ScatterChart, ZAxis, XAxis, YAxis, CartesianGrid, Tooltip, Legend, Scatter } from 'recharts'; - class TurkHit extends Component { constructor(props) { @@ -43,28 +40,28 @@ class TurkHit extends Component { const curHit = this.props.hit.hitData[0]; const data = curHit.dimensions.points.reduce((acc, val) => { - const point = [val.latitude, val.corresponding_height, val.longitude] + const point = [val.latitude, val.corresponding_height, val.longitude]; if (featuresDict[val.feature] === 'Building Point') { - acc.building_points.push(point); + acc.buildingPoints.push(point); } else { - acc.roof_points.push(point); + acc.roofPoints.push(point); } return acc; - }, {building_points: [], roof_points: []}); - const building_points = data.building_points; - const roof_points = data.roof_points; - Highcharts.getOptions().colors = Highcharts.getOptions().colors.map((color) => ( + }, { buildingPoints: [], roofPoints: [] }); + const buildingPoints = data.buildingPoints; + const roofPoints = data.roofPoints; + Highcharts.getOptions().colors = Highcharts.getOptions().colors.map(color => ( { radialGradient: { cx: 0.4, cy: 0.3, - r: 0.5 + r: 0.5, }, stops: [ [0, color], - [1, Highcharts.Color(color).brighten(-0.2).get('rgb')] - ] + [1, Highcharts.Color(color).brighten(-0.2).get('rgb')], + ], } )); const chart = new Highcharts.Chart({ @@ -82,51 +79,55 @@ class TurkHit extends Component { frame: { bottom: { size: 1, color: 'rgba(0,0,0,0.02)' }, back: { size: 1, color: 'rgba(0,0,0,0.04)' }, - side: { size: 1, color: 'rgba(0,0,0,0.06)' } - } + side: { size: 1, color: 'rgba(0,0,0,0.06)' }, + }, }, }, title: { - text: 'Roof and Building Points' + text: 'Roof and Building Points', }, subtitle: { - text: 'Click and drag the plot area to rotate in space' + text: 'Click and drag the plot area to rotate in space', }, plotOptions: { scatter: { lineWidth: 2, width: 10, height: 10, - depth: 10 - } + depth: 10, + }, }, yAxis: { - title: 'height' + title: 'height', }, xAxis: { - gridLineWidth: 1 + gridLineWidth: 1, }, zAxis: { - showFirstLabel: false + showFirstLabel: false, }, legend: { - enabled: false + enabled: false, }, series: [ { name: 'Building Points', colorByPoint: false, - data: building_points, + data: buildingPoints, }, { name: 'Roof Points', colorByPoint: false, - data: roof_points, - } - ] + data: roofPoints, + }, + ], }); + // We need to set state AFTER the component updates because + // the chart requires that the
it is targetting + // is already rendered + /* eslint-disable react/no-did-update-set-state */ this.setState({ chart }); - + chart.container.onmousedown = (event) => { this.setState({ chartDrag: { @@ -136,28 +137,28 @@ class TurkHit extends Component { posY: event.pageY, alpha: this.state.chart.options.chart.options3d.alpha, beta: this.state.chart.options.chart.options3d.beta, - } - }); + }, + }); }; chart.container.onmousemove = (event) => { const { dragging, beta, alpha, posX, posY, sensitivity } = this.state.chartDrag; if (dragging) { - const newBeta = beta + (posX - event.pageX) / sensitivity; + const newBeta = beta + ((posX - event.pageX) / sensitivity); this.state.chart.options.chart.options3d.beta = newBeta; - - const newAlpha = alpha + (event.pageY - posY) / sensitivity; + + const newAlpha = alpha + ((event.pageY - posY) / sensitivity); this.state.chart.options.chart.options3d.alpha = newAlpha; - + this.state.chart.redraw(false); } }; - chart.container.onmouseup = (event) => { + chart.container.onmouseup = () => { this.setState({ chartDrag: { ...this.state.chartDrag, dragging: false, - } - }) + }, + }); }; } // Resize the chart @@ -226,7 +227,7 @@ class TurkHit extends Component { renderCreateHitButton = () => { const { createHitConfirmation, address, building_id } = this.props; return ( -
+
+
+
+
+ ); + } + + renderHitActions = hit => ( +
+ + +
+ ) + + renderOldHits = oldHitList => ( + oldHitList.map((val) => { + const currStatus = turkStatus[val.status_id]; + return ( +
+
+ + + + + + +
Status{currStatus.message}
Message{val.response_message}
Creation Date{val.hit_date}
Creator{val.requester_name}
+

+ {this.renderDownloadLink(val.csv_document_key)} +

+
+ ); + }) + ) + + renderChartToggleButton = () => ( +
+ +
+ ) + + renderChart = () => { + let chartDiv = (
); + if (this.state.displayChart) { + chartDiv = ( +
+
+
+ ); + } + + return chartDiv; + } + + render() { + const { hit } = this.props; + const status = hit.status; + + let mainContent =
; + if (hit.loading) { + return ( +
+ {this.renderDefinitions()} +

Loading... Please be patient and do not refresh the page...

+
+ ); + } else if (hit.error && hit.error.response.status !== 404) { + return ( +
+ Retrieving HIT error. Response message: {hit.error.message} +
+ ); + } + + + let oldHits = (
); + if (hit.hitData.length > 0 && status !== null) { + const curHit = hit.hitData[0]; + const currStatus = turkStatus[status]; + if (hit.hitData.length > 1) { + oldHits = ( +
+

Previously created hits

+
Definitions
+

+ These are hits that are no longer active. +

+ {this.renderOldHits(hit.hitData.slice(1))} +
+ ); + } + mainContent = ( +
+ {currStatus.createBtn && this.renderCreateHitButton()} +
+ + + + {curHit.response_message ? + () : } + + + +
Status{currStatus.message}
Message{curHit.response_message}
Creation Date{curHit.hit_date}
Creator{curHit.requester_name}
+
+ {currStatus.downloadLink && this.renderDownloadLink(curHit.csv_document_key)} + {currStatus.fileActions && this.renderHitActions(curHit)} + {this.state.chart && this.renderChartToggleButton()} + {this.renderChart()} +
+
+
+ ); + } else { + mainContent = ( +
+

HIT has not been created yet.

+ {this.renderCreateHitButton()} +
+ ); + } + + return ( +
+
+ Failed to create HIT. Response message: {hit.create.error.message} +
+ {this.renderDefinitions()} + {mainContent} + {oldHits} +
+ ); + } +} + +TurkHit.propTypes = { + createHitConfirmation: PropTypes.func, + hitDecision: PropTypes.func, + address: PropTypes.string, + building_id: PropTypes.number, + hit: turkHitPropTypes, + documents: documentsPropType, +}; + +export default TurkHit; diff --git a/src/components/TurkHit/index.js b/src/components/TurkHit/index.js index 6b3c18ea..3d7f0fba 100644 --- a/src/components/TurkHit/index.js +++ b/src/components/TurkHit/index.js @@ -39,8 +39,26 @@ class TurkHit extends Component { !this.state.chart) { const curHit = this.props.hit.hitData[0]; + // Calculate the minLat to get a measurement + let minLat = null; + let minLong = null; + let maxFoot = null; + const data = curHit.dimensions.points.reduce((acc, val) => { - const point = [val.latitude, val.corresponding_height, val.longitude]; + // Convert latitude and longitude to feet + const latitudeFeet = (val.latitude * 364488.888889); + const longitudeFeet = (val.longitude * 364488.888889); + if ((minLat === null) || (latitudeFeet < minLat)) { + minLat = latitudeFeet; + } + if ((minLong === null) || (longitudeFeet < minLong)) { + minLong = longitudeFeet; + } + if ((maxFoot === null) || (val.corresponding_height > maxFoot)) { + maxFoot = val.corresponding_height; + } + + const point = [latitudeFeet, val.corresponding_height, longitudeFeet]; if (featuresDict[val.feature] === 'Building Point') { acc.buildingPoints.push(point); @@ -48,9 +66,63 @@ class TurkHit extends Component { acc.roofPoints.push(point); } return acc; - }, { buildingPoints: [], roofPoints: [] }); - const buildingPoints = data.buildingPoints; - const roofPoints = data.roofPoints; + }, { buildingPoints: [], roofPoints: [], basePoints: [] }); + + // Now clean the data we've create and add new series to support + // the visualization + + const buildingPointColor = '#5882FA'; + const roofPointColor = '#2E2E2E'; + const basePoints = []; + // Points that will visually connect the building points + // to the base points + const buildingBaseConnectPoints = []; + const buildingPoints = data.buildingPoints.map((val) => { + const newLat = val[0] - minLat; + const newLong = val[2] - minLong; + + if (newLat > maxFoot) { + maxFoot = newLat; + } + if (newLong > maxFoot) { + maxFoot = newLong; + } + const newBuildingPoint = [newLat, val[1], newLong]; + // A point with height of 0 + const basePoint = [newLat, 0, newLong]; + // Now connect the base points and the building point + buildingBaseConnectPoints.push({ + color: buildingPointColor, + data: [newBuildingPoint, basePoint], + stickyTracking: false, + enableMouseTracking: false, + }); + + basePoints.push([newLat, 0, newLong]); + return [newLat, val[1], newLong]; + }); + // Add the first point so it connects as a closed shape + if (buildingPoints.length > 0) { + buildingPoints.push(buildingPoints[0]); + basePoints.push(basePoints[0]); + } + + const roofPoints = data.roofPoints.map((val) => { + const newLat = val[0] - minLat; + const newLong = val[2] - minLong; + if (newLat > maxFoot) { + maxFoot = newLat; + } + if (newLong > maxFoot) { + maxFoot = newLong; + } + return [newLat, val[1], newLong]; + }); + // Add the first point so it connects as a closed shape + if (roofPoints.length > 0) { + roofPoints.push(roofPoints[0]); + } + Highcharts.getOptions().colors = Highcharts.getOptions().colors.map(color => ( { radialGradient: { @@ -67,11 +139,16 @@ class TurkHit extends Component { const chart = new Highcharts.Chart({ chart: { renderTo: 'chart-container', + // height: '100%', margin: 100, + marginLeft: 300, + marginRight: 400, + marginTop: 100, + zoomType: 'xyz', type: 'scatter', options3d: { enabled: true, - alpha: 10, + alpha: 30, beta: 30, depth: 250, viewDistance: 5, @@ -91,6 +168,9 @@ class TurkHit extends Component { }, plotOptions: { scatter: { + marker: { + symbol: 'circle', + }, lineWidth: 2, width: 10, height: 10, @@ -99,12 +179,18 @@ class TurkHit extends Component { }, yAxis: { title: 'height', + min: 0, + max: maxFoot, }, xAxis: { gridLineWidth: 1, + min: 0, + max: maxFoot, }, zAxis: { showFirstLabel: false, + min: 0, + max: maxFoot, }, legend: { enabled: false, @@ -112,14 +198,25 @@ class TurkHit extends Component { series: [ { name: 'Building Points', - colorByPoint: false, + color: buildingPointColor, data: buildingPoints, + stickyTracking: false, + }, + { + name: 'Base Points', + color: buildingPointColor, + data: basePoints, + showInLegend: false, + enableMouseTracking: false, }, { name: 'Roof Points', - colorByPoint: false, + color: roofPointColor, data: roofPoints, + stickyTracking: false, + lineWidth: 0, }, + ...buildingBaseConnectPoints, ], }); // We need to set state AFTER the component updates because @@ -294,12 +391,18 @@ class TurkHit extends Component { ) renderChart = () => { - let chartDiv = (
); + let chartDiv = ( +
+
+
+
); if (this.state.displayChart) { chartDiv = (
-
; -
); +
+
+
+ ); } return chartDiv; @@ -314,7 +417,7 @@ class TurkHit extends Component { return (
{this.renderDefinitions()} -

Loading...

+

Loading... Please be patient and do not refresh the page...

); } else if (hit.error && hit.error.response.status !== 404) { diff --git a/src/components/UtilityAccount/index.js b/src/components/UtilityAccount/index.js index e8003cca..e465b7a8 100644 --- a/src/components/UtilityAccount/index.js +++ b/src/components/UtilityAccount/index.js @@ -190,11 +190,43 @@ class UtilityAccount extends Component { renderFetchAndDownloadBtn = () => { - const { scrape, disaggregate } = this.state.documentURLs; + const { scrape } = this.state.documentURLs; let scrapeVisibility = 'hidden'; if (scrape !== undefined && scrape !== '') { scrapeVisibility = 'visible'; } + + return ( +
+ + Scraped Bill + + +
+ ); + } + + renderDeleteAccountBtn = () => ( + + ) + + renderDisaggregateButtons = () => { + const { disaggregate } = this.state.documentURLs; let disaggregateVisibility = 'hidden'; if (disaggregate !== undefined && disaggregate !== '') { disaggregateVisibility = 'visible'; @@ -221,16 +253,8 @@ class UtilityAccount extends Component { ); } } - return ( ); } @@ -347,12 +358,20 @@ class UtilityAccount extends Component { disabled={this.state.disabled} /> - {!this.state.disabled ? this.renderAddAccountBtn() : this.renderFetchAndDownloadBtn()} + {!this.state.disabled ? this.renderAddAccountBtn() : this.renderDeleteAccountBtn()} {this.renderNatGrid()} {this.showAccountWarning()} +
+
+ {this.state.disabled && this.renderFetchAndDownloadBtn()} +
+
+
+ {this.state.disabled && this.renderDisaggregateButtons()} + {this.renderDisaggregateChart()} +

- {this.renderDisaggregateChart()}
); } -- GitLab From 44fb407db5af74c9281cbd7b2eff95e8508dcc87 Mon Sep 17 00:00:00 2001 From: Conrad S Date: Fri, 24 Mar 2017 13:40:09 -0400 Subject: [PATCH 11/16] Remove weird ' file --- src/' | 487 ---------------------------------------------------------- 1 file changed, 487 deletions(-) delete mode 100644 src/' diff --git a/src/' b/src/' deleted file mode 100644 index 25321ab0..00000000 --- a/src/' +++ /dev/null @@ -1,487 +0,0 @@ -import React, { PropTypes, Component } from 'react'; -import defaultForm from './defaultForm'; -import './styles.css'; -import featuresDict from './features'; -import turkHitPropTypes from '../../containers/Dimensions/propTypes'; -import documentsPropType from '../../containers/Documents/propTypes'; -import turkStatus from './turkStatus'; - -const Highcharts = require('highcharts'); -const ReactHighcharts = require('react-highcharts'); -require('highcharts-3d')(ReactHighcharts.Highcharts); - -class TurkHit extends Component { - constructor(props) { - super(props); - - // TODO not being used - this.state = { - displayChart: false, - chart: null, - chartDrag: { - dragging: false, - posX: null, - posY: null, - alpha: null, - beta: null, - sensitivity: 5, - }, - error: false, - }; - } - - componentDidUpdate() { - // Create the chart when the component updates with turk data - const hit = this.props.hit; - if (!hit.loading && - (hit.hitData.length > 0) && - hit.hitData[0].dimensions && - !this.state.chart) { - const curHit = this.props.hit.hitData[0]; - - // Calculate the minLat to get a measurement - let minLat = null; - let minLong = null; - let maxHeight = null; - - const data = curHit.dimensions.points.reduce((acc, val) => { - // Convert latitude and longitude to feet - const latitudeFeet = (val.latitude * 364488.888889); - const longitudeFeet = (val.longitude * 364488.888889); - if ((minLat === null) || (latitudeFeet < minLat)) { - minLat = latitudeFeet; - } - if ((minLong === null) || (longitudeFeet < minLong)) { - minLong = longitudeFeet; - } - if ((maxHeight === null) || (val.corresponding_height > maxHeight)) { - maxHeight = val.corresponding_height; - } - - const point = [latitudeFeet, val.corresponding_height, longitudeFeet]; - - if (featuresDict[val.feature] === 'Building Point') { - acc.buildingPoints.push(point); - } else if (featuresDict[val.feature] === 'Roof Point') { - acc.roofPoints.push(point); - } - return acc; - }, { buildingPoints: [], roofPoints: [], basePoints: [] }); - - // Now clean the data we've create and add new series to support - // the visualization - - const buildingPointColor = '#5882FA'; - const roofPointColor = '#2E2E2E'; - const basePoints = []; - // Points that will visually connect the building points - // to the base points - const buildingBaseConnectPoints = []; - const buildingPoints = data.buildingPoints.map((val) => { - const newLat = val[0] - minLat; - const newLong = val[2] - minLong; - - const newBuildingPoint = [newLat, val[1], newLong]; - // A point with height of 0 - const basePoint = [newLat, 0, newLong]; - // Now connect the base points and the building point - buildingBaseConnectPoints.push({ - color: buildingPointColor, - data: [newBuildingPoint, basePoint], - stickyTracking: false, - enableMouseTracking: false, - }); - - basePoints.push([newLat, 0, newLong]); - return [newLat, val[1], newLong]; - }); - // Add the first point so it connects as a closed shape - if (buildingPoints.length > 0) { - buildingPoints.push(buildingPoints[0]); - basePoints.push(basePoints[0]); - } - - const roofPoints = data.roofPoints.map((val) => { - const newLat = val[0] - minLat; - const newLong = val[2] - minLong; - return [newLat, val[1], newLong]; - }); - // Add the first point so it connects as a closed shape - if (roofPoints.length > 0) { - roofPoints.push(roofPoints[0]); - } - - Highcharts.getOptions().colors = Highcharts.getOptions().colors.map(color => ( - { - radialGradient: { - cx: 0.4, - cy: 0.3, - r: 0.5, - }, - stops: [ - [0, color], - [1, Highcharts.Color(color).brighten(-0.2).get('rgb')], - ], - } - )); - const dim = 500 - const chart = new Highcharts.Chart({ - chart: { - renderTo: 'chart-container', - // height: '100%', - margin: 50, - type: 'scatter', - options3d: { - enabled: true, - alpha: 30, - beta: 30, - depth: 250, - viewDistance: 5, - fitToPlot: false, - frame: { - bottom: { size: 1, color: 'rgba(0,0,0,0.02)' }, - back: { size: 1, color: 'rgba(0,0,0,0.04)' }, - side: { size: 1, color: 'rgba(0,0,0,0.06)' }, - }, - }, - }, - title: { - text: 'Roof and Building Points', - }, - subtitle: { - text: 'Click and drag the plot area to rotate in space', - }, - plotOptions: { - scatter: { - marker: { - symbol: 'circle', - }, - lineWidth: 2, - width: 10, - height: 10, - depth: 10, - }, - }, - yAxis: { - title: 'height', - width: dim, -// min: 0, -// max: maxHeight, - }, - xAxis: { - gridLineWidth: 1, - width: dim, -// min: 0, -// max: maxHeight, - }, - zAxis: { - showFirstLabel: false, - width: dim, -// min: 0, -// max: maxHeight, - }, - legend: { - enabled: false, - }, - series: [ - { - name: 'Building Points', - color: buildingPointColor, - data: buildingPoints, - stickyTracking: false, - }, - { - name: 'Base Points', - color: buildingPointColor, - data: basePoints, - showInLegend: false, - enableMouseTracking: false, - }, - { - name: 'Roof Points', - color: roofPointColor, - data: roofPoints, - stickyTracking: false, - lineWidth: 0, - }, - ...buildingBaseConnectPoints, - ], - }); - // We need to set state AFTER the component updates because - // the chart requires that the
it is targetting - // is already rendered - /* eslint-disable react/no-did-update-set-state */ - this.setState({ chart }); - - chart.container.onmousedown = (event) => { - this.setState({ - chartDrag: { - ...this.state.chartDrag, - dragging: true, - posX: event.pageX, - posY: event.pageY, - alpha: this.state.chart.options.chart.options3d.alpha, - beta: this.state.chart.options.chart.options3d.beta, - }, - }); - }; - chart.container.onmousemove = (event) => { - const { dragging, beta, alpha, posX, posY, sensitivity } = this.state.chartDrag; - if (dragging) { - const newBeta = beta + ((posX - event.pageX) / sensitivity); - this.state.chart.options.chart.options3d.beta = newBeta; - - const newAlpha = alpha + ((event.pageY - posY) / sensitivity); - this.state.chart.options.chart.options3d.alpha = newAlpha; - - this.state.chart.redraw(false); - } - }; - chart.container.onmouseup = () => { - this.setState({ - chartDrag: { - ...this.state.chartDrag, - dragging: false, - }, - }); - }; - } - // Resize the chart - if (this.state.chart) { - this.state.chart.reflow(); - } - } - - handleHitDecision = (hit, approve) => { - const { hitDecision } = this.props; - let responseMessage = null; - if (!approve) { - /* eslint-disable no-alert */ - responseMessage = prompt('You must enter an explanation for the rejection'); - if (!responseMessage) { - return; - } - } - hitDecision(hit, approve, responseMessage); - } - - toggleDisplayChart = () => { - this.setState({ displayChart: !this.state.displayChart }); - } - - renderDefinitions = () => ( -
-

Mechanical Turk

-
Definitions
-

- Amazon Mechanical Turk is a marketplace for workers to complete Human - Intelligence Tasks or HITs. -
- We will be creating HITs for workers to measure the dimensions of a building. - HITs have 6 days to be completed from date of creation. -

-
- ); - - renderDownloadLink = (documentKey) => { - const dimensions = this.props.documents.files.buildingDimensions; - const document = dimensions.reduce((acc, val) => { - if (!acc) { - if (val.key === documentKey) { - return val; - } - } - return acc; - }, null); - if (this.props.documents.loading) { - return 'Loading documents...'; - } - if (document) { - return ( -
- Download - - ); - } - return (); - } - - renderCreateHitButton = () => { - const { createHitConfirmation, address, building_id } = this.props; - return ( -
- -
-
-
- ); - } - - renderHitActions = hit => ( -
- - -
- ) - - renderOldHits = oldHitList => ( - oldHitList.map((val) => { - const currStatus = turkStatus[val.status_id]; - return ( -
- - - - - - - -
Status{currStatus.message}
Message{val.response_message}
Creation Date{val.hit_date}
Creator{val.requester_name}
-

- {this.renderDownloadLink(val.csv_document_key)} -

-
- ); - }) - ) - - renderChartToggleButton = () => ( -
- -
- ) - - renderChart = () => { - let chartDiv = (
); - if (this.state.displayChart) { - chartDiv = ( -
-
-
- ); - } - - return chartDiv; - } - - render() { - const { hit } = this.props; - const status = hit.status; - - let mainContent =
; - if (hit.loading) { - return ( -
- {this.renderDefinitions()} -

Loading... Please be patient and do not refresh the page...

-
- ); - } else if (hit.error && hit.error.response.status !== 404) { - return ( -
- Retrieving HIT error. Response message: {hit.error.message} -
- ); - } - - - let oldHits = (
); - if (hit.hitData.length > 0 && status !== null) { - const curHit = hit.hitData[0]; - const currStatus = turkStatus[status]; - if (hit.hitData.length > 1) { - oldHits = ( -
-

Previously created hits

-
Definitions
-

- These are hits that are no longer active. -

- {this.renderOldHits(hit.hitData.slice(1))} -
- ); - } - mainContent = ( -
- {currStatus.createBtn && this.renderCreateHitButton()} -
- - - - {curHit.response_message ? - () : } - - - -
Status{currStatus.message}
Message{curHit.response_message}
Creation Date{curHit.hit_date}
Creator{curHit.requester_name}
-
- {currStatus.downloadLink && this.renderDownloadLink(curHit.csv_document_key)} - {currStatus.fileActions && this.renderHitActions(curHit)} - {this.state.chart && this.renderChartToggleButton()} - {this.renderChart()} -
-
-
- ); - } else { - mainContent = ( -
-

HIT has not been created yet.

- {this.renderCreateHitButton()} -
- ); - } - - return ( -
-
- Failed to create HIT. Response message: {hit.create.error.message} -
- {this.renderDefinitions()} - {mainContent} - {oldHits} -
- ); - } -} - -TurkHit.propTypes = { - createHitConfirmation: PropTypes.func, - hitDecision: PropTypes.func, - address: PropTypes.string, - building_id: PropTypes.number, - hit: turkHitPropTypes, - documents: documentsPropType, -}; - -export default TurkHit; -- GitLab From c8926eeef47d193b1c3628e99b0b5c833c5ee795 Mon Sep 17 00:00:00 2001 From: Conrad S Date: Fri, 24 Mar 2017 13:49:46 -0400 Subject: [PATCH 12/16] Removed the require calls --- src/components/TurkHit/index.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/TurkHit/index.js b/src/components/TurkHit/index.js index 3d7f0fba..d64c7b42 100644 --- a/src/components/TurkHit/index.js +++ b/src/components/TurkHit/index.js @@ -1,4 +1,7 @@ import React, { PropTypes, Component } from 'react'; +import Highcharts from 'highcharts'; +import ReactHighcharts from 'react-highcharts'; +import Highcharts3D from 'highcharts-3d'; import defaultForm from './defaultForm'; import './styles.css'; import featuresDict from './features'; @@ -6,9 +9,8 @@ import turkHitPropTypes from '../../containers/Dimensions/propTypes'; import documentsPropType from '../../containers/Documents/propTypes'; import turkStatus from './turkStatus'; -const Highcharts = require('highcharts'); -const ReactHighcharts = require('react-highcharts'); -require('highcharts-3d')(ReactHighcharts.Highcharts); +// Need to call this to load the 3D highcharts module +Highcharts3D(ReactHighcharts.Highcharts); class TurkHit extends Component { constructor(props) { -- GitLab From 93449370a15987924949861372eb10b42d6548e9 Mon Sep 17 00:00:00 2001 From: Conrad S Date: Mon, 27 Mar 2017 12:13:24 -0400 Subject: [PATCH 13/16] Update styling --- src/components/TurkHit/index.js | 12 +- src/components/UtilityAccount/index.js | 214 +++++++++++++------------ src/containers/Documents/sagas.js | 43 +++-- 3 files changed, 149 insertions(+), 120 deletions(-) diff --git a/src/components/TurkHit/index.js b/src/components/TurkHit/index.js index d64c7b42..efcab02f 100644 --- a/src/components/TurkHit/index.js +++ b/src/components/TurkHit/index.js @@ -48,8 +48,9 @@ class TurkHit extends Component { const data = curHit.dimensions.points.reduce((acc, val) => { // Convert latitude and longitude to feet - const latitudeFeet = (val.latitude * 364488.888889); - const longitudeFeet = (val.longitude * 364488.888889); + const DEG_TO_FT = 364488.888889; + const latitudeFeet = (val.latitude * DEG_TO_FT); + const longitudeFeet = (val.longitude * DEG_TO_FT); if ((minLat === null) || (latitudeFeet < minLat)) { minLat = latitudeFeet; } @@ -68,7 +69,7 @@ class TurkHit extends Component { acc.roofPoints.push(point); } return acc; - }, { buildingPoints: [], roofPoints: [], basePoints: [] }); + }, { buildingPoints: [], roofPoints: [] }); // Now clean the data we've create and add new series to support // the visualization @@ -385,7 +386,7 @@ class TurkHit extends Component {
@@ -397,7 +398,8 @@ class TurkHit extends Component {

-
); +
+ ); if (this.state.displayChart) { chartDiv = (
diff --git a/src/components/UtilityAccount/index.js b/src/components/UtilityAccount/index.js index e465b7a8..f60e5d8a 100644 --- a/src/components/UtilityAccount/index.js +++ b/src/components/UtilityAccount/index.js @@ -157,7 +157,7 @@ class UtilityAccount extends Component { let img = (
-
Upload
Disaggregation + Upload Disaggregation
); if (this.state.convertingFile || this.state.loadingUpload) { @@ -172,7 +172,7 @@ class UtilityAccount extends Component { ); } return ( -
+
{ - const { scrape } = this.state.documentURLs; - let scrapeVisibility = 'hidden'; - if (scrape !== undefined && scrape !== '') { - scrapeVisibility = 'visible'; - } - - return ( -
- - Scraped Bill - - -
- ); - } + renderFetchBtn = () => ( + + ) renderDeleteAccountBtn = () => (