2017-08-30 78 views
0

我想創建一個使用時間尺度(日期)作爲x軸的分歧條形圖。我在使用ScaleBands時遇到問題,日期標籤重疊。如何在d3 v4的scaleTime中使用rangeRound?

這就是我到目前爲止。 https://jsfiddle.net/14ch7yeo/當我使用scaleTime時,不幸的是,圖形不加載。

我需要在這個圖上使用縮放和筆刷。

<!DOCTYPE html> 
<meta charset="utf-8"> 
<svg width="960" height="500"></svg> 
<script src="https://d3js.org/d3.v4.min.js"></script> 
<script> 

var data = [{"Date":"2015-01-02T00:00:00.000Z","Buy":554646.5,"Sell":-406301.3547},{"Date":"2015-02-02T00:00:00.000Z","Buy":565499.5,"Sell":-673692.5697},{"Date":"2015-03-02T00:00:00.000Z","Buy":421954.5,"Sell":-571685.4629},{"Date":"2015-04-02T00:00:00.000Z","Buy":466242.0,"Sell":-457477.7121},{"Date":"2015-05-02T00:00:00.000Z","Buy":350199.7,"Sell":-579682.8772},{"Date":"2015-06-02T00:00:00.000Z","Buy":391035.1,"Sell":-338816.6205},{"Date":"2015-07-02T00:00:00.000Z","Buy":437644.6,"Sell":-502329.557},{"Date":"2015-08-02T00:00:00.000Z","Buy":291978.9,"Sell":-504067.0329},{"Date":"2015-09-02T00:00:00.000Z","Buy":360913.8,"Sell":-489519.6652},{"Date":"2015-10-02T00:00:00.000Z","Buy":505799.1,"Sell":-723353.7089},{"Date":"2015-11-02T00:00:00.000Z","Buy":510691.0,"Sell":-374061.8139},{"Date":"2015-12-02T00:00:00.000Z","Buy":527757.1,"Sell":-597800.0116},{"Date":"2016-01-02T00:00:00.000Z","Buy":564799.1,"Sell":-451779.1593},{"Date":"2016-02-02T00:00:00.000Z","Buy":336533.7,"Sell":-522601.1707},{"Date":"2016-03-02T00:00:00.000Z","Buy":460684.6,"Sell":-643556.0079999999},{"Date":"2016-04-02T00:00:00.000Z","Buy":428388.1,"Sell":-349216.2376},{"Date":"2016-05-02T00:00:00.000Z","Buy":525459.5,"Sell":-597258.4075},{"Date":"2016-06-02T00:00:00.000Z","Buy":677659.1,"Sell":-513192.107},{"Date":"2016-07-02T00:00:00.000Z","Buy":365612.8,"Sell":-287845.8089},{"Date":"2016-07-03T00:00:00.000Z","Buy":358775.2,"Sell":-414573.209}] 

var parseTime = d3.utcParse("%Y-%m-%dT%H:%M:%S.%LZ"); 

    data.forEach(d => { 
        d["Date"] = parseTime(d["Date"]); 

       }) 


var series = d3.stack() 
    .keys(["Buy", "Sell"]) 
    .offset(d3.stackOffsetDiverging) 
    (data); 

var svg = d3.select("svg"), 
    margin = {top: 20, right: 30, bottom: 30, left: 60}, 
    width = +svg.attr("width"), 
    height = +svg.attr("height"); 

var x = d3.scaleBand() 
    .domain(data.map(function(d) { return d['Date']; })) 
    .rangeRound([margin.left, width - margin.right]) 
    .padding(0.1); 

var y = d3.scaleLinear() 
    .domain([d3.min(series, stackMin), d3.max(series, stackMax)]) 
    .rangeRound([height - margin.bottom, margin.top]); 

var z = d3.scaleOrdinal() 
      .range(["green","red"]); 

svg.append("g") 
    .selectAll("g") 
    .data(series) 
    .enter().append("g") 
    .attr("fill", function(d) { return z(d.key); }) 
    .selectAll("rect") 
    .data(function(d) { return d; }) 
    .enter().append("rect") 
    .attr("width", x.bandwidth) 
    .attr("x", function(d) { return x(d.data["Date"]); }) 
    .attr("y", function(d) { return y(d[1]); }) 
    .attr("height", function(d) { return y(d[0]) - y(d[1]); }) 

svg.append("g") 
    .attr("transform", "translate(0,"+ (height-margin.top) + ")") 
    .call(d3.axisBottom(x)); 

svg.append("g") 
    .attr("transform", "translate(" + margin.left + ",0)") 
    .call(d3.axisLeft(y)); 

function stackMin(serie) { 
    return d3.min(serie, function(d) { return d[0]; }); 
} 

function stackMax(serie) { 
    return d3.max(serie, function(d) { return d[1]; }); 
} 

</script> 

回答

1

d3.scaleTime必須在多個方面區別對待。

規模不採取填充作爲參數:

var x = d3.scaleTime() 
    .domain(d3.extent(data, function(d) { return d.Date; })) 
    .rangeRound([margin.left, width - margin.right]); 

時間是連續的而不是離散的,因此條形的寬度需要手動計算爲比作爲rect屬性。我得到了這個工作,但也許你想要更優雅的東西:

.attr("width", width/series.length - 450) 
+0

謝謝,它的工作。你介意看看我發佈的這個問題嗎? https://stackoverflow.com/questions/45947715/how-to-draw-mirrored-x-axisinverted-bar-chart-in-d3。我認爲我接近解決我的問題。給我一些建議,用縮放和條形效果來實現這個圖。 –