Sök…


Koordinatsystem

I ett normalt matematiskt koordinatsystem är punkten x = 0, y = 0 i grafens nedre vänstra hörn. Men i SVG-koordinatsystemet är denna (0,0) punkt i det övre vänstra hörnet av 'duken', det liknar CSS när du anger positionen att absoluta / fixa och använda övre och vänstra för att kontrollera elementets exakta punkt.

Det är viktigt att komma ihåg att när y ökar i SVG förflyttas formerna nedåt.

Låt oss säga att vi ska skapa en spridningsdiagram med varje poängkorrespondent till axvärdet och y-värdet. För att skala värdet måste vi ställa in domänen och intervallet så här:

d3.svg.scale()
  .range([0, height])
  .domain([0,max])

Men om du bara behåller inställningarna så här, kommer punkterna att baseras på den övre horisontella kanten istället för den nedre horisontella linjen som vad vi förväntade oss.

Det trevliga med d3 är att du enkelt kan ändra detta genom en enkel justering i domäninställning:

d3.scale.linear()
  .range([height, 0])
  .domain([0, max])

Med ovanstående kod är domänens nollpunkt korrespondent till höjden på SVG, som är den nedersta raden i diagrammet i betraktarens ögon, samtidigt kommer maxvärdet för källdata att motsvara nollpunkten för SVG koordinatsystem, vilket maxvärde för tittarna.

De Element

<rect> representerar rektangel, bortsett från estetiska egenskaper som slag och fyllning, ska rektangel definieras av plats och storlek.

När det gäller platsen bestäms det av x- och y-attributen. Platsen är relativt rektangelns förälder. Och om du inte anger x- eller y-attributet kommer standarden att vara 0 i förhållande till överordnade element.

När du har angett platsen, eller snarare "startpunkten" för rektorn, är nästa sak att ange storleken, vilket är viktigt om du faktiskt vill rita sth på duken, det vill säga om du inte ange storleksattributen eller värdet är inställt som 0, du kommer inte att se någonting på duken.

Fall: stapeldiagram

Fortsätt med det första scenariot, y-axlarna, men den här gången, låt oss försöka rita ett stapeldiagram.

Förutsatt att inställningen för y-skalan är densamma, är y-axeln också korrekt inställd, den enda skillnaden mellan spridplottet och detta stapeldiagram är att vi måste ange bredd och höjd, särskilt höjden. För att vara mer specifik har vi redan fått "utgångspunkten", resten är att använda saker som för höjden:

.attr("height", function(d){
  return (height - yScale(d.value))
})

De Element

<svg> elementet är rotelementet eller duken när vi ritar diagram på det.

SVG-element kan kapslas inuti varandra, och på detta sätt kan SVG-former grupperas ihop, samtidigt kommer alla former som är kapslade inuti ett element att placeras relativt dess inneslutna element.

En sak som kan behöva nämnas är att vi inte kan bo i en annan, det fungerar inte.

Fall: Flera diagram

Exempelvis består detta diagram över flera donuts av flera element, som innehåller ett munkdiagram respektive. Detta kan uppnås genom att använda elementet, men i det här fallet där vi bara vill sätta munkdiagram en efter en bredvid varandra, är det mer praktiskt.

En sak att tänka på är att vi inte kan använda transformattribut om vi ändå kan använda x, y för position.

De Element

SVG stöder för närvarande inte automatisk rader eller ordomslag, det är när det gäller att rädda. element placerar nya textrader i förhållande till föregående textrad. Och genom att använda dx eller dy i varje av dessa spann kan vi placera ordet i förhållande till ordet före det.

Fall: Annotation på axlar

När vi till exempel vill lägga till en kommentar på y Ax:

svg.append("g")
  .attr("class", "y axis")
  .call(yAxis)
.append("text")
  .attr("transform", "rotate(-90)")
  .attr("y", 6)
  .attr("dy", ".71em")
  .style("text-anchor", "end")
  .text("Temperature (ºF)");

Korrekt bifoga ett SVG-element

Detta är ett relativt vanligt misstag: Du skapade ett rect element, till exempel i ett stapeldiagram, och du vill lägga till en textetikett (låt oss säga värdet på den stapeln). Så genom att använda samma variabel som du använde för att bifoga rect och definiera sin x och y position lägga du din text element. Mycket logik, kanske du tror. Men detta kommer inte att fungera.

Hur uppstår detta misstag?

Låt oss se ett konkret exempel, en mycket grundläggande kod för att skapa ett stapeldiagram ( fiol här ):

var data = [210, 36, 322, 59, 123, 350, 290];

var width = 400, height = 300;

var svg = d3.select("body")
    .append("svg")
    .attr("width", width)
    .attr("height", height);

var bars = svg.selectAll(".myBars")
    .data(data)
    .enter()
    .append("rect");

bars.attr("x", 10)
    .attr("y", function(d,i){ return 10 + i*40})
    .attr("width", function(d){ return d})
    .attr("height", 30);

Vilket ger oss detta resultat:

ange bildbeskrivning här

Men du vill lägga till några textelement, kanske ett enkelt värde i varje stapel. Så gör du det här:

bars.append("text")
   .attr("x", 10)
   .attr("y", function(d,i){ return 10 + i*40})
   .text(function(d){ return d});

Och, voilà: ingenting händer! Om du tvivlar på det, här är fiolen .

"Men jag ser taggen!"

Om du inspekterar SVG skapad med den här sista koden ser du detta:

ange bildbeskrivning här

Och just nu säger många människor: "Men jag ser texttaggen, den är bifogad!". Ja, det är det, men det betyder inte att det kommer att fungera. Du kan lägga till vad som helst ! Se detta till exempel:

svg.append("crazyTag");

Det ger dig detta resultat:

<svg>
    <crazyTag></crazyTag>
</svg>

Men du förväntar dig inte något resultat bara för att taggen är där, eller hur?

Lägg SVG-element på rätt sätt

Lär dig vilka SVG-element som kan hålla barn, läs specifikationerna . I vårt sista exempel, gör koden inte eftersom rect element inte kan innehålla text Så hur visar vi våra texter?

Skapa en annan variabel och bifoga text till SVG:

var texts = svg.selectAll(".myTexts")
    .data(data)
    .enter()
    .append("text");

texts.attr("x", function(d){ return d + 16})
    .attr("y", function(d,i){ return 30 + i*40})
    .text(function(d){ return d});

Och detta är resultatet:

ange bildbeskrivning här

Och här är fiolen .

SVG: ritningsordningen

Det här är något som kan vara frustrerande: du gör en visualisering med D3.js men rektangeln du vill ha ovanpå är gömd bakom en annan rektangel, eller linjen du planerade att vara bakom en cirkel är faktiskt över den. Du försöker lösa detta med hjälp av z-index i ditt CSS, men det fungerar inte (i SVG 1.1).

Förklaringen är enkel: I en SVG definierar elementens ordning ordningen på "målningen", och målningen i ordningen definierar vem som går på toppen.

Element i ett SVG-dokumentfragment har en implicit ritningsordning, där de första elementen i SVG-dokumentfragmentet blir "målade" först. Efterföljande element målas ovanpå tidigare målade element.

Så antar att vi har den här SVG:

<svg width="400" height=200>
    <circle cy="100" cx="80" r="60" fill="blue"></circle>
    <circle cy="100" cx="160" r="60" fill="yellow"></circle>
    <circle cy="100" cx="240" r="60" fill="red"></circle>
    <circle cy="100" cx="320" r="60" fill="green" z-index="-1"></circle>
</svg>

Han har fyra cirklar. Den blå cirkeln är den första som är "målad", så den kommer att bälja alla andra. Sedan har vi den gula, sedan den röda och slutligen den gröna. Den gröna är den sista och den kommer att vara på toppen.

Så här ser det ut:

ange bildbeskrivning här

Ändra ordningen på SVG-element med D3

Så är det möjligt att ändra ordning på elementen? Kan jag göra den röda cirkeln framför den gröna cirkeln?

Ja. Det första tillvägagångssättet som du måste ha i åtanke är ordningen på raderna i din kod: rita först elementen i bakgrunden, och senare i koden elementen i förgrunden.

Men vi kan dynamiskt ändra elementens ordning, även efter att de målats. Det finns flera vanliga JavaScript-funktioner som du kan skriva för att göra detta, men D3 har redan 2 fina funktioner, selection.raise() och selection.lower() .

Enligt API:

choice.raise (): Sätt tillbaka varje valt element i ordning som det sista barnet till sin förälder. choice.lower (): Sätter tillbaka varje valt element i ordning som det första barnet till sin förälder.

Så för att visa hur man manipulerar ordningen på elementen i vår tidigare SVG, här är en mycket liten kod:

d3.selectAll("circle").on("mouseover", function(){
    d3.select(this).raise(); 
});

Vad gör det? Den väljer alla cirklar och när användaren håller muspekaren över en cirkel väljer den den specifika cirkeln och tar den fram. Väldigt enkelt!

Och här är JSFiddle med live-koden.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow