株価チャート表示 サンプルプログラム

chart.js


日足チャート、一目均衡表、エンベロープ、ボリンジャーバンドを描画します。

var CNDL_WIDTH = 3;                 //ローソクの幅
var CNDL_INT = 2;                   //ローソクの間隔
var CNDL = CNDL_WIDTH + CNDL_INT;   //ローソク1本分
var CNDL_HIGE = 1;                  //ローソク足のひげのオフセット
var XPOS = 3.5;                     //X座標開始位置(CNDL_INT + CNDL_WIDTH / 2)
var VAL_WIDTH = 70;                 //チャートの価格表示幅

var COL_CANDLE = "#0000cd";         //ローソク足の色
var COL_AVE5 = "#ff0000";           //5日移動平均線の色
var COL_AVE25 = "#008b8b";          //25日移動平均線の色
var COL_AVE75 = "#ff8c00";          //75日移動平均線の色

var DAYS_TENKAN = 9;                //転換線の日数
var DAYS_KIJUN = 26;                //基準線の日数
var DAYS_SPAN2 = 52;                //先行スパン2の日数
var COL_TENKAN = "#ff0000";         //転換線の色
var COL_KIJUN = "#008b8b";          //基準線の色
var COL_CHIKOU = "#ff8c00";         //遅行線の色
var COL_CLUD1 = "#e6e6fa";          //良い雲の色
var COL_CLUD2 = "#ffe0f0";          //悪い雲の色

var COL_BOLLINGER0 = "#008b8b";     //ボリンジャーバンド25日平均移動線の色
var COL_BOLLINGER1 = "#ff8c00";     //ボリンジャーバンドσ1の色
var COL_BOLLINGER2 = "#4169e1";     //ボリンジャーバンドσ2の色
var COL_BOLLINGER3 = "#ff0000";     //ボリンジャーバンドσ3の色

var COL_ENVELOPE0 = "#008b8b";      //エンベロープ25日平均移動線の色
var COL_ENVELOPE1 = "#ff8c00";      //エンベロープ±2.5%の色
var COL_ENVELOPE2 = "#4169e1";      //エンベロープ±5.0%の色
var COL_ENVELOPE3 = "#ff0000";      //エンベロープ±7.5%の色

var CHT_HIASHI = 1;     //日足チャート
var CHT_ICHIMOKU = 2;   //一目均衡表
var CHT_ENVELOPE = 3;   //エンベロープ
var CHT_BOLLINGER = 4;  //ボリンジャーバンド

var gChartHeight;       //チャート高さ
var gChartYRate;        //1円の高さ
var gMax;               //最高値
var gMin;               //最安値
var gX;                 //描画開始X座標
var gCrntChart = 0;     //表示中チャート
                        //  0:非表示
                        //  1:日足
                        //  2:一目均衡表
                        //  3:ボリンジャーバンド
                        //  4:エンベロープ

//チャート表示
function dspChart() {

    //表示中年月インデックス
    if (gMonthDataNum.length <= 7) {
        gCrntYMIdx = 0;
    } else {
        gCrntYMIdx =  gMonthDataNum.length - 7;
    }

    //チャート表示サブ
    dspChartSub();
}

//スクロール表示
// scrollCnt : スクロール月数
function dspScroll(scrollCnt) {
    //表示中年月インデックス
    gCrntYMIdx += scrollCnt;

    //チャート表示サブ
    dspChartSub();
}

//チャート表示サブ
function dspChartSub() {
    //初期化
    gStartIdx = 0;  //チャート表示開始インデックス初期化
    gMax = 0;       //表示中最大値
    gMin = 99999999;//表示中最小値
    gCrntChart = 0; //表示中チャート

    //チャート表示開始位置を計算
    setStartEndIdx();

    //チャート縦軸の価格表示
    dspChartPrice();

    //1円の高さ
    gChartHeight = document.getElementById("idchart").height;
    gChartYRate = gChartHeight / (gMax - gMin);

    //年月表示
    dspYearMonth();

    //チャート表示
    var elm = document.getElementsByName("chartkind");
    if (elm[0].checked == true) {
        hiashi();        //日足チャート
    } else if(elm[1].checked == true) {
        envelope();      //エンベロープ
    } else if(elm[2].checked == true) {
        ichimoku();      //一目均衡表
    } else{
        bollinger();     //ボリンジャーバンド
    }

    dspMACD();      //MACD表示
    dspStcastics(); //ストキャスティックス表示
    dspRSI();       //RSI表示
}

//チャート表示開始、終了インデックスを設定
function setStartEndIdx() {
    var i;

    if (gCrntYMIdx == 0) {
        gStartIdx = 0;
    } else {
        for (i = 0; i < gCrntYMIdx; i++) {
            gStartIdx += gMonthDataNum[i];
        }
    }
    gEndIdx = gStartIdx;
    for (i = gCrntYMIdx; i < gMonthDataNum.length && i < gCrntYMIdx + 7; i++) {
        gEndIdx += gMonthDataNum[i];
    }
    gEndIdx--;
}

//チャート縦軸の価格表示
function dspChartPrice() {
    var i;
    var w;
    var a;

    //表示年月の最安値、最高値を求める
    for (i = gStartIdx; i <= gEndIdx; i++) {
        if (gMax < gHi[i]) {
            gMax = gHi[i];
        }
        if (gLo[i] < gMin) {
            gMin = gLo[i];
        }
    }

    //最高値、最安値からチャート表示領域の上限値、下限値を計算
    calcMaxMin();

    //縦軸の価格表示
    w = (gMax - gMin) / 10;
    a = document.getElementById("vchart1");
    a.text = String(gMin + w * 10).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,');
    a = document.getElementById("vchart2");
    a.text = String(gMin + w * 9).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,');
    a = document.getElementById("vchart3");
    a.text = String(gMin + w * 8).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,');
    a = document.getElementById("vchart4");
    a.text = String(gMin + w * 7).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,');
    a = document.getElementById("vchart5");
    a.text = String(gMin + w * 6).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,');
    a = document.getElementById("vchart6");
    a.text = String(gMin + w * 5).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,');
    a = document.getElementById("vchart7");
    a.text = String(gMin + w * 4).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,');
    a = document.getElementById("vchart8");
    a.text = String(gMin + w * 3).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,');
    a = document.getElementById("vchart9");
    a.text = String(gMin + w * 2).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,');
    a = document.getElementById("vchart10");
    a.text = String(gMin + w).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,');
    a = document.getElementById("vchart11");
    a.text = String(gMin).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,');
}

//最高値、最安値からチャート表示領域の上限値、下限値を計算
function calcMaxMin() {
    var w;

    //チャート表示領域の下限値計算
    if (gMin < 10) {
        gMin = 0;
    } else if (gMin < 100) {
        gMin = Math.floor(gMin / 10) * 10;
    } else if (gMin < 1000) {
        gMin -= (gMin % 10);
    } else if (gMin < 10000) {
        gMin -= (gMin % 100);
    } else if (gMin < 100000) {
        gMin -= (gMin % 1000);
    } else if (gMin < 1000000) {
        gMin -= (gMin % 10000);
    } else if (gMin < 10000000) {
        gMin -= (gMin % 100000);
    } else if (gMin < 100000000) {
        gMin -= (gMin % 1000000);
    }

    //チャート表示領域の上限値計算
    w = gMax - gMin;
    if (w < 10) {
        gMax = gMin + 10;
    } else if (w < 100) {
        w = Math.floor(w / 10) + 1;
        gMax = gMin + w * 10;
    } else if (w < 1000) {
        w = Math.floor(w / 100) + 1;
        gMax = gMin + w * 100;
    } else if (w < 10000) {
        w = Math.floor(w / 1000) + 1;
        gMax = gMin + w * 1000;
    } else if (w < 100000) {
        w = Math.floor(w / 10000) + 1;
        gMax = gMin + w * 10000;
    } else if (w < 1000000) {
        w = Math.floor(w / 100000) + 1;
        gMax = gMin + w * 100000;
    } else if (w < 10000000) {
        w = Math.floor(w / 1000000) + 1;
        gMax = gMin + w * 1000000;
    } else if (w < 100000000) {
        w = Math.floor(w / 10000000) + 1;
        gMax = gMin + w * 10000000;
    }
}

//年月表示、幅設定
function dspYearMonth() {
    var tblWidth;

    //年月表示
    dspYearMonthSub("ym1", gCrntYMIdx);
    dspYearMonthSub("ym2", gCrntYMIdx+1);
    dspYearMonthSub("ym3", gCrntYMIdx+2);
    dspYearMonthSub("ym4", gCrntYMIdx+3);
    dspYearMonthSub("ym5", gCrntYMIdx+4);
    dspYearMonthSub("ym6", gCrntYMIdx+5);
    dspYearMonthSub("ym7", gCrntYMIdx+6);

    //月の幅設定
    tblWidth = setMonthWidth("width1", gCrntYMIdx, gCrntYMIdx+1);
    tblWidth += setMonthWidth("width2", gCrntYMIdx+1, gCrntYMIdx+2);
    tblWidth += setMonthWidth("width3", gCrntYMIdx+2, gCrntYMIdx+3);
    tblWidth += setMonthWidth("width4", gCrntYMIdx+3, gCrntYMIdx+4);
    tblWidth += setMonthWidth("width5", gCrntYMIdx+4, gCrntYMIdx+5);
    tblWidth += setMonthWidth("width6", gCrntYMIdx+5, gCrntYMIdx+6);
    tblWidth += setMonthWidth("width7", gCrntYMIdx+6, gCrntYMIdx+6);

    //テーブル幅、キャンバス幅設定
    tblWidth += 6;
    if ((tblWidth % 2) == 1) {
        tblWidth += 1;
    } else {
        tblWidth -= 2;
    }
    document.getElementById("idchart").setAttribute("width", tblWidth);
    document.getElementById("idmacd").setAttribute("width", tblWidth);
    document.getElementById("idstcas").setAttribute("width", tblWidth);
    document.getElementById("idrsi").setAttribute("width", tblWidth);
    tblWidth += VAL_WIDTH;
    document.getElementById("idtable").setAttribute("width", tblWidth);
}

//年月表示サブ
// idname : 年/月のID
// p      : 表示対象の年、月のインデックス
function dspYearMonthSub(idname, p) {
    var ym = "";

    if (gYear[p] != "") {
        ym = gYear[p] + "/" + gMonth[p];
    }
    document.getElementById(idname).text = ym;
}

//月の幅設定サブ
// idname : 年/月のID
// p      : 表示対象の月の日数インデックス
// np     : 表示対象の次の月の日数インデックス(pが最終月のときはp=np)
function setMonthWidth(idname, p, np) {
    var monthWidth = 110;

    if (p != gMonthDataNum.length-1) {
        if (gMonthDataNum[p] != 0) {
            monthWidth = gMonthDataNum[p] * CNDL - 1;
            if (gMonthDataNum[np] == 0 && monthWidth < 100) {
                monthWidth = 100;
            }
            if ((gMonthDataNum[p] % 2) == 0) {
                monthWidth++;
            } else if (gMonthDataNum[p] == 22) {
                monthWidth++;
            }
        }
    }
    if (idname == "width7") {	//表示中最後の月幅は+2
        monthWidth += 2;
    }
    document.getElementById(idname).setAttribute("width", monthWidth);
    return monthWidth;
}

//日足チャート
function hiashi(){
    if (gCrntChart != CHT_HIASHI) {
        gCrntChart = CHT_HIASHI;
        getCanvas("idchart");   //キャンバス取得
        dspCandle();
        drawAverage(5, 1, COL_AVE5);    //5日平均線
        drawAverage(25, 1, COL_AVE25);  //25日平均線
        drawAverage(75, 1, COL_AVE75);  //75日平均線
    }
}

//一目均衡表
function ichimoku(){
    var tx;     //転換線X座標
    var ty;     //転換線Y座標
    var kx;     //基準線X座標
    var ky;     //基準線Y座標
    var sy1;    //先行スパン1Y座標
    var sy2;    //先行スパン2Y座標

    if (gCrntChart != CHT_ICHIMOKU) {
        gCrntChart = CHT_ICHIMOKU;
        tx = new Array(gEd.length);
        ty = new Array(gEd.length);
        kx = new Array(gEd.length);
        ky = new Array(gEd.length);
        sy1 = new Array(gEd.length);
        sy2 = new Array(gEd.length);

        calcTenkaKijun(DAYS_TENKAN, ty);//転換線座標計算
        calcTenkaKijun(DAYS_KIJUN, ky); //基準線座標計算
        calcSpan1(ty, ky, sy1);         //先行スパン1(上限線)計算
        calcSpan2(sy2);                 //先行スパン2(下限線)計算
        getCanvas("idchart");           //キャンバス取得
        drawCloud(sy1, sy2);            //雲表示
        dspCandle();                    //ローソク足
        drawTnknKjn(9, ty, COL_TENKAN); //転換線
        drawTnknKjn(26, ky, COL_KIJUN); //基準線
        chikou();                       //遅行線
    }
}

//エンベロープ
function envelope() {
    if (gCrntChart != CHT_ENVELOPE) {
        gCrntChart = CHT_ENVELOPE;
        getCanvas("idchart");   //キャンバス取得
        dspCandle();
        drawAverage(25, 1, COL_ENVELOPE0);      //25日平均線
        drawAverage(25, 1.025, COL_ENVELOPE1);  // 2.5%
        drawAverage(25, 0.975, COL_ENVELOPE1);  //-2.5%
        drawAverage(25, 1.05, COL_ENVELOPE2);   // 5.0%
        drawAverage(25, 0.95, COL_ENVELOPE2);   //-5.0%
        drawAverage(25, 1.075, COL_ENVELOPE3);  // 7.5%
        drawAverage(25, 0.925, COL_ENVELOPE3);  //-7.5%
    }
}

//ボリンジャーバンド
function bollinger() {
    if (gCrntChart != CHT_BOLLINGER) {
        gCrntChart = CHT_BOLLINGER;
        getCanvas("idchart");   //キャンバス取得
        dspCandle();
        drawAverage(25, 1, COL_BOLLINGER0);     //25日平均線
        drawBollinger(25, 1.0, COL_BOLLINGER1); //σ1
        drawBollinger(25, -1.0, COL_BOLLINGER1);//σ1
        drawBollinger(25, 2.0, COL_BOLLINGER2); //σ2
        drawBollinger(25, -2.0, COL_BOLLINGER2);//σ2
        drawBollinger(25, 3.0, COL_BOLLINGER3); //σ3
        drawBollinger(25, -3.0, COL_BOLLINGER3);//σ3
    }
}

//キャンバス取得
// idname : キャンバスのID
function getCanvas(idname) {
    var canvas = document.getElementById(idname);
    gCtx = canvas.getContext('2d');

    //キャンバスクリア
    gCtx.clearRect(0, 0, canvas.width, canvas.height);

    //キャンバス位置確認枠描画(座標が正しいか確認)
    drawCanvasPos(canvas.height);
}

//キャンバス位置確認枠描画
// height : キャンバスの高さ
function drawCanvasPos(height) {
    gCtx.beginPath();
    gCtx.strokeStyle = "#ff0000";
    gCtx.fillStyle = "#ff0000";

    //左上
    gCtx.moveTo(0, 0);
    gCtx.lineTo(20, 0);
    gCtx.moveTo(0, 0);
    gCtx.lineTo(0, 20);

    //左下
    gCtx.moveTo(0, height);
    gCtx.lineTo(20, height);
    gCtx.moveTo(0, height);
    gCtx.lineTo(0, height - 20);

    gCtx.stroke();
    gCtx.closePath();
}

//ローソク足表示
function dspCandle() {
    var i;
    var x;

    gCtx.strokeStyle = COL_CANDLE;
    gCtx.fillStyle = COL_CANDLE;
    x = CNDL_INT - 0.5;
    for (i = gStartIdx; i <= gEndIdx; i++) {
        drawCandle(gSt[i], gHi[i], gLo[i], gEd[i], x);
        x += CNDL;
    }
}

//ローソク足を1本描画
// st : 始値
// hi : 高値
// lo : 安値
// ed : 終値
function drawCandle(st, hi, lo, ed, x) {
    var xhige;
    var y1;
    var y2;

    st = st - gMin;
    hi = hi - gMin;
    lo = lo - gMin;
    ed = ed - gMin;

    xhige = x + CNDL_HIGE;
    gCtx.beginPath();

    if (st == ed) {
        if (lo < hi) {
            y1 = gChartHeight - lo * gChartYRate + 0.5;
            y2 = gChartHeight - hi * gChartYRate + 0.5;
            gCtx.moveTo(xhige, y1);
            gCtx.lineTo(xhige, y2);
        }
        y1 = gChartHeight - st * gChartYRate + 0.5;
        gCtx.moveTo(x, y1);
        gCtx.lineTo(x + CNDL_WIDTH, y1);
    } else if (st < ed) {
        if (lo < st) {
            y1 = gChartHeight - lo * gChartYRate + 0.5;
            y2 = gChartHeight - st * gChartYRate + 0.5;
            gCtx.moveTo(xhige, y1);
            gCtx.lineTo(xhige, y2);
        }
        y1 = gChartHeight - ed * gChartYRate + 0.5;
        y2 = (ed - st) * gChartYRate + 0.5;
        gCtx.strokeRect(x,  y1, CNDL_WIDTH, y2);

        if (ed < hi) {
            y1 = gChartHeight - hi * gChartYRate + 0.5;
            y2 = gChartHeight - ed * gChartYRate + 0.5;
            gCtx.moveTo(xhige, y1);
            gCtx.lineTo(xhige, y2);
        }
    } else {
        if (lo < ed) {
            y1 = gChartHeight - lo * gChartYRate + 0.5;
            y2 = gChartHeight - ed * gChartYRate + 0.5;
            gCtx.moveTo(xhige, y1);
            gCtx.lineTo(xhige, y2);
        }
        y1 = gChartHeight - st * gChartYRate + 0.5;
        y2 = (st - ed) * gChartYRate + 0.5;
        gCtx.fillRect(x,  y1, CNDL_WIDTH, y2);

        if (st < hi) {
            y1 = gChartHeight - hi * gChartYRate + 0.5;
            y2 = gChartHeight - st * gChartYRate + 0.5;
            gCtx.moveTo(xhige, y1);
            gCtx.lineTo(xhige, y2);
        }
    }
    gCtx.stroke();
    gCtx.closePath();
}

//平均移動線描画
// nissu : 平均移動線の日数
// jousu : 係数
// color : 表示色
function drawAverage(nissu, keisu, color) {
    var i;
    var ave;

    if ((nissu+1) < gEd.length) {
        gCtx.beginPath();
        gCtx.strokeStyle = color;

        //X座標と計算開始位置を求める
        stIdx = getDrawIdx(gStartIdx, nissu);

        for (i = stIdx; i <= gEndIdx; i++) {
            ave = calcAve(i, nissu);
            ave *= keisu;
            y = gChartHeight - (ave - gMin) * gChartYRate;
            if (i == stIdx) {
                gCtx.moveTo(gX, y);
            } else {
                gCtx.lineTo(gX, y);
            }
            gX += CNDL;
        }
        gCtx.stroke();
        gCtx.closePath();
    }
}

//終値の平均値を計算する
// p     : 終値の平均値を計算する開始位置
// nissu : 終値の平均値を計算する日数
function calcAve(p, nissu) {
    var i;
    var ave = 0;

    for (i = nissu - 1; 0 <= i; i--) {
        ave += gEd[p - i];
    }
    ave /= nissu;
    return ave;
}

//転換線、基準線の座標計算
// nissu : 転換線または基準線の日数
// y     : Y座標計算
function calcTenkaKijun(nissu, y) {
    var i;
    var j
    var low;
    var hi;

    nissu--;
    for (i = nissu - 1; i < gEd.length; i++) {
        low = 9999999;
        hi = 0;
        for (j = i - (nissu - 1); j <= i; j++) {
            if (gLo[j] < low) {
                low = gLo[j];
            }
            if (hi < gHi[j]) {
                hi = gHi[j];
            }
        }
        y[i] = gChartHeight - (((low + hi) / 2) - gMin) * gChartYRate;
    }
}

//先行スパン1計算
// ty : 転換線Y座標
// ky : 基準線Y座標
// sy : 先行スパン1Y座標
function calcSpan1(ty, ky, sy) {
    var i;

    //転換線と基準線の中間を計算
    for (i = DAYS_KIJUN - 1; i < gEd.length; i++) {
        sy[i] = (ty[i] + ky[i]) / 2;
    }
}

//先行スパン2計算
// sy : 先行スパン2Y座標
function calcSpan2(sy) {
    var i;
    var j;
    var hi;
    var lo;
    var p;

    //過去52日間の高値、安値の平均値を計算
    p = DAYS_SPAN2 - 1;
    for (i = p; i < gEd.length; i++) {
        hi = 0;
        lo = 99999999;
        for (j = i - p; j <= i; j++) {
            if (hi < gHi[j]) {
                hi = gHi[j];
            }
            if (gLo[j] < lo) {
                lo = gLo[j];
            }
            sy[i] = gChartHeight - (((hi + lo) / 2) - gMin) * gChartYRate;
        }
    }
}

//雲描画
// sy1 : 先行スパン1Y座標
// sy2 : 先行スパン2Y座標
function drawCloud(sy1, sy2) {
    var i;
    var stIdx;

    stIdx = getDrawIdx(gStartIdx, DAYS_SPAN2);
    gX -= XPOS;
    if (DAYS_SPAN2 < stIdx) {
        stIdx -= 26;
        if (stIdx < DAYS_SPAN2) {
            gX += (CNDL * (DAYS_SPAN2 - stIdx - 1));
            stIdx = DAYS_SPAN2 - 1;
        }
    } else {
        gX += (CNDL * 26);
    }
    gCtx.beginPath();
    for (i = stIdx; i < gEd.length - 1; i++) {
        if (sy1[i] >= sy2[i]) {
            gCtx.strokeStyle = COL_CLUD1;
            gCtx.fillStyle = COL_CLUD1;
            gCtx.fillRect(gX,  sy1[i], CNDL+1, sy2[i] - sy1[i]);
        } else {
            gCtx.strokeStyle = COL_CLUD2;
            gCtx.fillStyle = COL_CLUD2;
            gCtx.fillRect(gX,  sy2[i], CNDL+1, sy1[i] - sy2[i]);
        }
        gX += CNDL;
    }
    gCtx.stroke();
    gCtx.closePath();
}

//転換線、基準線描画
// nissu : 日数(9/26)
// y     : 転換線または基準線のY座標
// color : 転換線または基準線の色
function drawTnknKjn(nissu, y, color) {
    var i;

    stIdx = getDrawIdx(gStartIdx, nissu);

    gCtx.beginPath();
    gCtx.strokeStyle = color;
    gCtx.moveTo(gX, y[stIdx]);
    for (i = stIdx + 1; i < gEd.length; i++) {
        gX += CNDL;
        gCtx.lineTo(gX, y[i]);
    }
    gCtx.stroke();
    gCtx.closePath();
}

//遅行線
function chikou() {
    var i;
    var x = XPOS;
    var y;

    gCtx.beginPath();
    gCtx.strokeStyle = COL_CHIKOU;
    for (i = gStartIdx + 25; i < gEd.length; i++) {
        y = gChartHeight - (gEd[i] - gMin) * gChartYRate;
        if (i == gStartIdx) {
            gCtx.moveTo(x, y);
        } else {
            gCtx.lineTo(x, y);
        }
        x += CNDL;
    }
    gCtx.stroke();
    gCtx.closePath();
}

//ボリンジャバンド描画
// nissu : アベレージ日数
// jousu : 標準偏差乗数
// color : ボリンジャバンドの色
function drawBollinger(nissu, jousu, color) {
    var i;
    var j;
    var ave;
    var sum;
    var w;
    var variance;
    var y;
    var stIdx;

    if ((nissu+1) < gEd.length) {
        gCtx.beginPath();
        gCtx.strokeStyle = color;

        //X座標と計算開始位置を求める
        stIdx = getDrawIdx(gStartIdx, nissu)

        //開始インデックスから終了インデックスまでループ
        for (i = stIdx; i <= gEndIdx; i++) {
            //平均値計算
            ave = calcAve(i, nissu);

            //分散計算
            sum = 0;
            for (j = 0; j < nissu; j++) {
                w = gEd[i - j] - ave;
                sum += (w * w);
            }
            variance = sum / nissu;

            //標準偏差計算
            rstdDeviation = Math.sqrt(variance) * jousu;

            //X,Y座標
            y = gChartHeight - ((ave + rstdDeviation) - gMin) * gChartYRate;

            //線描画
            if (i == stIdx) {
                gCtx.moveTo(gX, y);
            } else {
                gCtx.lineTo(gX, y);
            }
            gX += CNDL;
        }
        gCtx.stroke();
        gCtx.closePath();
    }
}

//開始インデックスと日数により描画可能な開始インデックスとX座標を求める
// stIdx : 開始インデックス
// nissu : 日数
function getDrawIdx(stIdx, nissu) {
    var p;

    gX = XPOS;
    p = nissu - stIdx;
    if (0 < p) {
        p--;
        gX += CNDL * p;
        stIdx += p;
    }
    return stIdx;
}



管理人は、本サンプルプログラムを用いて行う判断の一切について責任を負うのもではありません。 ct7m-fnk@asahi-net.or.jp