Skip to content

Instantly share code, notes, and snippets.

@skokenes
Last active August 29, 2015 14:19
Show Gist options
  • Save skokenes/498a150f94cd21e2270f to your computer and use it in GitHub Desktop.
Save skokenes/498a150f94cd21e2270f to your computer and use it in GitHub Desktop.
Lasso Map Example
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.subunit {
fill: none;
stroke: #777;
}
.lasso path {
stroke: rgb(80,80,80);
stroke-width:2px;
}
.lasso .drawn {
fill-opacity:.05 ;
}
.lasso .loop_close {
fill:none;
stroke-dasharray: 4,4;
}
.lasso .origin {
fill:#3399FF;
fill-opacity:.5;
}
.not_possible {
fill:rgb(200,200,200);
}
.possible {
fill:#EC888C;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script src = "lasso.min.js"></script>
<script>
function lassoFunction (svg){
// Lasso functions to execute while lassoing
var lasso_start = function() {
lasso.items()
//.attr("r",3.5) // reset size
.style("fill",null) // clear all of the fills
.classed({"not_possible":true,"selected":false}); // style as not possible
};
var lasso_draw = function() {
// Style the possible dots
lasso.items().filter(function(d) {return d.possible===true})
.classed({"not_possible":false,"possible":true});
// Style the not possible dot
lasso.items().filter(function(d) {return d.possible===false})
.classed({"not_possible":true,"possible":false});
};
var lasso_end = function() {
var selected;
// var data = thisArea.data.objects;
//var keys = Object.keys(thisArea.database.data[0]);
var previousSelection=d3.selectAll(".selectedData");
// Reset the color of all dots
lasso.items()
.style("fill", function(d) { return "red"; });
// Style the selected dots
selected=lasso.items().filter(function(d) {
return d.selected===true})
.classed({"not_possible":false,"possible":false})
.attr({
"r":17,
})
.classed("selectedData",true)
.on("click",function(d){
operationsMenu(d3.mouse(this),thisArea);
});
// Reset the style of the not selected dots
lasso.items().filter(function(d) {return d.selected===false})
.classed({"not_possible":false,"possible":false})
//.attr("r",3.5);
for (i=0; i<selected[0].length;i++) {
selectedItems.push(data[selected[0][i].id.split("_")[1]])
}
//Each selection is made on one graph. Save the first element parent to the list in each lasso.
//parentsOfSelection.push(selected[0][0].classList[0]);
//parentsOfSelection=cleanArray(parentsOfSelection)
//Remove duplicates from selectedItems
//removeDuplicates(selectedItems,keys);
};
// Create the area where the lasso event can be triggered
var lasso_area = svg.append("rect")
.attr("width",width)
.attr("height",height)
.style("opacity",0);
// Define the lasso
var lasso = d3.lasso()
.closePathDistance(75) // max distance for the lasso loop to be closed
.closePathSelect(true) // can items be selected by closing the path?
.hoverSelect(true) // can items by selected by hovering over them?
.area(lasso_area) // area where the lasso can be started
.on("start",lasso_start) // lasso start function
.on("draw",lasso_draw) // lasso draw function
.on("end",lasso_end); // lasso end function
// Init the lasso on the svg:g that contains the dots
svg.call(lasso);
return lasso;
}
</script>
<script>
var data = [[19.084743376000063, -155.77583923699996],[21.276625083000056, -157.80294715899998],[21.30423490800007, -157.79986941499996]];
var width = 2000,
height = 2000;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var lasso = lassoFunction(svg);
var projection = d3.geo.mercator()
.scale(6000)
.translate([17000 , 2500]);
var path = d3.geo.path()
.projection(projection);
d3.json("test.json", function(error, hawaii) {
if (error) return console.error(error);
svg.selectAll(".subunit")
.data(topojson.feature(hawaii, hawaii.objects.filterMap).features)
.enter().append("path")
.attr("class", function(d) {
return "subunit " + d.id; })
.attr("d", path);
svg.append("path")
.datum(topojson.feature(hawaii, hawaii.objects.hawaiiPlaces))
.attr("d", path)
.attr("class", "place");
svg.selectAll(".place-label")
.data(topojson.feature(hawaii, hawaii.objects.hawaiiPlaces).features)
.enter().append("text")
.attr("class", "place-label")
.attr("transform", function(d) { return "translate(" + projection(d.geometry.coordinates) + ")"; })
.attr("dy", "-0.2em")
.text(function(d) { return d.properties.name; });
svg.selectAll(".pin")
.data(data)
.enter().append("circle")
.attr("class","pin")
.attr("r", 5)
.attr("fill","red")
.attr("transform", function(d) {
return "translate(" + projection([
//coordinates should be passed longitude,latitude
d[1],
d[0]
]) + ")"
});
lasso.items(d3.selectAll(".pin"));
});
</script>
</body>
</html>
d3.lasso=function(){function t(){function t(){u="",P.attr("d",null),v.attr("d",null),g=0;var t=y[0][0].getBoundingClientRect();n[0].forEach(function(e){e.hoverSelected=!1,e.loopSelected=!1;var n=(e.getBBox(),e.getBoundingClientRect());e.lassoPoint={cx:Math.round(n.left-t.left+n.width/2),cy:Math.round(n.top-t.top+n.height/2),edges:{top:0,right:0,bottom:0,left:0},close_edges:{left:0,right:0}}}),1==a&&n.on("mouseover.lasso",function(){d3.select(this)[0][0].hoverSelected=!0}),i.start()}function c(){var t=d3.mouse(this)[0],a=d3.mouse(this)[1];""==u?(u=u+"M "+t+" "+a,h=[t,a],M.attr("cx",t).attr("cy",a).attr("r",7).attr("display",null)):u=u+" L "+t+" "+a,n[0].forEach(function(t){t.lassoPoint.close_edges={left:0,right:0}});var l=Math.sqrt(Math.pow(t-h[0],2)+Math.pow(a-h[1],2)),c="M "+t+" "+a+" L "+h[0]+" "+h[1];P.attr("d",u),o>=l?v.attr("display",null):v.attr("display","none"),s=o>=l?!0:!1;var d=u+"Z";x.attr("d",d);for(var y=P.node(),p=y.getTotalLength(),m=(y.getPointAtLength(g-1),g);p>=m;m++){var _=y.getPointAtLength(m),S={x:Math.round(100*_.x)/100,y:Math.round(100*_.y)/100},b=y.getPointAtLength(m-1),L={x:Math.round(100*b.x)/100,y:Math.round(100*b.y)/100};n[0].filter(function(t){var n;return t.lassoPoint.cy===S.y&&t.lassoPoint.cy!=L.y?(f={x:L.x,y:L.y},n=!1):t.lassoPoint.cy===S.y&&t.lassoPoint.cy===L.y?n=!1:t.lassoPoint.cy===L.y&&t.lassoPoint.cy!=S.y?n=e(t.lassoPoint.cy-S.y)!=e(t.lassoPoint.cy-f.y):(f={x:L.x,y:L.y},n=e(t.lassoPoint.cy-S.y)!=e(t.lassoPoint.cy-L.y)),n}).forEach(function(t){S.x>t.lassoPoint.cx&&(t.lassoPoint.edges.right=t.lassoPoint.edges.right+1),S.x<t.lassoPoint.cx&&(t.lassoPoint.edges.left=t.lassoPoint.edges.left+1)})}if(1==s&&1==r){v.attr("d",c),close_path_node=v.node();for(var w=close_path_node.getTotalLength(),m=0;w>=m;m++){var _=close_path_node.getPointAtLength(m),b=close_path_node.getPointAtLength(m-1);n[0].filter(function(t){return t.lassoPoint.cy==Math.round(_.y)}).forEach(function(t){Math.round(_.y)!=Math.round(b.y)&&Math.round(_.x)>t.lassoPoint.cx&&(t.lassoPoint.close_edges.right=1),Math.round(_.y)!=Math.round(b.y)&&Math.round(_.x)<t.lassoPoint.cx&&(t.lassoPoint.close_edges.left=1)})}n[0].forEach(function(t){t.loopSelected=t.lassoPoint.edges.left+t.lassoPoint.close_edges.left>0&&(t.lassoPoint.edges.right+t.lassoPoint.close_edges.right)%2==1?!0:!1})}else n[0].forEach(function(t){t.loopSelected=!1});d3.selectAll(n[0].filter(function(t){return t.loopSelected&&s||t.hoverSelected})).attr("d",function(t){return t.possible=!0}),d3.selectAll(n[0].filter(function(t){return!(t.loopSelected&&s||t.hoverSelected)})).attr("d",function(t){return t.possible=!1}),i.draw(),g=p+1}function d(){n.on("mouseover.lasso",null),n.filter(function(t){return t.possible===!0}).attr("d",function(t){return t.selected=!0}),n.filter(function(t){return t.possible===!1}).attr("d",function(t){return t.selected=!1}),n.attr("d",function(t){return t.possible=!1}),P.attr("d",null),v.attr("d",null),M.attr("display","none"),i.end()}var u,h,f,g,y=d3.select(this[0][0]),p=y.append("g").attr("class","lasso"),P=p.append("path").attr("class","drawn"),v=p.append("path").attr("class","loop_close"),x=p.append("path").attr("display","none"),M=p.append("circle").attr("class","origin"),m=d3.behavior.drag().on("dragstart",t).on("drag",c).on("dragend",d);l.call(m)}function e(t){return t?0>t?-1:1:0}var n=null,o=75,r=!0,s=!1,a=!0,l=null,i={start:function(){},draw:function(){},end:function(){}};return t.items=function(e){return arguments.length?(n=e,n[0].forEach(function(t){var e=d3.select(t);"undefined"==typeof e.datum()?e.datum({possible:!1,selected:!1}):e.attr("d",function(t){return t.possible=!1,t.selected=!1,t})}),t):n},t.closePathDistance=function(e){return arguments.length?(o=e,t):o},t.closePathSelect=function(e){return arguments.length?(r=1==e?!0:!1,t):r},t.isPathClosed=function(e){return arguments.length?(s=1==e?!0:!1,t):s},t.hoverSelect=function(e){return arguments.length?(a=1==e?!0:!1,t):a},t.on=function(e,n){if(!arguments.length)return i;if(1===arguments.length)return i[e];var o=["start","draw","end"];return o.indexOf(e)>-1&&(i[e]=n),t},t.area=function(e){return arguments.length?(l=e,t):l},t};
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment