var width = 300, height = 300 var scale = 1500 var translate = [-100, 1500] var labelPadding = 3 var firs var svg = d3.select('#viz') .append('svg') .attr('width', width) .attr('height', height) // find proper scale and translation from bounds of europe polygon var projection = d3.geo.azimuthalEqualArea() .scale(scale) .translate(translate) var path = d3.geo.path().projection(projection) var selected = d3.set(['EYVLFIR', 'EPWWFIR']) // var selected = d3.set(['EYVLFIR']) // var selected = d3.set(['EPWWFIR']) // var selected = d3.set([ // 'LGGGFIR', // 'LIBBFIR', 'LIMMFIR', 'LIRRFIR', // 'LMMMFIR', // 'LCCCFIR' // ]) // ca. BBox for Poland and Lituania var geojObj = { 'type': 'FeatureCollection', 'features': [{ 'type': 'Feature', 'geometry': { 'type': 'Polygon', 'coordinates': [ [ [14.0, 48.7], [14.0, 56.6], [27.4, 56.6], [27.4, 48.7], [14.0, 48.7] ] ] }, 'properties': { 'name': 'A' } }] } var tooltip = d3.select('#tooltip').classed('hidden', true), tooltiptext = d3.select('#tooltiptext') var background = svg.selectAll('rect.background') .data([{}]).enter() .append('rect') .classed('background', true) var g = svg.selectAll('g.all') .data([{}]).enter() .append('g') .classed('all', true) var active = d3.select(null) var zoom = d3.behavior.zoom() .scaleExtent([1, 8000]) .on('zoom', zoomed) function zoomed () { g.style('stroke-width', 1.5 / d3.event.scale + 'px') g.attr('transform', 'translate(' + d3.event.translate + ')scale(' + d3.event.scale + ')') } // If the drag behavior prevents the default click, // also stop propagation so we don’t click-to-zoom. function stopped () { if (d3.event.defaultPrevented) d3.event.stopPropagation() } function reset () { active.classed('active', false) active = d3.select(null) svg.transition() .duration(750) .call(zoom.translate([0, 0]).scale(1).event) } function clicked (d) { if (active.node() === this) { console.log('this node is active') return reset() } active.classed('active', false) active = d3.select(this).classed('active', true) var bounds = path.bounds(d), dx = bounds[1][0] - bounds[0][0], dy = bounds[1][1] - bounds[0][1], x = (bounds[0][0] + bounds[1][0]) / 2, y = (bounds[0][1] + bounds[1][1]) / 2, scale = .95 / Math.max(dx / width, dy / height), translate = [width / 2 - scale * x, height / 2 - scale * y] svg.transition() .duration(750) .call(zoom.translate(translate).scale(scale).event) } // prj is the projection // pth is the path // gObj is the geojson object function scaleAndTranslate (prj, pth, gObj) { prj .scale(1) .translate([0, 0]) var b = pth.bounds(gObj), dx = (b[1][0] - b[0][0]), dy = (b[1][1] - b[0][1]), x = (b[1][0] + b[0][0]), y = (b[1][1] + b[0][1]), s = .95 / Math.max(dx / width, dy / height), t = [(width - s * x) / 2, (height - s * y) / 2] // return the scale and translate to be used to update the projection. // Such as // projection.scale(s).translate(t) return {'scale': s, 'translate': t} } svg.on('click', stopped, true) background.on('click', reset) g.style('stroke-width', '0.5px') svg .call(zoom) // delete this line to disable free zooming .call(zoom.event) svg.on('mousemove', function () { // update tooltip position tooltip.style('top', (event.pageY + 16) + 'px').style('left', (event.pageX + 10) + 'px') return true }) d3.json('FIRs_NM.json', function (error, fir) { if (error) throw error firs = topojson.feature(fir, fir.objects.FIRs_NM) var graticule = d3.geo.graticule() var myfirs = firs.features.filter(function (d) { return selected.has(d.id) }) // var sAndT = scaleAndTranslate(projection, path, firs) // projection.scale(sAndT.scale).translate(sAndT.translate) var gFIR = g.selectAll('.fir') .data(myfirs) .enter() .append('g') .attr('class', 'fir') var fff = gFIR .append('path') .attr('class', function (d) { return 'fir ' + d.id }) .attr('d', path) gFIR.selectAll('.point') .data(function (d, i) { return d.geometry.coordinates[0] }) .enter().append('circle') .attr('class', 'point') .attr('cx', function (d) { return projection([d[0], d[1]])[0] }) .attr('cy', function (d) { return projection([d[0], d[1]])[1] }) .attr('r', 1) .attr('fill', 'red') .attr('opacity', 0.3) var label = gFIR.selectAll('.label') .data(function (d) { return (d.geometry.coordinates[0]).filter(function (d, i) { // if (i%3 === 0) return true return true }) }) .enter().append('g') .attr('class', 'label') .attr('transform', function (d, i) { return 'translate(' + projection([d[0], d[1]])[0] + ',' + projection([d[0], d[1]])[1] + ')' }) label.append('text') // .attr("dy", ".35em") .text(function (d, i) { return i }) // from http://stackoverflow.com/a/16093597/963575 var mmm = topojson.merge( fir, fir.objects.FIRs_NM.geometries.filter(function (d) { return selected.has(d.id) })) g.append('path') .datum(mmm) .attr('class', 'merged') .attr('transform', 'translate(20, 30)') .attr('d', path) })