Peta geografis fungsional menggunakan SVG dan jQuery. Peta vektor interaktif Rusia JQVMap

Ayo berkreasi peta interaktif. Sesuatu. Apa yang dimaksud dengan interaktif? Ya, ia perlu berinteraksi dengan pengguna dan data di halaman web tempat ia berada. Saya rasa ini cukup untuk menganggapnya interaktif.

Baiklah, mari kita ambil SVG. Mengapa? Ya, karena mudah digunakan oleh orang yang akrab dengan HTML. SVG adalah format vektor, berdasarkan XML. Artinya, gambar SVG memiliki DOM sendiri, aturan CSS dapat diterapkan ke berbagai elemen dan dikontrol oleh JavaScript lama yang bagus.

Jadi, bisakah kita mulai?

Orang yang paling tidak sabar bisa langsung menonton demonya, tapi saya sarankan membaca semuanya secara berurutan.

Mempersiapkan peta Pertama, kita perlu esensinya. Artinya, kartu itu sendiri. Jika Google tidak membantu, maka Anda bisa menggambarnya sendiri, padahal tidak sulit melakukannya di Inkscape.

Misalnya, saya akan mengambil peta satu negara berbentuk bulat (sumber di Wikimedia Commons)

Karena, menurut rencana saya, area peta tidak boleh memiliki warna yang berbeda, maka pertama-tama saya memotong gaya isian dan guratan dari tag yang saya minati, tetapi sebagai imbalannya saya memberikan elemen ini kelas dan id yang saya butuhkan. Misalnya, class="area" untuk wilayah dan class="city" untuk kota.

Selanjutnya, di bagian gambar kami menempatkan yang sangat familiar:
.area ( guratan: hitam; lebar guratan: 2px; isi: #E9FFE9; ) .city ( guratan: hitam; lebar guratan: 2px; isi: merah; )
Inilah CSS yang saya janjikan dalam tindakan. Pada prinsipnya ini sudah cukup. Beda.

Hasil:

Memasukkan SVG ke dalam HTML Proses ini dibahas secara cukup rinci dalam habratopic Tentang masalah penggunaan SVG lintas-browser.

Kami akan menggunakan HTML5 dan menggunakan yang paling sederhana, paling manusiawi dan dengan cara standar:

Semua browser yang mendukung SVG akan “memakannya” dengan benar dan menampilkannya. Dan mereka bahkan akan membiarkan kita bekerja dengannya. Dengan satu syarat: jika server web menyajikannya dengan tipe MIME image/svg+xml. Tipe MIME yang berbeda bisa sangat membingungkan Google Chrome(tetapi bukan Opera, yang mengetahui dengan pasti dari tag bahwa ia mengikuti SVG dan tidak menyerah pada provokasi).

Kedua metode yang benar— memasukkan kode SVG langsung ke HTML. Bagus dari sudut pandang skrip, tetapi dukungan browser masih lebih buruk. Ngomong-ngomong, perhatikan bahwa SVG yang dimasukkan ke dalam HTML “liberal” masih tetap XML “keras”. Jadi diperlukan tanda kutip dan tag penutup.

Penggaruk bawah airTapi tidak semuanya sesederhana itu. Anda dapat segera melihat bahwa browser dengan keras kepala tidak ingin menskalakan peta kami, dan jika tidak sesuai, maka mereka akan menampilkan bilah gulir, seperti ini:

Agar browser bekerja dengan SVG seperti yang kita harapkan, kita harus menghapus atribut lebar dan tinggi dari tag di file SVG (atau mengaturnya ke 100%), dan memasukkan atribut viewBox yang dirancang khusus untuk browser dengan nilai untuk koordinat sudut gambar kiri atas dan kanan bawah :
viewBox="0 0 493 416" Berbeda .

Setelah ini, situasinya membaik secara signifikan, tetapi Google Chrome memberi kita keuntungan lain: Google Chrome terus berupaya untuk menskalakan tinggi gambar ke tinggi elemen, dan tidak menambah tinggi sesuai dengan lebar tag dan proporsi gambar. , bagaimana perilaku browser lain.

Sayang sekali. Anda harus menggunakan JavaScript dan menyesuaikan tinggi elemen secara manual.
var viewBox = svgdom.rootElement.getAttribute("viewBox" ).split(" ");var aspekRatio = viewBox / viewBox;svgobject.height = parseInt(svgobject.offsetWidth / aspekRatio);

Hasil:

Beda.

Berinteraksi dengan SVG Kita tidak memerlukan apa pun untuk berinteraksi dengan SVG yang ditulis langsung ke dalam HTML - itu sudah menjadi bagian dari DOM halaman web.
Sedikit lebih sulit untuk mengakses SVG yang dimasukkan melalui: jQuery(window).load(function () ( // Kita harus menunggu sampai semua grafik (dan juga peta kita) dimuat, jadi kita menggunakan window.onload, var svgobject = document.getElementById("svgmap" ); / / Temukan tag if ("contentDocument" di svgobject) ( // Apakah kita benar-benar memiliki sesuatu di sana? var svgdom = jQuery(svgobject.contentDocument); // Akses model objek
File SVG // Sekarang kita melakukan pekerjaan kita, misalnya: jQuery("#figure1" , svgdom).attr("fill" , "red" ); // Temukan tag dengan id="figure1" di DOM SVG dan isi dengan warna merah ) ));

Ya, jQuery berfungsi dengan SVG, tetapi hanya sebagian. Misalnya, saya perhatikan bahwa fungsi addClass dan deleteClass, serta pencarian kelas (jQuery(".class"), tidak berfungsi. Kita harus memutarbalikkan. Perhatikan bahwa saya menggunakan acara window.onload karena kita harus menunggu beban penuh halaman, beserta semua elemen terkait (termasuk peta kita). Namun, di sini juga Google Chrome sedang terburu-buru untuk mengacaukan kita: jika skrip dengan window.onload ada dalam kode html sebelum tag, maka kode di handler dijalankan SEBELUM peta benar-benar dimuat. Oleh karena itu, tag harus ditempatkan setelah peta kita. Sedih tapi

Interaktivitas satu: pilih area di peta dengan mengklik kotak centang di halaman. Untuk interaksi ini, kita memerlukan kotak centang di setiap baris tabel dengan area, serta id yang cocok atau serupa untuk baris tabel dan area di peta. .

Di sini, ketika Anda mengklik kotak centang, kami akan menetapkan atau menghapus kelas yang dipilih dari area terkait di peta, dan dari garis itu sendiri. Mudah saja:
$("#area masukan" ).perubahan(fungsi () ( var baris = $(ini ).parent().parent(); var id = baris.attr("id" ); if (ini .dicentang) ( baris.addClass("dipilih" ); $("#" +id, svgdom).myAddClass("dipilih" ) lain ( baris.removeClass("dipilih" ); $("#" +id, svgdom). myRemoveClass( "dipilih" )));
Oleh karena itu, Anda perlu menambahkan definisi gaya untuk dari kelas ini. Saya serahkan kepada Anda untuk melakukannya sendiri, sesuai dengan selera dan preferensi Anda. Beda.

Interaktivitas kedua: kami membuka/menampilkan nama-nama di peta dengan mengklik kotak centang di halaman. Kami memasukkan sedikit JavaScript ke dalam halaman, yang menambahkan/menghapus kelas tersembunyi (visibilitas: tersembunyi;) ke semua elemen yang terkait dengan nama di peta:
$("#titleswitch" ).perubahan(fungsi () ( var elements = $(svgdom.getElementsByClassName("areatitle" )) .add($(svgdom.getElementsByClassName("citytitle" ))) .add($(svgdom. getElementsByClassName("titlebox" ))) .add($(svgdom.getElementsByClassName("titleline" ))); if (ini .dicentang) ( elements.myAddClass("hidden" ); ) else ( elements.myRemoveClass("hidden" );
Seperti ini .
Interaktivitas ketiga: sorot area pada peta ketika Anda mengarahkan kursor ke baris tabel (dan sebaliknya) Untuk melakukan ini, Anda perlu melampirkan event handler onhover seperti pada tabel:
// Sorot wilayah pada peta saat Anda mengarahkan mouse ke wilayah yang sesuai. baris tabel. $("#area tr" ).hover(fungsi () ( var id = $(ini).attr("id" ); $("#" +id, svgdom).myAddClass("highlight" ); ), fungsi () ( var id = $(ini).attr("id" ); $("#" +id, svgdom).myRemoveClass("highlight" ); ));
...dan ke area di peta:
// Sorot baris dalam tabel saat Anda mengarahkan mouse ke baris yang sesuai. wilayah di peta $(svgdom.getElementsByClassName("area" )).hover(function () ( var id = $(this).attr("id" ); $("#areas #" +id).addClass( " sorot" ); ), fungsi () ( var id = $(ini).attr("id" ); $("#area #" +id).removeClass("sorot" ); ));
Agar kami dapat melihatnya, kami akan menambahkan aturan CSS yang sesuai ke halaman:
tr .highlight , tr :hover , tr :nth -child (even ):hover ( background : light yellow ;) ...dan ke peta SVG: .highlight , .area :hover ( fill : light yellow ; stroke : black ;)
Saat Anda mengarahkan mouse ke baris tabel (atau area di peta), kelas yang diperlukan untuk menyorot akan ditambahkan ke area terkait di peta (di baris tabel). Agar kode di atas dapat berfungsi, area pada peta dan baris pada tabel harus memiliki id yang sama (atau mirip). Beda.
Interaktivitas Keempat: Menampilkan data dari halaman pada peta Nah, tugas kelas yang dangkal mungkin sudah membosankan. Biarkan peta menunjukkan kepada kita beberapa data.

Hal pertama yang pertama: data. Mari tambahkan beberapa kolom ke tabel kita, misalnya “Orang” dan “Uang”. Perhatian: Data diambil dari orang bodoh dan tidak ada hubungannya dengan Amestris yang asli. Dan juga tombol radio yang akan kita gunakan untuk mengganti data apa yang akan ditampilkan.

Kedua, kita membutuhkan tempat di peta dimana data akan ditampilkan. Mari tambahkan lima blok ke peta (satu untuk setiap wilayah, mengkorelasikan idnya dengan wilayah) dan gaya yang sesuai di:

Nah, berikut kode JavaScript yang akan mengambil data dari sel tabel dan menempatkannya dalam blok teks:
$("input" ).change(function () ( var descnum = $(this ).parent().prevAll().length+1 ; $("#areas tbody tr" ).each(function () ( var id = $(ini ).attr("id" ).substring(4 ); var nilai = $(ini ).anak-anak(":nth-child(" +descnum+")" ).teks(); +id, svgdom).teks(nilai ));));
Dan dengan mengganti tombol radio, kartu akan menampilkan nomor yang diperlukan. Voila!

Interaktivitas kelima: tooltips Ini mungkin terlalu banyak, tapi biarlah. Untuk ukuran yang baik.

Untuk interaksi ini, mari gunakan plugin jQuery.tooltip dan ikat ke area di peta. Kami akan mengambil teks sebagai petunjuk, tentu saja, dari tabel:
$(svgdom.getElementsByClassName("area" )).tooltip(( bodyHandler: function () ( var id = $(this).attr("id" ); var area = $("#areas #" +id+" td :anak-n(2)" ).teks(); var hasil = $("

" ).append($("" ).text(area)); $("#areas #" +id+" td:nth-child(2)" ).nextAll().each(function () ( var pos = $(ini).prevAll().length+1 ; var title = $("#areas thead th:nth-child(" +pos+")" ).text(); (); hasil.tambahkan($("

" ).text(judul + ": " + nilai)); )); mengembalikan hasil; )));

Beda.

Dan seterusnya... Tentu saja, kemungkinan interaksi dengan SVG tidak terbatas pada hal ini. Anda bisa melakukan apa saja. Kocok DOM, ubah halaman dan SVG menggunakan permintaan AJAX dan masih banyak lagi. Lakukanlah.HasilPerangkap yang tersisaDari masalah yang diketahui Untuk saat ini, perlu diketahui bahwa Google Chrome tidak mencetak gambar SVG. Ini bisa jadi merupakan bugnya atau bug WebKit secara umum. Hampir semuanya browser modern mendukung SVG: IE 9+, Opera 8+, Firefox 3+ (Firefox 1.5+ memiliki dukungan parsial), Chrome semua versi, Safari 3.2+ (daftar lebih lengkap)

Namun sayang, masa depan cerah masih belum datang sama sekali dan kami masih harus memikirkan untuk mendukung browser lama.

Cara standar dan termudah, jika SVG hanya berupa gambar: masukkan konten pengganti (gambar yang dirender PNG dan paragraf teks) ke dalam tag.
Maaf, Anda sedang menggunakan versi usang browser yang tidak mendukung peta interaktif.
Jika browser tidak mendukung SVG, gambar dan teks PNG akan ditampilkan untuk memberi tahu pengguna bahwa browser mereka sudah kedaluwarsa. Tidak ada interaktivitas. Namun, hal itu mungkin tidak terlalu diperlukan. Benar, ada satu kelemahan - seperti yang saya perhatikan, browser modern dengan keras kepala mengunduh gambar png pengganti, meskipun faktanya mereka tetap tidak menampilkannya.

Mereka yang tertarik dapat memanfaatkan deteksi dukungan SVG menggunakan Modernizr dan membuat sesuatu yang lebih kompleks dalam JavaScript.

Lebih lanjut kasus-kasus sulit Berbagai solusi Flash, VML, atau Canvas (atau semuanya) dapat membantu Anda. Daftarnya dapat ditemukan di sini: HTML5 Crossbrowser Polyfills, tetapi sayangnya solusi yang saya coba tidak membantu saya. Mungkin karena SVG dengan CSS yang saya buat sketsa di lutut saya ternyata terlalu berlebihan bagi mereka.

Mengonversi SVG ke PNG Ada banyak tempat online di mana Anda dapat mengonversi gambar SVG ke gambar lain. Saya akan menyarankan menggunakan perintah rsvg-convert dari paket librsvg2-bin. Sesuatu seperti ini:
peta kucing.svg | rsvg-convert > peta.png
Namun, dapat mengkonversi ke format lain, serta memperbesar/memperkecil gambar, lihat --help.
Untuk transformasi massal, Anda dapat membuat perintah yang lebih kompleks atau melihat contoh di thread forum, di mana saya menemukan perintah ini Daripada kesimpulan, Itu saja. Jika diperiksa lebih dekat, hal ini tidak terlalu sulit, dan yang terpenting, semuanya dekat dan familiar bagi pengembang web. Lihat apa yang saya tulis di atas dalam bentuk halaman demo, sobek-sobek kode sumber dari repositori, jika Anda memiliki saran dan perbaikan, ungkapkan di komentar atau kirimkan ke repositori dalam bentuk pull request. Nikmati pekerjaan Anda dengan teknologi web modern!

Halo! Baru-baru ini, di salah satu situs saya perlu memasukkan peta interaktif Rusia dengan semua wilayahnya. Ternyata, hanya ada sedikit skrip peta seperti itu dan sebagian besar tidak memenuhi persyaratan atau berbayar. Persyaratan untuk kartu tersebut adalah sebagai berikut:

  • Peta harus digambar dengan cukup baik (Semua batas wilayah harus serupa dengan yang sebenarnya),
  • Anda dapat menambahkan objek ke peta yang akan muncul saat Anda mengarahkan kursor ke wilayah terkait,
  • Peta dapat dengan mudah disesuaikan ukuran dan warnanya agar sesuai dengan gaya situs,
  • Menyorot wilayah yang berisi objek dengan warna berbeda.

Dan kemudian saya menemukan JQVMap - peta dalam format SVG. Hal pertama yang saya suka adalah peta Rusia yang digambar dengan baik. Setelah membaca dokumentasi, saya menyadari bahwa semua masalah saya dapat diselesaikan, meskipun pada awalnya ada beberapa kesulitan yang muncul.

Setelah mengunduh arsip, saya menemukan di dalamnya contoh cara menghubungkan kartu ini ke situs. Semuanya sangat sederhana di sini. Kami menghubungkan skrip dan gaya:


Kami membuat blok untuk peta masa depan, menentukan dimensi:

Kami menginisialisasi kartu seperti yang dijelaskan dalam dokumentasi, mengganti kartu dengan milik kami. Semuanya berfungsi, tapi sayangnya nama semua daerah berfungsi Bahasa inggris, jadi semuanya harus diterjemahkan ke dalam bahasa Rusia. Sebagian pekerjaan telah selesai, sekarang kita harus menyelesaikan semua tugas yang diberikan. Hasilnya, kodenya menjadi seperti ini:

// Array semua objek
var data_obj = ( "no": ["Objek 1", "Objek 2"], "kr": ["Objek 3", "Objek 4", "Objek 5"], "ir": ["Objek 6" , "Objek 7", "Objek 8"] );
warnaWilayah = "#1076C8"; // Warna semua wilayah focusRegion = "#FF9900"; // Warna penyorotan wilayah saat mengarahkan kursor ke objek dari daftar selectRegion = "#0A4C82"; // Warna wilayah yang awalnya disorot
status_yang disorot =();
// Array wilayah yang disorot yang ditentukan dalam array data_obj for(iso in data_obj)( highlight_states = selectRegion; )
$(dokumen).siap(fungsi() ( $("#vmap").vectorMap(( peta: "rusia", warna latar: "#ffffff", warna batas: "#ffffff", lebar batas: 2, warna: wilayah warna, warna: status_yang disorot, hoverOpacity: 0,7, aktifkanZoom: benar, showTooltip: benar,
// Menampilkan objek jika ada diLabelShow: function(event, label, code)( name = ""+label.text()+"
";
jika(data_obj)( daftar_obj = "

    "; untuk(ob di data_obj)( daftar_obj += "
  • "+data_obj+"
  • "; ) daftar_obj += "
"; )lainnya( daftar_obj = ""; )
label.html(nama + daftar_obj);
daftar_obj = "";
),
// Klik pada wilayah
  • onRegionClick: function(elemen, kode, wilayah)( alert(wilayah+" - " +kode); ) )); ));
  • ");
    } } });
    // Keluarkan daftar objek dari array $(document).ready(function() ( for(region in data_obj)( for(obj in data_obj)( $(".list-object").append("
    "+data_obj+" ("+wilayah+")

    // Menyorot wilayah saat mengarahkan kursor ke objek $(function())( $(".focus-region").mouseover(function())( iso = $(this).prop("id"); fregion = () ; fregion = focusRegion; $("#vmap").vectorMap("set", "warna", fregion ));

    $(".wilayah fokus").mouseout(fungsi())( c = $(ini).attr("href"); cl = (c === "#")?colorRegion:c; iso = $ ( ini).prop("id"); fregion = cl; ));

    Pada awalnya ada array data_obj dengan semua objek yang tersedia di wilayah dalam format Data_obj = ("tidak": ["Objek 1", "Objek 2"]) Kode wilayah menurut standar ISO digunakan sebagai kunci, yang merupakan nilai dua huruf dalam bahasa Inggris (File dengan decoding semua sebutan terlampir dalam kode sumber). Dan nilainya adalah array lain dengan daftar objek di wilayah ini. Dalam kode di atas kita memiliki dua objek

    wilayah Novgorod
    (TIDAK). Berikutnya adalah variabel yang menentukan warna wilayah kita:
    colorRegion - warna default semua wilayah
    focusRegion - menyorot warna wilayah saat mengarahkan kursor ke objek dari daftar
    selectRegion - warna wilayah yang awalnya disorot
    peta – nama peta,
    backgroundColor – warna latar belakang peta,
    borderColor – warna batas wilayah,
    borderWidth – ketebalan batas,
    warna – warna default semua wilayah,
    warna - serangkaian wilayah yang disorot yang menunjukkan warna,
    hoverOpacity – transparansi warna suatu wilayah saat diarahkan ke atasnya,

    aktifkanZoom – aktifkan tombol zoom peta, showTooltip – menampilkan keterangan alat. dijalankan sebelum label nama wilayah ditampilkan. Di dalamnya kita menambahkan semua objek ke label untuk ditampilkan. Fungsi onRegionClick dijalankan ketika sebuah objek diklik. Dalam contoh kami, kami cukup menampilkan nama dan kode wilayah menggunakan alert. Ada juga fungsi onRegionOver - dijalankan saat Anda mengarahkan kursor ke suatu wilayah dan onRegionOut - dijalankan saat Anda memindahkan kursor mouse menjauh dari objek. Pada prinsipnya, masalah saya telah terpecahkan, tetapi saya memutuskan untuk terus mempelajari naskahnya. Bagaimana jika kita dapat menampilkan daftar wilayah di bawah peta dan ketika kita mengarahkan kursor ke wilayah yang bersangkutan, daftar tersebut akan disorot. Dokumentasi ini menjelaskan metode untuk memperbarui warna secara dinamis pada peta:

    JQuery("#vmap").vectorMap("set", "warna", (kami: "#0000ff"));

    Di dalamnya kita mengatur serangkaian daftar area pada peta dan, karenanya, warnanya. Misalnya, saya membuat daftar dan menulis fungsi kecil, yang ditunjukkan di atas:

    Sekarang, saat kita mengarahkan kursor ke namanya, nama itu akan disorot daerah yang diinginkan. Akan menyenangkan untuk menampilkan daftar semua objek, dan ketika Anda mengarahkan kursor ke objek tersebut, area terkait akan disorot. Kami tidak ingin menulis semuanya secara manual, terutama karena kami sudah memiliki array, jadi kami hanya menampilkannya dalam satu lingkaran. Perhatikan atribut href - ini menunjukkan warna wilayah yang akan berubah saat mouse menjauh. Kami melakukan ini agar wilayah di mana terdapat objek akan dicat ulang bukan dengan warna default, tetapi dengan warna wilayah yang awalnya disorot (selectRegion).

    Ya, semuanya ternyata tidak terlalu sulit, dan mungkin berguna dalam beberapa proyek. Kartu tambahan Anda juga dapat mengunduh dari situs resminya.

    Sekarang kita akan mengetahui langkah demi langkah cara membuat gambar apa pun di situs menjadi interaktif, yaitu sehingga semua bagian gambar dapat dipilih dengan mengarahkan mouse dan mengkliknya. Contoh jenis gambar ini mencakup foto di situs web real estate, situs dengan peta tempat Anda dapat mengklik bagian-bagiannya untuk membuka halaman lain atau untuk memicu tindakan tertentu atau untuk mengaktifkan animasi di situs. Mari kita mulai!

    LANGKAH 1. Mempersiapkan markup HTML dasar

    Tambahkan kode di bawah ini:

    Setelah Anda menambahkan kode ini, jangan khawatir jika Anda tidak melihat gambar yang Anda sambungkan. Gulir ke bawah halaman sedikit, itu akan ada di sana. Gambar yang Anda sertakan telah berpindah ke bawah karena elemen svg yang ditambahkan di depannya. Kami menuliskan dimensi gambar kami di dalamnya dan sekarang menempati ruang yang sama gambar asli. Catatan: Pada atribut viewBox elemen svg Anda perlu menentukan ukuran gambar yang akan Anda buat
    interaktif.

    LANGKAH 2. Buat elemen SVG

    Untuk pekerjaan lebih lanjut Anda perlu menginstal program yang memungkinkan Anda bekerja dengan svg Grafik Inkscape. Setelah menginstal program, silakan jalankan. Buka gambar Anda dalam program ini di tab "file" dan "buka...". Dalam kasus saya, ini adalah gambar peta dunia. Kemudian klik tombol di pojok kanan bawah “Lihat dan edit XML”. Setelah mengklik tombol ini, widget terkait akan muncul di sisi kanan layar.

    Setelah seleksi, pilih garis yang muncul dari bagian gambar yang Anda pilih di editor xml. Kemudian pilih bidang d elemen ini dan salin isinya sedikit lebih rendah.

    Bidang d akan berisi koordinat dengan volume yang cukup besar. Salin dan tempel semua ini dalam kode HTML Anda ke atribut d pada elemen path.

    Setelah menambahkan koordinat, Anda dapat menyegarkan halaman. Anda akan melihat bahwa proyeksi hitam dari gambar yang Anda jiplak sebelumnya telah muncul.

    LANGKAH 3. Menambahkan gaya

    Agar semuanya ditampilkan secara normal, kita perlu menambahkan gaya berikut ke elemen kita:

    Peta ( posisi: relatif; perataan teks: tengah; ) svg ( posisi: absolut; atas: 0; kiri: 0; tinggi: 100%; lebar: 100%; ) jalur ( opacity: 0,4; isi: oranye; kursor: penunjuk; transisi: 0,3 detik; ) jalur: arahkan kursor ( opasitas: 0,8; transisi: 0,3 detik; )

    Tergantung pada jenis gambar yang Anda gunakan, Anda akan memiliki sedikit tipe yang berbeda gambar. Misalnya, inilah yang terjadi pada saya. Saya menggambar garis besar gambarnya agak miring, tetapi bagi saya yang utama adalah menunjukkan apa yang keluar pada akhirnya) Saya tidak membuat keseluruhan peta menjadi interaktif dan lebih akurat karena akan memakan waktu lebih lama, tetapi hasilnya akan lebih baik. sudah sama. Hal utama adalah Anda memahami cara kerjanya dan cara mengimplementasikannya.

    Catatan: Anda dapat menambahkan tautan ke gambar interaktif tersebut dan menghubungkan berbagai skrip untuk meningkatkan fungsionalitas secara keseluruhan. Anda tidak dibatasi oleh imajinasi Anda.

    Semua! Sekarang Anda telah membuat peta svg interaktif pertama Anda.

    • tutorial

    Mari membuat peta interaktif. Sesuatu. Apa yang dimaksud dengan interaktif? Ya, ia perlu berinteraksi dengan pengguna dan data di halaman web tempat ia berada. Saya rasa ini cukup untuk menganggapnya interaktif.

    Baiklah, mari kita ambil SVG. Mengapa? Ya, karena mudah digunakan oleh orang yang akrab dengan HTML. SVG adalah format vektor berdasarkan XML. Artinya, gambar SVG memiliki DOM sendiri, aturan CSS dapat diterapkan ke berbagai elemen dan dikontrol oleh JavaScript lama yang bagus.

    Jadi, bisakah kita mulai?

    Orang yang paling tidak sabar bisa langsung menonton demonya, tapi saya sarankan membaca semuanya secara berurutan.

    Mempersiapkan peta Pertama, kita perlu esensinya. Artinya, kartu itu sendiri. Jika Google tidak membantu, maka Anda bisa menggambarnya sendiri, padahal tidak sulit melakukannya di Inkscape.

    Misalnya, saya akan mengambil peta satu negara berbentuk bulat (sumber di Wikimedia Commons)

    Karena, menurut rencana saya, area peta tidak boleh memiliki warna yang berbeda, maka pertama-tama saya memotong gaya isian dan guratan dari tag yang saya minati, tetapi sebagai imbalannya saya memberikan elemen ini kelas dan id yang saya butuhkan. Misalnya, class="area" untuk wilayah dan class="city" untuk kota.

    Selanjutnya, di bagian gambar kami menempatkan yang sangat familiar:
    .area ( guratan: hitam; lebar guratan: 2px; isi: #E9FFE9; ) .city ( guratan: hitam; lebar guratan: 2px; isi: merah; )
    Inilah CSS yang saya janjikan dalam tindakan. Pada prinsipnya ini sudah cukup. Beda.

    Hasil:

    Memasukkan SVG ke dalam HTML Proses ini dibahas secara cukup rinci di habratopic.

    Kami akan menggunakan HTML5 dan menggunakan cara paling sederhana, paling manusiawi dan standar:

    Semua browser yang mendukung SVG akan “memakannya” dengan benar dan menampilkannya. Dan mereka bahkan akan membiarkan kita bekerja dengannya. Dengan satu syarat: jika server web menyajikannya dengan tipe MIME image/svg+xml. Jenis MIME lainnya dapat sangat membingungkan Google Chrome (tetapi bukan Opera, yang mengetahui dengan pasti dari tag bahwa ia mengikuti SVG dan tidak menyerah pada provokasi).

    Cara kedua yang benar adalah dengan memasukkan kode SVG langsung ke dalam HTML. Bagus dari sudut pandang skrip, tetapi dukungan browser masih lebih buruk. Ngomong-ngomong, perhatikan bahwa SVG yang dimasukkan ke dalam HTML “liberal” masih tetap XML “keras”, sehingga diperlukan tanda kutip dan tag penutup.

    Penggaruk bawah air Tapi tidak semuanya sesederhana itu. Anda dapat segera melihat bahwa browser dengan keras kepala tidak ingin menskalakan peta kami, dan jika tidak sesuai, maka mereka akan menampilkan bilah gulir, seperti ini:

    Agar browser bekerja dengan SVG seperti yang kita harapkan, kita harus menghapus atribut lebar dan tinggi dari tag di file SVG (atau mengaturnya ke 100%), dan memasukkan atribut viewBox yang dirancang khusus untuk browser dengan nilai untuk koordinat sudut gambar kiri atas dan kanan bawah :
    viewBox="0 0 493 416" Berbeda .

    Setelah ini, situasinya membaik secara signifikan, tetapi Google Chrome memberi kita keuntungan lain: Google Chrome terus berupaya untuk menskalakan tinggi gambar ke tinggi elemen, dan tidak menambah tinggi sesuai dengan lebar tag dan proporsi gambar. , bagaimana perilaku browser lain.


    Sayang sekali. Anda harus menggunakan JavaScript dan menyesuaikan tinggi elemen secara manual.
    var viewBox = svgdom.rootElement.getAttribute("viewBox").split(" "); var aspekRatio = viewBox/viewBox; svgobject.height = parseInt(svgobject.offsetWidth / aspekRatio);

    Hasil:

    Beda.

    Berinteraksi dengan SVG Kita tidak memerlukan apa pun untuk berinteraksi dengan SVG yang ditulis langsung ke dalam HTML - itu sudah menjadi bagian dari DOM halaman web.
    jQuery(window).load(function () ( // Kita harus menunggu sampai semua grafik (dan juga peta kita) dimuat, jadi kita menggunakan window.onload, var svgobject = document.getElementById("svgmap"); / / Temukan tag if ("contentDocument" di svgobject) ( // Apakah kita benar-benar memiliki sesuatu di sana? var svgdom = jQuery(svgobject.contentDocument); // Akses model objek file SVG // Sekarang lakukan tugas kita, misalnya: jQuery ("#figure1", svgdom).attr("fill", "red"); // Temukan tag dengan id="figure1" di DOM SVG dan isi dengan warna merah ) ));
    Ya, jQuery berfungsi dengan SVG, tetapi hanya sebagian. Misalnya, saya perhatikan bahwa fungsi addClass dan deleteClass, serta pencarian kelas (jQuery(".class"), tidak berfungsi. Kita harus memutarbalikkan.

    Perhatikan bahwa saya menggunakan acara window.onload karena kita harus menunggu halaman dimuat sepenuhnya, bersama dengan semua elemen terkait (termasuk peta kita). Namun, di sini juga Google Chrome sedang terburu-buru untuk mengacaukan kita: jika skrip dengan window.onload ada dalam kode html sebelum tag, maka kode di handler dijalankan SEBELUM peta benar-benar dimuat. Oleh karena itu, tag harus ditempatkan setelah peta kita. Sedih tapi benar.

    Interaktivitas satu: sorot area pada peta dengan mengklik kotak centang di halaman. Untuk interaksi ini, kita memerlukan kotak centang di setiap baris tabel dengan area, serta id yang cocok atau serupa untuk baris tabel dan area di peta.

    Di sini, ketika Anda mengklik kotak centang, kami akan menetapkan atau menghapus kelas yang dipilih dari area terkait di peta, dan dari garis itu sendiri. Mudah saja:
    $("#area input").change(function() ( var row = $(this).parent().parent(); var id = row.attr("id"); if (ini.dicentang) ( baris.addClass("dipilih"); $("#"+id, svgdom).myAddClass("dipilih"); lain ( baris.removeClass("dipilih"); $("#"+id, svgdom). ("terpilih");
    Oleh karena itu, Anda perlu menambahkan definisi gaya untuk kelas ini. Saya menyerahkan kepada Anda untuk melakukannya sendiri, sesuai dengan selera dan preferensi Anda. Beda.

    Interaktivitas kedua: kita membuka/menampilkan nama-nama di peta dengan mengklik kotak centang di halaman. Interaksi ini menjadi lebih mudah. Kami memasukkan sedikit JavaScript ke dalam halaman, yang menambahkan/menghapus kelas tersembunyi (visibilitas: tersembunyi;) ke semua elemen yang terkait dengan nama di peta:
    $("#titleswitch").perubahan(fungsi () ( var elements = $(svgdom.getElementsByClassName("areatitle")) .add($(svgdom.getElementsByClassName("citytitle"))) .add($(svgdom. getElementsByClassName("titlebox"))) .add($(svgdom.getElementsByClassName("titleline"))); if (ini.dicentang) ( elements.myAddClass("hidden"); ) else ( elements.myRemoveClass("hidden" );
    Seperti ini .

    Interaktivitas ketiga: menyorot area pada peta ketika Anda mengarahkan kursor ke baris tabel (dan sebaliknya) Untuk melakukan ini, Anda perlu menggantung event handler onhover seperti pada tabel:
    // Sorot wilayah pada peta saat Anda mengarahkan mouse ke wilayah yang sesuai. baris tabel. $("#areas tr").hover(fungsi () ( var id = $(this).attr("id"); $("#"+id, svgdom).myAddClass("highlight"); ), fungsi () ( var id = $(ini).attr("id"); $("#"+id, svgdom).myRemoveClass("highlight"); ));
    ...dan ke area di peta:
    // Sorot baris dalam tabel saat Anda mengarahkan mouse ke baris yang sesuai. wilayah di peta $(svgdom.getElementsByClassName("area")).hover(function () ( var id = $(this).attr("id"); $("#areas #"+id).addClass( " sorot"); ), fungsi () ( var id = $(ini).attr("id"); $("#area #"+id).removeClass("highlight"); ));
    Agar kami dapat melihatnya, kami akan menambahkan aturan CSS yang sesuai ke halaman:
    tr.highlight, tr:hover, tr:nth-child(even):hover ( background: light yellow; ) ...dan ke peta SVG: .highlight, .area:hover ( fill: light yellow; stroke: black; )
    Saat Anda mengarahkan mouse ke baris tabel (atau area di peta), kelas yang diperlukan untuk menyorot akan ditambahkan ke area terkait di peta (di baris tabel). Agar kode di atas berfungsi, area pada peta dan baris dalam tabel harus memiliki id yang sama (atau serupa). Beda.

    Interaktivitas Keempat: Menampilkan data dari halaman pada peta Nah, tugas kelas yang dangkal mungkin sudah membosankan. Biarkan peta menunjukkan kepada kita beberapa data.

    Hal pertama yang pertama: data. Mari tambahkan beberapa kolom ke tabel kita, misalnya “Orang” dan “Uang”. Perhatian: Data diambil dari orang bodoh dan tidak ada hubungannya dengan Amestris yang asli. Dan juga tombol radio yang akan kita gunakan untuk mengganti data apa yang akan ditampilkan.

    Kedua, kita membutuhkan tempat di peta dimana data akan ditampilkan. Mari tambahkan lima blok ke peta (satu untuk setiap wilayah, mengkorelasikan idnya dengan wilayah) dan gaya yang sesuai di:

    Nah, berikut kode JavaScript yang akan mengambil data dari sel tabel dan menempatkannya dalam blok teks:
    $("input").change(function () ( var descnum = $(this).parent().prevAll().length+1; $("#areas tbody tr").each(function() ( var id = $(ini).attr("id").substring(4); var nilai = $(ini).anak-anak(":nth-child("+descnum+")").teks(); +id, svgdom).teks(nilai ) ));
    Dan dengan mengganti tombol radio, kartu akan menampilkan nomor yang diperlukan. Voila!

    Interaktivitas kelima: tooltips Ini mungkin terlalu banyak, tapi biarlah. Untuk ukuran yang baik.

    Untuk interaksi ini, mari gunakan plugin jQuery.tooltip dan ikat ke area di peta. Kami akan mengambil teks sebagai petunjuk, tentu saja, dari tabel:
    $(svgdom.getElementsByClassName("area")).tooltip(( bodyHandler: function() ( var id = $(this).attr("id"); var area = $("#areas #"+id+" td :anak ke-n(2)").teks(); var hasil = $("

    ").append($("").text(area)); $("#areas #"+id+" td:nth-child(2)").nextAll().each(function())( var pos = $(ini).prevAll().length+1; var title = $("#areas thead th:nth-child("+pos+")").text(); teks(); hasil.tambahkan($("

    ").text(judul + ": " + nilai)); )); mengembalikan hasil; ) ));


    Beda.

    Dan seterusnya... Tentu saja, kemungkinan berinteraksi dengan SVG tidak terbatas pada hal ini. Anda bisa melakukan apa saja. Kocok DOM, ubah halaman dan SVG menggunakan permintaan AJAX dan masih banyak lagi. Lakukanlah. Hasil
    Jebakan yang tersisa Di antara masalah yang diketahui sejauh ini, dapat dicatat bahwa Google Chrome tidak mencetak gambar SVG. Ini bisa berupa bug atau bug WebKit secara umum. Kompatibilitas mundur Hampir semua browser modern mendukung SVG: IE 9+, Opera 8+, Firefox 3+ (Firefox 1.5+ memiliki dukungan parsial), Chrome semua versi, Safari 3.2+ (selengkapnya). daftar lengkap)

    Namun sayang, masa depan cerah masih belum datang sama sekali dan kami masih harus memikirkan untuk mendukung browser lama.

    Cara standar dan termudah, jika SVG hanya berupa gambar: masukkan konten pengganti (gambar yang dirender PNG dan paragraf teks) ke dalam tag.

    Sayangnya, Anda menggunakan browser versi lama yang tidak mendukung peta interaktif.


    Jika browser tidak mendukung SVG, gambar dan teks PNG akan ditampilkan untuk memberi tahu pengguna bahwa browser mereka sudah kedaluwarsa. Tidak ada interaktivitas. Namun, hal itu mungkin tidak terlalu diperlukan. Benar, ada satu kelemahan - seperti yang saya perhatikan, browser modern dengan keras kepala mengunduh gambar png pengganti, meskipun faktanya mereka tetap tidak menampilkannya.

    Mereka yang tertarik dapat memanfaatkan deteksi dukungan SVG menggunakan Modernizr dan membuat sesuatu yang lebih kompleks dalam JavaScript.

    Untuk kasus yang lebih kompleks, berbagai solusi menggunakan Flash, VML, atau Canvas (atau semuanya) dapat membantu Anda. Daftarnya dapat ditemukan di sini: HTML5 Crossbrowser Polyfills, tetapi sayangnya solusi yang saya coba tidak membantu saya. Mungkin karena SVG dengan CSS yang saya buat sketsa di lutut saya ternyata terlalu sulit bagi mereka.

    Mengonversi SVG ke PNG Ada banyak tempat online di mana Anda dapat mengonversi gambar SVG ke gambar lain. Saya akan menyarankan menggunakan perintah rsvg-convert dari paket librsvg2-bin. Sesuatu seperti ini:
    peta kucing.svg | rsvg-convert > peta.png
    Namun, dapat mengkonversi ke format lain, serta memperbesar/memperkecil gambar, lihat --help.
    Untuk transformasi massal, Anda dapat membuat perintah yang lebih kompleks atau melihat contoh di thread forum peta interaktif Tambahkan tag
    • Sergei Savenkov

      semacam ulasan "pendek"... seolah-olah mereka sedang terburu-buru di suatu tempat