Large diffs are not rendered by default.

@@ -1,10 +1,11 @@
$(document).ready(function() {
$.get('/dashboard/index')
.success( function(data) {
console.log(data);

// New customers
$("#new-daily>span").text(data.new.daily);
$("#new-monthly>span").text(data.new.monthly);

// Customer demographics
$("#demographics-duration>span").text(data.totcustomers);
// Points

Large diffs are not rendered by default.

@@ -4,20 +4,38 @@ var Parse = require('parse').Parse;


// Mock data
// Hopefully we get some points data in parse soon!
// Hopefully we get more points data in parse soon!
var data = {
new: {
daily: 9999,
monthly: 9999
daily: 'N/A',
monthly: 'N/A'
},
totcustomers: 9999,
totcustomers: 'N/A',
points: {
earned: 9999,
redeemed: 9999
earned: 'N/A',
redeemed: 'N/A'
}
};


// Please rename this function. I dunno how to describe. I need sleep.
var doStuffToMuhObjectJSON = function(objName, stuff) {
var businessObj = Parse.Object.extend('Business');
var businessQuery = new Parse.Query(businessObj);
var query = new Parse.Query(Parse.Object.extend(objName));
businessQuery.equalTo('owner', Parse.User.current());

return businessQuery.first().then( function(business) {
// queries for this page.
query.equalTo('business', business);
return query.collection().fetch();
}).then( function (collection) {
// do stuff to muh JSON
stuff(collection.toJSON());
});
};


router.get('/', function(req, res, next) {

if (Parse.User.current()) {
@@ -29,56 +47,82 @@ router.get('/', function(req, res, next) {


router.get('/index', function(req, res, next) {
doStuffToMuhObjectJSON('Points', function(json) {
// new daily customers with points
data.new.daily = json.filter( function(point) {
date = new Date(point.createdAt);
return date.setDate(date.getDate() + 1) > new Date();
}).length;
// new monthly customers with points
data.new.monthly = json.filter( function(point) {
date = new Date(point.createdAt);
return date.setMonth(date.getMonth() + 1) > new Date();
}).length;
res.json(data);
});
});

// fetch actual points count for a business.
var businessObj = Parse.Object.extend('Business');
var pointsObj = Parse.Object.extend('Points');

var businessQuery = new Parse.Query(businessObj);
var pointsQuery = new Parse.Query(pointsObj);

businessQuery.equalTo('owner', Parse.User.current());

businessQuery.first().then( function(business) {
// get points matching current business
pointsQuery.equalTo('business', business);
return pointsQuery.count()

}).then( function(count) {
// set count
data.new.daily = count;
console.log(data);

}).then( function() {
// render
res.json(data);
}, function(error) {
console.log(error);
router.get('/points', function(req, res, next) {
var pointsData = [{
key : 'Points',
values : []
}];
doStuffToMuhObjectJSON('Points', function(json) {
// map collection into series, with js timestamps
var series = json.map( function (point) {
return {
x: +new Date(point.createdAt),
y: point.points,
size: 50
};
});
// set and display
pointsData[0].values = series;
res.json(pointsData);
});
});


router.get('/gethistoric', function(req, res, next) {
// this is just using mock data at the moment

var dataList = [
{'date':'2013-01','value': 53 },
{'date':'2013-02','value': 165},
{'date':'2013-03','value': 269},
{'date':'2013-04','value': 344},
{'date':'2013-05','value': 376},
{'date':'2013-06','value': 410},
{'date':'2013-07','value': 421},
{'date':'2013-08','value': 405},
{'date':'2013-09','value': 376},
{'date':'2013-10','value': 359},
{'date':'2013-11','value': 392},
{'date':'2013-12','value': 433},
{'date':'2014-01','value': 455},
{'date':'2014-02','value': 478},
router.get('/customers', function(req, res, next) {
var customerData = [
{
key : 'Visits',
values : []
},
{
key : 'New Customers',
values : []
},
];

res.json(dataList);
doStuffToMuhObjectJSON('NEW_Interval', function(json) {
// get dates, and unique visits counts binned by said dates.
var counts = {};
json.forEach( function(interval) {
var d = new Date(interval.from.iso);
d.setHours(0,0,0,0);
counts[+d] = 1 + (counts[+d] || 0);
});
for (key in counts)
customerData[0].values.push({x: parseInt(key), y: counts[key]});

}).then( function() {
// bin dates for points data (where unique business-customer
// relationships should first be instatiated... eventually)
var counts = {};
doStuffToMuhObjectJSON('Points', function(json) {
console.log(json);
json.forEach( function(point) {
var d = new Date(point.createdAt);
d.setHours(0,0,0,0);
counts[+d] = 1 + (counts[+d] || 0);
});
console.log(counts);
for (key in counts)
customerData[1].values.push({x: parseInt(key), y: counts[key]});
res.json(customerData);
});
});
});

module.exports = router;
@@ -1,6 +1,10 @@
<html>
<head>
<% include template/header %>
<link href="css/nv.d3.css" rel="stylesheet" type="text/css">

<script src="js/d3.min.js"></script>
<script src="js/nv.d3.js"></script>
</head>
<body>
<% include template/navbar %>
@@ -27,8 +31,8 @@
<span class="badge"></span>
</a>
</ul>
</div>
</div>
</div>
</div>
<div id="totcustomers" class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
@@ -42,8 +46,8 @@
</span>
</li>
</ul>
</div>
</div>
</div>
</div>
<div id="points" class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
@@ -59,94 +63,65 @@
<span class="badge"></span>
</a>
</ul>
</div>
</div>
</div>
</div>
</div>

<div class="row">
<div id="chart" class="col-md-8 col-md-offset-2">
<svg/>
</div>
</div>
</div>
<% include template/footer %>
</body>
<script>
// this needs to be redone and refactored
var generateGraph = function (data) {
var margin = {top: 20, right: 20, bottom: 70, left: 40},
width = 600 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
// Parse the date / time
var parseDate = d3.time.format("%Y-%m").parse;
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
var y = d3.scale.linear().range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickFormat(d3.time.format("%Y-%m"));
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10);
var svg = d3.select("#graph").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
data.forEach(function(d) {
d.date = parseDate(d.date);
d.value = +d.value;
// nvd3 chart
var drawPointsScatter = function() {
d3.selectAll("svg > *").remove();
d3.json('/dashboard/points', function(data) {
nv.addGraph( function() {
var width = 600, height = 400;
var chart = nv.models.scatterChart()
chart.xAxis
.tickFormat(function(d) {
return d3.time.format('%x')(new Date(d));
});
chart.forceY(0);
d3.select('#chart svg')
.datum(data)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
});
x.domain(data.map(function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.value; })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)" );
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Value");
svg.selectAll("bar")
.data(data)
.enter().append("rect")
.style("fill", "steelblue")
.attr("x", function(d) { return x(d.date); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); });
//});
}
$.get('/dashboard/gethistoric')
.success(function (barGraphData) {
generateGraph(barGraphData);
})
.error(function (xhr, textStatus, errorThrown) {
alert(xhr.responseText);
};
var drawCustomerLine = function() {
d3.selectAll("svg > *").remove();
d3.json('/dashboard/customers', function(data) {
nv.addGraph( function() {
var width = 600, height = 400;
var chart = nv.models.lineChart()
chart.xAxis.tickFormat(function(d) {
return d3.time.format('%x')(new Date(d));
});
chart.forceY(0);
d3.select('#chart svg')
.datum(data)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
});
};
$("#new-daily, #new-montly").click(drawCustomerLine);
$("#points-earned, #points-redeemed").click(drawPointsScatter);
drawCustomerLine();
</script>
</html>