2017-03-11 5 views
0

Ich versuche, diese Figur mit D3.js neu zu erstellen, aber ich habe ein paar Probleme.Ordinal Streudiagramm in D3

this

Ich bin sehr neu zu D3 und ich habe nicht in der Lage gewesen Beispiele für Scatterplots mit Ordinalwerte zu finden. Ich habe auch Probleme, sowohl positive als auch negative Werte auf der y-Achse einzubeziehen. Ich kam ziemlich nah bei einem Balkendiagramm-Beispiel, aber die Punkte sind nicht zentriert über die Achsen-Ticks und negative Werte fehlen in der Figur insgesamt.

my attempt

Ich verwende Daten für diese aus, aber die Punkte sollen auf den „Wert“ sein, und die Linie soll für jeden Phänotyp von min bis max gehen. Offensichtlich gibt es mehrere Probleme mit meinem Ansatz.

Wenn mir jemand auf ein Beispiel zeigen kann, das etwas ähnliches tut, würde es sehr geschätzt werden.

<script> 

var margin = {top: 20, right: 20, bottom: 70, left: 40}, 
    width = 600 - margin.left - margin.right, 
    height = 300 - margin.top - margin.bottom ; 
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05); 
var y = d3.scale.linear().range([height, 0]); 
var xAxis = d3.svg.axis() 
    .scale(x) 
    .orient("middle"); 

var yAxis = d3.svg.axis() 
    .scale(y) 
    .orient("left") 
    .ticks(4); 

var svg = d3.select("#cluster_".concat("{{ n }}")).append("svg") 
    .attr("width", width + margin.left + margin.right) 
    .attr("height", height + margin.top + margin.bottom) 
    .append("g") 
    .attr("transform", 
      "translate(" + margin.left + "," + margin.top + ")"); 

var plot_data = [ 
    [{Phenotype: 'TG', value: 0.01, min: -0.1, max: 0.4}, 
    {Phenotype: 'LDL', value: -0.29, min: -0.5, max: -0.1}, 
    {Phenotype: 'HDL', value: 0.41, min: 0.0, max: 0.5}, 
    {Phenotype: 'TC', value: 0.07, min: -0.2, max: 0.4}]]; 

plot_data.forEach(function(data){ 
    x.domain(data.map(function(d) { return d.Phenotype; })); 
    y.domain([0, d3.max(data, function(d) { return d.value; })]); 

    svg.append("g") 
     .attr("class", "x axis") 
     .attr("transform", "translate(0," + height + ")") 
     .call(xAxis) 
    .selectAll("text") 
     .style("text-anchor", "end") 
     .attr("dx", "-.8em") 
     .attr("dy", "-.55em") 
     .attr("transform", "rotate(-90)"); 

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

    svg.selectAll("scatter-dots") 
     .data(data) 
    .enter().append("svg:circle") 
     .style("fill", "steelblue") 
     .attr("cx", function(d) { return x(d.Phenotype); }) 

     .attr("cy", function(d) { return y(d.value); }) 
     .attr("r", 8); 

    svg.selectAll("bar") 
     .data(data) 
     .enter().append("rect") 
     .style("fill", "steelblue") 
     .attr("x", function(d) { return x(d.Phenotype); }) 
     .attr("width", 1) 
     .attr("y1", function(d) { return y(d.min); }) 
     .attr("y2", function(d) { return y(d.max); }) 
     .attr("height", function(d) { return Math.abs(y(d.max) - y(d.min));}); 
</script> 

Similar issues wurden, bevor geschrieben, aber offenbar nicht gelöst werden.

+0

Dies ist ** nicht ** ein Arbeitscode. Bitte schreiben Sie den Code, der das zweite Bild erstellt hat, damit wir nur die Positionierung der x-Achse und die negativen Werte behandeln können. –

Antwort

1

Sie haben ein paar Dinge, die behoben werden müssen, aber Sie sind auf dem richtigen Weg. Ich schlage vor, Sie schauen sich einige der guten Ressourcen online an. Insbesondere https://leanpub.com/D3-Tips-and-Tricks.

  1. Ihre plot_data Array sollte ein Array von Objekten, anstatt ein Array mit einem Array sein.

  2. Diese Schleife ist nicht notwendig - einer der Punkte von d3 ist, dass es „verbindet“, dass in vielen Fällen tritt an die Stelle von Schleifen:

    plot_data.forEach(function(data){...}

Werfen Sie einen Blick auf diese fiddle - jsfiddle ist ein großartiger Ort, um mit Code zu experimentieren und das Projekt langsam zu lernen und aufzubauen.

https://jsfiddle.net/sanandak/8h7hzyw5/1/

Hmm .. Stackoverflow hat es jetzt eigene "Geige" -ähnlichen Fähigkeit ist! Hier ist der gleiche Code ...

var svg = d3.select('body').append('svg') 
 
svg.attr('width', 300).attr('height', 300) 
 

 
svg.append('g').attr('class', 'axis x-axis') 
 
svg.append('g').attr('class', 'axis y-axis') 
 

 
var plot_data = [ 
 
    {Phenotype: 'TG', value: 0.01, min: -0.1, max: 0.4}, 
 
    {Phenotype: 'LDL', value: -0.29, min: -0.5, max: -0.1}, 
 
    {Phenotype: 'HDL', value: 0.41, min: 0.0, max: 0.5}, 
 
    {Phenotype: 'TC', value: 0.07, min: -0.2, max: 0.4}]; 
 
    
 
var xScale = d3.scalePoint() 
 
\t .domain(['TG', 'LDL', 'HDL', 'TC']) 
 
    .range([30,290]) 
 
    
 
var yScale = d3.scaleLinear() 
 
\t .domain([-1, 1]) 
 
    .range([290, 30]) 
 
    
 
var xAxis = d3.axisBottom(xScale); 
 
var yAxis = d3.axisRight(yScale); 
 

 
svg.select('.x-axis').call(xAxis); 
 
svg.select('.y-axis').call(yAxis); 
 
    
 
var circles = svg.append('g') 
 
\t .selectAll('.circle') 
 
    .data(plot_data) 
 
    .enter() 
 
    .append('circle') 
 
    .attr('class', 'circle') 
 
    .attr('cx', function(d) {return xScale(d.Phenotype);}) 
 
    .attr('cy', function(d) {return yScale(d.value);}) 
 
    .attr('r', 5) 
 
    .attr('fill', 'red') 
 
    
 
var eWidth = 2; 
 
var errbars = svg.append('g') 
 
\t .selectAll('.errbars') 
 
\t .data(plot_data) 
 
    .enter() 
 
    .append('rect') 
 
    .attr('class', 'errbars') 
 
    .attr('x', function(d) {return xScale(d.Phenotype) - eWidth/2;}) 
 
    .attr('y', function(d) {return yScale(d.max);}) 
 
    .attr('width', eWidth) 
 
    .attr('height', function(d) {return yScale(d.min) - yScale(d.max);})
<script src="//d3js.org/d3.v4.min.js"></script>

Verwandte Themen