Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export group #83

Merged
merged 29 commits into from
Sep 13, 2017
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
aef9792
Changes to linechart component to enable export of data. currently ab…
kooolbreez1 Mar 28, 2017
d3bb015
Changes to linechart component to enable export of data. currently ab…
kooolbreez1 Apr 4, 2017
e381bd2
Changes to LineChartComponent, Readings.js in actions and LineChartCo…
kooolbreez1 Apr 5, 2017
5f9996a
did stuff
RagingOcelot Apr 5, 2017
5e811fa
Merge branch 'master' into exportGroup
kooolbreez1 Apr 5, 2017
c3f6752
Merge branch 'master' into exportGroup
RagingOcelot Apr 5, 2017
7783382
Merge remote-tracking branch 'origin/exportGroup' into exportGroup
kooolbreez1 Apr 5, 2017
950b045
Able to access (compressed?) readings via the UIOptionsComponent.
kooolbreez1 Apr 6, 2017
1d56556
Able to format and download compressed meter data as a CSV file.
kooolbreez1 Apr 7, 2017
539401e
Merge branch 'master' into exportGroup
kooolbreez1 Apr 7, 2017
d610906
Merge branch 'master' into exportGroup
RagingOcelot Apr 7, 2017
eda9804
Merge remote-tracking branch 'origin/exportGroup' into exportGroup
kooolbreez1 Apr 7, 2017
ff4f005
added timestamp to exported Data
kooolbreez1 Apr 7, 2017
199d31d
Merge branch 'master' into exportGroup
RagingOcelot Apr 10, 2017
5082823
Merge branch 'master' into exportGroup
RagingOcelot Apr 13, 2017
b659757
changed name of the exported file to "exportedDataOED" instead of pro…
kooolbreez1 Apr 13, 2017
c3fc89f
fixed a comment I accidentally changed in dashboardContainer
kooolbreez1 Apr 13, 2017
3ae6e54
compressed filename variable in exportData.js to 1 line and removed u…
kooolbreez1 Apr 15, 2017
40dea5e
Moved exportData.js to new services directory.
kooolbreez1 Apr 15, 2017
9db2746
preparing to merge with master
kooolbreez1 Apr 23, 2017
3c22a47
Merging branch 'master' into exportGroup
kooolbreez1 Apr 23, 2017
6c0937f
Now works with the updated UIOptions component and barcharts. can cur…
kooolbreez1 Apr 25, 2017
dc03958
Successfully exports the displayed data from bar charts (for full dat…
kooolbreez1 Apr 25, 2017
538b85c
Successfully exports the displayed data from bar charts (for full dat…
kooolbreez1 Apr 25, 2017
c91b9a6
the name of the exported file now dynamically changes based on the ti…
kooolbreez1 Apr 26, 2017
16f4e3a
Name of exported file includes its chartType, the export button is wo…
kooolbreez1 May 3, 2017
4c6b4ec
updated a line of code to mitigate a likely bug that would appear if …
kooolbreez1 May 3, 2017
a8ca745
Export component is now rendered as art of the UI options component f…
kooolbreez1 May 3, 2017
394c155
ExportComponent is now a functional component instead of a class
kooolbreez1 May 3, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"nodemailer": "~2.6.4",
"pg-promise": "^5.3.5",
"react": "^15.4.2",
"react-bootstrap": "^0.31.0",
"react-chartjs-2": "^2.0.5",
"react-dom": "^15.4.2",
"react-rangeslider": "^2.0.1",
Expand Down
40 changes: 40 additions & 0 deletions src/client/app/components/ExportComponent.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import React from 'react';
import { Button } from 'react-bootstrap';
import moment from 'moment';
import graphExport from '../services/exportData';

export default class ExportComponent extends React.Component {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could easily be a functional component. No need for a class.

/**
* Initializes the component's state, binds all functions to 'this' ExportComponent
* @param props The props passed down through the ExportContainer
*/
constructor(props) {
super(props);
this.exportReading = this.exportReading.bind(this);
}

/**
* Called when Export button is clicked.
* Passes an object containing the selected meter data to a function for export.
*/
exportReading() {
const compressedData = this.props.exportVals.datasets;
let time = compressedData[0].exportVals[0].x;
const chart = compressedData[0].currentChart;
time = moment(time).format('ddddMMMDDYYYY');
const name = `oedExport${time}${chart}.csv`;
graphExport(compressedData, name);
}

render() {
return (
<div>
<Button bsStyle="default" onClick={this.exportReading}>Export!</Button>
</div>
);
}
}
3 changes: 3 additions & 0 deletions src/client/app/components/HomeComponent.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import React from 'react';
import HeaderComponent from './HeaderComponent';
import DashboardContainer from '../containers/DashboardContainer';
import ExportContainer from '../containers/ExportContainer';


/**
* Top-level React component that controls the home page
Expand All @@ -15,6 +17,7 @@ export default function HomeComponent() {
<div>
<HeaderComponent renderLoginButton />
<DashboardContainer />
<ExportContainer />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you move this to be in UIOptionsComponent (at the bottom) instead of here?

</div>
);
}
51 changes: 51 additions & 0 deletions src/client/app/containers/ExportContainer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import { connect } from 'react-redux';
import ExportComponent from '../components/ExportComponent';
import { chartTypes } from '../reducers/graph';

/**
* @param {State} state
* @return {{meterInfo: *, selectedMeters: Array}}
*/
function mapStateToProps(state) {
const timeInterval = state.graph.timeInterval;
const data = { datasets: [] };
let readingsData;
const chart = state.graph.chartToRender;
const barDuration = state.graph.barDuration;

for (const meterID of state.graph.selectedMeters) {
if (chart === chartTypes.line) {
readingsData = state.readings.line.byMeterID[meterID][timeInterval];
} else if (chart === chartTypes.bar) { readingsData = state.readings.bar.byMeterID[meterID][timeInterval][barDuration]; }
if (readingsData !== undefined && !readingsData.isFetching && chart === chartTypes.line) {
data.datasets.push({
label: state.meters.byMeterID[meterID].name,
id: state.meters.byMeterID[meterID].id,
timestamp: state.readings.line.byMeterID[meterID][timeInterval].start_timestamp,
currentChart: chart,
exportVals: state.readings.line.byMeterID[meterID][timeInterval].readings.map(arr => ({ x: arr[0], y: arr[1] }))
});
} else if (readingsData !== undefined && !readingsData.isFetching && chart === chartTypes.bar) {
data.datasets.push({
label: state.meters.byMeterID[meterID].name,
id: state.meters.byMeterID[meterID].id,
timestamp: state.readings.bar.byMeterID[meterID][timeInterval][barDuration].timestamp,
currentChart: chart,
exportVals: state.readings.bar.byMeterID[meterID][timeInterval][barDuration].readings.map(arr => ({ x: arr[0], y: arr[1] }))
});
}
}
return {
selectedMeters: state.graph.selectedMeters,
exportVals: data
};
}

/**
* Connects changes to the Redux store to UIOptionsComponent via mapStateToProps
*/
export default connect(mapStateToProps)(ExportComponent);
53 changes: 53 additions & 0 deletions src/client/app/services/exportData.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import moment from 'moment';


/**
* Function to converts the compressed meter data into a CSV formatted string.
* @param items The compressed meter data.
* @returns output A string containing the CSV formatted compressed meter data.
*/

function convertToCSV(items) {
let csvOutput = 'Label,Readings,Start Timestamp\n';
items.forEach(set => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You use a for ... of loop in UIOptionsContainer.js, but .forEach here. Why the inconsistency?

const data = set.exportVals;
const label = set.label;
data.forEach(reading => {
const info = reading.y;
const startTimeStamp = moment(reading.x).format('dddd MMM DD YYYY hh:mm a');
csvOutput += `${label},${info} kwh, ${startTimeStamp}\n`; // this assumes that meter readings are in kwh
});
});
return csvOutput;
}
/**
* Function to download the formatted CSV file to the users computer.
* @param inputCSV A String containing the formatted CSV data.
* @param fileName A string representing the name of the file.
*/
function downloadCSV(inputCSV, fileName) {
const element = document.createElement('a');
element.setAttribute('href', `data:text/csv;charset=utf-8,${encodeURIComponent(inputCSV)}`);
element.setAttribute('download', fileName);

element.style.display = 'none';
document.body.appendChild(element);

element.click();

document.body.removeChild(element);
}

/**
* Function to export compressed data from the graph currently displaying. May be used for routing if more export options are added
* @param dataSets An Object. The compressed data from each meter currently selected in the graph.
* @param name the name of the file.
*/
export default function graphExport(dataSets, name) {
const dataToExport = convertToCSV(dataSets);
downloadCSV(dataToExport, name);
}