|
function add_axes(scx, scy, dh, dw, space){ |
|
var x_axis = d3.svg.axis() |
|
.scale(scx) |
|
.orient("top") |
|
.innerTickSize(2) |
|
.outerTickSize(0) |
|
.tickPadding(2) |
|
.ticks(5); |
|
|
|
var y_axis = d3.svg.axis() |
|
.scale(scy) |
|
.orient("right") |
|
.innerTickSize(2) |
|
.outerTickSize(0) |
|
.tickPadding(2) |
|
.ticks(5); |
|
|
|
space.append("g") |
|
.attr("class", "axis") |
|
.attr("transform", "translate(0,"+dh+")") |
|
.call(x_axis); |
|
|
|
space.append("g") |
|
.attr("class", "axis") |
|
.call(y_axis); |
|
return |
|
} |
|
|
|
var helpers = { |
|
div_a: new function(){ |
|
this.getquadrants = function(dw, dh) { |
|
return{ |
|
"male-young": {minw: 0, maxw: dw/2, minh: 0, maxh: dh/2, title: "male-young"}, |
|
"male-old": {minw: dw/2, maxw: dw, minh: 0, maxh: dh/2, title: "male-old"}, |
|
"female-young": {minw: 0, maxw: dw/2, minh: dh/2, maxh: dh, title: "female-young"}, |
|
"female-old": {minw: dw/2, maxw: dw, minh: dh/2, maxh: dh, title: "female-old"} |
|
}; |
|
}, |
|
this.addquads = function(space, dw, dh){ |
|
//draw quadrants (hor and vert) |
|
var linespc = space.append("g"); |
|
linespc.append("line") |
|
.attr("x1", 0) |
|
.attr("y1", dh/2) |
|
.attr("x2", dw) |
|
.attr("y2", dh/2) |
|
.attr("class", "quadrant"); |
|
linespc.append("line") |
|
.attr("x1", dw/2) |
|
.attr("y1", 0) |
|
.attr("x2", dw/2) |
|
.attr("y2", dh) |
|
.attr("class", "quadrant"); |
|
return; |
|
}, |
|
this.addlabels = function(space, dw, dh){ |
|
var xmid = dw/2; |
|
var ymid = dh/2; |
|
var xr = xmid/2; |
|
var yr = ymid/2; |
|
var labelspc = space.append("g"); |
|
|
|
labelspc.append("text") |
|
.attr("class", "quadlabel") |
|
.attr("x", xmid - xr) |
|
.attr("y", 20) |
|
.text("YOUNG"); |
|
|
|
labelspc.append("text") |
|
.attr("class", "quadlabel") |
|
.attr("x", xmid + xr) |
|
.attr("y", 20) |
|
.text("OLD"); |
|
|
|
labelspc.append("text") |
|
.attr("class", "quadlabel") |
|
.attr("x", -(xmid - 1.9*yr)) |
|
.attr("y", 20) |
|
.attr("dy", ".35em") |
|
.attr("transform", "rotate(-90)") |
|
.style("text-anchor", "start") |
|
.text("MALE"); |
|
|
|
labelspc.append("text") |
|
.attr("class", "quadlabel") |
|
.attr("x", -(ymid + 1.3*yr)) |
|
.attr("y", 20) |
|
.attr("dy", ".35em") |
|
.attr("transform", "rotate(-90)") |
|
.style("text-anchor", "start") |
|
.text("FEMALE"); |
|
return; |
|
}, |
|
this.addlegend = function(space, dw, dh){ |
|
space.append("g") |
|
.attr("class", "legend") |
|
.attr("transform", "translate(30,30)") |
|
.style("font-size", "11px") |
|
.call(d3.legend); |
|
return; |
|
}, |
|
this.get_q = function(quadrants, d){ |
|
var qk = d.gender + "-" + ((d.young == true) ? "young" : "old"); |
|
return quadrants[qk]; |
|
}, |
|
this.interact = function(d, helpers){ |
|
helpers.div_ba.put(d); |
|
helpers.div_bb.put(d); |
|
helpers.div_bc.put(d); |
|
}, |
|
this.mouseleave = function(){ |
|
d3.select(this).transition().duration(200).attr("r", 3); |
|
}, |
|
this.pick_sign = function(v, r){ |
|
var rand = Math.cos(Math.random()) - Math.cos(Math.random()); |
|
if (rand < 0.6){ |
|
return v - (r * rand); |
|
} |
|
else{ |
|
return v + (r * rand); |
|
} |
|
} |
|
}, |
|
div_ba: new function() { |
|
this.getscales = function(dw, dh) { |
|
return { |
|
x_scale: d3.scale.linear().domain([0, this.max_x]).range([dw*0.2, dw*0.9]), |
|
y_scale: d3.scale.linear().domain([0, this.max_y]).range([dh*0.9, dh*0.2]) |
|
}; |
|
}, |
|
this.addaxes = function(scales, space, dw, dh){ |
|
add_axes(scales.x_scale, scales.y_scale, dh, dw, space); |
|
space.append("text") |
|
.attr("transform", "rotate(-90)") |
|
.attr("y", 10) |
|
.attr("x",0 - (dh / 2)) |
|
.attr("dy", "1em") |
|
.style("text-anchor", "middle") |
|
.text("# of purchases"); |
|
|
|
space.append("text") |
|
.attr("y", dh*0.85) |
|
.attr("x", dw/2) |
|
.attr("dy", "1em") |
|
.style("text-anchor", "middle") |
|
.text("family-size"); |
|
return; |
|
}, |
|
this.point = null, |
|
this.put = function(d){ |
|
var family_size = this.scales.x_scale(d.family_size); |
|
var purchases_per_visit = this.scales.y_scale(d.purchases_per_visit); |
|
|
|
if (! (this.point) ){ |
|
this.point = this.space.append("circle").attr("cx", family_size).attr("cy", purchases_per_visit).attr("r", 8).style("opacity", 0.5); |
|
} |
|
else{ |
|
this.point.transition().attr("cx", family_size).attr("cy", purchases_per_visit); |
|
} |
|
} |
|
}, |
|
div_bb: new function(){ |
|
this.getscales = function(dw, dh) { |
|
return { |
|
x_scale: d3.scale.ordinal().domain(["03-15", "04-15", "05-15", "06-15", "07-15"]).rangePoints([dw*0.2, dw*0.9]), |
|
y_scale: d3.scale.linear().domain([0, this.max_y]).range([dh*0.9, dh*0.1]) |
|
}; |
|
}, |
|
this.addaxes = function(scales, space, dw, dh){ |
|
add_axes(scales.x_scale, scales.y_scale, dh, dw, space); |
|
space.append("text") |
|
.attr("x", 50) |
|
.attr("y", 20) |
|
.text("VISITS (LAST 5 MONTHS)"); |
|
return; |
|
}, |
|
this.path = null, |
|
this.put = function(d){ |
|
var scales = this.scales; |
|
var last_n_months = d.last_n_months; |
|
|
|
var valueline = d3.svg.line() |
|
.x(function(d) { return scales.x_scale(d.month); }) |
|
.y(function(d) { return scales.y_scale(d.visits); }) |
|
.interpolate("cardinal"); |
|
|
|
if (!this.path){ |
|
this.path = this.space.append("path") |
|
.attr("class", "line") |
|
.style("fill", "none") |
|
.style("stroke", "rgba(231, 76, 60,1.0)") |
|
.style("stroke-width", 2) |
|
.style("opacity", 0.6) |
|
.attr("d", valueline(last_n_months)); |
|
} |
|
else{ |
|
this.path.transition() |
|
.attr("d", valueline(last_n_months)); |
|
} |
|
return; |
|
} |
|
}, |
|
div_bc: new function(){ |
|
this.getscales = function(dw, dh) { |
|
return { |
|
x_scale: d3.scale.ordinal().domain(["FOOD", "CLTHNG", "ELCTR", "JWLRY"]).rangeRoundBands([dw*0.1, dw], 0.05), |
|
y_scale: d3.scale.linear().domain([0, this.max_y]).range([dh*0.9, dh*0.1]) |
|
}; |
|
}, |
|
this.addaxes = function(scales, space, dw, dh){ |
|
add_axes(scales.x_scale, scales.y_scale, dh, dw, space); |
|
space.append("text") |
|
.attr("x", 50) |
|
.attr("y", 20) |
|
.text("PURCHASE HISTORY"); |
|
return; |
|
}, |
|
this.set = null, |
|
this.put = function(d){ |
|
var scales = this.scales; |
|
var purchase_history = d.purchase_history; |
|
var dw = this.dw; |
|
var dh = this.dh; |
|
|
|
if (!this.set){ |
|
this.set = this.space.selectAll() |
|
.data(purchase_history) |
|
.enter() |
|
.append("rect") |
|
.attr("x", function(d) { return scales.x_scale(d.item); }) |
|
.attr("y", function(d) { return scales.y_scale(d.count); }) |
|
.attr("width", (dw * 0.8)/purchase_history.length) |
|
.attr("height", function(d) { return (dh*0.9) - scales.y_scale(d.count)*0.99 ; }) |
|
.style("fill", "#87D37C") |
|
.style("stroke", "gray") |
|
.style("stroke-width", 0.6); |
|
} |
|
else{ |
|
this.set |
|
.data(purchase_history) |
|
.transition() |
|
.attr("height", function(d) { return (dh*0.9) - scales.y_scale(d.count)*0.99 ; }) |
|
.attr("y", function(d) { return scales.y_scale(d.count); }); |
|
} |
|
} |
|
} |
|
} |