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

spending vis hooked up to all-time data #103

Merged
merged 1 commit into from
Oct 14, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion browser/js/meals/meals.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ app.factory('MealFactory', function($http) {
MealFactory.getMealPlan = function(userId) {
return $http.get(`api/users/${userId}/meals`)
.then(function(response) {
return response.data;
return response.data[0];
});
};

Expand Down
3 changes: 3 additions & 0 deletions browser/js/my-account/my-account.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ app.config(function ($stateProvider) {
.then(function(user) {
return MemberInfoFactory.getUser(user.id);
})
},
activeMealPlan: function(VisFactory, currentUser) {
return VisFactory.getActiveMealPlan(currentUser.id)
}
}
})
Expand Down
12 changes: 3 additions & 9 deletions browser/js/visualizations/categories/categories-vis.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
app.controller('CategoriesCtrl', ($scope, $log, currentUser, VisFactory) => {
app.controller('CategoriesCtrl', ($scope, $log, currentUser, activeMealPlan, VisFactory) => {

VisFactory.getActiveMealPlan(currentUser.id)
.then(mealPlan => {
// array of recipe objects in active mealPlan
$scope.activeMealPlan = mealPlan;
$scope.data = VisFactory.buildCategoryData($scope.activeMealPlan);
})
.catch($log.error);
$scope.activeMealPlan = activeMealPlan[0];
$scope.data = VisFactory.buildCategoryData($scope.activeMealPlan);

$scope.options = {
chart: {
Expand All @@ -16,5 +11,4 @@ app.controller('CategoriesCtrl', ($scope, $log, currentUser, VisFactory) => {
duration: 250
}
};

});
43 changes: 0 additions & 43 deletions browser/js/visualizations/overlap/overlap-imports.json

This file was deleted.

62 changes: 28 additions & 34 deletions browser/js/visualizations/overlap/overlap-vis.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable */

app.controller('OverlapCtrl', ($scope, $log, currentUser, VisFactory) => {
app.controller('OverlapCtrl', ($scope, $log, currentUser, activeMealPlan, VisFactory) => {

$scope.diameter = 600;

Expand All @@ -21,8 +21,6 @@ app.controller('OverlapCtrl', ($scope, $log, currentUser, VisFactory) => {
.angle(function(d) { return d.x / 180 * Math.PI; });

var svg = d3.select("svg")
// .attr("width", $scope.diameter)
// .attr("height", $scope.diameter)
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", "0 0 600 600")
.append("g")
Expand All @@ -32,37 +30,33 @@ app.controller('OverlapCtrl', ($scope, $log, currentUser, VisFactory) => {
node = svg.append("g").selectAll(".node");

// get user data
VisFactory.getActiveMealPlan(currentUser.id)
.then(mealPlan => {
$scope.activeMealPlan = mealPlan;
$scope.data = VisFactory.buildOverlapData($scope.activeMealPlan)

// build data into chart
var nodes = cluster.nodes(packageHierarchy($scope.data)),
links = packageImports(nodes);

link = link
.data(bundle(links))
.enter().append("path")
.each(function(d) {
d.source = d[0];
d.target = d[d.length - 1]
})
.attr("class", "link")
.attr("d", line);

node = node
.data(nodes.filter(function(n) { return !n.children; }))
.enter().append("text")
.attr("class", "node")
.attr("dy", ".31em")
.attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + (d.y + 8) + ",0)" + (d.x < 180 ? "" : "rotate(180)"); })
.style("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
.text(function(d) { return d.key; })
.on("mouseover", mouseovered)
.on("mouseout", mouseouted);
})
.catch($log.error);
$scope.activeMealPlan = activeMealPlan[0];
$scope.data = VisFactory.buildOverlapData($scope.activeMealPlan)

// build data into chart
var nodes = cluster.nodes(packageHierarchy($scope.data)),
links = packageImports(nodes);

link = link
.data(bundle(links))
.enter().append("path")
.each(function(d) {
d.source = d[0];
d.target = d[d.length - 1]
})
.attr("class", "link")
.attr("d", line);

node = node
.data(nodes.filter(function(n) { return !n.children; }))
.enter().append("text")
.attr("class", "node")
.attr("dy", ".31em")
.attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + (d.y + 8) + ",0)" + (d.x < 180 ? "" : "rotate(180)"); })
.style("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
.text(function(d) { return d.key; })
.on("mouseover", mouseovered)
.on("mouseout", mouseouted);

function mouseovered(d) {
node
Expand Down
71 changes: 23 additions & 48 deletions browser/js/visualizations/spending/spending-vis.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,33 @@
app.controller('SpendingCtrl', ($scope, currentUser) => {
app.controller('SpendingCtrl', ($scope, $log, currentUser, activeMealPlan, VisFactory) => {

$scope.activeMealPlan = [activeMealPlan[0]];
$scope.lightActiveMealPlan = activeMealPlan[1];

VisFactory.getCompletedMealPlans(currentUser.id)
.then(mpArr => {
$scope.lightCompletedMealPlans = mpArr[0];
$scope.completedMealPlans = mpArr[1];
})
.then(() => {
VisFactory.getUserPrefs(currentUser.id)
.then(prefs => {
$scope.numPeople = prefs.numPeople;
let loadedMealArr = [...$scope.completedMealPlans, ...$scope.activeMealPlan];
let lightMealArr = [...$scope.lightCompletedMealPlans, $scope.lightActiveMealPlan];
$scope.data = VisFactory.buildSpendingData(loadedMealArr, lightMealArr, $scope.numPeople);
})
.catch($log.error);
})
.catch($log.error);

$scope.options = {
chart: {
type: 'lineChart',
height: 500,
margin: {
top: 20,
// right: 400,
bottom: 50
// left: 400
bottom: 50,
left: 40
},
x: (d) => { return d[0] },
y: (d) => { return d[1] },
Expand All @@ -28,48 +47,4 @@ app.controller('SpendingCtrl', ($scope, currentUser) => {
}
},
};

$scope.data = [{
key: 'Marley Spoon',
values: [[1, 10.33], [2, 10.33], [3, 10.33], [4, 10.33], [5, 10.33], [6, 10.33]] // $62
}, {
key: 'Blue Apron',
values: [[1, 9.99], [2, 9.99], [3, 9.99], [4, 9.99], [5, 9.99], [6, 9.99]] // $59.94
}, {
key: 'Dish\'d',
values: [
[1, 2.99], [2, 7.34], [3, 1.52], [4, 2.57], [5, 3.87], [6, 4.70]]
}]

// nv.utils.windowResize = function(scope, handler) {
// // Legacy support
// if (typeof scope === 'function') {
// handler = scope;
// scope = undefined;
// nv.deprecated('WARNING: Failed to pass $scope when binding to windowResize event');
// }

// if (window.addEventListener) {
// window.addEventListener('resize', handler);
// } else {
// nv.log("ERROR: Failed to bind to window.resize with: ", handler);
// }
// // return object with clear function to remove the single added callback.
// var retObj = {
// callback: handler,
// clear: function() {
// window.removeEventListener('resize', handler);
// }
// };

// // Hookup our auto-destroy if passed scope
// if (scope){
// scope.$on('$destroy', function(){
// 'use strict';
// retObj.clear();
// });
// }

// return retObj;
// };
});
51 changes: 50 additions & 1 deletion browser/js/visualizations/vis-factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,21 @@ app.factory('VisFactory', function($http){
return {
getActiveMealPlan: (userId) => {
return $http.get(`api/users/${userId}/meals`)
.then((response) => {
.then(response => {
return response.data;
})
},

getCompletedMealPlans: (userId) => {
return $http.get(`api/users/${userId}/history`)
.then(response => {
return response.data;
})
},

getUserPrefs: (userId) => {
return $http.get(`api/users/${userId}/preferences`)
.then(response => {
return response.data;
})
},
Expand Down Expand Up @@ -127,6 +141,41 @@ app.factory('VisFactory', function($http){
}
});
return data;
},

buildSpendingData: (loadedMealArr, lightMealArr, numPeople) => {
let data = [{
key: 'Marley Spoon',
values: []
}, {
key: 'Blue Apron',
values: []
}, {
key: 'Dish\'d',
values: []
}]

// build data in d3 format
for (let i = 0; i < lightMealArr.length; i++) {
let price = +lightMealArr[i].price;
let divisor = loadedMealArr[i].length * numPeople;
let pricePerServ = price / divisor;

data[0].values.push([i + 1, 10.33]);
data[1].values.push([i + 1, 9.99]);
data[2].values.push([i + 1, pricePerServ]);
}
return data;
}
}
});










4 changes: 2 additions & 2 deletions server/app/routes/user/history-routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ const Recipe = db.model('recipe');
const router = require('express').Router({mergeParams: true});
const Promise = require('bluebird');

// mounted on /api/users/:userId/history

// get detailed history.
router.get('', (req, res, next) => {

let id = req.params.userId;
let mealPlansLight = {}

Expand Down Expand Up @@ -37,7 +38,6 @@ router.get('', (req, res, next) => {
res.send([mealPlansLight, detailedMealPlans]);
})
.catch(next);

});

// get details of one meal plan.
Expand Down
16 changes: 15 additions & 1 deletion server/app/routes/user/meal-routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ router.get('', (req, res, next) => {
let planPromises = plan.meals.map(recId => Recipe.findById(recId));
Promise.all(planPromises)
.then(meals => {
res.send(meals)
res.send([meals, plan])
})
.catch(next);
}
Expand Down Expand Up @@ -57,6 +57,20 @@ router.get('', (req, res, next) => {
})
});

// add price for a particular meal plan
router.put('/:mealPlanId', (req, res, next) => {
MealPlan.findById(req.params.mealPlanId)
.then(mealPlan => {
return mealPlan.update({
price: req.body.price
})
.then(updatedPlan => {
res.json(updatedPlan);
})
})
.catch(next);
});

//mark existing plan as completed and get a fresh meal plan
router.put('', (req, res, next) => {

Expand Down
6 changes: 5 additions & 1 deletion server/db/models/meal-plan-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ const db = require('../_db');
module.exports = db.define('mealPlan', {
status: Sequelize.ENUM('active', 'complete'),
meals: Sequelize.ARRAY(Sequelize.INTEGER),
groceryList: Sequelize.JSON
groceryList: Sequelize.JSON,
price: {
type: Sequelize.DECIMAL,
defaultValue: 0.00
}
},
{
instanceMethods: {
Expand Down