HTML5のCanvasの使い方を【参考URL】にある「損益グラフ」を使って学習してみました。
1. HTML
index.htmlというファイルを作成して、以下のコードを記載します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>損益グラフ</title>
<link rel="stylesheet" href="app.css" type="text/css" />
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<h1>損益グラフ</h1>
<canvas id="canvasProfitLoss" width="1200" height="600" style="border:1px solid #000000;"></canvas>
<script type="text/javascript" src="test.js" charset="Shift-JIS"></script>
</body>
</html>
JavaScriptを外部ファイル(test.js)で記載して、読み込みます。
日本語を使うため、charset="Shift-JIS"を記載してください。
2. Javascript
(1)canvasにグラフ作成する関数を外部ファイル(test.js)に記載する
(ProfitLossChartという関数で、クラスの代わりとなります)
この関数を使って、返り値のインスタンス定義する(this.???がインスタンスが持つパラメータになります)
function ProfitLossChart(minPrice, minProfitLoss, maxPrice, maxProfitLoss, unitsPrice, unitsProfitLoss) {
this.canvas = document.getElementById("canvasProfitLoss");
this.minPrice = minPrice;
this.minProfitLoss = minProfitLoss;
this.maxPrice = maxPrice;
this.maxProfitLoss = maxProfitLoss;
this.unitsPrice = unitsPrice;
this.unitsProfitLoss = unitsProfitLoss;
this.tickSize = 20;
this.context = this.canvas.getContext('2d');
this.rangePrice = this.maxPrice - this.minPrice;
this.rangeProfitLoss = this.maxProfitLoss - this.minProfitLoss;
this.unitPrice = this.canvas.width / this.rangePrice;
this.unitProfitLoss = this.canvas.height / (this.rangeProfitLoss);
this.centerProfitLoss = Math.round(Math.abs(this.minProfitLoss / this.rangeProfitLoss) * this.canvas.height) ;
this.centerPrice = + Math.round(Math.abs(this.minPrice / this.rangePrice) * this.canvas.width);
this.iteration = (this.maxPrice - this.minPrice) / 1000;
this.scalePrice = this.canvas.width / this.rangePrice;
this.scaleProfitLoss = this.canvas.height / this.rangeProfitLoss;
};
※javascriptのインスタンスについては、次のURL一読するとよいと思います。
http://qiita.com/nmta/items/696eeab1d6b96e3bfc1a
コンテキスト(this.context)は、canvas に描画するための API にアクセスできるオブジェクトとなっています。
(2)X軸作成
刻みとラベルを表示した軸を作成する関数を定義します。
(クラス(ProfitLossChart)に関数を定義する)
ProfitLossChart.prototype.drawPriceAxis= function () {
var context = this.context;
context.save();
context.beginPath(); // 現在のパスをリセットします
//左から10 pix オフセット, y 方向は中心(開始点設定)
context.moveTo(10, this.centerProfitLoss);
//水平線を作成
context.lineTo(this.canvas.width, this.centerProfitLoss);
context.strokeStyle = this.axisColor;
context.lineWidth = 2;
context.stroke();
// 右側に刻みを書く
var pricePosIncrement = this.unitsPrice * this.unitPrice;
var pricePos, unit;
context.font = this.font;
context.textAlign = 'center';
context.textBaseline = 'top';
pricePos = pricePosIncrement;
unit = this.unitsPrice ;
while (pricePos < this.canvas.width) {
//刻み描画
context.moveTo(pricePos , this.centerProfitLoss - this.tickSize / 2);
context.lineTo(pricePos , this.centerProfitLoss + this.tickSize / 2);
context.stroke();
//刻みにラベル描画
context.fillText(unit + this.minPrice, pricePos, this.centerProfitLoss + this.tickSize / 2 - 30);
unit += this.unitsPrice;
pricePos = Math.round(pricePos + pricePosIncrement);
}
//X軸中心にラベルを表示
context.font = "12px 'ヒラギノ角ゴシックProN W3'";
context.fillStyle = "green";
context.fillText("価格(円)", this.canvas.width / 2, this.centerProfitLoss + this.tickSize / 2 -50);
context.restore();
};
(3) Y軸(利益/損失)作成
ProfitLossChart.prototype.drawProfitLossAxis = function () {
var context = this.context;
context.save();
context.beginPath();
//縦軸描画
context.moveTo( 20, 0)
context.lineTo( 20, this.canvas.height);
context.strokeStyle = this.axisColor;
context.lineWidth = 2;
context.stroke();
// 刻み描画
var profitLossPosIncrement = this.unitsProfitLoss * this.unitProfitLoss;
var profitLossPos, unit;
context.font = this.font;
context.textAlign = 'right';
context.textBaseline = 'middle';
profitLossPos = this.centerProfitLoss - profitLossPosIncrement;
unit = this.unitsProfitLoss;
while (profitLossPos > 0) {
context.moveTo(20 - this.tickSize / 2, profitLossPos);
context.lineTo(20 + this.tickSize / 2, profitLossPos);
context.stroke();
context.fillText(unit, 70 - this.tickSize / 2 - 3 , profitLossPos);
unit += this.unitsProfitLoss;
profitLossPos = Math.round(profitLossPos - profitLossPosIncrement);
}
profitLossPos = this.centerProfitLoss + profitLossPosIncrement;
unit = -1 * this.unitsProfitLoss;
while (profitLossPos < this.canvas.height) {
context.moveTo(20- this.tickSize / 2, profitLossPos);
context.lineTo(20 + this.tickSize / 2, profitLossPos);
context.stroke();
context.fillText(unit, 70 - this.tickSize / 2 - 3, profitLossPos);
unit -= this.unitsProfitLoss;
profitLossPos = Math.round(profitLossPos + profitLossPosIncrement);
}
// Y軸ラベルを作成
context.font = "12px 'ヒラギノ角ゴシックProN W3'";
context.fillStyle = "green";
context.fillText("利益/損失(円)", this.centerPrice + 140, this.canvas.height / 4);
context.restore();
};
(4) 損益ライン作成
ProfitLossChart.prototype.drawEquation = function (drawFunction) {
var context = this.context;
context.save();
this.transformContext();
context.beginPath();
context.moveTo(this.minPrice, drawFunction(this.minPrice));
for (var x = this.minPrice + this.iteration; x <= this.maxPrice; x += this.iteration) {
context.lineTo(x, drawFunction(x));
}
context.restore();
context.lineJoin = 'round';
context.lineWidth = 3;
context.strokeStyle = 'red';
context.stroke();
context.restore();
};
(5) コンテキストの変換
ProfitLossChart.prototype.transformContext = function () {
var context = this.context;
this.context.translate(this.centerPrice, this.centerProfitLoss);
context.scale(this.scalePrice , -this.scaleProfitLoss);
};
(6) 実行
パラメータを定義し、インスタンス作成し、描画実行する
インスタンスは、ファンクション(ProfitLossChart)をnewすることで作成することができます。
var minPrice = 0;
var maxPrice = 2200;
var minPL = -10000;
var maxPL = 10000;
var unitsPrice = 50;
var unitsProfitLoss = 500;
// インスタンス(chart)作成
var chart = new ProfitLossChart(minPrice, minPL, maxPrice, maxPL, unitsPrice, unitsProfitLoss);
chart.drawPriceAxis();
chart.drawProfitLossAxis();
//損益グラフ作成
var pStrike = 2110;
var pCall = 5.5;
chart.drawEquation(function (x) {
if (x > pStrike)
{
return 100 * (x - pStrike - pCall);
}
else
{
return -(100 * pCall);
}
});
【参考URL】
http://www.codeproject.com/Articles/1100873/Charting-Profit-Loss-of-Financial-Options-Using-HT
0 件のコメント:
コメントを投稿