You are here

private function ip_geoloc_plugin_style_leaflet::_add_cluster_differentiator in IP Geolocation Views & Maps 7

1 call to ip_geoloc_plugin_style_leaflet::_add_cluster_differentiator()
ip_geoloc_plugin_style_leaflet::options_form in views/ip_geoloc_plugin_style_leaflet.inc
Implements options_form().

File

views/ip_geoloc_plugin_style_leaflet.inc, line 735

Class

ip_geoloc_plugin_style_leaflet

Code

private function _add_cluster_differentiator(&$form, &$form_state, $lib_markercluster, &$weight) {
  $path = drupal_get_path('module', 'ip_geoloc');
  $intro = t('Region-aware marker clustering with <a target="regionbound" href="!url_regionbound">RegionBound</a>. See the <a target="readme" href="!url_readme">README</a> for details.', array(
    '!url_regionbound' => url('http://regionbound.com'),
    '!url_readme' => url("{$path}/README.txt"),
  ));
  $form['cluster_differentiator'] = array(
    '#type' => 'fieldset',
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
    '#title' => t('Cluster region differentiator'),
    '#description' => '<em>' . $intro . '</em><br/>',
    // The id in the prefix must match the AJAX submit handlers below.
    '#prefix' => '<div id="cluster-differentiator-wrapper">',
    '#suffix' => '</div>',
    '#weight' => $weight++,
  );
  $region_field_names = NULL;
  if (isset($form_state['triggering_element'])) {

    // Get here when any form element with #ajax was changed/clicked causing
    // an auto-rebuild of the form.
    if (strpos($form_state['triggering_element']['#id'], 'cluster-differentiator-field') > 0) {

      // Get here when it was the cluster-differentiator multi-select that was clicked.
      $region_field_names = $form_state['triggering_element']['#value'];
    }
  }
  else {
    $region_field_names = $this->options['cluster_differentiator']['cluster_differentiator_fields'];
  }
  if (!module_exists('leaflet_markercluster')) {
    $desc = t('Requires the <a target="project" href="!url_project">Leaflet MarkerCluster</a> module', array(
      '!url_project' => url('http://drupal.org/project/leaflet_markercluster'),
    ));
    $form['cluster_differentiator']['#description'] .= $desc . ' ' . t('and <a href="!url_regionbound">RegionBound</a> JS plugin.', array(
      '!url_regionbound' => url('http://regionbound.com'),
    ));
  }
  elseif ($lib_markercluster && (empty($region_field_names) || !reset($region_field_names))) {
    $note_region = t('Download the file %js from <a target="regionbound" href="!url_regionbound">Regionbound</a> and drop it in %directory, without renaming. Then select your region differentiator below.', array(
      '%js' => IP_GEOLOC_LEAFLET_MARKERCLUSTER_REGIONBOUND_JS,
      '%directory' => $lib_markercluster,
      '!url_regionbound' => url('http://regionbound.com'),
    ));
    $form['cluster_differentiator']['#description'] .= "<p>{$note_region}</p>";
  }
  $fields = ip_geoloc_get_display_fields($this->display->handler, FALSE, FALSE);
  $form['cluster_differentiator']['cluster_differentiator_fields'] = array(
    '#title' => t('Region differentiator'),
    '#type' => 'select',
    '#multiple' => TRUE,
    '#size' => 6,
    '#options' => $fields,
    '#default_value' => $region_field_names,
    '#ajax' => array(
      'callback' => '_ip_geoloc_plugin_style_leaflet_refresh_cluster_fieldset_js',
      'wrapper' => 'cluster-differentiator-wrapper',
      'effect' => 'fade',
      'speed' => 'fast',
    ),
    '#description' => t('Select a field (or sequence of fields) that reflect for each location marker the region hierarchy it belongs to. Examples are an <a target="drupal" href="!url_addressfield">AddressField</a>, a hierarchical taxonomy term based on regions, or individual fields for country, state, city, suburb (<em>in that order</em>). Make sure that the region differentiator you wish to use is included as a field in your view, so it appears in the list above. Note that region differentiators do <em>not</em> need to be associated with latitudes or longitudes. They are just name fields.', array(
      '!url_addressfield' => url('http://drupal.org/project/addressfield'),
    )),
  );
  $level = 0;
  if (!empty($region_field_names)) {
    foreach ($region_field_names as $region_field_name) {
      $region_field = field_info_field($region_field_name);
      $field_type = empty($region_field['type']) ? '' : $region_field['type'];
      $region_depth = $this
        ->get_region_field_depth($region_field);
      $zoom_titles = $this
        ->_get_zoom_titles($field_type, $fields[$region_field_name], $region_depth);
      foreach ($zoom_titles as $title) {
        $level++;
        $default_value = isset($this->options['cluster_differentiator']['zoom_ranges'][$level]) ? $this->options['cluster_differentiator']['zoom_ranges'][$level] : '';
        $form['cluster_differentiator']['zoom_ranges'][$level] = array(
          '#type' => 'textfield',
          '#title' => filter_xss_admin($title),
          '#size' => 28,
          '#default_value' => $default_value,
          '#element_validate' => array(
            'ip_geoloc_range_widget_validate',
          ),
        );
      }
    }
    if ($level > 0) {
      $desc1 = $level === 1 ? t('Below enter the zoom level range to be associated with the selected differentiator.') : t('Below enter the zoom level ranges to which each of the region hierarchy levels apply.') . '<br/>' . t('Zoom ranges may start and end at any level, but must not overlap.');
      $desc2 = '';

      // t('Minimum and maximum zoom levels for this map can be found below under <strong>More map options</strong>.');
      $desc3 = t('Or leave all fields blank to use the defaults and refine later.');
      $zoom1 = t('Typical zoom ranges for Europe: country: 3--6, province: 7--9, city: 10--14, postcode: 15--18');
      $zoom2 = t('Typical zoom ranges for US & Canada: country: 1--3, state: 4--8, city: 9--13, zip: 14--18');
      $zoom3 = t('Typical zoom ranges for Australia: country: 1--2, state: 3--9, city: 10--13, suburb/postcode: 14--18');
      $form['cluster_differentiator']['cluster_differentiator_fields']['#description'] = implode('<br/>', array(
        "{$desc1} {$desc2}<br/>{$desc3}<br/>",
        $zoom1,
        $zoom2,
        $zoom3,
      ));
    }
    $form['cluster_differentiator']['cluster_tooltips'] = array(
      '#title' => t('Add cluster tooltips'),
      '#type' => 'checkbox',
      '#default_value' => $this->options['cluster_differentiator']['cluster_tooltips'],
      '#description' => t("When hovering a cluster, tooltips reveal the cluster region name and the names of its populated subregions."),
    );
    $form['cluster_differentiator']['cluster_touch_mode'] = array(
      '#title' => t('Cluster action on touch devices (e.g. mobile phones)'),
      '#type' => 'radios',
      '#options' => array(
        1 => t('Single tap displays cluster regions, double-tap drills into cluster (default)'),
        0 => t('Single tap drills into cluster. Sub-region names not displayed, but visible on mouse devices.'),
      ),
      '#default_value' => $this->options['cluster_differentiator']['cluster_touch_mode'],
      '#description' => t('Applies only to devices that do not have a mouse, like mobile phones.'),
    );
    $form['cluster_differentiator']['cluster_outline'] = array(
      '#title' => t('Cluster population outline'),
      '#type' => 'select',
      '#options' => array(
        0 => t('Traditional (convex hull)'),
        1 => t('Avant-garde (heuristic hull)'),
      ),
      '#default_value' => $this->options['cluster_differentiator']['cluster_outline'],
      '#description' => t('When hovering a cluster, a <a target="regionbound" href="!url_regionbound">coverage outline</a> visualises the envelope or footprint of the underlying marker population. Select your preferred style of doing this.', array(
        '!url_regionbound' => url('http://regionbound.com/enhanced-cluster-envelope-using-heuristic-hull'),
      )),
    );
  }
  $intro = t('Use clusters to report on region aggregates; requires <a target="regionbound" href="!url_regionbound">RegionBound</a>', array(
    '!url_regionbound' => url('http://regionbound.com/coffee-prices-across-melbourne'),
  ));
  $desc = t('This feature aggregates values of a selected field across every region and displays the resulting <em>sum/average/min/max</em> on each cluster icon at every zoom level. It also colours each cluster icon based on its aggregated value, rather than its marker count.');
  $form['cluster_aggregation'] = array(
    '#type' => 'fieldset',
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#title' => t('Cluster aggregation'),
    '#description' => "<em>{$intro}</em><p>{$desc}</p>",
    '#weight' => $weight++,
  );
  $form['cluster_aggregation']['aggregation_field'] = array(
    '#title' => t('Field to perform aggregation on'),
    '#type' => 'select',
    '#default_value' => $this->options['cluster_aggregation']['aggregation_field'],
    '#options' => $fields,
    '#description' => t('For aggregation to make sense, the selected field must be numeric or represent a list. If a list, aggregation will be applied to the element <em>count</em>.'),
  );
  $form['cluster_aggregation']['aggregation_function'] = array(
    '#title' => t('Aggregation function'),
    '#type' => 'select',
    '#default_value' => $this->options['cluster_aggregation']['aggregation_function'],
    '#options' => array(
      'average' => t('Average'),
      'maximum' => t('Maximum'),
      'minimum' => t('Minimum'),
      'sum' => t('Sum'),
    ),
  );
  $form['cluster_aggregation']['ranges'] = array(
    '#type' => 'item',
    '#description' => t('Edit the above to change the color-coding of cluster icons based on their aggregate values.'),
    '#prefix' => '<div id="cluster-aggregation-aggregate">',
    '#suffix' => '</div>',
  );
  foreach (array(
    'small',
    'medium',
    'large',
  ) as $size) {
    $default_value = isset($this->options['cluster_aggregation']['ranges'][$size]) ? $this->options['cluster_aggregation']['ranges'][$size] : '';
    $form['cluster_aggregation']['ranges'][$size] = array(
      '#title' => "{$size} " . t('goes to'),
      '#type' => 'textfield',
      '#size' => 8,
      '#default_value' => $default_value,
    );
  }
  $form['cluster_aggregation']['precision'] = array(
    '#title' => t('Precision'),
    '#type' => 'textfield',
    '#size' => 2,
    '#default_value' => $this->options['cluster_aggregation']['precision'],
    '#description' => t('Number of significant digits used to display the aggregate value on the cluster icon. Leave blank for native formatting.'),
  );
}