
今回は、セントラル短資FX データダウンロードからCSVデータを取得して、日足チャートを表示する方法を紹介します。
※公開を目的としたアプリから直接データを取得する場合、予めデータ提供サイトに利用許可など確認する必要があります。
XMLHttpRequest()を利用してCSVデータを取得します。
CSVデータはShift-JISなのでUTF-8に文字コードを変換する必要がありますが、ヘッダー部の文字化けが発生するだけなので、変換せずに処理を行っています。
index.html
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52  | 
						<!DOCTYPE HTML> <html> <head>   <meta charset="utf-8">   <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover">   <meta http-equiv="Content-Security-Policy" content="default-src * data: gap: https://ssl.gstatic.com; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'">   <script src="components/loader.js"></script>   <script src="lib/onsenui/js/onsenui.min.js"></script>   <script src="js/moment.min.js"></script>   <script src="js/d3.min.js"></script>   <script src="js/d3chart.js"></script>   <script src="js/app.js"></script>   <link rel="stylesheet" href="components/loader.css">   <link rel="stylesheet" href="lib/onsenui/css/onsenui.css">   <link rel="stylesheet" href="lib/onsenui/css/onsen-css-components.css">   <link rel="stylesheet" href="css/style.css"> </head> <body>   <ons-page>     <ons-toolbar>       <div id="title" class="center">D3.js</div>     </ons-toolbar>     <ons-list>       <ons-list-item>         <div class="segment" style="width: 320px; margin: 0 auto;">           <div class="segment__item">             <input type="radio" class="segment__input" name="pear" onclick="getCsvData('USDJPY')" checked>             <div class="segment__button">USDJPY</div>           </div>           <div class="segment__item">             <input type="radio" class="segment__input" name="pear" onclick="getCsvData('EURJPY')" >             <div class="segment__button">EURJPY</div>           </div>           <div class="segment__item">             <input type="radio" class="segment__input" name="pear" onclick="getCsvData('EURUSD')" >             <div class="segment__button">EURUSD</div>           </div>           <div class="segment__item">             <input type="radio" class="segment__input" name="pear" onclick="getCsvData('GBPJPY')" >             <div class="segment__button">GBPJPY</div>           </div>           <div class="segment__item">             <input type="radio" class="segment__input" name="pear" onclick="getCsvData('GBPUSD')" >             <div class="segment__button">GBPUSD</div>           </div>         </div>       </ons-list-item>     </ons-list>     <div id="chart"></div>   </ons-page> </body>> </html>  | 
					
style.css
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32  | 
						#chart {   width: 100%;   height: 240px; } #d3-chart {   background-color: #000; } .axis text {   font-size: 9px;   color: #fff; } .axis path, .axis line {   fill: none;   stroke: #ccc;   stroke-width: 1px; } .tick line {   opacity: 0.3;   stroke-width: 1px; } /* candlestick */ .candlestick-yosen {   fill: #f00;   stroke: #f00;   stroke-width: 1px; } .candlestick-insen {   fill: #0ff;   stroke: #0ff;   stroke-width: 1px; }  | 
					
app.js
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57  | 
						"use strict"; var data = [];  // 日足データ var getCsvData = function (pear) {   var index = "";   var req = new XMLHttpRequest();   switch (pear) {     case "USDJPY":       index = "01";       break;     case "EURJPY":       index = "02";       break;     case "EURUSD":       index = "03";       break;     case "GBPJPY":       index = "04";       break;     case "GBPUSD":       index = "05";       break;     default:   }   if (index == "") return;   req.open("GET","https://info.ctfx.jp/service/market/csv/" + index + "_" + pear + "_D.csv");   req.onload = function () {     var csv = req.responseText;     var row = csv.split("\n");     var col = [];     var date = null;     var i = 0;     // 日足データ初期化     data = [];     for (i = row.length - 1; i > 0; i--) {       if (row[i].length > 0) {         // カンマで分割する         col = row[i].match(/[^,]+/g);         // 日付をYYYY/MM/DDからYYYYMMDDに変換する         date = moment(col[1], "YYYY/MM/DD").format("YYYYMMDD");         // 日足データ追加         data.push([date, Number(col[2]), Number(col[3]), Number(col[4]), Number(col[5])]);       }     }     if (data.length > 0) {       document.getElementById("title").innerHTML = "D3.js " + pear + " 日足";       showChart(pear);     }   };   req.send(null); }; var showChart = function (pear) {   var month = data.slice(data.length - 30);   window.fn.chart.createChart("chart", pear, month); }; ons.ready(function () {   getCsvData("USDJPY"); });  | 
					
d3chart.js
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126  | 
						"use strict"; //************************************************************ // module: d3chart.js // author: otak-lab // use: d3.min.js //************************************************************ if (!window.hasOwnProperty("fn")) {   window.fn = {}; } window.fn.chart = {}; //************************************************************ // create candlestick chart //************************************************************ window.fn.chart.createChart = function (id, pear, data) {   var elem = document.getElementById(id);   if (!elem) return;   if (data.length == 0) return;   // margin   var margin = {     top: 10, right: 45, bottom: 25, left: 10   };   // width, height   var w = elem.clientWidth - (margin.left + margin.right);   var h = elem.clientHeight - (margin.top + margin.bottom);   // min, max   var min = Math.min.apply(null, data.map(function (d) { return Math.min(d[2], d[3]); }));   var max = Math.max.apply(null, data.map(function (d) { return Math.max(d[2], d[3]); }));   // y   var y = d3.scaleLinear()     .domain([min, max])     .nice()     .range([h, 0]);   // x   var x = d3.scaleBand()     .domain(data.map(function (d) {       return d[0];     }))     .range([0, w]);   // adjust line x positon   var pos = (x(data[1][0]) - x(data[0][0])) / 2;   // axis   var yAxis = d3.axisRight(y)     .tickSizeInner(-w)     .tickSizeOuter(0)     .tickPadding(4)     .tickFormat(function (d) {       return (pear.search(/JPY/) == -1) ? d3.format(".5f")(d) : d3.format(".3f")(d);     })     .ticks(7);   var yRange = yAxis.scale().domain();   var xAxis = d3.axisBottom(x)     .tickValues(x.domain())     .tickSizeInner(-h)     .tickSizeOuter(0)     .tickPadding(8)     .tickFormat(function (d, i) {       var result = Number(d.substr(6, 2)).toString();       if ((i % 3) == 0) {         result = Number(d.substr(4, 2)).toString() + "/" + result;       } else {         result = null;       }       return result;     });   var xRange = xAxis.scale().domain();   // remove chart   d3.select("#d3-chart").remove();   // create svg   var svg = d3.select(elem)     .append("svg")     .attr("id", "d3-chart")     .attr("width", elem.clientWidth.toString())     .attr("height", elem.clientHeight.toString())     .append("g")     .attr("transform", "translate(" + margin.left.toString() + ", " + margin.top.toString() + ")");   // create x   svg.append("g")     .attr("class", "axis")     .attr("transform", "translate(0, " + h.toString() + ")")     .call(xAxis);   // create y   svg.append("g")     .attr("class", "axis")     .attr("transform", "translate(" + w.toString() + ", 0)")     .call(yAxis);   // candlestick body   var cbw = Math.abs(x(xRange[1]) - x(xRange[0])) - 3;   var cb = svg.selectAll("rect.b")     .data(data)     .enter()     .append("rect");   cb.attr("class", function (d) {     var cl = "candlestick-yosen";     if (d[1] > d[4]) {       cl = "candlestick-insen";     }     return cl;   })     .attr("x", function (d) { return (x(d[0]) + pos - (cbw / 2)); })     .attr("y", function (d) { return y((d[1] > d[4]) ? d[1] : d[4]); })     .attr("width", cbw)     .attr("height", function (d) {       var top = (d[1] > d[4]) ? d[1] : d[4];       var bottom = (d[1] > d[4]) ? d[4] : d[1];       var diff = Math.abs(y(top) - y(bottom));       if (diff == 0) diff = 0.1;       return diff;     });   // candlestick shadow   var csw = 0.5;   var cs = svg.selectAll("rect.s")     .data(data)     .enter()     .append("rect");   cs.attr("class", function (d) {     var cl = "candlestick-yosen";     if (d[1] > d[4]) {       cl = "candlestick-insen";     }     return cl;   })     .attr("x", function (d) { return (x(d[0]) + pos - (csw / 2)); })     .attr("y", function (d) { return y(d[2]); })     .attr("width", csw)     .attr("height", function (d) { return Math.abs(y(d[2]) - y(d[3])); }); };  | 
					
各通貨のセグメントをタップすると、日足のCSVデータを取得してチャートを表示します。
 
 
 
 
![]()  | 
 FX チャートリーディング マスターブック ~為替のプロが実践する本当に勝てるワザを大公開! 新品価格  | 
![]()





