Създаване на блок с карта на raphaeljs

US map

Идеята е да имаме блок с карта, по която потребителя може да кликва като под нея се показва текст за избраното в случая карта на Съединените щати с текст към всеки щат.

Накратко за плана, по койте е направена реализацията.

Тъй като това ще е една карта, само ще я поставим в блок, който да можем да извеждаме където поискаме. И понеже искаме някак да я поставим в стандартното поле Body, в което пишем текст и поставяме картинки и друга медия вероятно може да използваме token. За блокове има модул insert_block, който прави точно това - автоматично създава токъни за всичките ни блокове, които можем да поставяме в текстово поле, като добавя нобходимия за това текстов филтър. Този текстов филтър "Insert blocks" трябва да чекнем за използвание текстов формат - "Full HTML", "Filtered HTML".

Щатите разбира се ще са термини. Създаваме за това речник State и импортваме (виж накрая) или въвеждаме на ръка в него абревеатурата на щата като Name, името като State name. Създаваме трето поле Description за описанието.
Може да ви се струва, че за Name е по-логично да записваме пълното име на щата. Но след като сме проучили достатъчно избраната реализация за картата, всъщност по-подходящо в случая е за Name да вписваме абревеатурата.

Друг момент, който можем да решим с готов модул е създаването на собствен изглед (Display) за термините на State когато се използват в картата. Тук използваме entity_view_mode модула и създаваме нов Entity view mode за Taxonomy term наречен US map за речник State. За какво ние друг Display за термин? Ще го използваме за да показваме избраните полета на термина когато се визуализират под картата.

Следва кода на самия модул, след което още малко обяснения.

Модул mvm (mymodule се изтърка вече).

Съдаваме собствен модул mvm.
Добавяме стандартен .info file.

mvm.module в mvm папката

/**
 * Implements hook_block_info().
 */
function mvm_block_info() {
  $blocks['us_map'] = array(
    'info' => t('US map'), 
  );
 
  return $blocks;
}
 
/**
 * Implements hook_block_view().
 */
function mvm_block_view($delta = '') {
  $block = array();
 
  switch ($delta) {
    case 'us_map':
      // add necessary css and js
      $path = drupal_get_path('module', 'mvm') . '/misc';
      drupal_add_css($path . '/mvm_usmap.css');
      drupal_add_js($path . '/us-map-1.0.1/lib/raphael.js', array('weight' => 1));
      drupal_add_js($path . '/us-map-1.0.1/example/color.jquery.js', array('weight' => 2));
      drupal_add_js($path . '/us-map-1.0.1/jquery.usmap.js', array('weight' => 3));
      drupal_add_js($path . '/mvm_usmap.js', array('weight' => 4));
 
      // vocabulary id
      $vid = 4;
      // get all terms
      $states_data = taxonomy_term_load_multiple(array(), array('vid' => $vid));
 
      // use custom view_mode (created with entity_view_mode module)
      $view_mode = 'us_map';
      // build view
      $states_view = taxonomy_term_view_multiple($states_data, $view_mode, $weight = 0, $langcode = NULL);
 
      // block view
      $block['subject'] = t('US map');
      $block['content'] = theme('us_map', array('vocab' => $states_view));
      break;
  }
 
  return $block;
}
 
/**
 * Implements hook_theme().
 */
function mvm_theme() {
  return array (
    'us_map' => array(
      'template' => 'us-map',
      'variables' => array('vocab' => NULL),
    ),
  );
}
 
/**
 * Implements hook_preprocess_ENTITY().
 */
function mvm_preprocess_taxonomy_term(&$variables) {
  // add some classes to terms
  if ($variables['vid'] == 4) {
    $variables['classes_array'][] = 'map-text';
    $variables['classes_array'][] = $variables['name'];
  }
}

us-map.tpl.php в mvm

<div id="map"></div>
<div><?php print render($vocab); ?></div>

mvm_usmap.css в mvm/misc/

#map {
  width: 630px;
  height: 400px;
}
 
.map-text {
  display: none;
}

mvm_usmap.js в mvm/misc/

(function ($) {
 
Drupal.behaviors.mvm_usmap = {
  attach: function (context) {
		//
    $('#map').usmap({
      //showLabels: true,
      // The click action
      click: function(event, data) {
 
				$('.map-text').hide();
				$('.map-text.'+ data.name).show();
      },
			'stateStyles': {
        fill: "#4ECDC4",
        stroke: "#41A59B",
        "stroke-width": 1,
        "stroke-linejoin": "round",
        scale: [1, 1]
      },
      'stateHoverStyles': {
        fill: "#C7F464",
        stroke: "#ADCC56",
        scale: [1.1, 1.1]
      },
      'labelBackingStyles': {
        fill: "#4ECDC4",
        stroke: "#41A59B",
        "stroke-width": 1,
        "stroke-linejoin": "round",
        scale: [1, 1]
      },
 
      // The styles for the hover
      'labelBackingHoverStyles': {
        fill: "#C7F464",
        stroke: "#ADCC56",
      },
      'labelTextStyles': {
      fill: "#222",
        'stroke': 'none',
        'font-weight': 300,
        'stroke-width': 0,
        'font-size': '10px'
      },
    });
	}
};
 
})(jQuery);

Споменатите us-map са тук http://newsignature.github.io/us-map/#demo
Разархивират се в mvm/misc/ така че да стане mvm/misc/us-map-1.0.1/

Обяснения на кода

Първо, декларираме блок.
Второ, указваме какво ще се покаже в него: включваме js файловете на самата карта, също и нашите js и css файлове. Като content блока ще изведе подходящия маркъп където да се закачи картата.
Също така подготвяме термините на State вече ренднати през US map entity view mode. За content на блока използваме темплейт, на който предаваме термините така както трябва да се покажат под картата.
Този маркъп е подходящо да се напише в тепмлейт файл, затова
трето, добавяме декларация за темплейт и променливи в hook_theme.
Четвърто, в hook_preprocess_taxonomy_term добавяме някои css класове към термините на State ($vid = 4).
Пето, в самия темплейт на първия ред е маркъпа, в който се закача картата, на втория ред се извежда списък с трмините на State.
Шесто, с малко css задаваме размера на картата и скриваме целия списък с термините.
Седмо, в js се инициализира самата карта и добавяме малко код за показване на съответния текст за термин по щата на който се цъка.

Това е.

Как се импортват щатите? От csv файл.

$row = 1;
$file = $_SERVER['DOCUMENT_ROOT'] . '/sites/default/files/tmp/states.csv';
if (($handle = fopen($file, "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num = count($data); //dpm($num);
$row++;
$term = new stdClass();
$term -> vid = 4;
$term -> field_state_name['und'][0]['value'] = $data[0];
$term -> name = $data[1];
taxonomy_term_save($term);
}
fclose($handle);
}
Category: