コード例 #1
0
ファイル: helpers.js プロジェクト: Stalfur/iD
export function svgPath(projection, graph, isArea) {

    // Explanation of magic numbers:
    // "padding" here allows space for strokes to extend beyond the viewport,
    // so that the stroke isn't drawn along the edge of the viewport when
    // the shape is clipped.
    //
    // When drawing lines, pad viewport by 5px.
    // When drawing areas, pad viewport by 65px in each direction to allow
    // for 60px area fill stroke (see ".fill-partial path.fill" css rule)

    var cache = {};
    var padding = isArea ? 65 : 5;
    var viewport = projection.clipExtent();
    var paddedExtent = [
        [viewport[0][0] - padding, viewport[0][1] - padding],
        [viewport[1][0] + padding, viewport[1][1] + padding]
    ];
    var clip = d3_geoIdentity().clipExtent(paddedExtent).stream;
    var project = projection.stream;
    var path = d3_geoPath()
        .projection({stream: function(output) { return project(clip(output)); }});

    var svgpath = function(entity) {
        if (entity.id in cache) {
            return cache[entity.id];
        } else {
            return cache[entity.id] = path(entity.asGeoJSON(graph));
        }
    };

    svgpath.geojson = path;

    return svgpath;
}
コード例 #2
0
ファイル: data.js プロジェクト: brianhatchl/iD
        function drawLabels(selection, textClass, data) {
            var labelPath = d3_geoPath(projection);
            var labelData = data.filter(function(d) {
                return _showLabels && d.properties && (d.properties.desc || d.properties.name);
            });

            var labels = selection.selectAll('text.' + textClass)
                .data(labelData, featureKey);

            // exit
            labels.exit()
                .remove();

            // enter/update
            labels = labels.enter()
                .append('text')
                .attr('class', function(d) { return textClass + ' ' + featureClasses(d); })
                .merge(labels)
                .text(function(d) {
                    return d.properties.desc || d.properties.name;
                })
                .attr('x', function(d) {
                    var centroid = labelPath.centroid(d);
                    return centroid[0] + 11;
                })
                .attr('y', function(d) {
                    var centroid = labelPath.centroid(d);
                    return centroid[1];
                });
        }
コード例 #3
0
ファイル: MapJourneyCard.js プロジェクト: njho/journey
    componentWillMount() {
        const projection = geoMercator();
        const pathGenerator = geoPath().projection(projection)

        var dimensionsArray = pathGenerator.bounds(this.state.geojson);
        var xAspect = Math.abs(dimensionsArray[0][0] - dimensionsArray[1][0]);
        var yAspect = Math.abs(dimensionsArray[0][1] - dimensionsArray[1][1]);
        var aspectRatio = xAspect / yAspect;
        console.log('aspect ratio' + aspectRatio);

        var height = 60 / aspectRatio * 1.2;


        this.setState({
            ...this.state,
            svgHeight: height

        })


        console.log(pathGenerator(this.state.geojson));
        console.log(pathGenerator.bounds(this.state.geojson))


    }
コード例 #4
0
ファイル: labels.js プロジェクト: openstreetmap/iD
    function drawCollisionBoxes(selection, rtree, which) {
        var classes = 'debug ' + which + ' ' + (which === 'debug-skipped' ? 'orange' : 'yellow');

        var gj = [];
        if (context.getDebug('collision')) {
            gj = rtree.all().map(function(d) {
                return { type: 'Polygon', coordinates: [[
                    [d.minX, d.minY],
                    [d.maxX, d.minY],
                    [d.maxX, d.maxY],
                    [d.minX, d.maxY],
                    [d.minX, d.minY]
                ]]};
            });
        }

        var boxes = selection.selectAll('.' + which)
            .data(gj);

        // exit
        boxes.exit()
            .remove();

        // enter/update
        boxes.enter()
            .append('path')
            .attr('class', classes)
            .merge(boxes)
            .attr('d', d3_geoPath());
    }
コード例 #5
0
ファイル: norway.js プロジェクト: torgeir/norway.js
  constructor(el, { area = Country.County } = {}) {
    mixin(new Events, this);

    this.area = area;
    this._areas = [];

    const [x, y] = [400, 560];

    const svgEl= select(el)
          .append('svg:svg')
          .attr('viewBox', `0 0 ${x} ${y}`)
          .attr('preserveAspectRatio', 'xMidYMid')
          .attr('width', '100%')
          .attr('height', '100%');

    const projection = geoMercator()
          .scale(1000)
          .translate([-110, 1800]);

    this.path = geoPath(projection);

    this.svg = svgEl
      .append('svg:g')
      .attr('id', 'areas');

    setTimeout(() => this.load(this.area.data));
  }
コード例 #6
0
const renderPath = (cacheId, geography, projection, round, precision) => {
  if (pathCache[cacheId]) return pathCache[cacheId]

  const pathString = cacheId
    ? pathCache[cacheId]
      ? pathCache[cacheId]
      : round
        ? roundPath(geoPath().projection(projection)(geography), precision)
        : geoPath().projection(projection)(geography)
    : round
      ? roundPath(geoPath().projection(projection)(geography), precision)
      : geoPath().projection(projection)(geography)

  if (cacheId) pathCache[cacheId] = pathString

  return pathString
}
コード例 #7
0
export default (className, { topoJSONPath, topoJSONRoot, getPolygonClassName, showTooltipCallback, hideTooltipCallback, useRobinsonProjection }) => {
  const d3Container =  d3_select(className);
  d3Container.node().classList.remove('-with-legend');
  const containerComputedStyle = window.getComputedStyle(d3Container.node());
  const width = parseInt(containerComputedStyle.width);
  const height = parseInt(containerComputedStyle.height);

  const svg = d3Container.append('svg')
    .attr('width', width)
    .attr('height', height);

  const geoParent = svg.append('g');
  const container = geoParent.append('g');

  const projection = (useRobinsonProjection === true) ? d3_geoRobinson() : d3_geoMercator();
  const path = d3_geoPath()
    .projection(projection);

  d3_json(topoJSONPath, function(error, topoJSON) {
    const features = topojson.feature(topoJSON, topoJSON.objects[topoJSONRoot]);

    const polygons = container.selectAll('path')
      .data(features.features)
      .enter()
      .append('path')
      .attr('class', d => {
        return `polygon ${getPolygonClassName(d)}`;
      })
      .attr('d', path);

    if (showTooltipCallback !== undefined) {
      polygons.on('mousemove', function(d) {
        showTooltipCallback(d, d3_event.clientX + 10, d3_event.clientY + window.scrollY + 10);
      } )
      .on('mouseout', function() {
        hideTooltipCallback();
      });
    }

    const collection = {
      'type': 'FeatureCollection',
      'features' : features.features
    };
    const featureBounds = path.bounds(collection);
    const { scale, trans } = fitGeoInside(featureBounds, width, height);

    container.attr('transform', [
      'translate(' + trans + ')',
      'scale(' + scale + ')'
    ].join(' '));

    container.selectAll('path').style('stroke-width', .5 / scale);
  });
};
コード例 #8
0
ファイル: projections.js プロジェクト: glimpseio/vega
  return function projection() {
    var p = constructor();

    p.type = type;

    p.path = geoPath().projection(p);

    p.copy = p.copy || function() {
      var c = projection();
      projectionProperties.forEach(function(prop) {
        if (p.hasOwnProperty(prop)) c[prop](p[prop]());
      });
      c.path.pointRadius(p.path.pointRadius());
      return c;
    };

    return p;
  };
コード例 #9
0
  _redraw() {
    const pixelRatio = window.devicePixelRatio;
    const canvas = this.refs.overlay;
    const ctx = canvas.getContext('2d');
    const mercator = ViewportMercator(this.props);

    ctx.save();
    ctx.scale(pixelRatio, pixelRatio);
    ctx.clearRect(0, 0, this.props.width, this.props.height);

    function projectPoint(lon, lat) {
      const point = mercator.project([lon, lat]);
      /* eslint-disable no-invalid-this */
      this.stream.point(point[0], point[1]);
      /* eslint-enable no-invalid-this */
    }

    if (this.props.renderWhileDragging || !this.props.isDragging) {
      const transform = geoTransform({point: projectPoint});
      const path = geoPath().projection(transform).context(ctx);
      this._drawFeatures(ctx, path);
    }
    ctx.restore();
  }
コード例 #10
0
ファイル: labels.js プロジェクト: openstreetmap/iD
export function svgLabels(projection, context) {
    var path = d3_geoPath(projection);
    var detected = utilDetect();
    var baselineHack = (detected.ie || detected.browser.toLowerCase() === 'edge');
    var _rdrawn = rbush();
    var _rskipped = rbush();
    var _textWidthCache = {};
    var _entitybboxes = {};

    // Listed from highest to lowest priority
    var labelStack = [
        ['line', 'aeroway', '*', 12],
        ['line', 'highway', 'motorway', 12],
        ['line', 'highway', 'trunk', 12],
        ['line', 'highway', 'primary', 12],
        ['line', 'highway', 'secondary', 12],
        ['line', 'highway', 'tertiary', 12],
        ['line', 'highway', '*', 12],
        ['line', 'railway', '*', 12],
        ['line', 'waterway', '*', 12],
        ['area', 'aeroway', '*', 12],
        ['area', 'amenity', '*', 12],
        ['area', 'building', '*', 12],
        ['area', 'historic', '*', 12],
        ['area', 'leisure', '*', 12],
        ['area', 'man_made', '*', 12],
        ['area', 'natural', '*', 12],
        ['area', 'shop', '*', 12],
        ['area', 'tourism', '*', 12],
        ['area', 'camp_site', '*', 12],
        ['point', 'aeroway', '*', 10],
        ['point', 'amenity', '*', 10],
        ['point', 'building', '*', 10],
        ['point', 'historic', '*', 10],
        ['point', 'leisure', '*', 10],
        ['point', 'man_made', '*', 10],
        ['point', 'natural', '*', 10],
        ['point', 'shop', '*', 10],
        ['point', 'tourism', '*', 10],
        ['point', 'camp_site', '*', 10],
        ['line', 'name', '*', 12],
        ['area', 'name', '*', 12],
        ['point', 'name', '*', 10]
    ];


    function blacklisted(preset) {
        var noIcons = ['building', 'landuse', 'natural'];
        return noIcons.some(function(s) {
            return preset.id.indexOf(s) >= 0;
        });
    }


    function get(array, prop) {
        return function(d, i) { return array[i][prop]; };
    }


    function textWidth(text, size, elem) {
        var c = _textWidthCache[size];
        if (!c) c = _textWidthCache[size] = {};

        if (c[text]) {
            return c[text];

        } else if (elem) {
            c[text] = elem.getComputedTextLength();
            return c[text];

        } else {
            var str = encodeURIComponent(text).match(/%[CDEFcdef]/g);
            if (str === null) {
                return size / 3 * 2 * text.length;
            } else {
                return size / 3 * (2 * text.length + str.length);
            }
        }
    }


    function drawLinePaths(selection, entities, filter, classes, labels) {
        var paths = selection.selectAll('path')
            .filter(filter)
            .data(entities, osmEntity.key);

        // exit
        paths.exit()
            .remove();

        // enter/update
        paths.enter()
            .append('path')
            .style('stroke-width', get(labels, 'font-size'))
            .attr('id', function(d) { return 'labelpath-' + d.id; })
            .attr('class', classes)
            .merge(paths)
            .attr('d', get(labels, 'lineString'));
    }


    function drawLineLabels(selection, entities, filter, classes, labels) {
        var texts = selection.selectAll('text.' + classes)
            .filter(filter)
            .data(entities, osmEntity.key);

        // exit
        texts.exit()
            .remove();

        // enter
        texts.enter()
            .append('text')
            .attr('class', function(d, i) { return classes + ' ' + labels[i].classes + ' ' + d.id; })
            .attr('dy', baselineHack ? '0.35em' : null)
            .append('textPath')
            .attr('class', 'textpath');

        // update
        selection.selectAll('text.' + classes).selectAll('.textpath')
            .filter(filter)
            .data(entities, osmEntity.key)
            .attr('startOffset', '50%')
            .attr('xlink:href', function(d) { return '#labelpath-' + d.id; })
            .text(utilDisplayNameForPath);
    }


    function drawPointLabels(selection, entities, filter, classes, labels) {
        var texts = selection.selectAll('text.' + classes)
            .filter(filter)
            .data(entities, osmEntity.key);

        // exit
        texts.exit()
            .remove();

        // enter/update
        texts.enter()
            .append('text')
            .attr('class', function(d, i) {
                return classes + ' ' + labels[i].classes + ' ' + d.id;
            })
            .merge(texts)
            .attr('x', get(labels, 'x'))
            .attr('y', get(labels, 'y'))
            .style('text-anchor', get(labels, 'textAnchor'))
            .text(utilDisplayName)
            .each(function(d, i) {
                textWidth(utilDisplayName(d), labels[i].height, this);
            });
    }


    function drawAreaLabels(selection, entities, filter, classes, labels) {
        entities = entities.filter(hasText);
        labels = labels.filter(hasText);
        drawPointLabels(selection, entities, filter, classes, labels);

        function hasText(d, i) {
            return labels[i].hasOwnProperty('x') && labels[i].hasOwnProperty('y');
        }
    }


    function drawAreaIcons(selection, entities, filter, classes, labels) {
        var icons = selection.selectAll('use.' + classes)
            .filter(filter)
            .data(entities, osmEntity.key);

        // exit
        icons.exit()
            .remove();

        // enter/update
        icons.enter()
            .append('use')
            .attr('class', 'icon ' + classes)
            .attr('width', '17px')
            .attr('height', '17px')
            .merge(icons)
            .attr('transform', get(labels, 'transform'))
            .attr('xlink:href', function(d) {
                var preset = context.presets().match(d, context.graph());
                var picon = preset && preset.icon;

                if (!picon) {
                    return '';
                } else {
                    var isMaki = /^maki-/.test(picon);
                    return '#' + picon + (isMaki ? '-15' : '');
                }
            });
    }


    function drawCollisionBoxes(selection, rtree, which) {
        var classes = 'debug ' + which + ' ' + (which === 'debug-skipped' ? 'orange' : 'yellow');

        var gj = [];
        if (context.getDebug('collision')) {
            gj = rtree.all().map(function(d) {
                return { type: 'Polygon', coordinates: [[
                    [d.minX, d.minY],
                    [d.maxX, d.minY],
                    [d.maxX, d.maxY],
                    [d.minX, d.maxY],
                    [d.minX, d.minY]
                ]]};
            });
        }

        var boxes = selection.selectAll('.' + which)
            .data(gj);

        // exit
        boxes.exit()
            .remove();

        // enter/update
        boxes.enter()
            .append('path')
            .attr('class', classes)
            .merge(boxes)
            .attr('d', d3_geoPath());
    }


    function drawLabels(selection, graph, entities, filter, dimensions, fullRedraw) {
        var wireframe = context.surface().classed('fill-wireframe');
        var zoom = geoScaleToZoom(projection.scale());

        var labelable = [];
        var renderNodeAs = {};
        var i, j, k, entity, geometry;

        for (i = 0; i < labelStack.length; i++) {
            labelable.push([]);
        }

        if (fullRedraw) {
            _rdrawn.clear();
            _rskipped.clear();
            _entitybboxes = {};

        } else {
            for (i = 0; i < entities.length; i++) {
                entity = entities[i];
                var toRemove = []
                    .concat(_entitybboxes[entity.id] || [])
                    .concat(_entitybboxes[entity.id + 'I'] || []);

                for (j = 0; j < toRemove.length; j++) {
                    _rdrawn.remove(toRemove[j]);
                    _rskipped.remove(toRemove[j]);
                }
            }
        }

        // Loop through all the entities to do some preprocessing
        for (i = 0; i < entities.length; i++) {
            entity = entities[i];
            geometry = entity.geometry(graph);

            // Insert collision boxes around interesting points/vertices
            if (geometry === 'point' || (geometry === 'vertex' && isInterestingVertex(entity))) {
                var hasDirections = entity.directions(graph, projection).length;
                var markerPadding;

                if (!wireframe && geometry === 'point' && !(zoom >= 18 && hasDirections)) {
                    renderNodeAs[entity.id] = 'point';
                    markerPadding = 20;   // extra y for marker height
                } else {
                    renderNodeAs[entity.id] = 'vertex';
                    markerPadding = 0;
                }

                var coord = projection(entity.loc);
                var nodePadding = 10;
                var bbox = {
                    minX: coord[0] - nodePadding,
                    minY: coord[1] - nodePadding - markerPadding,
                    maxX: coord[0] + nodePadding,
                    maxY: coord[1] + nodePadding
                };

                doInsert(bbox, entity.id + 'P');
            }

            // From here on, treat vertices like points
            if (geometry === 'vertex') {
                geometry = 'point';
            }

            // Determine which entities are label-able
            var preset = geometry === 'area' && context.presets().match(entity, graph);
            var icon = preset && !blacklisted(preset) && preset.icon;

            if (!icon && !utilDisplayName(entity))
                continue;

            for (k = 0; k < labelStack.length; k++) {
                var matchGeom = labelStack[k][0];
                var matchKey = labelStack[k][1];
                var matchVal = labelStack[k][2];
                var hasVal = entity.tags[matchKey];

                if (geometry === matchGeom && hasVal && (matchVal === '*' || matchVal === hasVal)) {
                    labelable[k].push(entity);
                    break;
                }
            }
        }

        var positions = {
            point: [],
            line: [],
            area: []
        };

        var labelled = {
            point: [],
            line: [],
            area: []
        };

        // Try and find a valid label for labellable entities
        for (k = 0; k < labelable.length; k++) {
            var fontSize = labelStack[k][3];

            for (i = 0; i < labelable[k].length; i++) {
                entity = labelable[k][i];
                geometry = entity.geometry(graph);

                var getName = (geometry === 'line') ? utilDisplayNameForPath : utilDisplayName;
                var name = getName(entity);
                var width = name && textWidth(name, fontSize);
                var p = null;

                if (geometry === 'point' || geometry === 'vertex') {
                    // no point or vertex labels in wireframe mode
                    // no vertex labels at low zooms (vertices have no icons)
                    if (wireframe) continue;
                    var renderAs = renderNodeAs[entity.id];
                    if (renderAs === 'vertex' && zoom < 17) continue;

                    p = getPointLabel(entity, width, fontSize, renderAs);

                } else if (geometry === 'line') {
                    p = getLineLabel(entity, width, fontSize);

                } else if (geometry === 'area') {
                    p = getAreaLabel(entity, width, fontSize);
                }

                if (p) {
                    if (geometry === 'vertex') { geometry = 'point'; }  // treat vertex like point
                    p.classes = geometry + ' tag-' + labelStack[k][1];
                    positions[geometry].push(p);
                    labelled[geometry].push(entity);
                }
            }
        }


        function isInterestingVertex(entity) {
            var selectedIDs = context.selectedIDs();

            return entity.hasInterestingTags() ||
                entity.isEndpoint(graph) ||
                entity.isConnected(graph) ||
                selectedIDs.indexOf(entity.id) !== -1 ||
                graph.parentWays(entity).some(function(parent) {
                    return selectedIDs.indexOf(parent.id) !== -1;
                });
        }


        function getPointLabel(entity, width, height, geometry) {
            var y = (geometry === 'point' ? -12 : 0);
            var pointOffsets = {
                ltr: [15, y, 'start'],
                rtl: [-15, y, 'end']
            };

            var coord = projection(entity.loc);
            var textPadding = 2;
            var offset = pointOffsets[textDirection];
            var p = {
                height: height,
                width: width,
                x: coord[0] + offset[0],
                y: coord[1] + offset[1],
                textAnchor: offset[2]
            };

            // insert a collision box for the text label..
            var bbox;
            if (textDirection === 'rtl') {
                bbox = {
                    minX: p.x - width - textPadding,
                    minY: p.y - (height / 2) - textPadding,
                    maxX: p.x + textPadding,
                    maxY: p.y + (height / 2) + textPadding
                };
            } else {
                bbox = {
                    minX: p.x - textPadding,
                    minY: p.y - (height / 2) - textPadding,
                    maxX: p.x + width + textPadding,
                    maxY: p.y + (height / 2) + textPadding
                };
            }

            if (tryInsert([bbox], entity.id, true)) {
                return p;
            }
        }


        function getLineLabel(entity, width, height) {
            var viewport = geoExtent(context.projection.clipExtent()).polygon();
            var points = graph.childNodes(entity)
                .map(function(node) { return projection(node.loc); });
            var length = geoPathLength(points);

            if (length < width + 20) return;

            // todo: properly clip points to viewport

            // % along the line to attempt to place the label
            var lineOffsets = [50, 45, 55, 40, 60, 35, 65, 30, 70,
                               25, 75, 20, 80, 15, 95, 10, 90, 5, 95];
            var padding = 3;

            for (var i = 0; i < lineOffsets.length; i++) {
                var offset = lineOffsets[i];
                var middle = offset / 100 * length;
                var start = middle - width / 2;

                if (start < 0 || start + width > length) continue;

                // generate subpath and ignore paths that are invalid or don't cross viewport.
                var sub = subpath(points, start, start + width);
                if (!sub || !geoPolygonIntersectsPolygon(viewport, sub, true)) {
                    continue;
                }

                var isReverse = reverse(sub);
                if (isReverse) {
                    sub = sub.reverse();
                }

                var bboxes = [];
                var boxsize = (height + 2) / 2;

                for (var j = 0; j < sub.length - 1; j++) {
                    var a = sub[j];
                    var b = sub[j + 1];

                    // split up the text into small collision boxes
                    var num = Math.max(1, Math.floor(geoVecLength(a, b) / boxsize / 2));

                    for (var box = 0; box < num; box++) {
                        var p = geoVecInterp(a, b, box / num);
                        var x0 = p[0] - boxsize - padding;
                        var y0 = p[1] - boxsize - padding;
                        var x1 = p[0] + boxsize + padding;
                        var y1 = p[1] + boxsize + padding;

                        bboxes.push({
                            minX: Math.min(x0, x1),
                            minY: Math.min(y0, y1),
                            maxX: Math.max(x0, x1),
                            maxY: Math.max(y0, y1)
                        });
                    }
                }

                if (tryInsert(bboxes, entity.id, false)) {   // accept this one
                    return {
                        'font-size': height + 2,
                        lineString: lineString(sub),
                        startOffset: offset + '%'
                    };
                }
            }

            function reverse(p) {
                var angle = Math.atan2(p[1][1] - p[0][1], p[1][0] - p[0][0]);
                return !(p[0][0] < p[p.length - 1][0] && angle < Math.PI/2 && angle > -Math.PI/2);
            }

            function lineString(points) {
                return 'M' + points.join('L');
            }

            function subpath(points, from, to) {
                var sofar = 0;
                var start, end, i0, i1;

                for (var i = 0; i < points.length - 1; i++) {
                    var a = points[i];
                    var b = points[i + 1];
                    var current = geoVecLength(a, b);
                    var portion;
                    if (!start && sofar + current >= from) {
                        portion = (from - sofar) / current;
                        start = [
                            a[0] + portion * (b[0] - a[0]),
                            a[1] + portion * (b[1] - a[1])
                        ];
                        i0 = i + 1;
                    }
                    if (!end && sofar + current >= to) {
                        portion = (to - sofar) / current;
                        end = [
                            a[0] + portion * (b[0] - a[0]),
                            a[1] + portion * (b[1] - a[1])
                        ];
                        i1 = i + 1;
                    }
                    sofar += current;
                }

                var result = points.slice(i0, i1);
                result.unshift(start);
                result.push(end);
                return result;
            }
        }


        function getAreaLabel(entity, width, height) {
            var centroid = path.centroid(entity.asGeoJSON(graph, true));
            var extent = entity.extent(graph);
            var areaWidth = projection(extent[1])[0] - projection(extent[0])[0];

            if (isNaN(centroid[0]) || areaWidth < 20) return;

            var preset = context.presets().match(entity, context.graph());
            var picon = preset && preset.icon;
            var iconSize = 17;
            var padding = 2;
            var p = {};

            if (picon) {  // icon and label..
                if (addIcon()) {
                    addLabel(iconSize + padding);
                    return p;
                }
            } else {   // label only..
                if (addLabel(0)) {
                    return p;
                }
            }


            function addIcon() {
                var iconX = centroid[0] - (iconSize / 2);
                var iconY = centroid[1] - (iconSize / 2);
                var bbox = {
                    minX: iconX,
                    minY: iconY,
                    maxX: iconX + iconSize,
                    maxY: iconY + iconSize
                };

                if (tryInsert([bbox], entity.id + 'I', true)) {
                    p.transform = 'translate(' + iconX + ',' + iconY + ')';
                    return true;
                }
                return false;
            }

            function addLabel(yOffset) {
                if (width && areaWidth >= width + 20) {
                    var labelX = centroid[0];
                    var labelY = centroid[1] + yOffset;
                    var bbox = {
                        minX: labelX - (width / 2) - padding,
                        minY: labelY - (height / 2) - padding,
                        maxX: labelX + (width / 2) + padding,
                        maxY: labelY + (height / 2) + padding
                    };

                    if (tryInsert([bbox], entity.id, true)) {
                        p.x = labelX;
                        p.y = labelY;
                        p.textAnchor = 'middle';
                        p.height = height;
                        return true;
                    }
                }
                return false;
            }
        }


        // force insert a singular bounding box
        // singular box only, no array, id better be unique
        function doInsert(bbox, id) {
            bbox.id = id;

            var oldbox = _entitybboxes[id];
            if (oldbox) {
                _rdrawn.remove(oldbox);
            }
            _entitybboxes[id] = bbox;
            _rdrawn.insert(bbox);
        }


        function tryInsert(bboxes, id, saveSkipped) {
            var skipped = false;

            for (var i = 0; i < bboxes.length; i++) {
                var bbox = bboxes[i];
                bbox.id = id;

                // Check that label is visible
                if (bbox.minX < 0 || bbox.minY < 0 || bbox.maxX > dimensions[0] || bbox.maxY > dimensions[1]) {
                    skipped = true;
                    break;
                }
                if (_rdrawn.collides(bbox)) {
                    skipped = true;
                    break;
                }
            }

            _entitybboxes[id] = bboxes;

            if (skipped) {
                if (saveSkipped) {
                    _rskipped.load(bboxes);
                }
            } else {
                _rdrawn.load(bboxes);
            }

            return !skipped;
        }


        var layer = selection.selectAll('.layer-osm.labels');
        layer.selectAll('.labels-group')
            .data(['halo', 'label', 'debug'])
            .enter()
            .append('g')
            .attr('class', function(d) { return 'labels-group ' + d; });

        var halo = layer.selectAll('.labels-group.halo');
        var label = layer.selectAll('.labels-group.label');
        var debug = layer.selectAll('.labels-group.debug');

        // points
        drawPointLabels(label, labelled.point, filter, 'pointlabel', positions.point);
        drawPointLabels(halo, labelled.point, filter, 'pointlabel-halo', positions.point);

        // lines
        drawLinePaths(layer, labelled.line, filter, '', positions.line);
        drawLineLabels(label, labelled.line, filter, 'linelabel', positions.line);
        drawLineLabels(halo, labelled.line, filter, 'linelabel-halo', positions.line);

        // areas
        drawAreaLabels(label, labelled.area, filter, 'arealabel', positions.area);
        drawAreaLabels(halo, labelled.area, filter, 'arealabel-halo', positions.area);
        drawAreaIcons(label, labelled.area, filter, 'areaicon', positions.area);
        drawAreaIcons(halo, labelled.area, filter, 'areaicon-halo', positions.area);

        // debug
        drawCollisionBoxes(debug, _rskipped, 'debug-skipped');
        drawCollisionBoxes(debug, _rdrawn, 'debug-drawn');

        layer.call(filterLabels);
    }


    function filterLabels(selection) {
        var drawLayer = selection.selectAll('.layer-osm.labels');
        var layers = drawLayer.selectAll('.labels-group.halo, .labels-group.label');

        layers.selectAll('.nolabel')
            .classed('nolabel', false);

        var mouse = context.mouse();
        var graph = context.graph();
        var selectedIDs = context.selectedIDs();
        var ids = [];
        var pad, bbox;

        // hide labels near the mouse
        if (mouse) {
            pad = 20;
            bbox = { minX: mouse[0] - pad, minY: mouse[1] - pad, maxX: mouse[0] + pad, maxY: mouse[1] + pad };
            var nearMouse = _rdrawn.search(bbox).map(function(entity) { return entity.id; });
            ids.push.apply(ids, nearMouse);
        }

        // hide labels on selected nodes (they look weird when dragging / haloed)
        for (var i = 0; i < selectedIDs.length; i++) {
            var entity = graph.hasEntity(selectedIDs[i]);
            if (entity && entity.type === 'node') {
                ids.push(selectedIDs[i]);
            }
        }

        layers.selectAll(utilEntitySelector(ids))
            .classed('nolabel', true);


        // draw the mouse bbox if debugging is on..
        var debug = selection.selectAll('.labels-group.debug');
        var gj = [];
        if (context.getDebug('collision')) {
            gj = bbox ? [{
                type: 'Polygon',
                coordinates: [[
                    [bbox.minX, bbox.minY],
                    [bbox.maxX, bbox.minY],
                    [bbox.maxX, bbox.maxY],
                    [bbox.minX, bbox.maxY],
                    [bbox.minX, bbox.minY]
                ]]
            }] : [];
        }

        var box = debug.selectAll('.debug-mouse')
            .data(gj);

        // exit
        box.exit()
            .remove();

        // enter/update
        box.enter()
            .append('path')
            .attr('class', 'debug debug-mouse yellow')
            .merge(box)
            .attr('d', d3_geoPath());
    }


    var throttleFilterLabels = _throttle(utilCallWhenIdle(filterLabels), 100);


    drawLabels.observe = function(selection) {
        var listener = function() { throttleFilterLabels(selection); };
        selection.on('mousemove.hidelabels', listener);
        context.on('enter.hidelabels', listener);
    };


    drawLabels.off = function(selection) {
        throttleFilterLabels.cancel();
        selection.on('mousemove.hidelabels', null);
        context.on('enter.hidelabels', null);
    };


    return drawLabels;
}
コード例 #11
0
const computeGraticule = (projection, step) =>
  geoPath().projection(projection)(geoGraticule().step(step)())
コード例 #12
0
const computeOutline = (projection) =>
  geoPath().projection(projection)(geoGraticule().outline())
コード例 #13
0
ファイル: Projection.js プロジェクト: FourtekIT-incubator/vx
/**
 * Component for all projections.
 */
export default function Projection({
  data,
  projection = 'mercator',
  projectionFunc,
  clipAngle,
  clipExtent,
  scale,
  translate,
  center,
  rotate,
  precision,
  fitExtent,
  fitSize,
  centroid,
  graticule,
  graticuleLines,
  graticuleOutline,
  className,
  innerRef,
  pointRadius,
  ...restProps
}) {
  const currProjection = projectionMapping[projection]();

  if (clipAngle) currProjection.clipAngle(clipAngle);
  if (clipExtent) currProjection.clipExtent(clipExtent);
  if (scale) currProjection.scale(scale);
  if (translate) currProjection.translate(translate);
  if (center) currProjection.center(center);
  if (rotate) currProjection.rotate(rotate);
  if (precision) currProjection.rotate(precision);
  if (fitExtent) currProjection.fitExtent(...fitExtent);
  if (fitSize) currProjection.fitSize(...fitSize);

  const path = geoPath().projection(currProjection);

  if (pointRadius) path.pointRadius(pointRadius);

  return (
    <Group className={`vx-geo`}>
      {graticule &&
        !graticule.foreground &&
        <Graticule graticule={g => path(g)} {...graticule} />}
      {graticuleLines &&
        !graticuleLines.foreground &&
        <Graticule lines={g => path(g)} {...graticuleLines} />}
      {graticuleOutline &&
        !graticuleOutline.foreground &&
        <Graticule outline={g => path(g)} {...graticuleOutline} />}

      {data.map((feature, i) => {
        let c;
        if (centroid) c = path.centroid(feature);
        return (
          <g key={`${projection}-${i}`}>
            <path
              className={cx(`vx-geo-${projection}`, className)}
              d={path(feature)}
              ref={innerRef && innerRef(feature, i)}
              {...additionalProps(restProps, {
                ...feature,
                index: i,
                centroid: c,
              })}
            />
            {centroid && centroid(c, feature)}
          </g>
        );
      })}
      {/* TODO: Maybe find a different way to pass projection function to use for example invert */}
      {projectionFunc && projectionFunc(currProjection)}

      {graticule &&
        graticule.foreground &&
        <Graticule graticule={g => path(g)} {...graticule} />}
      {graticuleLines &&
        graticuleLines.foreground &&
        <Graticule lines={g => path(g)} {...graticuleLines} />}
      {graticuleOutline &&
        graticuleOutline.foreground &&
        <Graticule outline={g => path(g)} {...graticuleOutline} />}
    </Group>
  );
}
コード例 #14
0
const app = (data) => {
	const $link = $('#link');
	const $stateMap = $('#state_map');
	
	const max = {};		//// maximum values for primary areas
	const min = {};
	const rgbs = {};
	const scales = {};	//// scaling functions by area
	const colorcode = {	//// color multipliers
		r: 0.2,
		g: 1,
		b: 0.1
	};

	var w = 400;
	const windowWidth = $(window).width();
	if (windowWidth < w) {
		w = windowWidth * 0.9;
	}
	var h = w * 0.625;

	renderOptions();

	$stateMap.html('<strong>Loading state map '+LOADING_ICON+'</strong>');

	//// build max map
	Object.keys(data).forEach(state => {
		Object.keys(data[state]).forEach(type => {
			if (!(type in max) || parseInt(data[state][type]) > parseInt(max[type])) {
				max[type] = data[state][type];
			}
			if (!(type in min) || parseInt(data[state][type]) < parseInt(min[type])) {
				min[type] = data[state][type];
			}			
		});
	});

	//// Build basic scaling functions
	Object.keys(max).forEach(type => {
		scales[type] = scaleLinear()
			.domain([0, max[type]])
			.range([255, 0])
	});

	const getAreas = () => $('input[name=option]:checked').map(function() { return $(this).val(); }).get();

	const areas = getAreas();

	//// set up tooltip
	const tooltip = d3.select("body").append("div")
	    .attr("class", "tooltip")
	    .style("opacity", 0);	

	const showTooltip = d => {
       tooltip.transition()
         .duration(100)
         .style("opacity", .9);
       tooltip.html(function() {
	  		const areas = getAreas();
	  		const name = d.properties.NAME;
	    	return getTooltip(name, areas);
		})
        .style("left", (currentEvent.pageX) + "px")
        .style("top", (currentEvent.pageY - 28) + "px");
	};  

	const hideTooltip = d => {
		tooltip.transition()
         .duration(500)
         .style("opacity", 0);
	}

	//Define map projection
	const projection = geoAlbersUsa()
	   .translate([w/2, h/2])
	   .scale([500]);	  

	//Define path generator
	const path = geoPath()
		.projection(projection);	
	
	const updateLink = areas => {
		if (!areas || !areas.length) {
			$link.html(`Select at least one checkbox to see state tax comparisons.`);
			return;
		}		
		const $container = $('#options-container');
		let query = $container.serialize();
		if (areas.includes('total')) {
			areas = ['total'];
			query = 'option=total';
		}
		$link.html(`Showing results for <a href="/statetax?${query}">${areas.join('+')}</a>`);	
	};

	//Load in GeoJSON data
	json('/data/statetax/states.min.json', function(json) {	
		$stateMap.html('');
		const areas = getAreas();
		updateLink(areas);
		//Create SVG element
		const svg = select("#state_map")
					.append("svg")
					.attr("width", w)
					.attr("height", h);		
		// 	Bind data and create one path per GeoJSON feature
		svg.selectAll("path")
		   .data(json.features)
		   .enter()
		   .append("path")
		   .attr("d", path)
		   .attr('class', 'state')
		   .attr('id', function(d) { return d.properties.NAME; })
		   .style('fill', datum => {
		   		return getRgb(datum.properties.NAME, areas);
		   })
		   .on('click', function(data, i) {
		   		const key = data.properties.NAME;
		   		showTooltip(data);
		   })		   
		   .on('mouseover', showTooltip)
		   .on('mouseout', hideTooltip)
	});

	//// Change option
	$('#interface-container').on('click', 'input[name=option]', function(e)  {
		const areas = getAreas();
		updateLink(areas);
		const $states = $states || $('.state');
		$states.each(function(i, elem) {
			const name = $(this).attr('id');
			$(this).css('fill', getRgb(name, areas));
		});
	});	

	const getScale = (areas, key)  => {
		if (!scales[key]) {
			var mx = areas.reduce(function(p, c) { 
				return p + parseInt(max[c]); 
			}, 0);
			var mn = areas.reduce(function(p, c) { 
				return p + parseInt(min[c]); 
			}, 0);			
			scales[key] = scaleLinear()	
								.domain([mn, mx])
								.range([255, 0]);	
		}
		return scales[key];
	}

	const getRgb = (name, area)  => {
		if (area.includes('total')) {
			area = ['total'];
		}
		const key = area.join(':');
		if (!(name in data)) return {};
		const rgb = {};
		const areas = getAreas();
		//// create area in scales if it doesn't exist
		const scale = getScale(areas, key);
		////  rgb
		if (name in rgbs && key in rgbs[name]) {
			return rgbs[name][key];
		} else {
			var value = areas.reduce(function(p, c) {
				return p + parseInt(data[name][c]);
			}, 0);
			for (var color in colorcode) {
				rgb[color] = Math.floor(scale(value)*colorcode[color]);
			}
			var rgbstr = 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')';
			if (!rgbs[name]) {
				rgbs[name] = {};
			}
			rgbs[name][key] = rgbstr;
			return rgbstr;
		}
	};

	const getTooltip = (name, areas) => {
		let value = name;
		if (areas.includes('total')) {
			areas = ['total'];
		}
		if (name in data) {
			const total = areas.reduce(function(p, c) {
				return p + parseInt(data[name][c]);
			}, 0);
			value += ' - ' + dollars(total);
		} 
		return value;	
	};
}
コード例 #15
0
ファイル: labels.js プロジェクト: openstreetmap/iD
    function filterLabels(selection) {
        var drawLayer = selection.selectAll('.layer-osm.labels');
        var layers = drawLayer.selectAll('.labels-group.halo, .labels-group.label');

        layers.selectAll('.nolabel')
            .classed('nolabel', false);

        var mouse = context.mouse();
        var graph = context.graph();
        var selectedIDs = context.selectedIDs();
        var ids = [];
        var pad, bbox;

        // hide labels near the mouse
        if (mouse) {
            pad = 20;
            bbox = { minX: mouse[0] - pad, minY: mouse[1] - pad, maxX: mouse[0] + pad, maxY: mouse[1] + pad };
            var nearMouse = _rdrawn.search(bbox).map(function(entity) { return entity.id; });
            ids.push.apply(ids, nearMouse);
        }

        // hide labels on selected nodes (they look weird when dragging / haloed)
        for (var i = 0; i < selectedIDs.length; i++) {
            var entity = graph.hasEntity(selectedIDs[i]);
            if (entity && entity.type === 'node') {
                ids.push(selectedIDs[i]);
            }
        }

        layers.selectAll(utilEntitySelector(ids))
            .classed('nolabel', true);


        // draw the mouse bbox if debugging is on..
        var debug = selection.selectAll('.labels-group.debug');
        var gj = [];
        if (context.getDebug('collision')) {
            gj = bbox ? [{
                type: 'Polygon',
                coordinates: [[
                    [bbox.minX, bbox.minY],
                    [bbox.maxX, bbox.minY],
                    [bbox.maxX, bbox.maxY],
                    [bbox.minX, bbox.maxY],
                    [bbox.minX, bbox.minY]
                ]]
            }] : [];
        }

        var box = debug.selectAll('.debug-mouse')
            .data(gj);

        // exit
        box.exit()
            .remove();

        // enter/update
        box.enter()
            .append('path')
            .attr('class', 'debug debug-mouse yellow')
            .merge(box)
            .attr('d', d3_geoPath());
    }
コード例 #16
0
ファイル: debug.js プロジェクト: 1ec5/iD
    function drawDebug(selection) {
        var showsTile = context.getDebug('tile'),
            showsCollision = context.getDebug('collision'),
            showsImagery = context.getDebug('imagery'),
            showsImperial = context.getDebug('imperial'),
            showsDriveLeft = context.getDebug('driveLeft'),
            path = d3_geoPath(projection);


        var debugData = [];
        if (showsTile) {
            debugData.push({ class: 'red', label: 'tile' });
        }
        if (showsCollision) {
            debugData.push({ class: 'yellow', label: 'collision' });
        }
        if (showsImagery) {
            debugData.push({ class: 'orange', label: 'imagery' });
        }
        if (showsImperial) {
            debugData.push({ class: 'cyan', label: 'imperial' });
        }
        if (showsDriveLeft) {
            debugData.push({ class: 'green', label: 'driveLeft' });
        }


        var legend = d3_select('#content')
            .selectAll('.debug-legend')
            .data(debugData.length ? [0] : []);

        legend.exit()
            .remove();

        legend = legend.enter()
            .append('div')
            .attr('class', 'fillD debug-legend')
            .merge(legend);


        var legendItems = legend.selectAll('.debug-legend-item')
            .data(debugData, function(d) { return d.label; });

        legendItems.exit()
            .remove();

        legendItems.enter()
            .append('span')
            .attr('class', function(d) { return 'debug-legend-item ' + d.class; })
            .text(function(d) { return d.label; });


        var layer = selection.selectAll('.layer-debug')
            .data(showsImagery || showsImperial || showsDriveLeft ? [0] : []);

        layer.exit()
            .remove();

        layer = layer.enter()
            .append('g')
            .attr('class', 'layer-debug')
            .merge(layer);


        var extent = context.map().extent(),
            dataImagery = data.imagery || [],
            availableImagery = showsImagery && multipolygons(dataImagery.filter(function(source) {
                if (!source.polygon) return false;
                return source.polygon.some(function(polygon) {
                    return geoPolygonIntersectsPolygon(polygon, extent, true);
                });
            }));

        var imagery = layer.selectAll('path.debug-imagery')
            .data(showsImagery ? availableImagery : []);

        imagery.exit()
            .remove();

        imagery.enter()
            .append('path')
            .attr('class', 'debug-imagery debug orange');


        var imperial = layer
            .selectAll('path.debug-imperial')
            .data(showsImperial ? [dataImperial] : []);

        imperial.exit()
            .remove();

        imperial.enter()
            .append('path')
            .attr('class', 'debug-imperial debug cyan');


        var driveLeft = layer
            .selectAll('path.debug-drive-left')
            .data(showsDriveLeft ? [dataDriveLeft] : []);

        driveLeft.exit()
            .remove();

        driveLeft.enter()
            .append('path')
            .attr('class', 'debug-drive-left debug green');


        // update
        layer.selectAll('path')
            .attr('d', path);
    }
コード例 #17
0
ファイル: map_in_map.js プロジェクト: developmentseed/iD
        function redraw() {
            clearTimeout(timeoutId);
            if (isHidden) return;

            updateProjection();

            var dMini = utilGetDimensions(wrap);
            var zMini = geoScaleToZoom(projection.scale());

            // setup tile container
            tiles = wrap
                .selectAll('.map-in-map-tiles')
                .data([0]);

            tiles = tiles.enter()
                .append('div')
                .attr('class', 'map-in-map-tiles')
                .merge(tiles);

            // redraw background
            backgroundLayer
                .source(context.background().baseLayerSource())
                .projection(projection)
                .dimensions(dMini);

            var background = tiles
                .selectAll('.map-in-map-background')
                .data([0]);

            background.enter()
                .append('div')
                .attr('class', 'map-in-map-background')
                .merge(background)
                .call(backgroundLayer);


            // redraw overlay
            var overlaySources = context.background().overlayLayerSources();
            var activeOverlayLayers = [];
            for (var i = 0; i < overlaySources.length; i++) {
                if (overlaySources[i].validZoom(zMini)) {
                    if (!overlayLayers[i]) overlayLayers[i] = rendererTileLayer(context);
                    activeOverlayLayers.push(overlayLayers[i]
                        .source(overlaySources[i])
                        .projection(projection)
                        .dimensions(dMini));
                }
            }

            var overlay = tiles
                .selectAll('.map-in-map-overlay')
                .data([0]);

            overlay = overlay.enter()
                .append('div')
                .attr('class', 'map-in-map-overlay')
                .merge(overlay);


            var overlays = overlay
                .selectAll('div')
                .data(activeOverlayLayers, function(d) { return d.source().name(); });

            overlays.exit()
                .remove();

            overlays = overlays.enter()
                .append('div')
                .merge(overlays)
                .each(function(layer) { d3_select(this).call(layer); });


            var dataLayers = tiles
                .selectAll('.map-in-map-data')
                .data([0]);

            dataLayers.exit()
                .remove();

            dataLayers = dataLayers.enter()
                .append('svg')
                .attr('class', 'map-in-map-data')
                .merge(dataLayers)
                .call(dataLayer)
                .call(debugLayer);


            // redraw viewport bounding box
            if (gesture !== 'pan') {
                var getPath = d3_geoPath(projection);
                var bbox = { type: 'Polygon', coordinates: [context.map().extent().polygon()] };

                viewport = wrap.selectAll('.map-in-map-viewport')
                    .data([0]);

                viewport = viewport.enter()
                    .append('svg')
                    .attr('class', 'map-in-map-viewport')
                    .merge(viewport);


                var path = viewport.selectAll('.map-in-map-bbox')
                    .data([bbox]);

                path.enter()
                    .append('path')
                    .attr('class', 'map-in-map-bbox')
                    .merge(path)
                    .attr('d', getPath)
                    .classed('thick', function(d) { return getPath.area(d) < 30; });
            }
        }
コード例 #18
0
  render() {
    const {
      animation,
      bandwidth,
      className,
      colorRange,
      data,
      innerHeight,
      innerWidth,
      marginLeft,
      marginTop,
      style
    } = this.props;

    if (!data || !innerWidth || !innerHeight) {
      return null;
    }

    if (animation) {
      return (
        <Animation {...this.props} animatedProps={ANIMATED_SERIES_PROPS}>
          <ContourSeries {...this.props} animation={null} />
        </Animation>
      );
    }

    const x = this._getAttributeFunctor('x');
    const y = this._getAttributeFunctor('y');

    const contouredData = contourDensity()
      .x(d => x(d))
      .y(d => y(d))
      .size([innerWidth, innerHeight])
      .bandwidth(bandwidth)(data);

    const geo = geoPath();
    const {min, max} = getDomain(contouredData);
    const colorScale = scaleLinear()
      .domain([min, max])
      .range(colorRange || CONTINUOUS_COLOR_RANGE);
    return (
      <g
        className={`${predefinedClassName} ${className}`}
        transform={`translate(${marginLeft},${marginTop})`}
      >
        {contouredData.map((polygon, index) => {
          return (
            <path
              className="rv-xy-plot__series--contour-line"
              key={`rv-xy-plot__series--contour-line-${index}`}
              d={geo(polygon)}
              style={{
                fill: colorScale(polygon.value),
                ...style
              }}
            />
          );
        })}
      </g>
    );
  }
コード例 #19
0
ファイル: geojson.js プロジェクト: mybsktb/ant-d
const getPointAtLength = require('point-at-length');
const cloneDeep = require('lodash/cloneDeep');
const {
  geoPath
} = require('d3-geo');
const {
  GEO,
  registerConnector
} = require('../data-set');

const geoPathGenerator = geoPath();

function GeoJSONConnector(data, options, dataView) {
  dataView.dataType = GEO;
  const features = cloneDeep(data.features);

  // pre-process
  features.forEach(feature => {
    feature.name = feature.properties.name;
    feature.longitude = [];
    feature.latitude = [];
    const pathData = feature.pathData = geoPathGenerator(feature);
    const points = getPointAtLength(pathData);
    points._path.forEach(point => {
      feature.longitude.push(point[1]);
      feature.latitude.push(point[2]);
    });
    const centroid = geoPathGenerator.centroid(feature);
    feature.centroidX = centroid[0];
    feature.centroidY = centroid[1];
  });
コード例 #20
0
ファイル: map.js プロジェクト: barrymcgee/snapcraft.io
  function render(mapEl, snapData, world) {
    const width = mapEl.property("clientWidth");
    const height = width * 0.5;
    // some offset position center of the map properly
    const offset = width * 0.1;

    const projection = geoNaturalEarth1()
      .scale(width * 0.2)
      .translate([width / 2, (height + offset) / 2])
      .precision(0.1);

    // rotate not to split Asia
    projection.rotate([-10, 0]);

    const path = geoPath().projection(projection);

    // clean up HTML before rendering map
    mapEl.html("");

    const svg = mapEl
      .append("svg")
      .attr("width", width)
      .attr("height", height);

    const tooltip = mapEl
      .append("div")
      .attr("class", "snapcraft-territories__tooltip u-no-margin");

    const tooltipMsg = tooltip
      .append("div")
      .attr("class", "p-tooltip__message");

    const countries = feature(world, world.objects.countries).features;

    const g = svg.append("g");
    const country = g
      .selectAll(".snapcraft-territories__country")
      .data(countries);

    country
      .enter()
      .insert("path")
      .attr("class", countryData => {
        const countrySnapData = snapData[countryData.id];

        if (countrySnapData) {
          return `snapcraft-territories__country snapcraft-territories__country-default`;
        }

        return "snapcraft-territories__country";
      })
      .attr("style", countryData => {
        const countrySnapData = snapData[countryData.id];

        if (countrySnapData) {
          if (countrySnapData.color_rgb) {
            return (
              "fill: rgb(" +
              countrySnapData.color_rgb[0] +
              "," +
              countrySnapData.color_rgb[1] +
              "," +
              countrySnapData.color_rgb[2] +
              ")"
            );
          }
        }
      })
      .attr("d", path)
      .attr("id", function(d) {
        return d.id;
      })
      .attr("title", function(d) {
        return d.properties.name;
      })
      .on("mousemove", countryData => {
        const pos = mouse(mapEl.node());
        const countrySnapData = snapData[countryData.id];

        if (countrySnapData) {
          tooltip
            .style("top", pos[1] + "px")
            .style("left", pos[0] + "px")
            .style("display", "block");

          let content = [
            '<span class="u-no-margin--top">',
            countrySnapData.name
          ];
          if (countrySnapData["number_of_users"] !== undefined) {
            content.push(`<br />${countrySnapData["number_of_users"]} active`);
          }
          content.push("</span>");
          tooltipMsg.html(
            `<span
               class="snapcraft-territories__swatch"
               style="background-color: rgb(${countrySnapData.color_rgb[0]}, ${
              countrySnapData.color_rgb[1]
            }, ${countrySnapData.color_rgb[2]})"></span>
             ${content.join(" ")}`
          );
        }
      })
      .on("mouseout", function() {
        tooltip.style("display", "none");
      });

    g.append("path")
      .datum(
        mesh(world, world.objects.countries, function(a, b) {
          return a !== b;
        })
      )
      .attr("class", "snapcraft-territories__boundary")
      .attr("d", path);
  }
コード例 #21
0
ファイル: projections.js プロジェクト: glimpseio/vega
  geoAzimuthalEquidistant,
  geoConicConformal,
  geoConicEqualArea,
  geoConicEquidistant,
  geoEquirectangular,
  geoGnomonic,
  geoIdentity,
  geoMercator,
  geoNaturalEarth1,
  geoOrthographic,
  geoStereographic,
  geoTransverseMercator,
  geoPath
} from 'd3-geo';

var defaultPath = geoPath();

export var projectionProperties = [
  // standard properties in d3-geo
  'clipAngle',
  'clipExtent',
  'scale',
  'translate',
  'center',
  'rotate',
  'parallels',
  'precision',
  'reflectX',
  'reflectY',

  // extended properties in d3-geo-projections
コード例 #22
0
ファイル: MapJourneyCard.js プロジェクト: njho/journey
    render() {
        console.log('svgHeight: ' + this.state.svgHeight);
        const projection = geoMercator().fitExtent([[0, 0], [60, this.state.svgHeight]], this.state.geojson);
        const pathGenerator = geoPath().projection(projection)


        return (
            <View style={styles.cardContainer}>
                <TouchableOpacity style={styles.cardContainer}>
                    <View style={styles.cardContainer}>

                        <Image
                            style={{width: width, height: this.state.imgHeight}}
                            source={{uri: 'http://www.cocokelley.com/wp-content/uploads/2017/06/the-candy-colored-streets-in-Tallin-Estonia-visual-travel-diary-on-coco-kelley.4.jpg'}}/>
                        <View style={{
                            width: width,
                            height: this.state.imgHeight,
                            position: 'absolute',
                            backgroundColor: 'rgba(0,0,0,0.5)',
                        }}>

                        </View>
                        <View style={{
                            flexDirection: 'column',
                            flexWrap: 'wrap',
                            width: width,
                            justifyContent: 'flex-start',
                            position: 'absolute',
                            top: 40,
                            left: 20
                        }}>
                            <Text style={styles.subStoryText}>
                                /{this.props.substory.toUpperCase()}
                            </Text>
                            <View>
                                <Text style={styles.titleText}>
                                    {this.props.name.toUpperCase()}
                                </Text>
                            </View>

                        </View>

                        <View style={{
                            position: 'absolute',
                            alignItems: 'center',
                            flexDirection: 'column',
                            bottom: 0,
                            width: '100%',

                        }}>
                            <View style={{
                                flexDirection: 'row', backgroundColor: 'rgba(0,0,0,0.4)',width: '100%', alignItems: 'center'
                            }}>
                                <View style={{flexDirection: 'column', alignItems: 'center'}}>
                                    <Icon name="ios-photos-outline" style={{color: 'white', marginTop: 10}} size={25}/>
                                    <Text
                                        style={{color: 'white', marginHorizontal: 25, marginBottom: 5}}>25</Text>
                                </View>
                                <View style={{flexDirection: 'column', alignItems: 'center'}}>
                                    <Svg
                                        style={{marginTop: 10, }}
                                        height={this.state.svgHeight}
                                        width={60}
                                    >
                                        <Path
                                            d={pathGenerator(this.state.geojson)}
                                            fill="none"
                                            stroke="white"
                                            strokeWidth={2}
                                        />
                                    </Svg>
                                    <Text style={{color: 'white', marginVertical: 5,}}>Madrid, Spain</Text>
                                </View>
                            </View>
                            <CommentBarV2 color={'white'} likes={10} comments={20} style={{marginHorizontal: 15}}/>


                        </View>
                    </View>
                </TouchableOpacity>
            </View>
        );
    }
コード例 #23
0
ファイル: now.js プロジェクト: Carreau/d4
const pi = Math.PI;
const radians = pi / 180;
const degrees = 180 / pi;

const circle = geoCircle()
  .radius(90);

const projection = geoAzimuthalEquidistant()
  .scale(85)
  .translate([width / 2, height / 2])
  .clipAngle(180 - 1e-3)
  .rotate([0, 90])
  .precision(.1);

const path = geoPath()
  .projection(projection);

const graticule = geoGraticule();

export default function World() {
  const now = new Date();
  const today = utcDay(now);
  const sun = antipode(solarPosition(now));
  const angle = 180 - sun[0];
  const translate1 = `translate(${width / 2}, ${height / 2})`;
  const rotate = `rotate(${angle})`;
  const translate2 = `translate(${-width / 2}, ${ -height / 2})`;
  const transform = translate1 + rotate + translate2;

  return (