Vitamin – сервис для выгодного управления вашей рекламой
  • Все популярные рекламные сети в одном окне
  • Агентское вознаграждение до 16% на личный счет или рекламу
  • Любые дополнительные услуги под ваши потребности
  • Бесплатное обучение маркетингу
  1. Главная >
  2. Блог >
  3. Функциональные географические карты с помощью SVG и jQuery

Функциональные географические карты с помощью SVG и jQuery

italy

Когда мне нужно создать карты, то первым делом, я обращаюсь к Google Charts или любой другой специализированной библиотеке. Но иногда мне могут понадобиться специфические особенности, которые я не могу там найти. В этом случае SVG-изображения оказываются очень ценными (полезными).

Недавно, мне нужно было проектировать страницу отчета, которая могла бы показывать карту Италии, на которой каждый регион имел бы свой цвет, в зависимости от некоторых значений выборки из базы данных. Благодаря SVG, эта задача стала очень простой.

Создаем SVG карту в Illustrator

Первым делом я нарисовал карту Италии в Adobe Illustrator:

italy2

Каждый регион рисовался как отдельный объект, который помещался на свой отдельный слой, с названием совпадающим с кодом, используемом в базе данных, чтобы определить соотносимые данные (например, «tos» для Тосканы).

Наконец, карта должна быть сохранена в формате SVG. Вам следует обратить внимание на то, чтобы установить опцию «CSS property» в графе «Элементы стиля» в Иллюстраторе, как показано ниже:

svg

Открыв только что созданный файл, вы увидите, что он содержит набор тегов g, идентификаторы которого совпадают с названиями уровней в Illustrator.

Построение нашего HTML файла

Каждый элемент, содержащийся в тегах g имеет класс st0, так чтобы обводки и заливки CSSс войства <strong>stroke</strong> и fill:

itacode

Если вы попытаетесь изменить эти значения, карта изменится тоже:

itayello

Теперь мы можем использовать этот код, чтобы создать наш HTML файл со встроенным SVG, как показано ниже (код был сокращен для удобства):

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Map Sample</title>
    <style type="text/css" media="all">
        .map svg {
            height: auto;
            width: 350px;
        }
        .map g {
            fill: #ccc;
            stroke: #333;
            stroke-width: 1;
        }
    </style>
</head>
<body>
    <div class="map">
        <svg version="1.1" id="Livello_1" xmlns="//www.w3.org/2000/svg" xmlns:xlink="//www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 -21.6 761 919" style="enable-background:new 0 -21.6 761 919;" xml:space="preserve">
            <g id="sar">
                <polygon class="st0" points="193,463 ...	"/>
            </g>

            <!-- etc ... -->

        </svg>
    </div>
</body>
</html>

Можно заметить, что атрибут style из тега svg был перенесен в секцию head, и все элементы g изначально залиты светло-серым цветом.

Класс st0 уже не используется (его можно удалить из вашего кода), и он был заменен селектором .map g. В любом случае, это не было обязательным действием – вы можете использовать любые CSS селекторы – на ваше усмотрение.

Вторым шагом надо привязать нашу карту к данным, получаемым из внешнего источника. В данном примере мы будет раскрашивать регионы в цвета, зависящие от населенности этих регионов.

Добавляем JSON-данные и JavaScript

Данные мы получаем в формате JSON, и вставляем их в HTML файл напрямую (в реальных условиях, мы, конечно же, будет получать данные по Ajax, или подобным способом).

Теперь наша страница будет содержать JSON внутри нашего файла с JavaScript, который будет выглядеть примерно так:
 

var regions=[
    {
        "region_name": "Lombardia",
        "region_code": "lom",
        "population": 9794525
    },
    {
        "region_name": "Campania",
        "region_code": "cam",
        "population": 5769750
    },

    // etc ...

];

После этого мы выбираем цвет (в данном случае – #0b68aa), и принимаем его за цвет региона с самым большим населением. Остальные регионы будут раскрашены в тона основного цвета в пропорциях процента населенности (по отношению к максимальному населению).

Далее мы добавим немного JavaScript.

Первым делом надо определить регион с самым большим населением. Это можно сделать несколькими строчками кода.

Как только мы составим массив со значениями размера населения, из него можно получить максимальное значение с помощью метода Math.max:

var temp_array= regions.map( function( item ) {
    return item.population;
});

var highest_value = Math.max.apply( Math, temp_array );

Далее можно пройтись по всем элементам regions, и применить уровень прозрачности, в зависимости от вычисленного параметра население / максимальное значение (с небольшой помощью jQuery):
 

$(function() {
  for(i=0; i < regions.length; i++) {
    $('#'+ regions[i].region_code).css({'fill': 'rgba(11, 104, 170,'
     + regions[i].population/highest_value
     + ')'});
    }
});

А вот и результат:

italyblue

Добавляем интерактивности с помощью CSS и jQuery

Карту можно улучшить, добавив немного интерактивности. Нам бы хотелось показать размер населения при наведении курсора на регион.

Сначала добавим правила CSS для селектора g:hover и класса info_panel, чтобы стилизовать информационный всплывающий блок:

.map g:hover {
  fill: #fc0 !important;
  cursor: help;
}

.info_panel {
  background-color: rgba(255,255,255, .7);
  padding: .3em;
  font-size: .8em;
  font-family: Helvetica, Arial, sans-serif;
  position: absolute;
}

.info_panel::first-line {
   font-weight: bold;
}

 

Модификатор !important в селекторе .map g:hover нужен для того, чтобы переопределить свойство fill, иначе будет использовано правило встроенного в элемент CSS.

Также нам нужно модифицировать цикл for, определенный ранее, чтобы добавить data-атрибут, в котором будет хранится значение, отображаемое при наведении:

for (i = 0; i < regions.length; i++) {
    $('#'+ regions[i].region_code)
    .css({'fill': 'rgba(11, 104, 170,'
         + regions[i].population/highest_value
         +')'}).data('region', regions[i]);
}

 

И, наконец, разнообразим наш скрипт добавлением некоторых эффектов при наведении:

$('.map g').mouseover(function (e) {
  var region_data=$(this).data('region');
  $('<div class="info_panel">'
    + region_data.region_name
    + '<br>'
    + 'Population: '
    + region_data.population.toLocaleString("en-UK")
    + '</div>').appendTo('body');
}).mouseleave(function () {
  $('.info_panel').remove();
}).mousemove(function(e) {
    var mouseX = e.pageX, // X coordinates of mouse
        mouseY = e.pageY; // Y coordinates of mouse

    $('.info_panel').css({
      top: mouseY-50,
      left: mouseX - ($('.info_panel').width() / 2)
    });
});

Как это работает:

  • с помощью mouseover мы добавили элемент div, содержащий отображаемую информацию (имя региона и населенность). Div создается при каждом наведении на элемент g, и добавляется в элемент body документа;
  • mouseleave удаляет этот div, когда курсор выходит за пределы региона;
  • последний метод, mousemove, получает координаты мыши, и применяет их к сгенерированным div’ам.

blog comments powered by Disqus
Vitamin – сервис для выгодного управления вашей рекламой
  • Все популярные рекламные сети в одном окне
  • Агентское вознаграждение до 16% на личный счет или рекламу
  • Любые дополнительные услуги под ваши потребности
  • Бесплатное обучение маркетингу
copyright © 2011–2024 Все права защищены
Запрещено любое копирование материалов ресурса без письменного согласия владельца — ООО "Феникс-Маркетинг". ИНН:7725812838, КПП:772501001, ОГРН: 513774619323915280, Москва, ул. Ленинская слобода, д. 19, стр. 1, этаж/пом 3/25

Генеральный партнёр: STRATE FZ-LLC License number 47005249 Address: B03-227 Business Center 02 RAKEZ Business Zone-FZ RAK (Ras Al Khaimah), United Arab Emirates Email: corporate@strate.ae