PerfectVector
Oleh Irene Kim

Gambar Node SVG Cytoscape.js: Atur Fit dan Padding

Pasang gambar SVG khusus dalam node Cytoscape.js dengan contoh yang berfungsi. Bandingkan ruang kosong sumber, contain dan cover, lalu periksa pemuatan serta penempatan label.

9 menit baca
Di halaman ini

Gunakan URL gambar SVG dalam gaya background-image node, lalu pilih penyesuaian ukuran untuk gambar yang ingin ditampilkan. Jika lambang berhasil dimuat tetapi terlihat kecil, periksa ruang kosong dalam viewport SVG-nya sebelum memperbesar node graf. Jika ujungnya menghilang, bandingkan proporsi gambar dengan node dan periksa pemotongannya.

Cytoscape.js mendokumentasikan latar SVG untuk node, termasuk penyesuaian contain, cover, dan none. Panduan ini memakai lambang asli satu path untuk memisahkan batas sumber dari gaya graf. Simpan master gambar yang bisa diedit bersama konfigurasi graf.

Pisahkan gambar sumber dari node graf

Ada tiga kotak yang perlu diperiksa: batas gambar yang benar-benar digambar, viewport gambar SVG, dan badan node. SVG viewBox menentukan persegi panjang koordinat sumber yang dipetakan ke viewport-nya. Area itu bisa memuat jauh lebih banyak ruang daripada gambar yang terlihat.

Sumber dengan batas rapat kami berukuran 120 × 60, dengan lambang koral membentang dari x=6 hingga x=114 dan y=6 hingga y=54. Bukaan tengahnya merupakan bagian dari path yang sama:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg>
<svg xmlns="http://www.w3.org/2000/svg"
     width="120" height="60" viewBox="0 0 120 60">
  <path fill="#f36f59" fill-rule="evenodd"
    d="M6 30L30 6H90L114 30L90 54H30Z M50 20H70V40H50Z"/>
</svg>

Varian dengan ruang tambahan hanya mengubah dimensi SVG luar dan viewBox:

<svg xmlns="http://www.w3.org/2000/svg"
     width="200" height="140" viewBox="-40 -40 200 140">

Pertahankan header, path, dan tag penutup yang sama. Kedua berkas menggambar koordinat path identik. Berkas kedua mengelilinginya dengan lebih banyak ruang sumber kosong. Ruang itu ikut diskalakan bersama gambar, sehingga mengubah background fit tidak dapat diandalkan sebagai pengganti pemilihan batas sumber yang sesuai. Panduan kotak pembatas SVG membantu saat viewport berkas dan gambar terlihat tidak sesuai.

Jalankan contoh empat kasus

Kami menguji Cytoscape.js 3.34.3 dengan bundle peramban resmi yang versinya dikunci dan disajikan secara lokal. Simpan bundle dari tag rilis tersebut sebagai cytoscape-3.34.3.min.js di samping example.html di bawah. Sajikan folder melalui HTTP lokal, misalnya dengan python3 -m http.server 8000, lalu buka http://localhost:8000/example.html.

Contoh ini mengodekan SVG asli menjadi data URI. encodeURIComponent() meng-escape karakter URI, termasuk # pada warna fill kami. Panduan SVG pustaka merekomendasikan pengodean ini alih-alih Base64 serta header XML yang ditampilkan di sini. Ini satu lambang mandiri tanpa font atau gambar eksternal.

<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>SVG node fit comparison</title>
<style>
  body { font: 16px system-ui; margin: 20px; }
  #cy { width: 1100px; height: 250px; border: 1px solid #ddd; }
  #status { white-space: pre-wrap; }
</style>
<div id="cy"></div>
<pre id="status">Loading images</pre>
<script src="cytoscape-3.34.3.min.js"></script>
<script>
const header = '<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg>';
const path = 'M6 30L30 6H90L114 30L90 54H30Z M50 20H70V40H50Z';
function artwork(padded) {
  const width = padded ? 200 : 120;
  const height = padded ? 140 : 60;
  const viewBox = padded ? '-40 -40 200 140' : '0 0 120 60';
  return header + `<svg xmlns="http://www.w3.org/2000/svg"
    width="${width}" height="${height}" viewBox="${viewBox}">
    <path fill="#f36f59" fill-rule="evenodd" d="${path}"/></svg>`;
}
const cases = [
  ['tight contain', false, 'contain'],
  ['tight cover', false, 'cover'],
  ['padded contain', true, 'contain'],
  ['padded cover', true, 'cover']
].map(([label, padded, fit]) => ({
  label, fit,
  image: 'data:image/svg+xml;utf8,' + encodeURIComponent(artwork(padded))
}));
Promise.all(cases.map(item => new Promise((resolve, reject) => {
  const image = new Image();
  image.onload = () => resolve({
    label: item.label,
    width: image.naturalWidth,
    height: image.naturalHeight
  });
  image.onerror = () => reject(new Error(item.label + ' failed to load'));
  image.src = item.image;
}))).then(loaded => {
  cytoscape({
    container: document.getElementById('cy'),
    elements: cases.map((item, index) => ({
      data: { id: 'n' + index, ...item },
      position: { x: 110 + index * 260, y: 95 }
    })),
    style: [{ selector: 'node', style: {
      width: 120, height: 80, padding: 0, shape: 'rectangle',
      'background-color': '#f1f3f5',
      'background-image': 'data(image)',
      'background-fit': node => node.data('fit'),
      'background-width': 'auto', 'background-height': 'auto',
      'background-width-relative-to': 'inner',
      'background-height-relative-to': 'inner',
      'background-position-x': '50%', 'background-position-y': '50%',
      'background-repeat': 'no-repeat', 'background-clip': 'node',
      'border-width': 1, 'border-color': '#222',
      label: 'data(label)', 'text-valign': 'bottom',
      'text-halign': 'center', 'text-margin-y': 10, 'font-size': 12
    }}],
    layout: { name: 'preset', fit: false },
    zoom: 1, pan: { x: 0, y: 0 },
    userZoomingEnabled: false, userPanningEnabled: false,
    boxSelectionEnabled: false
  });
  document.getElementById('status').textContent =
    'Cytoscape ' + cytoscape.version + '\n' +
    JSON.stringify(loaded, null, 2);
}).catch(error => {
  document.getElementById('status').textContent = error.message;
});
</script>
</html>

Blok status melaporkan dimensi gambar yang dimuat terlebih dahulu sebelum inisialisasi graf. naturalWidth membaca lebar intrinsik gambar yang dikoreksi kepadatannya dalam piksel CSS, seperti dijelaskan oleh MDN. Dalam contoh uji ini, gambar dengan batas rapat melaporkan 120 × 60 dan gambar dengan ruang tambahan 200 × 140. Itu dimensi gambar, bukan pengukuran path koral.

Bandingkan perubahan pada ukuran node yang sama

Keempat node model berukuran 120 × 80 dengan padding node nol. Kami memeriksa contoh uji asli di Chrome pada zoom graf 1 dan 1,5. Gaya node tetap 120 × 80; dimensi hasil render yang dilaporkan menjadi 180 × 120 pada 1,5. Ini perbandingan statis dalam peramban tersebut, bukan tolok ukur kompatibilitas atau performa zoom.

Sumber dan fitTampilan yang diamati dalam contoh uji ini
Batas rapat, containLambang lengkap dengan ujung runcing terlihat
Batas rapat, coverLambang lebih besar dengan ujung kiri dan kanan terpotong di node
Ruang tambahan, containLambang lebih kecil dikelilingi ruang kosong yang luas
Ruang tambahan, coverSedikit lebih besar daripada contain dengan ruang tambahan, tetap jauh lebih kecil daripada kasus batas rapat

Sumber batas rapat memiliki rasio gambar 2:1, sedangkan node 1,5:1. Memuat seluruh gambar 120 × 60 di dalam 120 × 80 menyisakan ruang vertikal. Cover menskalakan gambar menjadi 160 × 80 sebelum dipotong, sehingga ujung horizontalnya melampaui badan node.

Untuk sumber dengan ruang tambahan, persegi panjang gambar yang tersedia memuat 40 satuan ruang tambahan di setiap sisi. Dengan contain, skalanya dibatasi oleh 80/140, bukan 120/200. Karena itu lambang yang lebarnya tetap 108 satuan menempati sekitar 62 satuan model. Angka itu merupakan perhitungan dari dimensi yang dinyatakan, bukan pengukuran piksel tangkapan layar.

Batas sumber dan penyesuaian ukuran
Ilustrasi lambang kecil dengan ruang sumber kosong yang luas, lambang lengkap lebih besar dalam bingkai node, dan lambang yang ujungnya terpotong oleh bingkai lebih sempit.
Ilustrasi: ruang kosong sumber dan penyesuaian ukuran dapat mengubah gambar terlihat secara terpisah. Diagram konseptual ini bukan tangkapan layar Cytoscape atau hasil konversi.

Pilih fit setelah meninjau batas gambar

Mulailah dengan sumber batas rapat dan contain ketika keseluruhan lambang penting. Sisakan margin sumber yang cukup untuk stroke atau efek yang harus tetap terlihat. Mempersempit viewport terlalu jauh dapat memotong gambar yang semestinya ada; ini bukan instruksi untuk menghapus semua margin.

Gunakan cover ketika pemotongan tepi dapat diterima untuk desain. Dalam contoh kami, cover menyembunyikan ujung runcing, sehingga kurang sesuai jika ujung itu menjadi ciri lambang. Node lebih lebar dapat mengubah rasio penyesuaian dan memperlihatkan ujungnya, tetapi juga mengubah tata letak graf. Memperbesar kedua dimensi secara proporsional mempertahankan pemotongan yang sama. Tentukan batasan mana yang ingin diubah.

Pertahankan background-width dan background-height pada auto untuk perbandingan ini. Nilai eksplisit dapat menimpa dimensi gambar yang digunakan dalam penyesuaian. padding node merupakan masukan lain yang terpisah; pustaka menjelaskan apakah ukuran latar menyertakannya atau memakai badan dalam. Lihat referensi background-image sebelum menambahkan kontrol tersebut. Contoh uji tanpa padding kami mengisolasi ruang kosong sumber terlebih dahulu.

Untuk keputusan meet, slice, dan perataan pada tingkat SVG, lanjutkan dengan panduan preserveAspectRatio. Mengubah penyesuaian internal SVG dan mengubah penyesuaian latar Cytoscape merupakan operasi terpisah.

Diagnosis pemuatan sebelum diagnosis pemotongan

Jika status melaporkan kegagalan pemuatan, mengubah contain menjadi cover bukan langkah berikutnya. Buka sumber daya gambar itu sendiri, periksa URL dan dimensi yang dinyatakan, lalu sederhanakan menjadi lambang mandiri yang hanya berisi path di atas. Untuk data URI, kodekan seluruh string SVG alih-alih menggabungkan markup mentah atau nilai warna yang belum di-escape.

SVG yang dipakai sebagai gambar memiliki pembatasan berbeda dari SVG yang dibuka sebagai dokumen. Panduan SVG sebagai gambar MDN menjelaskan pembatasan skrip dan sumber daya eksternal dalam konteks gambar. Berkas gambar yang bergantung pada stylesheet atau font eksternal memerlukan pengujian penyerahan terpisah. Contoh ini menghindari dependensi tersebut dan menempatkan label graf di luar SVG.

Jika gambar dimuat, periksa fit dan pemotongan node dengan bentuk lebar yang jelas. Kemudian uji gambar sebenarnya pada ukuran node dan lingkungan peramban yang didukung aplikasi. Dokumentasi Cytoscape mencatat pertimbangan SVG yang bergantung pada peramban; pengamatan Chrome ini tidak menyelesaikannya untuk Firefox atau semua engine lain.

Pisahkan label dan gambar yang bisa diedit

Contoh memakai label: 'data(label)' untuk label graf dan tidak memuat teks SVG. Anda dapat mengubah kata-katanya tanpa membangun ulang lambang. Path SVG tetap berada dalam master sumber, sedangkan graf mengelola identitas node, penempatan, dan relasi.

Contoh uji yang diperiksa menggambar ke permukaan Canvas. Melihat latar SVG di sana tidak menjadikan path internalnya elemen graf yang bisa diedit secara terpisah. Simpan master saat perlu mengubah bukaan, siluet, atau warna. Ekspor graf merupakan alur terpisah yang memerlukan pemilihan pengekspor dan pengujian penyerahan sendiri; panduan ini tidak menjanjikan graf hasil ekspor mempertahankan path lambang yang bisa diedit. Panduan gambar Graphviz membahas penyerahan referensi gambar pada renderer diagram lain.

Jika lambang khusus Anda hanya tersedia sebagai PNG atau JPG, ubah sumber itu menjadi gambar vektor, lalu periksa siluet, bukaan, dan detail kecil sebelum menetapkan batas SVG-nya. PerfectVector dapat membantu memulihkan geometri sumber yang bisa diedit. Gaya latar, label node, dan ekspor graf tetap merupakan tahap terpisah. SVG yang sudah sesuai bisa langsung masuk ke pemeriksaan fit.

Pertanyaan umum

Mengapa gambar node SVG saya kecil meskipun memakai cover? Gambar sumber dapat memuat ruang viewport kosong yang luas di sekitar path. Bandingkan salinan dengan batas rapat pada dimensi node yang sama sebelum mengubah tata letak graf.

Sebaiknya saya memakai contain atau cover untuk lambang khusus? Pilih contain ketika keseluruhan lambang penting. Pilih cover hanya jika pemotongan tepi yang diamati dapat diterima untuk desain Anda, dan verifikasi dengan sumber serta bentuk node Anda sendiri.

Apakah latar node SVG menciptakan path graf yang bisa diedit? Contoh uji Canvas yang diuji memakai SVG sebagai gambar untuk digambar. Simpan master untuk pengeditan path; kontur internalnya bukan node atau edge graf terpisah dalam contoh ini.

Bisakah saya menaruh label di dalam SVG? Contoh ini menyimpan label dalam data graf dan memakai gambar yang hanya berisi path. Teks SVG, font, dan dependensi konteks gambar memerlukan pemeriksaan peramban serta penyerahan sendiri.

Sumber

  1. Cytoscape.js — Gambar latar — gaya URL gambar, fit, penimpaan ukuran, acuan padding, dan pertimbangan SVG.
  2. Cytoscape.js — Rilis v3.34.3 — rilis terkunci yang dipakai dalam contoh uji asli.
  3. Cytoscape.js — Bundle peramban v3.34.3 — implementasi resmi bertag yang disajikan lokal untuk pengujian peramban.
  4. MDN — viewBox — persegi panjang koordinat sumber dan pemetaan viewport.
  5. MDN — encodeURIComponent — escape komponen data URI SVG.
  6. MDN — naturalWidth — dimensi gambar yang dimuat, berbeda dari batas path.
  7. MDN — SVG sebagai gambar — pembatasan konteks gambar dan pemeriksaan dependensi.

Jika lambang Anda berawal dari raster, buat master SVG yang bisa diedit, periksa kontur dan batas sumbernya, lalu bandingkan contain dan cover dalam tata letak node Anda sendiri.

Lebih banyak dari blog

PerfectVector

Mulai dengan SVG yang lebih rapi
dan lebih mudah diedit

Tanpa kartu kredit