2016-12-16 4 views
2

Ich erstelle ein Balkendiagramm mit d3.js. Oben auf jeder Leiste zeige ich Text an. Wenn der Benutzer über die Leiste schwebt, sollte er den Text anzeigen. Wenn sie sich bewegen, verschwindet der Text. Um das zu tun, muss ich die <text> und <rect> Elemente innerhalb eines <g> Elements gruppieren.Gruppe jedes Rect und Text in D3

Beispiel

<g class="gbar"> 
    <rect x="0" y="50" width="10" height="50" /> 
    <text x="15" y="40">A</text> 
</g> 
<g class="gbar"> 
    <rect x="11" y="75" width="10" height="25" /> 
    <text x="16" y="65">B</text> 
</g> 
<g class="gbar"> 
    <rect x="22" y="25" width="10" height="75" /> 
    <text x="27" y="35">C</text> 
</g> 

Also diese Weise kann ich eine .gbar:hover rect, .gbar:hover text { ... } CSS-Stil machen die Farbe und die Opazität der beiden <rect> und <text> Elemente zu ändern. Wie kann ich für jedes Datenelement die <rect> und <text> Elemente in ein <g> Element mit d3.js setzen?

Dank

EDIT: Um mehr Kontext hinzufügen, das ist, was habe ich bisher ...

var svg = d3.select('.mygraph') 
      .append('svg') 
      .attr('height', 100); 

svg.selectAll('rect') 
    .data(dataSet) 
    .enter() 
    .append('rect') 
    .attr('x', calcX) 
    .attr('y', calcY) 
    .attr('width', 10) 
    .attr('height', calcH); 

svg.selectAll('text') 
    .data(dataSet) 
    .enter() 
    .append('text') 
    .text(function (d) { 
     return d.Text; 
    }) 
    .attr('x', textX) 
    .attr('y', textY); 

Dieser Code erzeugt:

<svg> 
    <rect x="0" y="50" width="10" height="50" /> 
    <rect x="11" y="75" width="10" height="25" /> 
    <rect x="22" y="25" width="10" height="75" /> 
    <text x="15" y="40">A</text> 
    <text x="16" y="65">B</text> 
    <text x="27" y="35">C</text> 
</svg> 

Ich bin sehr still neu zu d3.js.

+2

was d3 Code haben Sie bisher? –

Antwort

4

Dies ist der Standardansatz.

Zuerst fügen Sie die <g> Elemente eine „Eingabe“ Auswahl mit:

var groups = svg.selectAll(".groups") 
    .data(dataset) 
    .enter() 
    .append("g") 
    .attr("class", "gbar"); 

Dann verwenden Sie diese Auswahl sowohl Ihre Rechtecke und Ihre Texte anhängen:

groups.append('rect') 
    .attr('x', calcX) 
    .attr('y', calcY) 
    .attr('width', 10) 
    .attr('height', calcH); 

groups.append('text') 
    .text(function (d) { 
     return d.Text; 
    }) 
    .attr('x', textX) 
    .attr('y', textY); 

tun, dass Ihre Rechtecke und Texte werden, jedes Paar, innerhalb desselben <g> Elements.

Hier ist eine einfache Demo (ein sehr einfacher Code, voller magischer Zahlen). Bewegen Sie die Maus über die Balken oder die Texte:

var data = d3.range(8).map(()=>~~(Math.random()*130)); 
 

 
var svg = d3.select("svg") 
 

 
var groups = svg.selectAll(".groups") 
 
\t .data(data) 
 
\t .enter() 
 
\t .append("g") 
 
    .attr("class", "gbar"); 
 
\t 
 
groups.append("rect") 
 
\t .attr("x", (d,i)=> i*40) 
 
\t .attr("width", 20) 
 
\t .attr("y", d=> 150 - d) 
 
\t .attr("height", d=> d) 
 
\t .attr("fill", "teal"); 
 
\t 
 
groups.append("text") 
 
\t .attr("x", (d,i)=> i*40) 
 
\t .attr("y", d=> 145 - d) 
 
\t .text(d=>d)
.gbar:hover rect{ 
 
    fill:brown; 
 
    } 
 

 
.gbar:hover text{ 
 
    fill:brown; 
 
    font-weight:700; 
 
    }
<script src="https://d3js.org/d3.v4.min.js"></script> 
 
<svg></svg>

Wenn Sie das SVG erstellt durch diese Schnipsel untersuchen, ist es das, was Sie bekommen:

<g class="gbar"> 
    <rect x="0" width="20" y="142" height="8" fill="teal"></rect> 
    <text x="0" y="137">8</text> 
</g> 
<g class="gbar"> 
    <rect x="40" width="20" y="136" height="14" fill="teal"></rect> 
    <text x="40" y="131">14</text> 
</g> 
<g class="gbar"> 
    <rect x="80" width="20" y="89" height="61" fill="teal"></rect> 
    <text x="80" y="84">61</text> 
</g> 
//etc... 
1

I-Gruppe "g" verwenden Um mit diesem Problem umzugehen: Jedes Paar Balken und Label wird in einer Gruppe gespeichert. Jedes Mal, wenn Sie auf eine Gruppe klicken, führen Sie die Sortierfunktion sowohl auf dem Etikett als auch auf der Leiste aus.

var w = 600; 
 
var h = 250; 
 

 
var dataset = [ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13, 
 
\t \t \t \t 11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ]; 
 

 
var xScale = d3.scale.ordinal() 
 
\t \t \t \t .domain(d3.range(dataset.length)) 
 
\t \t \t \t .rangeRoundBands([0, w], 0.05); 
 

 
var yScale = d3.scale.linear() 
 
\t \t \t \t .domain([0, d3.max(dataset)]) 
 
\t \t \t \t .range([0, h]); 
 

 

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

 

 
var groups = svg.selectAll("g") 
 
     .data(dataset) 
 
     .enter() 
 
     .append("g"); 
 

 

 
groups.append("rect") 
 
    .attr("x", function(d, i) { 
 
    \t \t return xScale(i); 
 
    }) 
 
    .attr("y", function(d) { 
 
    \t \t return h - yScale(d); 
 
    }) 
 
    .attr("width", xScale.rangeBand()) 
 
    .attr("height", function(d) { 
 
    \t \t return yScale(d); 
 
    }) 
 
    .attr("fill", function(d) { 
 
\t \t return "rgb(0, 0, " + (d * 10) + ")"; 
 
    }) 
 
    .on("mouseover", function() { 
 
    \t \t d3.select(this) 
 
    \t \t \t .attr("fill", "orange"); 
 
    }) 
 
    .on("mouseout", function(d) { 
 
\t d3.select(this) 
 
\t  \t \t .transition() 
 
\t  \t \t .duration(250) 
 
\t \t \t .attr("fill", "rgb(0, 0, " + (d * 10) + ")"); 
 
    }) 
 
    ; 
 

 

 
groups.append("text") 
 
    .text(function(d) { 
 
     return d; 
 
    }) 
 
    .attr("text-anchor", "middle") 
 
    .attr("x", function(d, i) { 
 
     return xScale(i) + xScale.rangeBand()/2; 
 
    }) 
 
    .attr("y", function(d) { 
 
     return h - yScale(d) + 14; 
 
    }) 
 
    .attr("font-family", "sans-serif") 
 
    .attr("font-size", "11px") 
 
    .attr("fill", "white"); 
 
    groups.on("click", function(){ 
 
     sortBars(); 
 
    }) 
 
    ; 
 

 

 
var sortBars = function() { 
 
    svg.selectAll("rect") 
 
    .sort(function(a, b) { 
 
     return d3.ascending(a, b); 
 
     }) 
 
    .transition() 
 
    .duration(1000) 
 
    .attr("x", function(d, i) { 
 
     return xScale(i);}); 
 

 

 
    svg.selectAll("text") 
 
    .sort(function(a, b) { 
 
     return d3.ascending(a, b); 
 
     }) 
 
    .transition() 
 
    .duration(1000) 
 
    .attr("x", function(d, i) { 
 
     return xScale(i) + xScale.rangeBand()/2; 
 
    }); 
 

 
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>