Bahan, terjemahan yang kami terbitkan hari ini, dikhususkan untuk proses pengembangan sistem visualisasi untuk diagram pohon yang dinamis. Untuk menggambar kurva Bezier kubik, teknologi SVG (Scalable Vector Graphics, scalable vector graphics) digunakan di sini. Pekerjaan reaktif dengan data diatur oleh Vue.js.
Ini adalah versi demo dari sistem yang dapat digunakan untuk percobaan.
Bagan Pohon InteraktifKombinasi fitur kuat dari SVG dan kerangka kerja Vue.js memungkinkan kami untuk membuat sistem untuk membangun diagram yang berbasis data, interaktif, dan dapat disesuaikan.
Diagram adalah kumpulan kurva Bezier kubik mulai dari satu titik. Kurva berakhir pada titik yang berbeda berjarak sama satu sama lain. Posisi akhir mereka tergantung pada data yang dimasukkan oleh pengguna. Akibatnya, bagan ini dapat bereaksi secara reaktif terhadap perubahan data.
Pertama, kita akan berbicara tentang bagaimana kurva kubik Bezier terbentuk, kemudian kita akan mencari cara untuk merepresentasikannya dalam sistem koordinat elemen
<svg>
, dan berbicara tentang membuat topeng untuk gambar.
Penulis materi mengatakan bahwa dia menyiapkan banyak ilustrasi untuknya, berusaha membuatnya dimengerti dan menarik. Tujuan dari materi ini adalah untuk membantu semua orang mendapatkan pengetahuan dan keterampilan yang diperlukan untuk mengembangkan sistem diagram mereka sendiri.
Svg
โ Bagaimana kurva Bezier kubik terbentuk?
Kurva yang digunakan dalam proyek ini disebut Cubic Bezier Curve. Gambar berikut menunjukkan elemen kunci dari kurva ini.
Elemen Kunci dari Kurva Kubik BezierKurva digambarkan oleh empat pasang koordinat. Pasangan pertama
(x0, y0)
adalah titik awal jangkar kurva. Pasangan koordinat terakhir
(x3, y3)
adalah titik referensi akhir.
Di antara titik-titik ini, Anda dapat melihat apa yang disebut titik kontrol. Ini intinya
(x1, y1)
dan intinya
(x2, y2)
.
Lokasi titik kontrol sehubungan dengan titik kontrol menentukan bentuk kurva. Jika kurva ditetapkan hanya oleh titik awal dan akhir, koordinat
(x0, y0)
dan
(x3, y3)
, maka kurva ini akan terlihat seperti segmen lurus yang terletak di diagonal.
Sekarang kita akan menggunakan koordinat dari empat titik yang dijelaskan di atas untuk memplot kurva menggunakan elemen
<path>
SVG. Berikut adalah sintaks yang digunakan dalam elemen
<path>
untuk membangun kurva Bezier kubik:
<path D="M x0,y0 C x1,y1 x2,y2 x3,y3" />
Huruf
, yang dapat dilihat dalam kode, adalah singkatan dari Cubic Bezier Curve. Huruf kecil (
c
) berarti penggunaan nilai relatif, huruf besar (
C
) berarti penggunaan nilai absolut. Saya menggunakan nilai absolut untuk membangun diagram, ini ditunjukkan dengan huruf kapital yang digunakan dalam contoh.
โMembuat diagram simetris
Simetri adalah aspek kunci dari proyek ini. Untuk membangun diagram simetris, saya hanya menggunakan satu variabel, menerima atas dasar nilai-nilai seperti tinggi, lebar atau koordinat pusat dari objek tertentu.
Beri nama
size
variabel ini. Karena bagan diorientasikan secara horizontal - variabel
size
dapat dianggap sebagai seluruh ruang horisontal yang tersedia untuk bagan.
Tetapkan nilai yang realistis untuk variabel ini. Kami akan menggunakan nilai ini untuk menghitung koordinat elemen bagan.
size = 1000
Menemukan koordinat elemen bagan
Sebelum kita dapat menemukan koordinat yang diperlukan untuk membangun diagram, kita perlu berurusan dengan sistem koordinat SVG.
โSistem koordinasi dan kotak tampilan
Atribut
<svg> viewBox
sangat penting dalam proyek kami. Faktanya adalah ini menggambarkan sistem koordinat pengguna dari gambar SVG. Sederhananya,
viewBox
menentukan posisi dan ukuran ruang di mana gambar SVG terlihat di layar akan dibuat.
Atribut
viewBox
terdiri dari empat angka yang menentukan parameter sistem koordinat dan berikut ini dalam urutan ini:
min-x
,
min-y
,
width
,
height
. Parameter
min-x
dan
min-y
mengatur asal sistem koordinat pengguna, parameter
width
dan
height
mengatur lebar dan tinggi gambar yang ditampilkan. Di sini akan terlihat seperti apa atribut
viewBox
:
<svg viewBox="min-x min-y width height">...</svg>
Variabel
size
yang kami jelaskan di atas akan digunakan untuk mengontrol parameter
width
dan
height
sistem koordinat ini.
Kemudian, di bagian Vue.js, kita akan mengikat
viewBox
ke properti yang dihitung untuk menentukan nilai
width
dan
height
. Selain itu, dalam proyek kami, properti
min-x
dan
min-y
akan selalu disetel ke 0.
Perhatikan bahwa kita tidak menggunakan atribut
height
dan
width
dari elemen
<svg>
itu sendiri. Kami akan mengaturnya menjadi
width: 100%
dan
height: 100%
menggunakan CSS. Ini akan memungkinkan kami untuk membuat gambar SVG yang secara fleksibel menyesuaikan dengan ukuran halaman.
Sekarang setelah sistem koordinat pengguna siap untuk menggambar bagan, mari kita bicara tentang menggunakan variabel
size
untuk menghitung koordinat elemen-elemen bagan.
Coordinates Koordinat tidak berubah dan dinamis
Konsep baganLingkaran di mana gambar ditampilkan adalah bagian dari diagram. Itulah mengapa penting untuk memasukkannya dalam perhitungan sejak awal. Mari kita, berdasarkan ilustrasi di atas, mencari koordinat untuk lingkaran dan satu kurva eksperimental.
Ketinggian grafik dibagi menjadi dua bagian. Ini adalah
topHeight
(
size
20%) dan
bottomHeight
(ukuran 80% sisanya). Lebar total diagram dibagi menjadi 2 bagian - panjang masing-masing adalah 50% dari
size
.
Ini membuat kesimpulan dari parameter lingkaran tidak memerlukan penjelasan khusus (di sini indikator
topHeight
dan
topHeight
digunakan). Parameter
radius
diatur ke setengah nilai
topHeight
. Berkat ini, lingkarannya sangat cocok dengan ruang yang tersedia.
Sekarang mari kita lihat koordinat kurva.
- Koordinat
(x0, y0)
menentukan titik referensi awal dari kurva. Koordinat ini tetap konstan sepanjang waktu. Koordinat x0
adalah pusat bagan (setengah size
), dan y0
adalah koordinat di mana bagian bawah lingkaran berakhir. Oleh karena itu, dalam rumus untuk menghitung koordinat ini, jari-jari lingkaran digunakan. Hasilnya, koordinat titik ini dapat ditemukan dengan rumus berikut : (50% size, 20% size + radius)
. - Koordinat
(x1, y1)
adalah titik kontrol pertama dari kurva. Itu juga tetap tidak berubah untuk semua kurva. Jika kita tidak lupa bahwa kurva harus simetris, ternyata nilai x1
dan y1
selalu sama dengan setengah dari nilai size
. Maka rumus untuk perhitungan mereka: (50% size, 50% size)
. - Koordinat
(x2, y2)
mewakili titik kontrol kedua dari kurva Bezier. Di sini x2
menunjukkan bentuk kurva yang seharusnya. Indikator ini dihitung secara dinamis untuk setiap kurva. Dan indikator y2
, seperti sebelumnya, akan menjadi setengah size
. Maka rumus berikut untuk menghitung koordinat ini: (x2, 50% size)
. - Koordinat
(x3, y3)
adalah titik referensi ujung kurva. Koordinat ini menunjukkan di mana Anda ingin selesai menggambar garis. Di sini, nilai x3
, seperti x2
, dihitung secara dinamis. Dan y3
mengambil nilai yang sama dengan size
80%. Hasilnya, kami memperoleh rumus berikut: (x3, 80% size)
.
Kami menulis ulang, secara umum, kode untuk elemen
<path>
, dengan mempertimbangkan formula yang baru saja kami peroleh. Persentase yang digunakan di atas disajikan di sini dengan membaginya dengan 100.
<path d="M size*0.5, (size*0.2) + radius C size*0.5, size*0.5 x2, size*0.5 x3, size*0.8" >
Harap perhatikan bahwa pada pandangan pertama, penggunaan persentase dalam formula kami mungkin tampak opsional, hanya berdasarkan pendapat saya sendiri. Namun, nilai-nilai ini tidak diterapkan pada kemauan, tetapi karena penggunaannya membantu mencapai simetri dan proporsi diagram yang benar. Setelah Anda merasakan peran mereka dalam pembuatan bagan, Anda dapat mencoba nilai persentase Anda sendiri dan memeriksa hasil yang diperoleh dengan menerapkannya.
Sekarang mari kita bicara tentang bagaimana kita akan mencari koordinat
x2
dan
x3
. Mereka memungkinkan Anda untuk secara dinamis membuat banyak kurva berdasarkan
index
elemen dalam array yang sesuai.
Membagi ruang horisontal yang tersedia dari bagan menjadi bagian yang sama didasarkan pada jumlah elemen dalam array. Akibatnya, setiap bagian menerima ruang yang sama di sepanjang sumbu x.
Rumus yang kami peroleh selanjutnya harus bekerja dengan sejumlah elemen. Tapi di sini kita akan bereksperimen dengan array yang mengandung 5 elemen:
[0,1,2,3,4]
. Visualisasi array seperti itu berarti perlu menggambar 5 kurva.
โMenemukan koordinat dinamis (x2 dan x3)
Pertama, saya membagi
size
dengan jumlah elemen, yaitu dengan panjang array. Saya menyebut
distance
variabel ini. Ini mewakili jarak antara dua elemen.
distance = size/arrayLength
Lalu saya berjalan di sekitar array dan mengalikan indeks masing-masing elemen (
index
) dengan
distance
. Untuk kesederhanaan, saya cukup memanggil
x
baik parameter
x2
dan parameter
x3
.
Jika Anda menerapkan nilai yang diperoleh saat membuat diagram, yaitu, menggunakan nilai
x
dihitung di atas untuk
x2
dan
x3
, itu akan terlihat sedikit aneh.
Diagram asimetrisSeperti yang Anda lihat, elemen-elemen tersebut berada di area di mana seharusnya mereka berada, tetapi diagram tersebut ternyata asimetris. Tampaknya di bagian kirinya ada lebih banyak elemen daripada di kanan.
Sekarang saya perlu membuat nilai
x3
terletak di tengah segmen yang sesuai, yang panjangnya diatur menggunakan variabel
distance
.
Untuk membawa diagram ke bentuk yang saya butuhkan, saya hanya menambahkan
x
setengah nilai
distance
.
x = index * distance + (distance * 0.5)
Akibatnya, saya menemukan pusat segmen
distance
dan menempatkan koordinat
x3
di dalamnya. Selain itu, saya membawa ke formulir yang kita butuhkan koordinat
x2
untuk kurva No. 2.
Bagan simetrisMenambahkan setengah nilai
distance
ke koordinat
x2
dan
x3
membuat rumus perhitungan untuk koordinat ini cocok untuk memvisualisasikan array yang berisi elemen genap dan ganjil.
โ Penyembunyian gambar
Kita perlu gambar tertentu untuk ditampilkan di bagian atas diagram, di dalam lingkaran. Untuk mengatasi masalah ini, saya membuat topeng kliping yang berisi lingkaran.
<defs> <mask id="svg-mask"> <circle :r="radius" :cx="halfSize" :cy="topHeight" fill="white"/> </mask> </defs>
Kemudian, dengan menggunakan tag
<image>
dari elemen
<image>
<svg>
<image>
untuk menampilkan gambar, saya menautkan gambar ke elemen
<mask>
yang dibuat di atas menggunakan atribut
mask
dari elemen
<image>
.
<image mask="url(#svg-mask)" :x="(halfSize-radius)" :y="(topHeight-radius)" ... > </image>
Karena kami mencoba menyesuaikan gambar persegi menjadi "jendela" bundar, saya menyesuaikan posisi elemen dengan mengurangi parameter
radius
dari parameter yang sesuai. Hasilnya, gambar terlihat melalui topeng yang dibuat dalam bentuk lingkaran.
Mari kita kumpulkan semua yang kita bicarakan dalam satu gambar. Ini akan membantu kita melihat gambaran keseluruhan dari kemajuan pekerjaan.
Data yang digunakan dalam menghitung parameter grafikMembuat gambar SVG dinamis menggunakan Vue.js
Pada titik ini, kami menemukan kurva Bezier kubik dan melakukan perhitungan yang diperlukan untuk membentuk diagram. Akibatnya, kita sekarang dapat membuat diagram SVG statis. Jika kita menggabungkan kemampuan SVG dan Vue.js, kita dapat membuat diagram yang didorong oleh data. Grafik statis akan menjadi dinamis.
Pada bagian ini, kami merevisi diagram SVG, menyajikannya sebagai satu set komponen Vue. Kami juga akan melampirkan atribut SVG ke properti yang dihitung dan membuat bagan menanggapi perubahan data.
Selain itu, pada akhir proyek, kami akan membuat komponen yang merupakan panel konfigurasi. Komponen ini akan digunakan untuk memasukkan data yang akan dikirim ke bagan.
โMengikat data dengan melihat parameter Box
Mari kita mulai dengan menyesuaikan sistem koordinat. Tanpa melakukan ini, kita tidak akan bisa menggambar gambar SVG. Properti
viewbox
dikomputasi akan mengembalikan apa yang kita butuhkan menggunakan variabel
size
. Akan ada empat nilai yang dipisahkan oleh spasi. Semua ini akan menjadi nilai atribut
viewBox
dari elemen
<svg>
.
viewbox() { return "0 0 " + this.size + " " + this.size; }
Di SVG, nama atribut
viewBox
sudah ditulis menggunakan gaya unta.
<svg viewBox="0 0 1000 1000"> </svg>
Oleh karena itu, untuk mengikat atribut ini dengan benar ke properti yang dihitung, saya menuliskan nama atribut dalam gaya kebab dan menempatkan pengubah
.camel
setelahnya. Dengan pendekatan ini, dimungkinkan untuk "menipu" HTML dan menerapkan ikatan atribut dengan benar.
<svg :view-box.camel="viewbox"> ... </svg>
Sekarang ketika mengubah
size
bagan dikonfigurasi ulang secara independen. Kami tidak perlu mengubah tata letak secara manual.
โ Penghitungan parameter kurva
Karena sebagian besar nilai yang diperlukan untuk membangun kurva dihitung berdasarkan variabel tunggal (
size
), saya biasa mencari semua koordinat tetap dengan properti yang dihitung. Apa yang kita sebut "koordinat tetap" di sini dihitung berdasarkan
size
, dan setelah itu tidak berubah dan tidak tergantung pada berapa banyak kurva yang akan dimasukkan oleh diagram.
Jika Anda mengubah
size
- "koordinat tetap" akan dihitung ulang. Setelah itu, mereka tidak akan berubah sampai
size
berikutnya berubah. Diberikan di atas, berikut adalah lima nilai yang perlu kita gambar kurva Bezier:
topHeight โ size * 0.2
bottomHeight โ size * 0.8
width โ size
halfSize โ size * 0.5
distance โ size/arrayLength
Sekarang kita hanya memiliki dua nilai yang tidak diketahui yang tersisa -
x2
dan
x3
. Rumus untuk menghitungnya telah kami peroleh:
x = index * distance + (distance * 0.5)
Untuk menemukan nilai tertentu, kita perlu mengganti indeks elemen array dalam rumus ini.
Sekarang mari kita bertanya pada diri sendiri apakah properti yang dihitung tepat untuk kita temukan
x
. Jawab dengan singkat pertanyaan ini, lalu - tidak, itu tidak akan berhasil.
Properti yang dihitung tidak dapat melewati parameter. Faktanya adalah bahwa ini adalah properti, bukan fungsi. Selain itu, kebutuhan untuk menggunakan parameter untuk menghitung sesuatu berarti bahwa tidak ada keuntungan nyata dari menggunakan properti yang dihitung dalam hal caching.
Harap dicatat bahwa ada pengecualian terkait prinsip di atas. Ini tentang Vuex. Jika Anda menggunakan Vuex getter yang mengembalikan fungsi, Anda bisa meneruskan parameter kepada mereka.
Dalam hal ini, kami tidak menggunakan Vuex. Tetapi bahkan dalam situasi ini, kami memiliki beberapa cara untuk menyelesaikan masalah ini.
โ Opsi nomor 1
Anda dapat mendeklarasikan fungsi ke mana
index
dilewatkan sebagai argumen, dan yang mengembalikan hasil yang kita butuhkan. Pendekatan ini terlihat lebih bersih jika kita akan menggunakan nilai yang dikembalikan oleh fungsi serupa di beberapa tempat di templat.
<g v-for="(item, i) in itemArray"> <path :d="'M' + halfSize + ',' + (topHeight+r) +' '+ 'C' + halfSize + ',' + halfSize +' '+ calculateXPos(i) + ',' + halfSize +' '+ calculateXPos(i) + ',' + bottomHeight" /> </g>
Metode
calculateXPos()
akan melakukan perhitungan setiap kali dipanggil. Metode ini sebagai argumen indeks elemen -
i
.
<script> methods: { calculateXPos (i) { return distance * i + (distance * 0.5) } } </script>
Berikut adalah contoh pada CodePen yang menggunakan solusi ini.
Layar untuk varian aplikasi pertamaโ Opsi nomor 2
Opsi ini lebih baik daripada yang pertama. Kita dapat mengekstrak markup SVG kecil yang diperlukan untuk membangun kurva menjadi komponen anak kecil yang terpisah dan meneruskan
index
kepadanya sebagai salah satu properti.
Dengan pendekatan ini, Anda bahkan dapat menggunakan properti yang dihitung untuk menemukan
x2
dan
x3
.
<g v-for="(item, i) in items"> <cubic-bezier :index="i" :half-size="halfSize" :top-height="topHeight" :bottom-height="bottomHeight" :r="radius" :d="distance" > </cubic-bezier> </g>
Opsi ini memberi kita kesempatan untuk mengatur kode dengan lebih baik. Misalnya, kita bisa membuat komponen anak lain untuk topeng:
<clip-mask :title="title" :half-size="halfSize" :top-height="topHeight" :r="radius"> </clip-mask>
โ Panel konfigurasi
Panel konfigurasiAnda mungkin sudah melihat panel konfigurasi, dipanggil oleh tombol yang terletak di sudut kiri atas layar
contoh di atas. Panel ini memudahkan untuk menambahkan elemen ke array dan menghapusnya dari itu. Mengikuti ide-ide yang dibahas di bagian "Opsi # 2", saya membuat komponen turunan untuk panel konfigurasi. Berkat ini, komponen tingkat atas bersih dan mudah dibaca. Hasilnya, komponen Vue kami yang kecil dan bagus terlihat seperti di bawah ini.
Pohon Komponen ProyekIngin melihat kode yang mengimplementasikan versi proyek ini? Jika demikian, lihat di
sini .
Layar untuk varian aplikasi keduaRepositori proyek
Ini adalah repositori GitHub proyek ("Opsi # 2" diimplementasikan di sini). Saya percaya ini akan berguna bagi Anda untuk melihatnya sebelum Anda melanjutkan ke bagian selanjutnya.
PR
Cobalah untuk membuat diagram yang sama dengan yang kami jelaskan di sini, tetapi buatlah itu berorientasi vertikal. Manfaatkan ide-ide yang diuraikan dalam artikel ini.
Jika Anda berpikir bahwa ini adalah tugas yang mudah, bahwa untuk membangun diagram seperti itu cukup untuk menukar koordinat
x
dan
y
, maka Anda benar. Mempertimbangkan bahwa proyek yang dipertimbangkan di sini tidak dibuat sebagai universal, setelah mengubah koordinat di mana Anda membutuhkannya, Anda juga perlu mengedit kode dengan mengganti nama beberapa variabel dan metode.
Berkat Vue.js, bagan sederhana kami dapat dilengkapi dengan fitur tambahan. Misalnya, berikut ini:
- Anda dapat membuat mekanisme yang memungkinkan Anda untuk beralih antara mode grafik horizontal dan vertikal.
- Kurva dapat mencoba menghidupkan. Misalnya, menggunakan GSAP.
- Anda dapat menyesuaikan properti kurva (katakan - warna dan lebar garis) dari panel konfigurasi.
- Anda dapat menggunakan perpustakaan eksternal untuk mengatur penyimpanan diagram dalam format grafik apa pun atau sebagai file PDF. Bahan-bahan ini dapat diunduh untuk mereka yang bekerja dengan bagan.
Coba pekerjaan rumah ini. Dan jika Anda memiliki masalah - di bawah ini akan diberikan tautan ke solusinya.
Ringkasan
Elemen
<path>
adalah salah satu fitur kuat dari SVG. Elemen ini memungkinkan Anda membuat berbagai gambar dengan akurasi tinggi. Di sini kami menemukan bagaimana kurva Bezier terstruktur, dan bagaimana mempraktikkannya untuk membuat diagram Anda sendiri.
, , JavaScript-. Vue.js . , , , , DOM. , โ .
, , , , , Vue.js SVG. โ
, Vue.js.
โ .
, - , , , โ .
Pembaca yang budiman! ?
