function dataPrep(states, recipe, parameter, width, height, margin) { // Parameters var cgX = width*recipe.cgX; var cgY = height*recipe.cgY; var scale = recipe.scale*width/800*height/700; // Color codes for states colorCode(states, parameter); states.map(function(state) { state.space = state[parameter]*scale; }); recipe.rows.forEach(function(f) { var getParam = function(d) { return (d.position=="absolute")?d.offsetY*cgY:d.master; } placeRow(f.set, f.width*width, states, f.offset*cgX, f.position, getParam(f), margin); }); recipe.singles.forEach(function(f) { placeRelative(states, f.unit, f.aspect, f.master, f.direction, f.position, f.distance+margin); }); states.map(function(state) { state.cx = state.x + state.width/2; state.cy = state.y + state.height/2; }); } function createSVG(element, width, height, states) { d3.select(element).select("svg").remove(); var svg = d3.select(element).append("svg") .attr("width", width) .attr("height", height); d3.select(element).select("#tooltip").remove(); var div = d3.select(element).append("div") .attr("id", "tooltip") .style("opacity", 0); var selectState = svg.selectAll("g").data(states).enter().append("g").attr("class", "state"); var selectRect = selectState.append("rect"); var selectText = selectState.append("text"); selectRect .style("fill", function(d) { return d.color; }) .attr({ rx: 5, ry: 5, x: function (d) { return d.x; }, y: function (d) { return d.y; }, width: function (d) { return d.width; }, height: function (d) { return d.height; } }); selectText .attr("class", function(d) { return "label " + d.id; }) .attr("dy", ".35em") .attr("transform", function(d) { return "translate(" + [d.cx, d.cy] + ")"; }); } function stateCarto(states, recipe, parameter) { var width = 800; var height = 700; var margin = 2; var transit = false; function render(selection) { selection.each(function() { dataPrep(states, recipe, parameter, width, height, margin); if (!transit) { createSVG(this, width, height, states); } var svg = d3.select(this).select("svg") var div = d3.select(this).select("#tooltip") var selectRect = svg.selectAll("g rect").data(states); var selectText = svg.selectAll("g text").data(states); if (transit) { selectRect.transition().duration(transit) .attr({ x: function (d) { return d.x; }, y: function (d) { return d.y; }, width: function (d) { return d.width; }, height: function (d) { return d.height; } }); selectText.transition().duration(transit) .attr("transform", function(d) { return "translate(" + [d.cx, d.cy] + ")"; }); } selectText .text(function(d) { return (d.name == d.alias)?d.name: (d.width > d.name.length*8)?d.name: (d.width > 16)?d.alias:''; }); selectRect .on("mouseover", function(d) { d3.select("#tooltip").transition() .duration(200) .style("opacity", .9); d3.select("#tooltip").html("

"+(d.name)+"

"+ ""+ "
"+parameter+""+(d[parameter])+"
") .style("left", (d3.event.pageX-document.getElementById('map').offsetLeft + 20) + "px") .style("top", (d3.event.pageY-document.getElementById('map').offsetTop - 60) + "px"); }) .on("mouseout", function(d) { d3.select("#tooltip").transition() .duration(500) .style("opacity", 0); }); }); } // render render.height = function(value) { if (!arguments.length) return height; height = value; return render; }; render.width = function(value) { if (!arguments.length) return width; width = value; return render; }; render.transit = function(value) { if (!arguments.length) return transit; transit = value; return render; }; return render; } // stateMap function getArea(bounds) { return (bounds[1][0]-bounds[0][0])*(bounds[1][1]-bounds[0][1]); } function placeRow(set, width, states, centre, align, param, margin) { var setStates = states.filter(function (d) { return set.indexOf(d.name) > -1 }); var space = d3.sum(setStates, function(d) { return d.space; }); var height = space / width; var yloc = (align=="absolute")?(param - height/2):0; if (align=="above") { var bigB = states.filter(function (d) { return d.name==param }).pop(); yloc = bigB.y - height - margin; } else if (align=="below") { var bigB = states.filter(function (d) { return d.name==param }).pop(); yloc = bigB.y + bigB.height + margin; } var xloc = centre - width/2; set.forEach(function(name) { var state = setStates.filter(function (d) { return d.name==name }).pop(); state.height = (state.space == 0)? 1: height; state.width = (state.space == 0)? 1: state.space / state.height; state.x = xloc; state.y = yloc; xloc += state.width + margin; }); } function placeRelative(states, target, aspect, master, direction, position, distance) { var state = states.filter(function (d) { return d.name==target }).pop(); var bigB = states.filter(function (d) { return d.name==master }).pop(); var width = Math.sqrt(aspect*state.space) state.width = (state.space == 0)? 1: width; state.height = (state.space == 0)? 1: state.space / width; var xvert = (position=="start")?bigB.x:(position=="middle")?(bigB.x+bigB.width/2-state.width/2):(bigB.x+bigB.width-state.width); var yhorz = (position=="start")?bigB.y:(position=="middle")?(bigB.y+bigB.height/2-state.height/2):(bigB.y+bigB.height-state.height); state.x = (direction=="west")?(bigB.x-state.width-distance):(direction=="east")?(bigB.x+bigB.width+distance):xvert; state.y = (direction=="north")?(bigB.y-state.height-distance):(direction=="south")?(bigB.y+bigB.height+distance):yhorz; }