Zoeken…


Coördinatie systeem

In een normaal wiskundig coördinatensysteem bevindt het punt x = 0, y = 0 zich in de linkerbenedenhoek van de grafiek. Maar in het SVG-coördinatensysteem bevindt dit (0,0) punt zich in de linkerbovenhoek van het 'canvas', het is een beetje vergelijkbaar met CSS wanneer u de positie voor absolute / fix opgeeft en boven en links gebruikt om de exacte punt van het element.

Het is van essentieel belang om te onthouden dat wanneer y in SVG toeneemt, de vormen naar beneden gaan.

Laten we zeggen dat we een spreidingsdiagram maken met elk punt dat overeenkomt met de bijlwaarde en de y-waarde. Om de waarde te schalen, moeten we het domein en het bereik als volgt instellen:

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

Als u de instellingen echter zo houdt, worden de punten gebaseerd op de bovenste horizontale rand in plaats van de onderste horizontale lijn zoals verwacht.

Het leuke van d3 is dat je dit eenvoudig kunt wijzigen door een eenvoudige aanpassing in de domeininstelling:

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

Met bovenstaande code komt het nulpunt van het domein overeen met de hoogte van de SVG, wat de onderste regel van de grafiek is in de ogen van de kijker. Ondertussen zal de maximale waarde van de brongegevens overeenkomen met het nulpunt van de SVG coördinatensysteem, dat de maximale waarde voor kijkers.

De Element

<rect> staat voor rechthoek, afgezien van esthetische eigenschappen zoals lijn en vulling, wordt de rechthoek bepaald door de locatie en de grootte.

Wat de locatie betreft, deze wordt bepaald door de kenmerken x en y. De locatie is relatief ten opzichte van het bovenliggende element van de rechthoek. En als u het x- of y-kenmerk niet opgeeft, is de standaardwaarde 0 ten opzichte van het bovenliggende element.

Nadat u de locatie hebt opgegeven, of liever het 'startpunt' van de rect, is het volgende dat u de grootte moet opgeven, wat essentieel is als u daadwerkelijk sth op het canvas wilt tekenen, dat wil zeggen, als u dat niet doet geef de maatkenmerken op of de waarde is ingesteld op 0, u ziet niets op het canvas.

Case: staafdiagram

Ga verder met het eerste scenario, de y-assen, maar laten we dit keer proberen een staafdiagram te tekenen.

Ervan uitgaande dat de y-schaalinstelling hetzelfde is, is de y-as ook correct ingesteld, het enige verschil tussen de spreidingsplot en dit staafdiagram is dat we de breedte en de hoogte moeten opgeven, met name de hoogte. Om specifieker te zijn, we hebben al het 'startpunt', de rest is om dingen te gebruiken zoals voor de hoogte:

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

De Element

<svg> -element is het basiselement, of het canvas terwijl we er grafieken op tekenen.

SVG-elementen kunnen in elkaar worden genest, en op deze manier kunnen SVG-vormen worden gegroepeerd. Ondertussen worden alle vormen die in een element zijn genest, ten opzichte van het omringende element geplaatst.

Eén ding moet misschien worden vermeld, dat we niet in een ander kunnen nestelen, het zal niet werken.

Case: meerdere grafieken

Dit diagram met meerdere donuts bestaat bijvoorbeeld uit meerdere elementen, die respectievelijk een diagram voor donut bevatten. Dit kan worden bereikt door het element te gebruiken, maar in dit geval, waar we alleen de ringdiagrammen één voor één naast elkaar willen plaatsen, is het handiger.

Een ding om in gedachten te houden is dat we transformattribuut niet kunnen gebruiken, maar we kunnen x, y gebruiken voor positie.

De Element

SVG biedt momenteel geen ondersteuning voor automatische regeleinden of tekstterugloop, dat is wanneer het om redding gaat. element plaatst nieuwe tekstregels ten opzichte van de vorige tekstregel. En door dx of dy binnen elk van deze reeksen te gebruiken, kunnen we het woord in relatie tot het woord ervoor plaatsen.

Case: Annotatie op assen

Als we bijvoorbeeld een annotatie op y Axe willen toevoegen:

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)");

Een SVG-element correct toevoegen

Dit is een relatief veel voorkomende fout: u hebt een rect element gemaakt, bijvoorbeeld in een staafdiagram, en u wilt een tekstlabel toevoegen (laten we zeggen de waarde van die balk). Dus met dezelfde variabele die u hebt gebruikt om de rect toe te voegen en de x en y positie te definiëren, voegt u uw text . Heel logisch, denk je misschien. Maar dit zal niet werken.

Hoe komt deze fout voor?

Laten we een concreet voorbeeld bekijken, een zeer eenvoudige code voor het maken van een staafdiagram ( viool hier ):

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);

Wat ons dit resultaat oplevert:

voer hier de afbeeldingsbeschrijving in

Maar u wilt enkele tekstelementen toevoegen, misschien een eenvoudige waarde voor elke balk. Dus je doet dit:

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

En, voilà: er gebeurt niets! Als je eraan twijfelt, hier is de viool .

"Maar ik zie de tag!"

Als u de SVG inspecteert die met deze laatste code is gemaakt, ziet u dit:

voer hier de afbeeldingsbeschrijving in

En op dit punt zeggen veel mensen: "Maar ik zie het tekstlabel, het is toegevoegd!". Ja, dat is het, maar dit betekent niet dat het zal werken. Je kunt alles toevoegen! Zie dit bijvoorbeeld:

svg.append("crazyTag");

Het geeft je dit resultaat:

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

Maar je verwacht geen enkel resultaat omdat de tag er is, of wel?

Voeg SVG-elementen op de juiste manier toe

Ontdek welke SVG-elementen kinderen kunnen vasthouden door de specificaties te lezen. In ons laatste voorbeeld werkt de code niet omdat rect elementen geen text kunnen bevatten. Dus, hoe onze teksten te tonen?

Maak nog een variabele en voeg de text aan de 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});

En dit is het resultaat:

voer hier de afbeeldingsbeschrijving in

En hier is de viool .

SVG: de tekenvolgorde

Dit is iets dat frustrerend kan zijn: je maakt een visualisatie met D3.js maar de rechthoek die je bovenaan wilt hebben, is verborgen achter een andere rechthoek, of de lijn die je gepland had achter een cirkel te zijn, is er eigenlijk overheen. U probeert dit op te lossen met behulp van de z-index in uw CSS, maar het werkt niet (in SVG 1.1).

De uitleg is eenvoudig: in een SVG definieert de volgorde van de elementen de volgorde van het "schilderij" en bepaalt de volgorde van het schilderij wie er bovenaan komt.

Elementen in een SVG-documentfragment hebben een impliciete tekenvolgorde, waarbij de eerste elementen in het SVG-documentfragment eerst "geverfd" worden. Daaropvolgende elementen worden bovenop eerder geverfde elementen geschilderd.

Dus stel dat we deze SVG hebben:

<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>

Hij heeft vier cirkels. De blauwe cirkel is de eerste "geverfd", dus het zal alle andere balg zijn. Dan hebben we de gele, dan de rode en ten slotte de groene. De groene is de laatste en deze staat bovenaan.

Zo ziet het eruit:

voer hier de afbeeldingsbeschrijving in

De volgorde van SVG-elementen wijzigen met D3

Dus, is het mogelijk om de volgorde van de elementen te veranderen? Kan ik de rode cirkel voor de groene cirkel maken?

Ja. De eerste benadering die u in gedachten moet houden, is de volgorde van de regels in uw code: teken eerst de elementen van de achtergrond en later in de code de elementen van de voorgrond.

Maar we kunnen de volgorde van de elementen dynamisch wijzigen, zelfs nadat ze zijn geverfd. Er zijn verschillende eenvoudige JavaScript-functies die u kunt schrijven om dit te doen, maar D3 heeft al 2 leuke functies, selection.raise() en selection.lower() .

Volgens de API:

selection.raise (): voegt elk geselecteerd element opnieuw in volgorde in als het laatste kind van zijn ouder. selection.lower (): voegt elk geselecteerd element opnieuw in volgorde in als het eerste kind van het bovenliggende element.

Dus, om te laten zien hoe de volgorde van de elementen in onze vorige SVG te manipuleren, is hier een zeer kleine code:

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

Wat doet het? Het selecteert alle cirkels en, wanneer de gebruiker over één cirkel zweeft, selecteert hij die bepaalde cirkel en brengt deze naar voren. Erg makkelijk!

En hier is de JSFiddle met de live code.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow