• main.js

  • §

    Run after the DOM loads

    $(function () {
      'use strict';
  • §

    First we define some helper functions to draw our layers.

  • §

    Create an svg layer and return a reference to its dom element.

      function getSvgLayer(map, opts) {
    
        opts.renderer = 'svg';
        var layer = map.createLayer('feature', opts);
  • §

    The canvas is a d3 context to geojs managed svg element.

        return {
          layer: layer,
          svg: layer.canvas()
        };
      }
    
      function drawLayer(map, type, text, index, rescale) {
        var layer, svg, obj;
  • §

    The sticky option keeps the element fixed relative to the map, which is the default behavior.

        var sticky = (type !== 'fixed');
        obj = getSvgLayer(map, {sticky: sticky});
    
        layer = obj.layer;
        svg = obj.svg;
  • §

    Put everything in a group with classes for styling in the css.

        var g = svg.append('g')
          .classed(type + '-layer', true)
          .classed('layer', true);
  • §

    Get the size of the map for the layout.

        var height = map.node().height() / 4;
        var width = map.node().width() / 4;
  • §

    Translate the group to where we want it.

        g.attr('transform', 'translate(0,' + (index * height) + ')');
  • §

    Attach a description.

        g.append('text')
          .attr('x', 30)
          .attr('y', height / 2)
          .style('font-size', '20px')
          .text(text);
  • §

    Attach a rectangle

        g.append('rect')
          .attr('x', 2 * width)
          .attr('y', height / 4)
          .attr('rx', 10)
          .attr('ry', 10)
          .attr('width', width / 2)
          .attr('height', height / 2)
          .style('stroke-width', '2px');
  • §

    Attach a circle.

        var radius = 5;
        g.append('circle')
          .attr('cx', 3 * width)
          .attr('cy', height / 2)
          .attr('r', radius)
          .style('stroke-width', '2px');
  • §

    Attach a spiral using some d3 magic.

        function theta(d) {
          return 9 * d * Math.PI / 100;
        }
        var alpha = 0.1;
        var xScale = d3.scaleLinear()
          .domain([-6, 6])
          .range([width * 3.3, width * 4]);
        var yScale = d3.scaleLinear()
          .domain([-6, 6])
          .range([width * 0.7, 0]);
        var spiral = d3.line()
          .x(function (d) {
            var t = theta(d);
            return xScale(alpha * t * Math.cos(t));
          })
          .y(function (d) {
            var t = theta(d);
            return yScale(alpha * t * Math.sin(t));
          })
          .interpolate('basis');
    
        g.append('path')
          .attr('d', spiral(d3.range(100)))
          .attr('transform', 'translate(0,' + (height - width * 0.7) / 2 + ')')
          .style('stroke-width', '3px');
  • §

    Attach a scaling function

        if (rescale) {
          layer.geoOn([geo.event.zoom, geo.event.resize], function () {
  • §

    Get the scaling factor from the renderer.

            var scl = layer.renderer().scaleFactor();
  • §

    Rescale all properties that require it. In general, this depends on the design of the elements, but often one wants to rescale stroke widths and point radii.

            g.selectAll('text')
              .style('font-size', (20 / scl) + 'px');
    
            g.selectAll('rect')
              .style('stroke-width', (2 / scl) + 'px');
    
            g.selectAll('circle')
              .attr('r', radius / scl)
              .style('stroke-width', 2 / scl);
    
            g.selectAll('path')
              .style('stroke-width', (3 / scl) + 'px');
          });
        }
      }
  • §

    Create a map object

      var map = geo.map({
        node: '#map',
        center: {
          x: -98.0,
          y: 39.5
        },
        zoom: 4
      });
  • §

    Add a base layer

      map.createLayer('osm');
  • §

    Create the layers

      drawLayer(map, 'fixed', 'This is a fixed layer', 0);
      drawLayer(map, 'unscaled-moving', 'This is a moving layer without rescaling.', 1);
      drawLayer(map, 'scaled-moving', 'This is a moving layer with rescaling.', 2, true);
    
    });