var Utils = (function () { 'use strict'; function parsePlaces(geo) { geo.features.sort(function (a, b) { return a.properties.name.localeCompare(b.properties.name); }); geo.features.forEach(function (v, k) { v.properties.id = k; v.properties.description = v.properties.description || 'place'; }); } function pointsToFeatures(points, type, name, shift) { return points.coordinates.map(function (p) { var sh = p[0] + shift; sh = (sh > 180) ? (sh - 360) : sh; return { coordinates: p, geometry: { coordinates: [sh, p[1]], type: 'Point' }, type: type, properties: { name: name } } }); } function trans(path) { return function (d) { var p = path.centroid(d); if (isNaN(p[0]) || isNaN(p[1])) { p[0] = -1e10; p[1] = -1e10; } return d.translate = 'translate(' + p + ')'; }; } function addSymbols(root, cfg, scale) { var g = root.append('defs'); d3.keys(cfg.symbols).forEach(function (d) { g.append('path') .attr('id', d) .attr('class', 'symbol ' + d) .attr('d', d3.svg.symbol() .size(scale * scale * cfg.sizes[d]) .type(cfg.symbols[d])()); }); return g.selectAll('path'); } function svgPlaces(root, geo, t, scale, cfg, clicked) { t = trans(t); var defs = addSymbols(root, cfg, scale); var places = root.selectAll() .data(geo.features) .enter() .append('use') .attr('transform', t) .attr('xlink:href', function (d) { return '#' + d.properties.description; }) .on('click', clicked); return { defs: defs, places: places } } function _svgPlaces(root, geo, t, scale, cfg, clicked) { t = trans(t); return root.selectAll() .data(geo.features) .enter() .append('path') .attr('transform', t) .attr('class', function (d) { return 'symbol ' + d.properties.description; }) .attr('d', function (d) { return d3.svg.symbol() .size(scale * cfg.sizes[d.properties.description]) .type(cfg.symbols[d.properties.description])(); }) .on('click', clicked); } function svgLines(root, path, data, type) { return root.append('path') .datum(data) .attr('class', 'line ' + type) .attr('d', path); } function svgPoints(root, points, type, projection, clicked, display) { points = points.filter(function (d) { var p = projection(d.coordinates); if (Math.abs(p[0]) !== Infinity && Math.abs(p[1]) !== Infinity) { d.projected = p; return true; } }); var p = root.selectAll('.point.' + type).data(points); p.enter().append('circle') .attr('class', 'point ' + type) .style('display', display) .attr('r', 5) .attr('transform', function (d) { return 'translate(' + d.projected + ')'; }) .on('click', clicked); } function svgControls(root, setIndex, reset) { root.append('path') .attr('class', 'control') .attr('d', d3.svg.symbol().size(120).type('triangle-up')) .attr('transform', 'translate(60,10)rotate(90)') .on('click', function () { setIndex(+1); }); root.append('path') .attr('class', 'control') .attr('d', d3.svg.symbol().size(120).type('circle')) .attr('transform', 'translate(35,10)') .on('click', reset); root.append('path') .attr('class', 'control') .attr('d', d3.svg.symbol().size(120).type('triangle-up')) .attr('transform', 'translate(10,10)rotate(-90)') .on('click', function () { setIndex(-1); }); } return { svgLines: svgLines, svgPoints: svgPoints, svgPlaces: svgPlaces, svgControls: svgControls, parsePlaces: parsePlaces, pointsToFeatures: pointsToFeatures }; })();