> [Site index](https://perfectvector.com/llms.txt) — available pages and descriptions.

# Obrazy SVG w węzłach Cytoscape.js: dopasowanie i marginesy

> Dopasuj własną grafikę SVG do węzłów Cytoscape.js na działającym przykładzie. Porównaj puste miejsce, contain i cover, potem sprawdź ładowanie oraz położenie etykiet.

Source: https://perfectvector.com/pl/blog/cytoscape-svg-node-artwork

Language: pl
Author: Irene Kim
Published: 2026-10-02T08:00:00+09:00
Updated: 2026-10-02T08:00:00+09:00

Użyj adresu obrazu SVG w stylu `background-image` węzła, a potem wybierz dopasowanie do grafiki, którą chcesz pokazać. Jeśli znak ładuje się, lecz wygląda na maleńki, sprawdź puste miejsce w viewporcie SVG przed powiększeniem węzła grafu. Jeśli końce znikają, porównaj proporcje obrazu z węzłem i sprawdź przycinanie.

Cytoscape.js [opisuje tła SVG węzłów](https://js.cytoscape.org/#style/background-image), w tym dopasowania `contain`, `cover` i `none`. Ten poradnik używa naszego oryginalnego znaku z jedną ścieżką, aby oddzielić granice źródła od stylu grafu. Zachowaj edytowalną wersję wzorcową grafiki obok konfiguracji grafu.

## Oddziel obraz źródłowy od węzła grafu

Trzeba sprawdzić trzy prostokąty: granice narysowanej grafiki, viewport obrazu SVG i korpus węzła. [`viewBox` SVG](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute/viewBox) definiuje prostokąt współrzędnych źródłowych mapowany do viewportu. Może obejmować znacznie więcej miejsca niż widoczny rysunek.

Nasze źródło z małymi marginesami ma 120 × 60, a koralowy znak rozciąga się od x=6 do x=114 i od y=6 do y=54. Otwór w środku jest częścią tej samej ścieżki:

```svg
<?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>
```

Wariant z większymi marginesami zmienia tylko zewnętrzne wymiary SVG i `viewBox`:

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

Zachowaj ten sam nagłówek, ścieżkę i znacznik zamykający. Oba pliki rysują identyczne współrzędne ścieżki. Drugi otacza je większą ilością pustego miejsca w źródle. Miejsce skaluje się z obrazem, więc zmiana dopasowania tła nie zastępuje niezawodnie wyboru odpowiednich granic źródła. [Poradnik obwiedni SVG](https://perfectvector.com/pl/blog/svg-bounding-box) pomaga, gdy viewport pliku i widoczna grafika się nie zgadzają.

## Uruchom przykład czterech przypadków

Testowaliśmy Cytoscape.js [3.34.3](https://github.com/cytoscape/cytoscape.js/releases/tag/v3.34.3) z oficjalnym pakietem przeglądarkowym przypiętym do tej wersji, serwowanym lokalnie. Zapisz [pakiet z tego tagu wydania](https://raw.githubusercontent.com/cytoscape/cytoscape.js/v3.34.3/dist/cytoscape.min.js) jako `cytoscape-3.34.3.min.js` obok poniższego `example.html`. Udostępnij folder przez lokalne HTTP, na przykład `python3 -m http.server 8000`, i otwórz `http://localhost:8000/example.html`.

Przykład koduje oryginalny SVG do URI danych. [`encodeURIComponent()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) koduje znaki URI, w tym `#` w naszym kolorze wypełnienia. Wskazówki SVG biblioteki zalecają to kodowanie zamiast Base64 oraz pokazany tutaj nagłówek XML. To jeden samowystarczalny znak bez zewnętrznych fontów lub obrazów.

```html
<!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 stanu podaje wymiary obrazów wstępnie wczytanych przed inicjalizacją grafu. `naturalWidth` odczytuje wewnętrzną szerokość obrazu skorygowaną o gęstość w pikselach CSS, zgodnie z opisem [MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/naturalWidth). W tym teście obrazy z małymi marginesami podawały 120 × 60, a z większymi 200 × 140. To wymiary obrazów, a nie pomiary koralowej ścieżki.

## Porównaj zmiany przy tym samym rozmiarze węzła

Wszystkie cztery węzły modelu mają 120 × 80 i zerowy wewnętrzny margines. Sprawdziliśmy oryginalny przykład w Chrome przy powiększeniu grafu 1 i 1.5. Styl węzła pozostał 120 × 80; raportowane wymiary renderowane wyniosły 180 × 120 przy 1.5. Było to statyczne porównanie w tej przeglądarce, a nie test zgodności lub wydajności powiększania.

| Źródło i dopasowanie    | Wygląd zaobserwowany w tym teście                                                               |
| ----------------------- | ----------------------------------------------------------------------------------------------- |
| Małe marginesy, contain | Cały znak z widocznymi spiczastymi końcami                                                      |
| Małe marginesy, cover   | Większy znak z lewą i prawą końcówką przyciętą na granicy węzła                                 |
| Duże marginesy, contain | Mniejszy znak otoczony znaczną pustą przestrzenią                                               |
| Duże marginesy, cover   | Nieco większy niż poprzedni contain, nadal znacznie mniejszy niż przypadki z małymi marginesami |

Źródło z małymi marginesami ma proporcje obrazu 2:1, a węzeł 1.5:1. Umieszczenie całego obrazu 120 × 60 wewnątrz 120 × 80 pozostawia miejsce w pionie. Pokrycie węzła skaluje obraz do 160 × 80 przed przycięciem, więc jego poziome końce wychodzą poza korpus.

W źródle z większymi marginesami dostępny prostokąt obrazu obejmuje dodatkowe 40 jednostek miejsca z każdej strony. Przy contain skalę ogranicza 80/140, a nie 120/200. Niezmieniony znak o szerokości 108 jednostek zajmuje więc około 62 jednostek modelu. To obliczenie z zadeklarowanych wymiarów, a nie pikselowy pomiar zrzutu ekranu.

**Granice źródła i dopasowanie**

![Ilustracja małego znaku z dużym pustym marginesem źródłowym, całego większego znaku w ramce węzła oraz znaku z końcami przyciętymi przez węższą ramkę.](https://perfectvector.com/blog/cytoscape-svg-node-artwork/source-bounds-fit.webp)

*Ilustracja: puste miejsce źródła i dopasowanie mogą niezależnie zmieniać widoczną grafikę. Schemat koncepcyjny nie jest zrzutem Cytoscape ani wynikiem konwersji.*

## Wybierz dopasowanie po sprawdzeniu granic grafiki

Zacznij od źródła z małymi marginesami i contain, gdy ważny jest cały znak. Zachowaj dość miejsca dla konturu lub efektu, który musi pozostać widoczny. Zbyt ciasny viewport może przyciąć właściwą grafikę; nie jest to nakaz usunięcia każdego marginesu.

Używaj cover, gdy przycięcie krawędzi jest akceptowalne dla projektu. W naszym przykładzie ukrywa spiczaste końce, więc jest złym wyborem, jeśli identyfikują znak. Szerszy węzeł może zmienić proporcje dopasowania i pokazać końce, ale zmienia też układ grafu. Proporcjonalne powiększenie obu wymiarów zachowuje to samo przycięcie. Ustal, które ograniczenie chcesz zmienić.

W tym porównaniu pozostaw `background-width` i `background-height` na `auto`. Jawne wartości mogą nadpisać wymiary obrazu używane do dopasowania. `padding` węzła jest kolejnym oddzielnym parametrem; biblioteka opisuje, czy wymiarowanie tła go obejmuje, czy używa korpusu wewnętrznego. Zobacz [opis background-image](https://js.cytoscape.org/#style/background-image) przed dodaniem tych ustawień. Nasz przykład z zerowym marginesem wewnętrznym najpierw izoluje puste miejsce źródła.

Decyzje o meet, slice i wyrównaniu na poziomie SVG opisuje [poradnik preserveAspectRatio](https://perfectvector.com/pl/blog/svg-preserveaspectratio). Zmiana wewnętrznego dopasowania SVG i zmiana dopasowania tła Cytoscape to oddzielne operacje.

## Diagnozuj ładowanie przed przycinaniem

Jeśli stan zgłasza błąd ładowania, zmiana contain na cover nie jest następnym krokiem. Otwórz sam zasób obrazu, sprawdź jego adres i zadeklarowane wymiary, a potem uprość go do samowystarczalnego znaku z samymi ścieżkami powyżej. Dla URI danych zakoduj cały ciąg SVG, zamiast łączyć surowy kod znaczników lub niezakodowany kolor.

SVG używany jako obraz ma inne ograniczenia niż SVG otwarty jako dokument. [Poradnik MDN o SVG jako obrazie](https://developer.mozilla.org/en-US/docs/Web/SVG/Guides/SVG_as_an_image) opisuje ograniczenia skryptów i zewnętrznych zasobów w kontekstach obrazowych. Grafika zależna od zewnętrznego arkusza stylów lub fontu wymaga osobnego testu przekazania. Ten przykład unika tych zależności i umieszcza etykiety grafu poza SVG.

Jeśli obraz się ładuje, sprawdź dopasowanie i przycinanie węzła z wyraźnie szerokim kształtem. Potem przetestuj prawdziwą grafikę przy rozmiarze węzła i w środowiskach przeglądarkowych obsługiwanych przez aplikację. Dokumentacja Cytoscape wskazuje kwestie SVG zależne od przeglądarki; ta obserwacja w Chrome nie rozstrzyga ich dla Firefoksa lub każdego innego silnika.

## Oddziel etykiety od edytowalnej grafiki

Przykład używa `label: 'data(label)'` dla etykiet grafu i nie zawiera tekstu SVG. Możesz zmienić słowa bez przebudowy znaku. Ścieżka SVG pozostaje we wzorcu źródłowym, a graf zarządza tożsamością, położeniem i relacjami węzłów.

Badany przykład rysował na powierzchniach Canvas. Widoczne tam tło SVG nie zamienia jego wewnętrznych ścieżek w oddzielnie edytowalne elementy grafu. Zachowaj wzorzec, jeśli chcesz zmienić otwór, sylwetkę lub kolory. Eksport grafu to osobny proces wymagający wybranego eksportera i własnego testu przekazania; poradnik nie gwarantuje zachowania edytowalnych ścieżek znaku w eksportowanym grafie. [Poradnik grafiki Graphviz](https://perfectvector.com/pl/blog/graphviz-svg-node-images) omawia przekazanie odwołań do obrazów w innym rendererze diagramów.

Jeśli własny znak istnieje tylko jako PNG lub JPG, [przekonwertuj to źródło na grafikę wektorową](https://perfectvector.com/pl/image-to-vector), a potem sprawdź sylwetkę, otwór i małe detale przed ustawieniem granic SVG. PerfectVector może pomóc odzyskać edytowalną geometrię źródłową. Style tła, etykiety węzłów i eksport grafu pozostają oddzielnymi etapami. Istniejący odpowiedni SVG może przejść od razu do kontroli dopasowania.

## Najczęstsze pytania

**Dlaczego obraz SVG węzła jest mały nawet przy cover?**
Obraz źródłowy może zawierać dużo pustego miejsca viewportu wokół ścieżki. Porównaj kopię z ciaśniejszymi granicami przy tych samych wymiarach węzła przed zmianą układu grafu.

**Czy wybrać contain czy cover dla własnego znaku?**
Wybierz contain, gdy ważny jest cały znak. Wybieraj cover tylko wtedy, gdy obserwowane przycięcie krawędzi jest akceptowalne, i sprawdź to z własnym źródłem oraz kształtem węzła.

**Czy tło SVG węzła tworzy edytowalne ścieżki grafu?**
Testowany przykład Canvas używa SVG jako malowanego obrazu. Zachowaj wzorzec grafiki do edycji ścieżek; jej wewnętrzne kontury nie są w tym przykładzie osobnymi węzłami ani krawędziami grafu.

**Czy mogę umieścić etykiety w SVG?**
Ten przykład zachowuje etykiety w danych grafu i używa grafiki z samych ścieżek. Tekst SVG, fonty i zależności kontekstu obrazu wymagają osobnych kontroli przeglądarek i przekazania.

## Źródła

1. [Cytoscape.js — Obraz tła](https://js.cytoscape.org/#style/background-image) — style z adresem obrazu, dopasowanie, nadpisanie wymiarów, odniesienia marginesów wewnętrznych i kwestie SVG.
2. [Cytoscape.js — Wydanie v3.34.3](https://github.com/cytoscape/cytoscape.js/releases/tag/v3.34.3) — przypięte wydanie użyte w oryginalnym teście.
3. [Cytoscape.js — Pakiet przeglądarkowy v3.34.3](https://raw.githubusercontent.com/cytoscape/cytoscape.js/v3.34.3/dist/cytoscape.min.js) — oficjalna implementacja z tagiem udostępniona lokalnie do testu przeglądarkowego.
4. [MDN — viewBox](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute/viewBox) — prostokąt współrzędnych źródłowych i mapowanie viewportu.
5. [MDN — encodeURIComponent](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) — kodowanie składnika SVG w URI danych.
6. [MDN — naturalWidth](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/naturalWidth) — wymiary załadowanego obrazu, odrębne od granic ścieżki.
7. [MDN — SVG jako obraz](https://developer.mozilla.org/en-US/docs/Web/SVG/Guides/SVG_as_an_image) — ograniczenia kontekstu obrazu i kontrole zależności.

Jeśli znak zaczyna się od rastra, [utwórz edytowalny wzorzec SVG](https://perfectvector.com/pl/image-to-vector), sprawdź kontury i granice źródła, a potem porównaj contain i cover we własnym układzie węzłów.

## Explore

- [Read the HTML article](https://perfectvector.com/pl/blog/cytoscape-svg-node-artwork)
- [Znaczniki SVG Leaflet: wyrównaj czubek przez iconAnchor](https://perfectvector.com/pl/blog/leaflet-svg-marker-anchor.md)
- [Mierz długość ścieżki SVG bez mylenia skali](https://perfectvector.com/pl/blog/measure-svg-path-length.md)
- [Product facts](https://perfectvector.com/product-facts.md)
- [FAQ](https://perfectvector.com/faq.md)
- [Pricing and credits](https://perfectvector.com/pricing.md)
