D3.js學習(五)

上一節咱們已經學習瞭如何設置填充區域,其實理解了他的實現原理仍是很是簡單了。這一節中, 咱們主要學習多條曲線的繪製,以及給不一樣的曲線指定不一樣的縱座標。html

 

新的數據

因爲咱們要畫兩條曲線,因此咱們要在原來的基礎上新增一組測試數據,如今咱們的數據是這樣的:app

date    close    open
1-May-12    58.13    3.41
30-Apr-12    53.98    4.55
27-Apr-12    67.00    6.78
26-Apr-12    89.70    7.85
25-Apr-12    99.00    8.92
24-Apr-12    130.28    9.92
23-Apr-12    166.70    10.13
20-Apr-12    234.98    12.23
19-Apr-12    345.44    13.45
18-Apr-12    443.34    16.04
17-Apr-12    543.70    18.03
16-Apr-12    580.13    21.02
13-Apr-12    605.23    22.34
12-Apr-12    622.77    20.15
11-Apr-12    626.20    21.26
10-Apr-12    628.44    31.04
9-Apr-12    636.23    35.04
5-Apr-12    633.68    41.02
4-Apr-12    624.31    43.05
3-Apr-12    629.32    46.03
2-Apr-12    618.63    51.03
30-Mar-12    599.55    53.42
29-Mar-12    609.86    57.82
28-Mar-12    617.62    59.01
27-Mar-12    614.48    56.03
26-Mar-12    606.98    58.01

咱們把data-close做爲一個數據集,把data-open做爲一個數據集。如今咱們把這些數據存在文件data2.tsv中,並將文件導入:
//Get the data
  d3.tsv("../data/data2.tsv", function(error, data){
    data.forEach(function(d){
      d.date = parseDate(d.date);
      d.close = +d.close;
      d.open = +d.open;
    });
在這裏須要注意的是,記得要作一個數據的轉換,確保d.open中存儲的是一個數字!

定義新的曲線

像前面定義曲線同樣,咱們定義次日曲線的時候徹底能夠按照定義第一條曲線的方法進行定義:dom

//定義線條2
  var valueline2 = d3.svg.line()
    .interpolate("basis")
    .x(function(d){ return x(d.date) })
    .y(function(d){ return y(d.open) });

 

繪製新的曲線

爲了區別於第一條曲線,咱們給新的曲線添加一個樣式,把它變成搶眼的紅色:svg

//繪製線條2
    svg.append("path")
      .attr("class", "line")
      .style("stroke", "red")
      .attr("d", valueline2(data));

 

這樣,咱們的曲線就繪製成功啦,效果以下:
image學習

 

改進

雖然咱們已經把圖形繪製出來,可是,咱們的代碼仍是不完善的,比方說,若是個人d.open有個值很是很是大,他比d.close中的任何一個值都要大不少,那麼咱們圖形繪製出來會變成什麼效果呢?
image測試

紅色線條是否是跑到畫布外面去了!也就是說咱們的畫布已經沒法容納這個最大的d.open值了,由於咱們以前設置y軸的規模(domain)時用的是d.close的最大值:spa

 y.domain([0, d3.max(data, function(d){
      return d.close;
    })]);


因此,咱們要對它進行一個改進,咱們要取兩組值中的最大值:3d

y.domain([0, d3.max(data, function(d){
      return Math.max(d.close, d.open);
    })]);
這樣,咱們就解決了圖像超出畫布的問題了,不過咱們的數據怎麼變化,都是適應的:

image

兩條縱座標軸

仔細觀察原來的數據,咱們會發現,d.open的值相對於d.close的取發展趨勢更加平穩。可是,若是咱們要更好的體現它的細節(也就是把趨勢放大)的話改怎麼作呢?很簡單,給他們設置不一樣的座標軸!code

//定義座標軸的範圍
 
  var x = d3.time.scale().range([0, width]);
  var y = d3.scale.linear().range([height, 0]);
  var y2 = d3.scale.linear().range([height, 0]);

y跟y2的範圍(也就是像素高)應該是同樣的。咱們把y2的tick標籤放在右邊,這樣看起來會更對稱:orm

//定義座標軸
  var xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(5);
  var yAxis = d3.svg.axis().scale(y).orient("left").ticks(5);
  var y2Axis = d3.svg.axis().scale(y2).orient("right").ticks(5);

如今,咱們還須要修改一下咱們的valueline,讓valueline2使用y2做爲縱軸方向的基準:

//定義線條1
  var valueline = d3.svg.line()
    .interpolate("basis")
    .x(function(d){return x(d.date);})
    .y(function(d){return y(d.close);});
  //定義線條2
  var valueline2 = d3.svg.line()
    .interpolate("basis")
    .x(function(d){ return x(d.date) })
    .y(function(d){ return y2(d.open) });

同時,咱們還要給他們設置不一樣的規模:

//Scale(規模) the range of the data
    x.domain(d3.extent(data, function(d){
      return d.date;
    }));
    y.domain([0, d3.max(data, function(d){
      return d.close;
    })]);
    y2.domain([0, d3.max(data, function(d){
      return d.open;
    })]);

最後,咱們再來繪製它們!

//繪製x座標軸
svg.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + height + ")")
  .call(xAxis);
//繪製y座標軸
svg.append("g")
  .attr("class", "y axis")
  .call(yAxis);
//繪製y2座標軸
svg.append("g")
  .attr("class", "y axis")
  .attr("transform", "translate(" + width + ", 0)")
  .style("fill", "red")
  .call(y2Axis);

最後的效果以下:
image

 

下一節,咱們將學習如何x軸的tick標籤不少的狀況下,如何旋轉標籤,使他們更便於閱讀!

相關文章
相關標籤/搜索