//廖雪峯的博客的這個教程的答案//https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/00143449990549914b596ac1da54a228a6fa9643e88bc0c000#0 var canvas = document.getElementById('stock-canvas'), width = canvas.width, height = canvas.height, ctx = canvas.getContext('2d'); console.log(JSON.stringify(data[0])); // {"date":"20150602","open":4844.7,"close":4910.53,"high":4911.57,"low":4797.55,"vol":62374809900,"change":1.69} ctx.clearRect(0, 0, width, height); //已知函數傳進來的data是一個數組,數組的每一個元素是一個對象,格式以下 //{"date":"20150602","open":4844.7,"close":4910.53,"high":4911.57,"low":4797.55,"vol":62374809900,"change":1.69} //其中咱們能用到的是 open , close, high, low //解釋一下四個參數的含義,咱們知道K線圖的形狀 相似於漢字 中 其中 //high表示的是中字中間一豎的最上邊一點的Y座標, //low 是中字中間一豎的最下邊一點的Y座標, //若是open大於close,則表示股票交易結束的時候比開始的時候低了,則要用綠色表示 //open是中字中間的口的上邊一橫的Y座標, //close是下邊一橫的Y座標 //data = data.slice(data.length-2) console.log("width="+width+" heigth="+height ); //計算最上和最下的留白 liubai = 0.01 * height; arangeY = { startY : liubai, endY : height-liubai }; calcBulk = function(inputdata, xrange, arangeY){ var widthPerBulk = xrange/inputdata.length; //繪製節點信息列表 var paintBulkList = []; //繪製的一個節點 var paintBulk = {color:null, lineStart:{x:0, y:0},lineEnd:{x:0, y:0}, boxStart:{x:0, y:0},boxEnd:{x:0, y:0}}; //求最高點 var highest = inputdata.reduce(function(x,y){ x => {if(x.high) x.high; else x;} if(x>y.high) { return x; } else { return y.high; } }); //求最低點 var lowest = inputdata.reduce(function(x,y){ x => {if(x.low) x.low; else x;} if(x<y.low) { return x; } else { return y.low; } }); //每一個點數對應多少像素 var hightRate = (arangeY.endY - arangeY.startY)/(highest-lowest); console.log("high="+highest+" low="+lowest+" rate="+hightRate); for(let i=0;i<inputdata.length;i++) { //計算顏色 var boxColor = ""; var boxStartVal = NaN; var boxHeightVal = NaN; if(inputdata[i].open > inputdata[i].close) {//green boxColor = "#dc0000"; boxStartVal = inputdata[i].close; } else {//red boxColor = "#1caa3d"; boxStartVal = inputdata[i].open; } boxHeightVal = Math.abs(inputdata[i].open-inputdata[i].close); paintBulkList.push({color:boxColor, lineStart:{x:Math.round((i*widthPerBulk)+(widthPerBulk/2)), y:Math.round(arangeY.startY+(inputdata[i].low-lowest)*hightRate)}, lineEnd:{x:Math.round((i*widthPerBulk)+(widthPerBulk/2)), y:Math.round(arangeY.startY+(inputdata[i].high-lowest)*hightRate)}, boxStart:{x:Math.round((i*widthPerBulk)+1), y:Math.round(arangeY.startY+(boxStartVal-lowest)*hightRate)}, boxRange:{width:Math.round(widthPerBulk-2), height:Math.round(arangeY.startY+boxHeightVal*hightRate)}}); } return paintBulkList; } paintList = calcBulk(data, width, arangeY); console.log("paintList="+JSON.stringify(paintList)); //畫圖 ctx.clearRect(0, 0, width, height ); // ctx.fillStyle = '#000000'; // ctx.fillRect(0, 0, width, height ); // for(let i=0;i<data.length;i++) { ////////////////////box ctx.fillStyle = paintList[i].color; // 設置顏色 ctx.fillRect(paintList[i].boxStart.x, paintList[i].boxStart.y, paintList[i].boxRange.width, paintList[i].boxRange.height ); // ///////////////////line // 設置線條的顏色 ctx.strokeStyle = 'white'; // 設置線條的寬度 ctx.lineWidth = 1; // 繪製直線 ctx.beginPath(); // 起點 ctx.moveTo(paintList[i].lineStart.x, paintList[i].lineStart.y); // 終點 ctx.lineTo(paintList[i].lineEnd.x, paintList[i].lineEnd.y); ctx.closePath(); ctx.stroke(); }