iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 37
10
Modern Web

重新認識 JavaScript系列 第 33

重新認識 JavaScript 番外篇 (3) - 鐵人賽戰況分析

這篇其實跟 JavaScript 沒有太大關係,純粹是為了好玩才寫的。

因為在這篇的留言處
https://ithelp.ithome.com.tw/upload/images/20180109/20065504ndwcVuWTGI.png
看到有大大把爬好的資料提供出來,師父說拿到資料不畫是棒槌 於是手癢用 D3.js 寫著玩 XD

[註] 後續在 重新認識 JavaScript 番外篇 (5) - 鐵人賽戰況分析 II 還有持續更新


首先是目前戰況的分析
https://ithelp.ithome.com.tw/upload/images/20180109/20065504uC4FkZ9bFj.png

可以看到到目前爲止在 Day 20 奮戰的朋友佔大多數,因為這天剛好是最終開賽日。
換句話說,停在這天之前的朋友就算是被淘汰了 QQ


然後來調查一下大家都在哪天爆掉,意外發現好多人報名後一篇都沒寫...
https://ithelp.ithome.com.tw/upload/images/20180109/20065504ZDWCe6lFjR.png


把沒開賽的人去掉之後,可以看出在開賽前幾日就停掉的還是佔多數。
https://ithelp.ithome.com.tw/upload/images/20180109/20065504vQG57jS5vi.png

還有人撐到 Day 27 爆掉的 QQ

原始碼如下:

d3.json("http://ironmans.goodideas-studio.com/itHelp", function(error, json) {
  var data = json.topic['on going'];
  var f = json.topic.topics.filter( (d) => {
    return d.status !== "challenge";
  });

  var f_day = [];
  for( let i = 0; i < 30; i++ ){ f_day[i] = 0; }

  f.forEach( d => {
    d.day = isNaN( d.day ) ? 0 : d.day;
    f_day[ d.day ]++;
  })

  // 把未開賽的清掉
  f_day[0] = 0;

  var svg = d3.select('.svg');

  // 設定畫布尺寸 & 邊距
  var margin = 40,
      width = 960 - margin * 2,
      height = 460 - margin * 2;

  svg.attr({
    "width": width + margin,
    "height": height + margin * 2,
    "transform": "translate(" + margin + "," + margin + ")"
  });

  // x 軸比例尺
  var xScale = d3.scale.linear()
  .domain([-1, 31])
  .range([0, width]);

  // y 軸比例尺 給繪製矩形用
  var yScale = d3.scale.linear()
  .domain([0, 18])
  .range([0, height]);

  // y 軸比例尺 2 繪製座標軸用
  var yScale2 = d3.scale.linear()
  .domain([0, 18])
  .range([height, 0]);

  // x 軸
  var xAxis = d3.svg.axis()
  .scale(xScale)
  .orient("bottom")
  .ticks(31)
  .tickFormat(function(v) {
    return (v >= 0 && v < 31) ? v : '';
  });

  // y 軸
  var yAxis = d3.svg.axis()
  .scale(yScale2)
  .orient("left");

  var colors = d3.scale.category20c();

  // 繪製矩形
  svg.selectAll('.bar')
    .data(data)
    .enter()
    .append('g')
    .classed('bar', true)
    .append('rect')
    .attr({
    'x': function(d, i) {
      // console.log( d.day );
      return xScale(i) + 13;
    },
    'y': function(d, i) {
      return height - yScale(f_day[i]) + margin;
    },
    'width': '2%',
    'height': function(d, i) {
      return yScale(f_day[i]);
    },
    'fill': function(d, i) {
      return colors(i);
    }
  });

  // 繪製 x 軸
  svg.append("g")
    .attr({
    "class": "x axis",
    "transform": "translate(" + margin + "," + (height + margin) + ")",
  })
    .call(xAxis);

  // 繪製 y 軸
  svg.append("g")
    .attr({
    "class": "y axis",
    "transform": "translate(" + margin + ", " + margin + ")",
  })
    .call(yAxis);

  svg.append("text")
    .text('人數')
    .attr({
    x: 10,
    y: 20
  });

  svg.append("text")
    .text('日期')
    .attr({
    x: 880,
    y: 450
  });

  // 處理位移
  svg.selectAll('.bar').attr('transform', 'translate(' + width * 0.02 + ', 0)');
});

按慣例還是提供 JSBin 給大家玩: http://jsbin.com/dezuzojibi/1/edit?js,output
使用的版本是 D3 v3.5.6

還未完賽的朋友們請加油 XD


上一篇
重新認識 JavaScript 番外篇 (2) - 你所不知道的 pushState
下一篇
重新認識 JavaScript 番外篇 (4) - 台灣街景封面產生器 with Google map 街景
系列文
重新認識 JavaScript37

1 則留言

2
Howard
iT邦新手 5 級 ‧ 2018-01-09 11:08:07

我只是提供新鮮蔬菜的菜農
還要靠各位廚師大大變魔法端菜上桌了

我要留言

立即登入留言