2014-01-05 78 views
2

第一次使用D3.js.我堅持讓條形圖在條上顯示數值標籤,並在刷新數據時轉換x/y軸。我沒有收到任何錯誤,代碼來自於將幾個例子放在一起。代碼如下,jfiddle here工作示例。在真正的代碼中,我使用d3.json來拉取數據,在jsfiddle中我使用了靜態變量fyi。任何幫助表示讚賞。下面D3.js條形圖 - 軸和標籤不工作/正在轉換

代碼:

var data; 

var margin = { 
    top: 20, 
    right: 0, 
    bottom: 30, 
    left: 30 
}, 
width = 838 - margin.left - margin.right, 
    height = 300 - margin.top - margin.bottom; 

var x = d3.scale.ordinal() 
    .rangeRoundBands([0, width], 0.05); 

var y = d3.scale.linear() 
    .range([height, 0]); 

var xAxis = d3.svg.axis() 
    .scale(x) 
    .orient("bottom"); 

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

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


d3.json("http://10.0.0.13/sma/sma-php/inverterdata.php?var=CDAY&id=C1200031", function (error, data) { 
data.forEach(function (d) { 
    d.max_energy = +d.max_energy; 
}); 

x.domain(data.map(function (d) { 
    return d.xaxis; 
})); 
y.domain([0, d3.max(data, function (d) { 
    return d.max_energy; 
})]); 

svg.append("g") 
    .attr("class", "x axis") 
    .attr("transform", "translate(0," + height + ")") 
    .call(xAxis) 
    .append("text") 
    .attr("transform", "rotate(0)") 
    .attr("y", 23) 
    .attr("x", 340) 
    .attr("dy", ".71em") 
    .style("text-anchor", "bottom") 
    .text("Timeline"); 

svg.append("g") 
    .attr("class", "y axis") 
    .call(yAxis) 
    .append("text") 
    .attr("transform", "rotate(0)") 
    .attr("y", -15) 
    .attr("x", -25) 
    .attr("dy", ".71em") 
    .style("text-anchor", "top") 
    .text("Energy - KWh"); 

svg.selectAll(".bar") 
    .data(data) 
    .enter().append("rect") 
    .attr("class", "bar") 
    .attr("x", function (d) { 
    return x(d.xaxis); 
}) 
    .attr("width", x.rangeBand()) 
    .attr("y", function (d) { 
    return y(d.max_energy); 
}) 
    .transition().delay(function (d, i) { 
    return i * 10; 
}).duration(10) 
    .attr("height", function (d) { 
    return height - y(d.max_energy); 
}); 

//Create labels 
svg.selectAll("text") 
    .data(data) 
    .enter() 
    .append("text") 
    .text(function (d) { 
    return parseFloat(Math.round(d.max_energy * 100)/100).toFixed(1); 
}) 
    .attr("x", function (d) { 
    return x(d.xaxis) + x.rangeBand()/2; 
}) 
    .attr("y", function (d) { 
    return height - y(d.max_energy) + 14; 
}) 
    .attr("text-anchor", "middle") 
    .attr("font-family", "sans-serif") 
    .attr("font-size", "11px") 
    .attr("fill", "black"); 

//}); 

//On click, update with new data    
d3.select("p").on("click", function() { 

    // Get the data again 
     d3.json("http://10.0.0.13/sma/sma-php/inverterdata.php?var=PDAY&id=P100023", function (error, data) { 
    data.forEach(function (d) { 
     d.max_energy = +d.max_energy; 
    }); 

    // Scale the range of the data again 
    x.domain(data.map(function (d) { 
     return d.xaxis; 
    })); 
    y.domain([0, d3.max(data, function (d) { 
     return d.max_energy; 
    })]); 

    // Make the changes 
    svg.selectAll(".bar") // change the bar 
    .data(data) // Update the data within. 
    .transition().delay(function (d, i) { 
     return i/data.length * 1000; 
    }) 
     .duration(500) 
     .attr("x", function (d) { 
     return x(d.xaxis); 
    }) 
     .attr("y", function (d) { 
     return y(d.max_energy); 
    }) 
     .attr("width", x.rangeBand()) 
     .attr("height", function (d) { 
     return height - y(d.max_energy); 
    }); 

    //Update all labels 
    svg.selectAll("text") 
     .data(data).transition() 
     .delay(function (d, i) { 
     return i/data.length * 1000; 
    }) 
     .duration(500) 
     .text(function (d) { 
     return parseFloat(Math.round(d.max_energy * 100)/100).toFixed(1); 
    }) 
     .attr("x", function (d, i) { 
     return x(i) + x.rangeBand()/2; 
    }) 
     .attr("y", function (d) { 
     return height - y(d.max_energy) + 24; 
    }); 

    }); 

}); 

HTML:

<p>CLICK ME</p> 
<svg id="daychart"></svg> 

回答

2

它比你想象的其實更容易。你只需要再次調用軸功能:

svg.select("g.x").call(xAxis); 
svg.select("g.y").call(yAxis); 

更改的jsfiddle here

要讓標籤起作用,您可以爲這些text元素指定一個特定的類並進行相應的選擇。默認情況下,D3會根據索引匹配元素。也就是說,在通過調用軸添加軸標籤後,將選擇這些軸並與數據匹配。因此,.enter()選擇將是空的,不添加新的標籤。

Jsfiddle以及here

+0

拉斯您好,感謝!你的JFiddle鏈接雖然不起作用。另外,爲什麼我的條形圖標籤不顯示?謝謝! – TheRealPapa

+0

哎呀,對不起。不知道哪裏出了問題 - 鏈接固定。不確定你想要什麼類型的標籤 - 就像[本教程](http://bost.ocks.org/mike/bar/)中的東西? –

+0

嗨拉爾斯,再次感謝!是的,這是我從代碼中提取代碼的教程,但不幸的是,欄上的值標籤不起作用。我想將這個值放在每個小節的頂部。非常感謝您花時間! – TheRealPapa

2

對於你的問題的第二部分:

,因爲你只是使用selectAll("text")抓住他們將標籤無法正確顯示了。問題在於,座標軸上的刻度標籤也是文本元素,所以它們被選中並分配了數據 - 但不包含在「輸入」中。這也是爲什麼當您更新數據時軸標籤移出屏幕的原因(因爲在這種情況下,您正在設置所有元素的屬性,而不僅僅是新元素)。

要解決:添加類酒吧標籤,並用它來選擇它們具體是:

svg.selectAll("text.barLabels") //use this selector in your update as well 
    .data(data) 
    .enter() 
    .append("text") 
    .classed("barLabels", true) //remember to actually add the class! 

它現在應該所有的工作......幾乎。

你也許可以自己弄清楚這一點,但是你的標籤y-定位功能沒有考慮到你使用的是反轉比例的事實,所以標籤都以奇怪的位置結束了。你還需要改變

.attr("y", function (d) { 
    return height - y(d.max_energy) + 24; 
}); 

.attr("y", function (d) { 
    return y(d.max_energy) + 24; 
}) 

.attr("y", function (d) { 
    return Math.min(y(d.max_energy) + 24, height); 
}) 

讓 「0.0」 的標籤沒有被定位超出軸線;或者甚至

.attr("y", function (d,i) { 
    return Math.min(y(d.max_energy) + 24*(1+i%2), height); 
}) 

因此如果相鄰標籤對於條太寬而不相互重疊。 (對於偶數,i%2只返回0,奇數返回1;模運算符%從整數除法返回「餘數」。)

的最後一個版本就是我來到這裏實現:http://jsfiddle.net/h8Rsg/40/

+0

嗨阿米莉亞,謝謝你的建議!真棒幫助! – TheRealPapa