10243 lines
383 KiB
JavaScript
10243 lines
383 KiB
JavaScript
var Kline = function (option) {
|
|
|
|
this.element = "#kline_container";
|
|
this.chartMgr = null;
|
|
this.G_HTTP_REQUEST = null;
|
|
this.timer = null;
|
|
this.buttonDown = false;
|
|
this.init = false;
|
|
this.requestParam = "";
|
|
this.data = {};
|
|
this.width = 1200;
|
|
this.height = 650;
|
|
this.symbol = "";
|
|
this.symbolName = "";
|
|
this.range = null;
|
|
this.url = "";
|
|
this.limit = 1000;
|
|
this.type = "poll";
|
|
this.subscribePath = "";
|
|
this.sendPath = "";
|
|
this.socketClient = null;
|
|
this.intervalTime = 5000;
|
|
this.debug = true;
|
|
this.language = "zh-cn";
|
|
this.theme = "dark";
|
|
this.ranges = ["1w", "1d", "1h", "30m", "15m", "5m", "1m", "line"];
|
|
this.showTrade = true;
|
|
this.tradeWidth = 250;
|
|
this.socketConnected = false;
|
|
this.enableSockjs = true;
|
|
this.reverseColor = false;
|
|
|
|
this.periodMap = {
|
|
"01w": 7 * 86400 * 1000,
|
|
"03d": 3 * 86400 * 1000,
|
|
"01d": 86400 * 1000,
|
|
"12h": 12 * 3600 * 1000,
|
|
"06h": 6 * 3600 * 1000,
|
|
"04h": 4 * 3600 * 1000,
|
|
"02h": 2 * 3600 * 1000,
|
|
"01h": 3600 * 1000,
|
|
"30m": 30 * 60 * 1000,
|
|
"15m": 15 * 60 * 1000,
|
|
"05m": 5 * 60 * 1000,
|
|
"03m": 3 * 60 * 1000,
|
|
"01m": 60 * 1000,
|
|
"line": 60 * 1000
|
|
};
|
|
|
|
this.tagMapPeriod = {
|
|
"1w": "01w",
|
|
"3d": "03d",
|
|
"1d": "01d",
|
|
"12h": "12h",
|
|
"6h": "06h",
|
|
"4h": "04h",
|
|
"2h": "02h",
|
|
"1h": "01h",
|
|
"30m": "30m",
|
|
"15m": "15m",
|
|
"5m": "05m",
|
|
"3m": "03m",
|
|
"1m": "01m",
|
|
"line": "line"
|
|
};
|
|
|
|
Object.assign(this, option);
|
|
};
|
|
|
|
Kline.prototype = {
|
|
|
|
/*********************************************
|
|
* Methods
|
|
*********************************************/
|
|
|
|
draw: function () {
|
|
draw(this);
|
|
},
|
|
|
|
resize: function (width, height) {
|
|
this.width = width;
|
|
this.height = height;
|
|
on_size(this.width, this.height);
|
|
},
|
|
|
|
setSymbol: function (symbol, symbolName) {
|
|
KlineIns.symbol = symbol;
|
|
KlineIns.symbolName = symbolName;
|
|
switch_symbol(symbol);
|
|
KlineIns.onSymbolChange(symbol, symbolName);
|
|
},
|
|
|
|
setTheme: function (style) {
|
|
KlineIns.theme = style;
|
|
switch_theme(style);
|
|
},
|
|
|
|
setLanguage: function (lang) {
|
|
KlineIns.language = lang;
|
|
chart_switch_language(lang);
|
|
},
|
|
|
|
setShowTrade: function (isShow) {
|
|
this.showTrade = isShow;
|
|
if (isShow) {
|
|
$(".trade_container").show();
|
|
} else {
|
|
$(".trade_container").hide();
|
|
}
|
|
on_size(this.width, this.height);
|
|
},
|
|
|
|
toggleTrade: function () {
|
|
if (!this.showTrade) {
|
|
this.showTrade = true;
|
|
$(".trade_container").show();
|
|
} else {
|
|
this.showTrade = false;
|
|
$(".trade_container").hide();
|
|
}
|
|
on_size(this.width, this.height);
|
|
},
|
|
|
|
setIntervalTime: function (intervalTime) {
|
|
this.intervalTime = intervalTime;
|
|
if (this.debug) {
|
|
console.log('DEBUG: interval time changed to ' + intervalTime);
|
|
}
|
|
},
|
|
|
|
connect: function () {
|
|
if (this.type != 'socket') {
|
|
if (this.debug) {
|
|
console.log('DEBUG: this is for socket type');
|
|
}
|
|
return;
|
|
}
|
|
socketConnect();
|
|
RequestData();
|
|
},
|
|
|
|
disconnect: function () {
|
|
if (this.type != 'socket') {
|
|
if (this.debug) {
|
|
console.log('DEBUG: this is for socket type');
|
|
}
|
|
return;
|
|
}
|
|
if (this.socketClient) {
|
|
this.socketClient.disconnect();
|
|
KlineIns.socketConnected = false;
|
|
}
|
|
if (this.debug) {
|
|
console.log('DEBUG: socket disconnected');
|
|
}
|
|
},
|
|
|
|
|
|
/*********************************************
|
|
* Events
|
|
*********************************************/
|
|
|
|
onResize: function (width, height) {
|
|
if (this.debug) {
|
|
console.log("DEBUG: chart resized to width: " + width + " height: " + height);
|
|
}
|
|
},
|
|
|
|
onLangChange: function (lang) {
|
|
if (this.debug) {
|
|
console.log("DEBUG: language changed to " + lang);
|
|
}
|
|
},
|
|
|
|
onSymbolChange: function (symbol, symbolName) {
|
|
if (this.debug) {
|
|
console.log("DEBUG: symbol changed to " + symbol + " " + symbolName);
|
|
}
|
|
},
|
|
|
|
onThemeChange: function (theme) {
|
|
if (this.debug) {
|
|
console.log("DEBUG: theme changed to : " + theme);
|
|
}
|
|
},
|
|
|
|
onRangeChange: function (range) {
|
|
if (this.debug) {
|
|
console.log("DEBUG: range changed to " + range);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
var KlineIns = null;
|
|
|
|
|
|
var KlineTrade = function (option) {
|
|
|
|
this.browerState = 0;
|
|
this.tradeDate = new Date();
|
|
this.tradesLimit = 20;
|
|
this.lastDepth = null;
|
|
this.depthShowSize = 15;
|
|
this.priceDecimalDigits = 6;
|
|
this.amountDecimalDigits = 4;
|
|
this.symbol = null;
|
|
this.curPrice = null;
|
|
this.title = "";
|
|
|
|
Object.assign(this, option);
|
|
};
|
|
|
|
KlineTrade.prototype = {
|
|
|
|
reset: function (symbol) {
|
|
this.symbol = symbol;
|
|
this.lastDepth = null;
|
|
this.curPrice = null;
|
|
this.klineTradeInit = false;
|
|
$("#trades .trades_list").empty();
|
|
$("#gasks .table").empty();
|
|
$("#gbids .table").empty();
|
|
$("#asks .table").empty();
|
|
$("#bids .table").empty();
|
|
},
|
|
pushTrades: function (array) {
|
|
var $trades = $("#trades .trades_list");
|
|
var totalUls = "";
|
|
for (var i = 0; i < array.length; i++) {
|
|
var item = array[i];
|
|
if (i >= array.length - this.tradesLimit) {
|
|
this.tradeDate.setTime(item.time);
|
|
var dateStr = this.dateFormatTf(this.tradeDate.getHours())
|
|
+ ":" + this.dateFormatTf(this.tradeDate.getMinutes())
|
|
+ ":" + this.dateFormatTf(this.tradeDate.getSeconds());
|
|
var arr = (item.amount.toFixed(4) + "").split(".");
|
|
var price = item.price;
|
|
if (price > 1) {
|
|
price = price.toFixed(2)
|
|
}
|
|
if (price < 1 && price > 0.00001) {
|
|
price = price.toFixed(4)
|
|
}
|
|
if (price < 0.00001) {
|
|
price = price.toFixed(6)
|
|
}
|
|
|
|
if (this.klineTradeInit) {
|
|
totalUls = "<ul class='newul'><li class='tm'>" + dateStr + "</li><li class='pr-" + (item.type == 'buy' ? 'green' : 'red') + "'>" + price + "</li><li class='vl'>" + arr[0] + "<g>" + (arr.length > 1 ? '.' + arr[1] : '') + "</g></li></ul>" + totalUls;
|
|
} else {
|
|
totalUls = "<ul><li class='tm'>" + dateStr + "</li><li class='pr-" + (item.type == 'buy' ? 'green' : 'red') + "'>" + price + "</li><li class='vl'>" + arr[0] + "<g>" + (arr.length > 1 ? '.' + arr[1] : '') + "</g></li></ul>" + totalUls;
|
|
}
|
|
}
|
|
}
|
|
var j = 0;
|
|
var that = this;
|
|
if (this.klineTradeInit) {
|
|
clearInterval(myTime);
|
|
var myTime = setInterval(function () {
|
|
var item = array[j]
|
|
//that.curPrice = item.price
|
|
var price = Number(item.price)
|
|
if (price > 1) {
|
|
price = price.toFixed(2)
|
|
}
|
|
|
|
if (price < 1 && price > 0.0001) {
|
|
price = price.toFixed(4)
|
|
}
|
|
if (price < 0.0001) {
|
|
price = price.toFixed(6)
|
|
}
|
|
that.curPrice = price;
|
|
$("div#price").attr("class", item.type == 'buy' ? 'green' : 'red').text(price);
|
|
j++;
|
|
if (j >= array.length) {
|
|
clearInterval(myTime);
|
|
}
|
|
}, 100)
|
|
} else {
|
|
if (array.length > 0) {
|
|
//this.curPrice=array[array.length-1].price.toFixed(6);
|
|
var price = Number(array[array.length - 1].price)
|
|
if (price > 1) {
|
|
price = price.toFixed(2)
|
|
}
|
|
|
|
if (price < 1 && price > 0.0001) {
|
|
price = price.toFixed(4)
|
|
}
|
|
if (price < 0.0001) {
|
|
price = price.toFixed(6)
|
|
}
|
|
that.curPrice = price;
|
|
$("div#price").attr("class", array[array.length - 1].type == 'buy' ? 'green' : 'red').text(price);
|
|
}
|
|
}
|
|
|
|
if (this.klineTradeInit) {
|
|
$trades.prepend(totalUls);
|
|
} else {
|
|
$trades.append(totalUls);
|
|
}
|
|
totalUls = null;
|
|
$trades.find("ul.newul").slideDown(1000, function () {
|
|
$(this).removeClass("newul");
|
|
});
|
|
$trades.find("ul:gt(" + (this.tradesLimit - 1) + ")").remove();
|
|
},
|
|
updateDepth: function (data) {
|
|
window._set_current_depth(data);
|
|
if (!data) return;
|
|
$("#gasks .table").html(this.getgview(this.getgasks(data.asks)));
|
|
$("#gbids .table").html(this.getgview(this.getgbids(data.bids)));
|
|
if (this.lastDepth == null) {
|
|
this.lastDepth = {};
|
|
this.lastDepth.asks = this.getAsks(data.asks, this.depthShowSize);
|
|
this.depthInit(this.lastDepth.asks, $("#asks .table"));
|
|
this.lastDepth.bids = this.getBids(data.bids, this.depthShowSize);
|
|
this.depthInit(this.lastDepth.bids, $("#bids .table"));
|
|
} else {
|
|
var parentAsks = $("#asks .table");
|
|
parentAsks.find("div.remove").remove();
|
|
parentAsks.find("div.add").removeClass("add");
|
|
var newasks = this.getAsks(data.asks, this.depthShowSize);
|
|
var oldasks = this.lastDepth.asks;
|
|
this.lastDepth.asks = newasks;
|
|
this.asksAndBids(newasks.slice(0), oldasks, parentAsks);
|
|
|
|
var parentBids = $("#bids .table");
|
|
parentBids.find("div.remove").remove();
|
|
parentBids.find("div.add").removeClass("add");
|
|
var newbids = this.getBids(data.bids, this.depthShowSize);
|
|
var oldbids = this.lastDepth.bids;
|
|
this.lastDepth.bids = newbids;
|
|
this.asksAndBids(newbids.slice(0), oldbids, $("#bids .table"));
|
|
}
|
|
},
|
|
depthInit: function (data, $obj) {
|
|
$obj.empty();
|
|
if (data && data.length > 0) {
|
|
var lastInt, view = "";
|
|
for (var i = 0; i < data.length; i++) {
|
|
var arr = (data[i][0] + "").split(".");
|
|
var prices = this.getPrice(arr, lastInt);
|
|
lastInt = arr[0];
|
|
arr = (data[i][1] + "").split(".");
|
|
var amounts = this.getAmount(arr);
|
|
view += "<div class='row'><span class='price'>" + prices[0] + "<g>" + prices[1] + "</g></span> <span class='amount'>" + amounts[0] + "<g>" + amounts[1] + "</g></span></div>";
|
|
}
|
|
$obj.append(view);
|
|
view = null;
|
|
}
|
|
},
|
|
asksAndBids: function (addasks, oldasks, tbDiv) {
|
|
for (var i = 0; i < oldasks.length; i++) {
|
|
var isExist = false;
|
|
for (var j = 0; j < addasks.length; j++) {
|
|
if (oldasks[i][0] == addasks[j][0]) {
|
|
isExist = true;
|
|
if (oldasks[i][1] != addasks[j][1]) {
|
|
var $amount = tbDiv.find("div:eq(" + i + ") .amount");
|
|
$amount.addClass(oldasks[i][1] > addasks[j][1] ? "red" : "green");
|
|
var amounts = this.getAmount((addasks[j][1] + "").split("."));
|
|
setTimeout((function ($amount, amounts) {
|
|
return function () {
|
|
$amount.html(amounts[0] + "<g>" + amounts[1] + "</g>");
|
|
$amount.removeClass("red").removeClass("green");
|
|
$amount = null;
|
|
amounts = null;
|
|
};
|
|
})($amount, amounts), 500);
|
|
}
|
|
addasks.splice(j, 1);
|
|
break;
|
|
}
|
|
}
|
|
if (!isExist) {
|
|
tbDiv.find("div:eq(" + i + ")").addClass("remove");
|
|
oldasks[i][2] = -1;//标识该数据对应div被移除
|
|
}
|
|
}
|
|
for (var j = 0; j < oldasks.length; j++) {
|
|
for (var i = 0; i < addasks.length; i++) {
|
|
if (addasks[i][0] > oldasks[j][0]) {
|
|
var arr = (addasks[i][1] + "").split(".");
|
|
var amounts = this.getAmount(arr);
|
|
tbDiv.find("div:eq(" + j + ")").before("<div class='row add'><span class='price'></span> <span class='amount'>" + amounts[0] + "<g>" + amounts[1] + "</g></span></div>");
|
|
oldasks.splice(j, 0, addasks[i]);
|
|
addasks.splice(i, 1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
var totalDiv = "";
|
|
for (var i = 0; i < addasks.length; i++) {
|
|
oldasks.push(addasks[i]);
|
|
var arr = (addasks[i][1] + "").split(".");
|
|
var amounts = this.getAmount(arr);
|
|
totalDiv += "<div class='row add'><span class='price'></span> <span class='amount'>" + amounts[0] + "<g>" + amounts[1] + "</g></span></div>";
|
|
}
|
|
if (totalDiv.length > 0) {
|
|
tbDiv.append(totalDiv);
|
|
}
|
|
totalDiv = null;
|
|
|
|
var lastInt;
|
|
for (var i = 0; i < oldasks.length; i++) {
|
|
var $div = tbDiv.find("div:eq(" + i + ")");
|
|
if (!(oldasks[i].length >= 3 && oldasks[i][2] == -1)) {
|
|
var arr = (oldasks[i][0] + "").split(".");
|
|
var prices = this.getPrice(arr, lastInt);
|
|
lastInt = arr[0];
|
|
$div.find(".price").html(prices[0] + "<g>" + prices[1] + "</g>");
|
|
}
|
|
}
|
|
addasks = null;
|
|
oldasks = null;
|
|
tbDiv.find("div.add").slideDown(800);
|
|
setTimeout((function ($remove, $add) {
|
|
return function () {
|
|
$remove.slideUp(500, function () {
|
|
$(this).remove();
|
|
});
|
|
$add.removeClass("add");
|
|
};
|
|
})(tbDiv.find("div.remove"), tbDiv.find("div.add")), 1000);
|
|
|
|
},
|
|
getAsks: function (array, len) {
|
|
if (array.length > len) {
|
|
array.splice(0, array.length - len);
|
|
}
|
|
return array;
|
|
},
|
|
getBids: function (array, len) {
|
|
if (array.length > len) {
|
|
array.splice(len, array.length - 1);
|
|
}
|
|
return array;
|
|
},
|
|
getgview: function (g) {
|
|
var gstr = "";
|
|
var lastInt;
|
|
for (var i = 0; i < g.length; i++) {
|
|
var arr = g[i][0].split(".");
|
|
if (arr.length == 1 || arr[0] != lastInt) {
|
|
gstr += "<div class='row'><span class='price'>" + g[i][0] + "</span> <span class='amount'>" + g[i][1] + "</span></div>";
|
|
lastInt = arr[0];
|
|
} else {
|
|
gstr += "<div class='row'><span class='price'><h>" + arr[0] + ".</h>" + arr[1] + "</span> <span class='amount'>" + g[i][1] + "</span></div>";
|
|
}
|
|
}
|
|
return gstr;
|
|
},
|
|
getgasks: function (array) {
|
|
if (array.length < 2) {
|
|
return [];
|
|
}
|
|
var low = array[array.length - 1][0];//最低价
|
|
var high = array[0][0];//最高价
|
|
var r = high - low;
|
|
var block = this.getBlock(r, 100);
|
|
var n = Math.abs(Number(Math.log(block) / Math.log(10))).toFixed(0);//精确小数位数
|
|
if (r / block < 2) {
|
|
block = block / 2;
|
|
n++;
|
|
}
|
|
if (block >= 1) (n = 0);
|
|
low = parseInt(low / block) * block;
|
|
high = parseInt(high / block) * block;
|
|
var gasks = [];
|
|
var amount = 0;
|
|
for (var i = array.length - 1; i >= 0; i--) {
|
|
if (array[i][0] > low) {
|
|
var amountInt = parseInt(amount, 10);
|
|
if (amountInt > 0) {
|
|
gasks.unshift([Number(low).toFixed(n), amountInt]);
|
|
}
|
|
if (low >= high) {
|
|
break;
|
|
}
|
|
low += block;
|
|
}
|
|
amount += array[i][1];
|
|
}
|
|
return gasks;
|
|
},
|
|
getgbids: function (array) {
|
|
if (array.length < 2) {
|
|
return [];
|
|
}
|
|
var low = array[array.length - 1][0];
|
|
var high = array[0][0];
|
|
var r = high - low;
|
|
var block = this.getBlock(r, 100);
|
|
var n = Math.abs(Number(Math.log(block) / Math.log(10))).toFixed(0);//精确小数位数
|
|
if (r / block < 2) {
|
|
block = block / 2;
|
|
n++;
|
|
}
|
|
if (block >= 1) (n = 0);
|
|
low = parseInt(low / block) * block;
|
|
high = parseInt(high / block) * block;
|
|
|
|
var gbids = [];
|
|
var amount = 0;
|
|
for (var i = 0; i < array.length; i++) {
|
|
if (array[i][0] < high) {
|
|
var amountInt = parseInt(amount, 10);
|
|
if (amountInt > 0) {
|
|
gbids.push([Number(high).toFixed(n), amountInt]);
|
|
}
|
|
if (high <= low) {
|
|
break;
|
|
}
|
|
high -= block;
|
|
}
|
|
amount += array[i][1];
|
|
}
|
|
return gbids;
|
|
},
|
|
getBlock: function (b, scale) {
|
|
if (b > scale || b <= 0) {
|
|
return scale;
|
|
} else {
|
|
scale = scale / 10;
|
|
return this.getBlock(b, scale);
|
|
}
|
|
},
|
|
getZeros: function (i) {
|
|
var zeros = "";
|
|
while (i > 0) {
|
|
i--;
|
|
zeros += "0";
|
|
}
|
|
return zeros;
|
|
},
|
|
getPrice: function (arr, lastInt) {
|
|
var price1 = arr[0];
|
|
if (lastInt == price1) {
|
|
price1 = "<h>" + price1 + ".</h>";
|
|
} else {
|
|
price1 += ".";
|
|
}
|
|
var price2 = "";
|
|
if (arr.length == 1) {
|
|
price1 += "0";
|
|
price2 = this.getZeros(this.priceDecimalDigits - 1);
|
|
} else {
|
|
price1 += arr[1];
|
|
price2 = this.getZeros(this.priceDecimalDigits - arr[1].length);
|
|
}
|
|
return [price1, price2];
|
|
},
|
|
getAmount: function (arr) {
|
|
var amount1 = arr[0];
|
|
var amount2 = "";
|
|
var zerosLen = this.amountDecimalDigits - amount1.length + 1;
|
|
if (zerosLen > 0) {
|
|
amount2 = ".";
|
|
if (arr.length == 1) {
|
|
amount2 += this.getZeros(zerosLen);
|
|
} else if (zerosLen > arr[1].length) {
|
|
amount2 += arr[1] + this.getZeros(zerosLen - arr[1].length);
|
|
} else if (zerosLen == arr[1].length) {
|
|
amount2 += arr[1];
|
|
} else {
|
|
amount2 += arr[1].substring(0, zerosLen);
|
|
}
|
|
}
|
|
return [amount1, amount2];
|
|
},
|
|
dateFormatTf: function (i) {
|
|
return (i < 10 ? '0' : '') + i;
|
|
},
|
|
};
|
|
|
|
var KlineTradeIns = null;
|
|
|
|
|
|
var classId = 0;
|
|
|
|
/**
|
|
* Class.
|
|
*/
|
|
function create_class() {
|
|
var argc = arguments.length;
|
|
var func = function () {
|
|
};
|
|
var superClass;
|
|
if (argc) {
|
|
superClass = arguments[0];
|
|
for (var k in superClass.prototype)
|
|
func.prototype[k] = superClass.prototype[k];
|
|
}
|
|
for (var i = 1; i < argc; i++) {
|
|
var feature = arguments[i];
|
|
var f = feature.prototype.__construct;
|
|
if (f) {
|
|
if (!func.prototype.__featureConstructors)
|
|
func.prototype.__featureConstructors = [];
|
|
func.prototype.__featureConstructors.push(f);
|
|
delete feature.prototype.__construct;
|
|
}
|
|
for (var k in feature.prototype)
|
|
func.prototype[k] = feature.prototype[k];
|
|
if (f)
|
|
feature.prototype.__construct = f;
|
|
}
|
|
var newClass = function () {
|
|
if (this.__construct)
|
|
this.__construct.apply(this, arguments);
|
|
if (this.__featureConstructors) {
|
|
var a = this.__featureConstructors;
|
|
var i, c = a.length;
|
|
for (i = 0; i < c; i++)
|
|
a[i].apply(this, arguments);
|
|
}
|
|
};
|
|
func.prototype.__classId = classId++;
|
|
if (superClass != undefined) {
|
|
newClass.__super = superClass.prototype;
|
|
func.prototype.__super = superClass;
|
|
}
|
|
newClass.prototype = new func();
|
|
return newClass;
|
|
}
|
|
|
|
function is_instance(obj, clazz) {
|
|
var classId = clazz.prototype.__classId;
|
|
if (obj.__classId == classId)
|
|
return true;
|
|
var __super = obj.__super;
|
|
while (__super != undefined) {
|
|
if (__super.prototype.__classId == classId)
|
|
return true;
|
|
__super = __super.prototype.__super;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Class: MEvent.
|
|
*/
|
|
var MEvent = create_class();
|
|
MEvent.prototype.__construct = function () {
|
|
this._handlers = [];
|
|
};
|
|
MEvent.prototype.addHandler = function (o, f) {
|
|
if (this._indexOf(o, f) < 0)
|
|
this._handlers.push({obj: o, func: f});
|
|
};
|
|
MEvent.prototype.removeHandler = function (o, f) {
|
|
var i = this._indexOf(o, f);
|
|
if (i >= 0)
|
|
this._handlers.splice(i, 1);
|
|
};
|
|
MEvent.prototype.raise = function (s, g) {
|
|
var a = this._handlers;
|
|
var e, i, c = a.length;
|
|
for (i = 0; i < c; i++) {
|
|
e = a[i];
|
|
e.func.call(e.obj, s, g);
|
|
}
|
|
};
|
|
MEvent.prototype._indexOf = function (o, f) {
|
|
var a = this._handlers;
|
|
var e, i, c = a.length;
|
|
for (i = 0; i < c; i++) {
|
|
e = a[i];
|
|
if (o == e.obj && f == e.func)
|
|
return i;
|
|
}
|
|
return -1;
|
|
};
|
|
String.fromFloat = function (v, fractionDigits) {
|
|
// debugger;
|
|
var text = v.toFixed(fractionDigits);
|
|
for (var i = text.length - 1; i >= 0; i--) {
|
|
if (text[i] == '.')
|
|
return text.substring(0, i);
|
|
if (text[i] != '0')
|
|
return text.substring(0, i + 1);
|
|
}
|
|
};
|
|
var ExprEnv = create_class();
|
|
ExprEnv.get = function () {
|
|
return ExprEnv.inst;
|
|
};
|
|
ExprEnv.set = function (env) {
|
|
ExprEnv.inst = env;
|
|
};
|
|
ExprEnv.prototype.getDataSource = function () {
|
|
return this._ds;
|
|
};
|
|
ExprEnv.prototype.setDataSource = function (ds) {
|
|
return this._ds = ds;
|
|
};
|
|
ExprEnv.prototype.getFirstIndex = function () {
|
|
return this._firstIndex;
|
|
};
|
|
ExprEnv.prototype.setFirstIndex = function (n) {
|
|
return this._firstIndex = n;
|
|
};
|
|
var Expr = create_class();
|
|
Expr.prototype.__construct = function () {
|
|
this._rid = 0;
|
|
};
|
|
Expr.prototype.execute = function (index) {
|
|
};
|
|
Expr.prototype.reserve = function (rid, count) {
|
|
};
|
|
Expr.prototype.clear = function () {
|
|
};
|
|
var OpenExpr = create_class(Expr);
|
|
var HighExpr = create_class(Expr);
|
|
var LowExpr = create_class(Expr);
|
|
var CloseExpr = create_class(Expr);
|
|
var VolumeExpr = create_class(Expr);
|
|
OpenExpr.prototype.execute = function (index) {
|
|
return ExprEnv.get()._ds.getDataAt(index).open;
|
|
};
|
|
HighExpr.prototype.execute = function (index) {
|
|
return ExprEnv.get()._ds.getDataAt(index).high;
|
|
};
|
|
LowExpr.prototype.execute = function (index) {
|
|
return ExprEnv.get()._ds.getDataAt(index).low;
|
|
};
|
|
CloseExpr.prototype.execute = function (index) {
|
|
return ExprEnv.get()._ds.getDataAt(index).close;
|
|
};
|
|
VolumeExpr.prototype.execute = function (index) {
|
|
return ExprEnv.get()._ds.getDataAt(index).volume;
|
|
};
|
|
var ConstExpr = create_class(Expr);
|
|
ConstExpr.prototype.__construct = function (v) {
|
|
ConstExpr.__super.__construct.call(this);
|
|
this._value = v;
|
|
};
|
|
ConstExpr.prototype.execute = function (index) {
|
|
return this._value;
|
|
};
|
|
var ParameterExpr = create_class(Expr);
|
|
ParameterExpr.prototype.__construct = function (name, minValue, maxValue, defaultValue) {
|
|
ParameterExpr.__super.__construct.call(this);
|
|
this._name = name;
|
|
this._minValue = minValue;
|
|
this._maxValue = maxValue;
|
|
this._value = this._defaultValue = defaultValue;
|
|
};
|
|
ParameterExpr.prototype.execute = function (index) {
|
|
return this._value;
|
|
};
|
|
ParameterExpr.prototype.getMinValue = function () {
|
|
return this._minValue;
|
|
};
|
|
ParameterExpr.prototype.getMaxValue = function () {
|
|
return this._maxValue;
|
|
};
|
|
ParameterExpr.prototype.getDefaultValue = function () {
|
|
return this._defaultValue;
|
|
};
|
|
ParameterExpr.prototype.getValue = function () {
|
|
return this._value;
|
|
};
|
|
ParameterExpr.prototype.setValue = function (v) {
|
|
if (v == 0)
|
|
this._value = 0;
|
|
else if (v < this._minValue)
|
|
this._value = this._minValue;
|
|
else if (v > this._maxValue)
|
|
this._value = this._maxValue;
|
|
else
|
|
this._value = v;
|
|
};
|
|
var OpAExpr = create_class(Expr);
|
|
var OpABExpr = create_class(Expr);
|
|
var OpABCExpr = create_class(Expr);
|
|
var OpABCDExpr = create_class(Expr);
|
|
OpAExpr.prototype.__construct = function (a) {
|
|
OpAExpr.__super.__construct.call(this);
|
|
this._exprA = a;
|
|
};
|
|
OpAExpr.prototype.reserve = function (rid, count) {
|
|
if (this._rid < rid) {
|
|
this._rid = rid;
|
|
this._exprA.reserve(rid, count);
|
|
}
|
|
};
|
|
OpAExpr.prototype.clear = function () {
|
|
this._exprA.clear();
|
|
};
|
|
OpABExpr.prototype.__construct = function (a, b) {
|
|
OpABExpr.__super.__construct.call(this);
|
|
this._exprA = a;
|
|
this._exprB = b;
|
|
};
|
|
OpABExpr.prototype.reserve = function (rid, count) {
|
|
if (this._rid < rid) {
|
|
this._rid = rid;
|
|
this._exprA.reserve(rid, count);
|
|
this._exprB.reserve(rid, count);
|
|
}
|
|
};
|
|
OpABExpr.prototype.clear = function () {
|
|
this._exprA.clear();
|
|
this._exprB.clear();
|
|
};
|
|
OpABCExpr.prototype.__construct = function (a, b, c) {
|
|
OpABCExpr.__super.__construct.call(this);
|
|
this._exprA = a;
|
|
this._exprB = b;
|
|
this._exprC = c;
|
|
};
|
|
OpABCExpr.prototype.reserve = function (rid, count) {
|
|
if (this._rid < rid) {
|
|
this._rid = rid;
|
|
this._exprA.reserve(rid, count);
|
|
this._exprB.reserve(rid, count);
|
|
this._exprC.reserve(rid, count);
|
|
}
|
|
};
|
|
OpABCExpr.prototype.clear = function () {
|
|
this._exprA.clear();
|
|
this._exprB.clear();
|
|
this._exprC.clear();
|
|
};
|
|
OpABCDExpr.prototype.__construct = function (a, b, c, d) {
|
|
OpABCDExpr.__super.__construct.call(this);
|
|
this._exprA = a;
|
|
this._exprB = b;
|
|
this._exprC = c;
|
|
this._exprD = d;
|
|
};
|
|
OpABCDExpr.prototype.reserve = function (rid, count) {
|
|
if (this._rid < rid) {
|
|
this._rid = rid;
|
|
this._exprA.reserve(rid, count);
|
|
this._exprB.reserve(rid, count);
|
|
this._exprC.reserve(rid, count);
|
|
this._exprD.reserve(rid, count);
|
|
}
|
|
};
|
|
OpABCDExpr.prototype.clear = function () {
|
|
this._exprA.clear();
|
|
this._exprB.clear();
|
|
this._exprC.clear();
|
|
this._exprD.clear();
|
|
};
|
|
var NegExpr = create_class(OpAExpr);
|
|
NegExpr.prototype.__construct = function (a) {
|
|
NegExpr.__super.__construct.call(this, a);
|
|
};
|
|
NegExpr.prototype.execute = function (index) {
|
|
return -(this._exprA.execute(index));
|
|
};
|
|
var AddExpr = create_class(OpABExpr);
|
|
var SubExpr = create_class(OpABExpr);
|
|
var MulExpr = create_class(OpABExpr);
|
|
var DivExpr = create_class(OpABExpr);
|
|
AddExpr.prototype.__construct = function (a, b) {
|
|
AddExpr.__super.__construct.call(this, a, b);
|
|
};
|
|
SubExpr.prototype.__construct = function (a, b) {
|
|
SubExpr.__super.__construct.call(this, a, b);
|
|
};
|
|
MulExpr.prototype.__construct = function (a, b) {
|
|
MulExpr.__super.__construct.call(this, a, b);
|
|
};
|
|
DivExpr.prototype.__construct = function (a, b) {
|
|
DivExpr.__super.__construct.call(this, a, b);
|
|
};
|
|
AddExpr.prototype.execute = function (index) {
|
|
return this._exprA.execute(index) + this._exprB.execute(index);
|
|
};
|
|
SubExpr.prototype.execute = function (index) {
|
|
return this._exprA.execute(index) - this._exprB.execute(index);
|
|
};
|
|
MulExpr.prototype.execute = function (index) {
|
|
return this._exprA.execute(index) * this._exprB.execute(index);
|
|
};
|
|
DivExpr.prototype.execute = function (index) {
|
|
var a = this._exprA.execute(index);
|
|
var b = this._exprB.execute(index);
|
|
if (a == 0)
|
|
return a;
|
|
if (b == 0)
|
|
return (a > 0) ? 1000000 : -1000000;
|
|
return a / b;
|
|
};
|
|
var GtExpr = create_class(OpABExpr);
|
|
var GeExpr = create_class(OpABExpr);
|
|
var LtExpr = create_class(OpABExpr);
|
|
var LeExpr = create_class(OpABExpr);
|
|
var EqExpr = create_class(OpABExpr);
|
|
GtExpr.prototype.__construct = function (a, b) {
|
|
GtExpr.__super.__construct.call(this, a, b);
|
|
};
|
|
GeExpr.prototype.__construct = function (a, b) {
|
|
GeExpr.__super.__construct.call(this, a, b);
|
|
};
|
|
LtExpr.prototype.__construct = function (a, b) {
|
|
LtExpr.__super.__construct.call(this, a, b);
|
|
};
|
|
LeExpr.prototype.__construct = function (a, b) {
|
|
LeExpr.__super.__construct.call(this, a, b);
|
|
};
|
|
EqExpr.prototype.__construct = function (a, b) {
|
|
EqExpr.__super.__construct.call(this, a, b);
|
|
};
|
|
GtExpr.prototype.execute = function (index) {
|
|
return this._exprA.execute(index) > this._exprB.execute(index) ? 1 : 0;
|
|
};
|
|
GeExpr.prototype.execute = function (index) {
|
|
return this._exprA.execute(index) >= this._exprB.execute(index) ? 1 : 0;
|
|
};
|
|
LtExpr.prototype.execute = function (index) {
|
|
return this._exprA.execute(index) < this._exprB.execute(index) ? 1 : 0;
|
|
};
|
|
LeExpr.prototype.execute = function (index) {
|
|
return this._exprA.execute(index) <= this._exprB.execute(index) ? 1 : 0;
|
|
};
|
|
EqExpr.prototype.execute = function (index) {
|
|
return this._exprA.execute(index) == this._exprB.execute(index) ? 1 : 0;
|
|
};
|
|
var MaxExpr = create_class(OpABExpr);
|
|
MaxExpr.prototype.__construct = function (a, b) {
|
|
MaxExpr.__super.__construct.call(this, a, b);
|
|
};
|
|
MaxExpr.prototype.execute = function (index) {
|
|
return Math.max(this._exprA.execute(index), this._exprB.execute(index));
|
|
};
|
|
var AbsExpr = create_class(OpAExpr);
|
|
AbsExpr.prototype.__construct = function (a) {
|
|
AbsExpr.__super.__construct.call(this, a);
|
|
};
|
|
AbsExpr.prototype.execute = function (index) {
|
|
return Math.abs(this._exprA.execute(index));
|
|
};
|
|
var RefExpr = create_class(OpABExpr);
|
|
RefExpr.prototype.__construct = function (a, b) {
|
|
RefExpr.__super.__construct.call(this, a, b);
|
|
this._offset = -1;
|
|
};
|
|
RefExpr.prototype.execute = function (index) {
|
|
if (this._offset < 0) {
|
|
this._offset = this._exprB.execute(index);
|
|
if (this._offset < 0)
|
|
throw "offset < 0";
|
|
}
|
|
index -= this._offset;
|
|
if (index < 0)
|
|
throw "index < 0";
|
|
var result = this._exprA.execute(index);
|
|
if (isNaN(result))
|
|
throw "NaN";
|
|
return result;
|
|
};
|
|
var AndExpr = create_class(OpABExpr);
|
|
var OrExpr = create_class(OpABExpr);
|
|
AndExpr.prototype.__construct = function (a, b) {
|
|
AndExpr.__super.__construct.call(this, a, b);
|
|
};
|
|
OrExpr.prototype.__construct = function (a, b) {
|
|
OrExpr.__super.__construct.call(this, a, b);
|
|
};
|
|
AndExpr.prototype.execute = function (index) {
|
|
return (this._exprA.execute(index) != 0) && (this._exprB.execute(index) != 0) ? 1 : 0;
|
|
};
|
|
OrExpr.prototype.execute = function (index) {
|
|
return (this._exprA.execute(index) != 0) || (this._exprB.execute(index) != 0) ? 1 : 0;
|
|
};
|
|
var IfExpr = create_class(OpABCExpr);
|
|
IfExpr.prototype.__construct = function (a, b, c) {
|
|
IfExpr.__super.__construct.call(this, a, b, c);
|
|
};
|
|
IfExpr.prototype.execute = function (index) {
|
|
return this._exprA.execute(index) != 0 ? this._exprB.execute(index) : this._exprC.execute(index);
|
|
};
|
|
var AssignExpr = create_class(OpAExpr);
|
|
AssignExpr.prototype.__construct = function (name, a) {
|
|
AssignExpr.__super.__construct.call(this, a);
|
|
this._name = name;
|
|
this._buf = [];
|
|
};
|
|
AssignExpr.prototype.getName = function () {
|
|
return this._name;
|
|
};
|
|
AssignExpr.prototype.execute = function (index) {
|
|
return this._buf[index];
|
|
};
|
|
AssignExpr.prototype.assign = function (index) {
|
|
this._buf[index] = this._exprA.execute(index);
|
|
if (ExprEnv.get()._firstIndex >= 0)
|
|
if (isNaN(this._buf[index]) && !isNaN(this._buf[index - 1]))
|
|
throw this._name + ".assign(" + index + "): NaN";
|
|
};
|
|
AssignExpr.prototype.reserve = function (rid, count) {
|
|
if (this._rid < rid) {
|
|
for (var c = count; c > 0; c--)
|
|
this._buf.push(NaN);
|
|
}
|
|
AssignExpr.__super.reserve.call(this, rid, count);
|
|
};
|
|
AssignExpr.prototype.clear = function () {
|
|
AssignExpr.__super.clear.call(this);
|
|
this._buf = [];
|
|
};
|
|
var OutputStyle = {
|
|
None: 0,
|
|
Line: 1,
|
|
VolumeStick: 2,
|
|
MACDStick: 3,
|
|
SARPoint: 4
|
|
};
|
|
var OutputExpr = create_class(AssignExpr);
|
|
OutputExpr.prototype.__construct = function (name, a, style, color) {
|
|
OutputExpr.__super.__construct.call(this, name, a);
|
|
this._style = (style === undefined) ? OutputStyle.Line : style;
|
|
this._color = color;
|
|
};
|
|
OutputExpr.prototype.getStyle = function () {
|
|
return this._style;
|
|
};
|
|
OutputExpr.prototype.getColor = function () {
|
|
return this._color;
|
|
};
|
|
var RangeOutputExpr = create_class(OutputExpr);
|
|
RangeOutputExpr.prototype.__construct = function (name, a, style, color) {
|
|
RangeOutputExpr.__super.__construct.call(this, name, a, style, color);
|
|
};
|
|
RangeOutputExpr.prototype.getName = function () {
|
|
return this._name + this._exprA.getRange();
|
|
};
|
|
var RangeExpr = create_class(OpABExpr);
|
|
RangeExpr.prototype.__construct = function (a, b) {
|
|
RangeExpr.__super.__construct.call(this, a, b);
|
|
this._range = -1;
|
|
this._buf = [];
|
|
};
|
|
RangeExpr.prototype.getRange = function () {
|
|
return this._range;
|
|
};
|
|
RangeExpr.prototype.initRange = function () {
|
|
this._range = this._exprB.execute(0);
|
|
};
|
|
RangeExpr.prototype.execute = function (index) {
|
|
if (this._range < 0)
|
|
this.initRange();
|
|
var rA = this._buf[index].resultA = this._exprA.execute(index);
|
|
var r = this._buf[index].result = this.calcResult(index, rA);
|
|
return r;
|
|
};
|
|
RangeExpr.prototype.reserve = function (rid, count) {
|
|
if (this._rid < rid) {
|
|
for (var c = count; c > 0; c--)
|
|
this._buf.push({resultA: NaN, result: NaN});
|
|
}
|
|
RangeExpr.__super.reserve.call(this, rid, count);
|
|
};
|
|
RangeExpr.prototype.clear = function () {
|
|
RangeExpr.__super.clear.call(this);
|
|
this._range = -1;
|
|
this._buf = [];
|
|
};
|
|
var HhvExpr = create_class(RangeExpr);
|
|
var LlvExpr = create_class(RangeExpr);
|
|
HhvExpr.prototype.__construct = function (a, b) {
|
|
HhvExpr.__super.__construct.call(this, a, b);
|
|
};
|
|
LlvExpr.prototype.__construct = function (a, b) {
|
|
LlvExpr.__super.__construct.call(this, a, b);
|
|
};
|
|
HhvExpr.prototype.calcResult = function (index, resultA) {
|
|
if (this._range == 0)
|
|
return NaN;
|
|
var first = ExprEnv.get()._firstIndex;
|
|
if (first < 0)
|
|
return resultA;
|
|
if (index > first) {
|
|
var n = this._range;
|
|
var result = resultA;
|
|
var start = index - n + 1;
|
|
var i = Math.max(first, start);
|
|
for (; i < index; i++) {
|
|
var p = this._buf[i];
|
|
if (result < p.resultA)
|
|
result = p.resultA;
|
|
}
|
|
return result;
|
|
} else {
|
|
return resultA;
|
|
}
|
|
};
|
|
LlvExpr.prototype.calcResult = function (index, resultA) {
|
|
if (this._range == 0)
|
|
return NaN;
|
|
var first = ExprEnv.get()._firstIndex;
|
|
if (first < 0)
|
|
return resultA;
|
|
if (index > first) {
|
|
var n = this._range;
|
|
var result = resultA;
|
|
var start = index - n + 1;
|
|
var i = Math.max(first, start);
|
|
for (; i < index; i++) {
|
|
var p = this._buf[i];
|
|
if (result > p.resultA)
|
|
result = p.resultA;
|
|
}
|
|
return result;
|
|
} else {
|
|
return resultA;
|
|
}
|
|
};
|
|
var CountExpr = create_class(RangeExpr);
|
|
CountExpr.prototype.__construct = function (a, b) {
|
|
CountExpr.__super.__construct.call(this, a, b);
|
|
};
|
|
CountExpr.prototype.calcResult = function (index, resultA) {
|
|
if (this._range == 0)
|
|
return NaN;
|
|
var first = ExprEnv.get()._firstIndex;
|
|
if (first < 0)
|
|
return 0;
|
|
if (index >= first) {
|
|
var n = this._range - 1;
|
|
if (n > index - first)
|
|
n = index - first;
|
|
var count = 0;
|
|
for (; n >= 0; n--) {
|
|
if (this._buf[index - n].resultA != 0.0)
|
|
count++;
|
|
}
|
|
return count;
|
|
} else {
|
|
return 0;
|
|
}
|
|
};
|
|
var SumExpr = create_class(RangeExpr);
|
|
SumExpr.prototype.__construct = function (a, b) {
|
|
SumExpr.__super.__construct.call(this, a, b);
|
|
};
|
|
SumExpr.prototype.calcResult = function (index, resultA) {
|
|
var first = ExprEnv.get()._firstIndex;
|
|
if (first < 0)
|
|
return resultA;
|
|
if (index > first) {
|
|
var n = this._range;
|
|
if (n == 0 || n >= index + 1 - first) {
|
|
return this._buf[index - 1].result + resultA;
|
|
}
|
|
return this._buf[index - 1].result + resultA - this._buf[index - n].resultA;
|
|
} else {
|
|
return resultA;
|
|
}
|
|
};
|
|
var StdExpr = create_class(RangeExpr);
|
|
StdExpr.prototype.__construct = function (a, b) {
|
|
StdExpr.__super.__construct.call(this, a, b);
|
|
};
|
|
StdExpr.prototype.calcResult = function (index, resultA) {
|
|
if (this._range == 0)
|
|
return NaN;
|
|
var stdData = this._stdBuf[index];
|
|
var first = ExprEnv.get()._firstIndex;
|
|
if (first < 0) {
|
|
stdData.resultMA = resultA;
|
|
return 0.0;
|
|
}
|
|
if (index > first) {
|
|
var n = this._range;
|
|
if (n >= index + 1 - first) {
|
|
n = index + 1 - first;
|
|
stdData.resultMA = this._stdBuf[index - 1].resultMA * (1.0 - 1.0 / n) + (resultA / n);
|
|
} else {
|
|
stdData.resultMA = this._stdBuf[index - 1].resultMA + (resultA - this._buf[index - n].resultA) / n;
|
|
}
|
|
var sum = 0;
|
|
for (var i = index - n + 1; i <= index; i++)
|
|
sum += Math.pow(this._buf[i].resultA - stdData.resultMA, 2);
|
|
return Math.sqrt(sum / n);
|
|
}
|
|
stdData.resultMA = resultA;
|
|
return 0.0;
|
|
};
|
|
StdExpr.prototype.reserve = function (rid, count) {
|
|
if (this._rid < rid) {
|
|
for (var c = count; c > 0; c--)
|
|
this._stdBuf.push({resultMA: NaN});
|
|
}
|
|
StdExpr.__super.reserve.call(this, rid, count);
|
|
};
|
|
StdExpr.prototype.clear = function () {
|
|
StdExpr.__super.clear.call(this);
|
|
this._stdBuf = [];
|
|
};
|
|
var MaExpr = create_class(RangeExpr);
|
|
MaExpr.prototype.__construct = function (a, b) {
|
|
MaExpr.__super.__construct.call(this, a, b);
|
|
};
|
|
MaExpr.prototype.calcResult = function (index, resultA) {
|
|
if (this._range == 0)
|
|
return NaN;
|
|
var first = ExprEnv.get()._firstIndex;
|
|
if (first < 0)
|
|
return resultA;
|
|
if (index > first) {
|
|
var n = this._range;
|
|
if (n >= index + 1 - first) {
|
|
n = index + 1 - first;
|
|
return this._buf[index - 1].result * (1.0 - 1.0 / n) + (resultA / n);
|
|
}
|
|
return this._buf[index - 1].result + (resultA - this._buf[index - n].resultA) / n;
|
|
} else {
|
|
return resultA;
|
|
}
|
|
};
|
|
var EmaExpr = create_class(RangeExpr);
|
|
EmaExpr.prototype.__construct = function (a, b) {
|
|
EmaExpr.__super.__construct.call(this, a, b);
|
|
};
|
|
EmaExpr.prototype.initRange = function () {
|
|
EmaExpr.__super.initRange.call(this);
|
|
this._alpha = 2.0 / (this._range + 1);
|
|
};
|
|
EmaExpr.prototype.calcResult = function (index, resultA) {
|
|
if (this._range == 0)
|
|
return NaN;
|
|
var first = ExprEnv.get()._firstIndex;
|
|
if (first < 0)
|
|
return resultA;
|
|
if (index > first) {
|
|
var prev = this._buf[index - 1];
|
|
return this._alpha * (resultA - prev.result) + prev.result;
|
|
}
|
|
return resultA;
|
|
};
|
|
var ExpmemaExpr = create_class(EmaExpr);
|
|
ExpmemaExpr.prototype.__construct = function (a, b) {
|
|
ExpmemaExpr.__super.__construct.call(this, a, b);
|
|
};
|
|
ExpmemaExpr.prototype.calcResult = function (index, resultA) {
|
|
var first = ExprEnv.get()._firstIndex;
|
|
if (first < 0)
|
|
return resultA;
|
|
if (index > first) {
|
|
var n = this._range;
|
|
var prev = this._buf[index - 1];
|
|
if (n >= index + 1 - first) {
|
|
n = index + 1 - first;
|
|
return prev.result * (1.0 - 1.0 / n) + (resultA / n);
|
|
}
|
|
return this._alpha * (resultA - prev.result) + prev.result;
|
|
}
|
|
return resultA;
|
|
};
|
|
var SmaExpr = create_class(RangeExpr);
|
|
SmaExpr.prototype.__construct = function (a, b, c) {
|
|
SmaExpr.__super.__construct.call(this, a, b);
|
|
this._exprC = c;
|
|
this._mul;
|
|
};
|
|
SmaExpr.prototype.initRange = function () {
|
|
SmaExpr.__super.initRange.call(this);
|
|
this._mul = this._exprC.execute(0);
|
|
};
|
|
SmaExpr.prototype.calcResult = function (index, resultA) {
|
|
if (this._range == 0)
|
|
return NaN;
|
|
var first = ExprEnv.get()._firstIndex;
|
|
if (first < 0)
|
|
return resultA;
|
|
if (index > first) {
|
|
var n = this._range;
|
|
if (n > index + 1 - first)
|
|
n = index + 1 - first;
|
|
return ((n - 1) * this._buf[index - 1].result + resultA * this._mul) / n;
|
|
}
|
|
return resultA;
|
|
};
|
|
var SarExpr = create_class(OpABCDExpr);
|
|
SarExpr.prototype.__construct = function (a, b, c, d) {
|
|
SarExpr.__super.__construct.call(this, a, b, c, d);
|
|
this._buf = [];
|
|
this._range = -1;
|
|
this._min;
|
|
this._step;
|
|
this._max;
|
|
};
|
|
SarExpr.prototype.execute = function (index) {
|
|
if (this._range < 0) {
|
|
this._range = this._exprA.execute(0);
|
|
this._min = this._exprB.execute(0) / 100.0;
|
|
this._step = this._exprC.execute(0) / 100.0;
|
|
this._max = this._exprD.execute(0) / 100.0;
|
|
}
|
|
var data = this._buf[index];
|
|
var exprEnv = ExprEnv.get();
|
|
var first = exprEnv._firstIndex;
|
|
if (first < 0) {
|
|
data.longPos = true;
|
|
data.sar = exprEnv._ds.getDataAt(index).low;
|
|
data.ep = exprEnv._ds.getDataAt(index).high;
|
|
data.af = 0.02;
|
|
} else {
|
|
var high = exprEnv._ds.getDataAt(index).high;
|
|
var low = exprEnv._ds.getDataAt(index).low;
|
|
var prev = this._buf[index - 1];
|
|
data.sar = prev.sar + prev.af * (prev.ep - prev.sar);
|
|
if (prev.longPos) {
|
|
data.longPos = true;
|
|
if (high > prev.ep) {
|
|
data.ep = high;
|
|
data.af = Math.min(prev.af + this._step, this._max);
|
|
} else {
|
|
data.ep = prev.ep;
|
|
data.af = prev.af;
|
|
}
|
|
if (data.sar > low) {
|
|
data.longPos = false;
|
|
var i = index - this._range + 1;
|
|
for (i = Math.max(i, first); i < index; i++) {
|
|
var h = exprEnv._ds.getDataAt(i).high;
|
|
if (high < h) high = h;
|
|
}
|
|
data.sar = high;
|
|
data.ep = low;
|
|
data.af = 0.02;
|
|
}
|
|
} else {
|
|
data.longPos = false;
|
|
if (low < prev.ep) {
|
|
data.ep = low;
|
|
data.af = Math.min(prev.af + this._step, this._max);
|
|
} else {
|
|
data.ep = prev.ep;
|
|
data.af = prev.af;
|
|
}
|
|
if (data.sar < high) {
|
|
data.longPos = true;
|
|
var i = index - this._range + 1;
|
|
for (i = Math.max(i, first); i < index; i++) {
|
|
var l = exprEnv._ds.getDataAt(i).low;
|
|
if (low > l) low = l;
|
|
}
|
|
data.sar = low;
|
|
data.ep = high;
|
|
data.af = 0.02;
|
|
}
|
|
}
|
|
}
|
|
return data.sar;
|
|
};
|
|
SarExpr.prototype.reserve = function (rid, count) {
|
|
if (this._rid < rid) {
|
|
for (var c = count; c > 0; c--)
|
|
this._buf.push({longPos: true, sar: NaN, ep: NaN, af: NaN});
|
|
}
|
|
SarExpr.__super.reserve.call(this, rid, count);
|
|
};
|
|
SarExpr.prototype.clear = function () {
|
|
SarExpr.__super.clear.call(this);
|
|
this._range = -1;
|
|
};
|
|
var Indicator = create_class();
|
|
Indicator.prototype.__construct = function () {
|
|
this._exprEnv = new ExprEnv();
|
|
this._rid = 0;
|
|
this._params = [];
|
|
this._assigns = [];
|
|
this._outputs = [];
|
|
};
|
|
Indicator.prototype.addParameter = function (expr) {
|
|
this._params.push(expr);
|
|
};
|
|
Indicator.prototype.addAssign = function (expr) {
|
|
this._assigns.push(expr);
|
|
};
|
|
Indicator.prototype.addOutput = function (expr) {
|
|
this._outputs.push(expr);
|
|
};
|
|
Indicator.prototype.getParameterCount = function () {
|
|
return this._params.length;
|
|
};
|
|
Indicator.prototype.getParameterAt = function (index) {
|
|
return this._params[index];
|
|
};
|
|
Indicator.prototype.getOutputCount = function () {
|
|
return this._outputs.length;
|
|
};
|
|
Indicator.prototype.getOutputAt = function (index) {
|
|
return this._outputs[index];
|
|
};
|
|
Indicator.prototype.clear = function () {
|
|
this._exprEnv.setFirstIndex(-1);
|
|
var i, cnt;
|
|
cnt = this._assigns.length;
|
|
for (i = 0; i < cnt; i++) {
|
|
this._assigns[i].clear();
|
|
}
|
|
cnt = this._outputs.length;
|
|
for (i = 0; i < cnt; i++) {
|
|
this._outputs[i].clear();
|
|
}
|
|
};
|
|
Indicator.prototype.reserve = function (count) {
|
|
this._rid++;
|
|
var i, cnt;
|
|
cnt = this._assigns.length;
|
|
for (i = 0; i < cnt; i++) {
|
|
this._assigns[i].reserve(this._rid, count);
|
|
}
|
|
cnt = this._outputs.length;
|
|
for (i = 0; i < cnt; i++) {
|
|
this._outputs[i].reserve(this._rid, count);
|
|
}
|
|
};
|
|
Indicator.prototype.execute = function (ds, index) {
|
|
if (index < 0)
|
|
return;
|
|
this._exprEnv.setDataSource(ds);
|
|
ExprEnv.set(this._exprEnv);
|
|
try {
|
|
var i, cnt;
|
|
cnt = this._assigns.length;
|
|
for (i = 0; i < cnt; i++) {
|
|
this._assigns[i].assign(index);
|
|
}
|
|
cnt = this._outputs.length;
|
|
for (i = 0; i < cnt; i++) {
|
|
this._outputs[i].assign(index);
|
|
}
|
|
if (this._exprEnv.getFirstIndex() < 0)
|
|
this._exprEnv.setFirstIndex(index);
|
|
} catch (e) {
|
|
if (this._exprEnv.getFirstIndex() >= 0) {
|
|
alert(e);
|
|
throw e;
|
|
}
|
|
}
|
|
};
|
|
Indicator.prototype.getParameters = function () {
|
|
var params = [];
|
|
var i, cnt = this._params.length;
|
|
for (i = 0; i < cnt; i++)
|
|
params.push(this._params[i].getValue());
|
|
return params;
|
|
};
|
|
Indicator.prototype.setParameters = function (params) {
|
|
if ((params instanceof Array) && params.length == this._params.length) {
|
|
for (var i in this._params)
|
|
this._params[i].setValue(params[i]);
|
|
}
|
|
};
|
|
var HLCIndicator = create_class(Indicator);
|
|
HLCIndicator.prototype.__construct = function () {
|
|
HLCIndicator.__super.__construct.call(this);
|
|
var M1 = new ParameterExpr("M1", 2, 1000, 60);
|
|
this.addParameter(M1);
|
|
this.addOutput(new OutputExpr("HIGH",
|
|
new HighExpr(),
|
|
OutputStyle.None
|
|
));
|
|
this.addOutput(new OutputExpr("LOW",
|
|
new LowExpr(),
|
|
OutputStyle.None
|
|
));
|
|
this.addOutput(new OutputExpr("CLOSE",
|
|
new CloseExpr(),
|
|
OutputStyle.Line,
|
|
Theme.Color.Indicator0
|
|
));
|
|
this.addOutput(new RangeOutputExpr("MA",
|
|
new MaExpr(new CloseExpr(), M1),
|
|
OutputStyle.Line,
|
|
Theme.Color.Indicator1
|
|
));
|
|
};
|
|
HLCIndicator.prototype.getName = function () {
|
|
return "CLOSE";
|
|
};
|
|
var MAIndicator = create_class(Indicator);
|
|
MAIndicator.prototype.__construct = function () {
|
|
MAIndicator.__super.__construct.call(this);
|
|
var M1 = new ParameterExpr("M1", 2, 1000, 7);
|
|
var M2 = new ParameterExpr("M2", 2, 1000, 30);
|
|
var M3 = new ParameterExpr("M3", 2, 1000, 0);
|
|
var M4 = new ParameterExpr("M4", 2, 1000, 0);
|
|
var M5 = new ParameterExpr("M5", 2, 1000, 0);
|
|
var M6 = new ParameterExpr("M6", 2, 1000, 0);
|
|
this.addParameter(M1);
|
|
this.addParameter(M2);
|
|
this.addParameter(M3);
|
|
this.addParameter(M4);
|
|
this.addParameter(M5);
|
|
this.addParameter(M6);
|
|
this.addOutput(new RangeOutputExpr("MA",
|
|
new MaExpr(new CloseExpr(), M1)
|
|
));
|
|
this.addOutput(new RangeOutputExpr("MA",
|
|
new MaExpr(new CloseExpr(), M2)
|
|
));
|
|
this.addOutput(new RangeOutputExpr("MA",
|
|
new MaExpr(new CloseExpr(), M3)
|
|
));
|
|
this.addOutput(new RangeOutputExpr("MA",
|
|
new MaExpr(new CloseExpr(), M4)
|
|
));
|
|
this.addOutput(new RangeOutputExpr("MA",
|
|
new MaExpr(new CloseExpr(), M5)
|
|
));
|
|
this.addOutput(new RangeOutputExpr("MA",
|
|
new MaExpr(new CloseExpr(), M6)
|
|
));
|
|
};
|
|
MAIndicator.prototype.getName = function () {
|
|
return "MA";
|
|
};
|
|
var EMAIndicator = create_class(Indicator);
|
|
EMAIndicator.prototype.__construct = function () {
|
|
EMAIndicator.__super.__construct.call(this);
|
|
var M1 = new ParameterExpr("M1", 2, 1000, 7);
|
|
var M2 = new ParameterExpr("M2", 2, 1000, 30);
|
|
var M3 = new ParameterExpr("M3", 2, 1000, 0);
|
|
var M4 = new ParameterExpr("M4", 2, 1000, 0);
|
|
var M5 = new ParameterExpr("M5", 2, 1000, 0);
|
|
var M6 = new ParameterExpr("M6", 2, 1000, 0);
|
|
this.addParameter(M1);
|
|
this.addParameter(M2);
|
|
this.addParameter(M3);
|
|
this.addParameter(M4);
|
|
this.addParameter(M5);
|
|
this.addParameter(M6);
|
|
this.addOutput(new RangeOutputExpr("EMA",
|
|
new EmaExpr(new CloseExpr(), M1)
|
|
));
|
|
this.addOutput(new RangeOutputExpr("EMA",
|
|
new EmaExpr(new CloseExpr(), M2)
|
|
));
|
|
this.addOutput(new RangeOutputExpr("EMA",
|
|
new EmaExpr(new CloseExpr(), M3)
|
|
));
|
|
this.addOutput(new RangeOutputExpr("EMA",
|
|
new EmaExpr(new CloseExpr(), M4)
|
|
));
|
|
this.addOutput(new RangeOutputExpr("EMA",
|
|
new EmaExpr(new CloseExpr(), M5)
|
|
));
|
|
this.addOutput(new RangeOutputExpr("EMA",
|
|
new EmaExpr(new CloseExpr(), M6)
|
|
));
|
|
};
|
|
EMAIndicator.prototype.getName = function () {
|
|
return "EMA";
|
|
};
|
|
var VOLUMEIndicator = create_class(Indicator);
|
|
VOLUMEIndicator.prototype.__construct = function () {
|
|
VOLUMEIndicator.__super.__construct.call(this);
|
|
var M1 = new ParameterExpr("M1", 2, 500, 5);
|
|
var M2 = new ParameterExpr("M2", 2, 500, 10);
|
|
this.addParameter(M1);
|
|
this.addParameter(M2);
|
|
var VOLUME = new OutputExpr("VOLUME",
|
|
new VolumeExpr(),
|
|
OutputStyle.VolumeStick,
|
|
Theme.Color.Text4
|
|
);
|
|
this.addOutput(VOLUME);
|
|
this.addOutput(new RangeOutputExpr("MA",
|
|
new MaExpr(VOLUME, M1),
|
|
OutputStyle.Line,
|
|
Theme.Color.Indicator0
|
|
));
|
|
this.addOutput(new RangeOutputExpr("MA",
|
|
new MaExpr(VOLUME, M2),
|
|
OutputStyle.Line,
|
|
Theme.Color.Indicator1
|
|
));
|
|
};
|
|
VOLUMEIndicator.prototype.getName = function () {
|
|
return "VOLUME";
|
|
};
|
|
var MACDIndicator = create_class(Indicator);
|
|
MACDIndicator.prototype.__construct = function () {
|
|
MACDIndicator.__super.__construct.call(this);
|
|
var SHORT = new ParameterExpr("SHORT", 2, 200, 12);
|
|
var LONG = new ParameterExpr("LONG", 2, 200, 26);
|
|
var MID = new ParameterExpr("MID", 2, 200, 9);
|
|
this.addParameter(SHORT);
|
|
this.addParameter(LONG);
|
|
this.addParameter(MID);
|
|
var DIF = new OutputExpr("DIF",
|
|
new SubExpr(
|
|
new EmaExpr(new CloseExpr(), SHORT),
|
|
new EmaExpr(new CloseExpr(), LONG)
|
|
)
|
|
);
|
|
this.addOutput(DIF);
|
|
var DEA = new OutputExpr("DEA",
|
|
new EmaExpr(DIF, MID)
|
|
);
|
|
this.addOutput(DEA);
|
|
var MACD = new OutputExpr("MACD",
|
|
new MulExpr(
|
|
new SubExpr(DIF, DEA),
|
|
new ConstExpr(2)
|
|
),
|
|
OutputStyle.MACDStick
|
|
);
|
|
this.addOutput(MACD);
|
|
};
|
|
MACDIndicator.prototype.getName = function () {
|
|
return "MACD";
|
|
};
|
|
var DMIIndicator = create_class(Indicator);
|
|
DMIIndicator.prototype.__construct = function () {
|
|
DMIIndicator.__super.__construct.call(this);
|
|
var N = new ParameterExpr("N", 2, 90, 14);
|
|
var MM = new ParameterExpr("MM", 2, 60, 6);
|
|
this.addParameter(N);
|
|
this.addParameter(MM);
|
|
var MTR = new AssignExpr("MTR",
|
|
new ExpmemaExpr(
|
|
new MaxExpr(
|
|
new MaxExpr(
|
|
new SubExpr(new HighExpr(), new LowExpr()),
|
|
new AbsExpr(
|
|
new SubExpr(
|
|
new HighExpr(),
|
|
new RefExpr(new CloseExpr(), new ConstExpr(1))
|
|
)
|
|
)
|
|
),
|
|
new AbsExpr(
|
|
new SubExpr(
|
|
new RefExpr(new CloseExpr(), new ConstExpr(1)),
|
|
new LowExpr()
|
|
)
|
|
)
|
|
),
|
|
N
|
|
)
|
|
);
|
|
this.addAssign(MTR);
|
|
var HD = new AssignExpr("HD",
|
|
new SubExpr(
|
|
new HighExpr(),
|
|
new RefExpr(new HighExpr(), new ConstExpr(1))
|
|
)
|
|
);
|
|
this.addAssign(HD);
|
|
var LD = new AssignExpr("LD",
|
|
new SubExpr(
|
|
new RefExpr(new LowExpr(), new ConstExpr(1)),
|
|
new LowExpr()
|
|
)
|
|
);
|
|
this.addAssign(LD);
|
|
var DMP = new AssignExpr("DMP",
|
|
new ExpmemaExpr(
|
|
new IfExpr(
|
|
new AndExpr(
|
|
new GtExpr(HD, new ConstExpr(0)),
|
|
new GtExpr(HD, LD)
|
|
),
|
|
HD,
|
|
new ConstExpr(0)
|
|
),
|
|
N
|
|
)
|
|
);
|
|
this.addAssign(DMP);
|
|
var DMM = new AssignExpr("DMM",
|
|
new ExpmemaExpr(
|
|
new IfExpr(
|
|
new AndExpr(
|
|
new GtExpr(LD, new ConstExpr(0)),
|
|
new GtExpr(LD, HD)
|
|
),
|
|
LD,
|
|
new ConstExpr(0)
|
|
),
|
|
N
|
|
)
|
|
);
|
|
this.addAssign(DMM);
|
|
var PDI = new OutputExpr("PDI",
|
|
new MulExpr(
|
|
new DivExpr(DMP, MTR),
|
|
new ConstExpr(100)
|
|
)
|
|
);
|
|
this.addOutput(PDI);
|
|
var MDI = new OutputExpr("MDI",
|
|
new MulExpr(
|
|
new DivExpr(DMM, MTR),
|
|
new ConstExpr(100)
|
|
)
|
|
);
|
|
this.addOutput(MDI);
|
|
var ADX = new OutputExpr("ADX",
|
|
new ExpmemaExpr(
|
|
new MulExpr(
|
|
new DivExpr(
|
|
new AbsExpr(
|
|
new SubExpr(MDI, PDI)
|
|
),
|
|
new AddExpr(MDI, PDI)
|
|
),
|
|
new ConstExpr(100)
|
|
),
|
|
MM
|
|
)
|
|
);
|
|
this.addOutput(ADX);
|
|
var ADXR = new OutputExpr("ADXR",
|
|
new ExpmemaExpr(ADX, MM)
|
|
);
|
|
this.addOutput(ADXR);
|
|
};
|
|
DMIIndicator.prototype.getName = function () {
|
|
return "DMI";
|
|
};
|
|
var DMAIndicator = create_class(Indicator);
|
|
DMAIndicator.prototype.__construct = function () {
|
|
DMAIndicator.__super.__construct.call(this);
|
|
var N1 = new ParameterExpr("N1", 2, 60, 10);
|
|
var N2 = new ParameterExpr("N2", 2, 250, 50);
|
|
var M = new ParameterExpr("M", 2, 100, 10);
|
|
this.addParameter(N1);
|
|
this.addParameter(N2);
|
|
this.addParameter(M);
|
|
var DIF = new OutputExpr("DIF",
|
|
new SubExpr(
|
|
new MaExpr(new CloseExpr(), N1),
|
|
new MaExpr(new CloseExpr(), N2)
|
|
)
|
|
);
|
|
this.addOutput(DIF);
|
|
var DIFMA = new OutputExpr("DIFMA",
|
|
new MaExpr(DIF, M)
|
|
);
|
|
this.addOutput(DIFMA);
|
|
};
|
|
DMAIndicator.prototype.getName = function () {
|
|
return "DMA";
|
|
};
|
|
var TRIXIndicator = create_class(Indicator);
|
|
TRIXIndicator.prototype.__construct = function () {
|
|
TRIXIndicator.__super.__construct.call(this);
|
|
var N = new ParameterExpr("N", 2, 100, 12);
|
|
var M = new ParameterExpr("M", 2, 100, 9);
|
|
this.addParameter(N);
|
|
this.addParameter(M);
|
|
var MTR = new AssignExpr("MTR",
|
|
new EmaExpr(
|
|
new EmaExpr(
|
|
new EmaExpr(new CloseExpr(), N), N), N)
|
|
);
|
|
this.addAssign(MTR);
|
|
var TRIX = new OutputExpr("TRIX",
|
|
new MulExpr(
|
|
new DivExpr(
|
|
new SubExpr(
|
|
MTR,
|
|
new RefExpr(
|
|
MTR,
|
|
new ConstExpr(1)
|
|
)
|
|
),
|
|
new RefExpr(
|
|
MTR,
|
|
new ConstExpr(1)
|
|
)
|
|
),
|
|
new ConstExpr(100)
|
|
)
|
|
);
|
|
this.addOutput(TRIX);
|
|
var MATRIX = new OutputExpr("MATRIX",
|
|
new MaExpr(TRIX, M)
|
|
);
|
|
this.addOutput(MATRIX);
|
|
};
|
|
TRIXIndicator.prototype.getName = function () {
|
|
return "TRIX";
|
|
};
|
|
var BRARIndicator = create_class(Indicator);
|
|
BRARIndicator.prototype.__construct = function () {
|
|
BRARIndicator.__super.__construct.call(this);
|
|
var N = new ParameterExpr("N", 2, 120, 26);
|
|
this.addParameter(N);
|
|
var REF_CLOSE_1 = new AssignExpr("REF_CLOSE_1",
|
|
new RefExpr(new CloseExpr(), new ConstExpr(1))
|
|
);
|
|
this.addAssign(REF_CLOSE_1);
|
|
var BR = new OutputExpr("BR",
|
|
new MulExpr(
|
|
new DivExpr(
|
|
new SumExpr(
|
|
new MaxExpr(
|
|
new ConstExpr(0),
|
|
new SubExpr(
|
|
new HighExpr(),
|
|
REF_CLOSE_1
|
|
)
|
|
),
|
|
N
|
|
),
|
|
new SumExpr(
|
|
new MaxExpr(
|
|
new ConstExpr(0),
|
|
new SubExpr(
|
|
REF_CLOSE_1,
|
|
new LowExpr()
|
|
)
|
|
),
|
|
N
|
|
)
|
|
),
|
|
new ConstExpr(100)
|
|
)
|
|
);
|
|
this.addOutput(BR);
|
|
var AR = new OutputExpr("AR",
|
|
new MulExpr(
|
|
new DivExpr(
|
|
new SumExpr(
|
|
new SubExpr(
|
|
new HighExpr(),
|
|
new OpenExpr()
|
|
),
|
|
N
|
|
),
|
|
new SumExpr(
|
|
new SubExpr(
|
|
new OpenExpr(),
|
|
new LowExpr()
|
|
),
|
|
N
|
|
)
|
|
),
|
|
new ConstExpr(100)
|
|
)
|
|
);
|
|
this.addOutput(AR);
|
|
};
|
|
BRARIndicator.prototype.getName = function () {
|
|
return "BRAR";
|
|
};
|
|
var VRIndicator = create_class(Indicator);
|
|
VRIndicator.prototype.__construct = function () {
|
|
VRIndicator.__super.__construct.call(this);
|
|
var N = new ParameterExpr("N", 2, 100, 26);
|
|
var M = new ParameterExpr("M", 2, 100, 6);
|
|
this.addParameter(N);
|
|
this.addParameter(M);
|
|
var REF_CLOSE_1 = new AssignExpr("REF_CLOSE_1",
|
|
new RefExpr(new CloseExpr(), new ConstExpr(1))
|
|
);
|
|
this.addAssign(REF_CLOSE_1);
|
|
var TH = new AssignExpr("TH",
|
|
new SumExpr(
|
|
new IfExpr(
|
|
new GtExpr(
|
|
new CloseExpr(),
|
|
REF_CLOSE_1
|
|
),
|
|
new VolumeExpr(),
|
|
new ConstExpr(0)
|
|
),
|
|
N
|
|
)
|
|
);
|
|
this.addAssign(TH);
|
|
var TL = new AssignExpr("TL",
|
|
new SumExpr(
|
|
new IfExpr(
|
|
new LtExpr(
|
|
new CloseExpr(),
|
|
REF_CLOSE_1
|
|
),
|
|
new VolumeExpr(),
|
|
new ConstExpr(0)
|
|
),
|
|
N
|
|
)
|
|
);
|
|
this.addAssign(TL);
|
|
var TQ = new AssignExpr("TQ",
|
|
new SumExpr(
|
|
new IfExpr(
|
|
new EqExpr(
|
|
new CloseExpr(),
|
|
REF_CLOSE_1
|
|
),
|
|
new VolumeExpr(),
|
|
new ConstExpr(0)
|
|
),
|
|
N
|
|
)
|
|
);
|
|
this.addAssign(TQ);
|
|
var VR = new OutputExpr("VR",
|
|
new MulExpr(
|
|
new DivExpr(
|
|
new AddExpr(
|
|
new MulExpr(
|
|
TH,
|
|
new ConstExpr(2)
|
|
),
|
|
TQ
|
|
),
|
|
new AddExpr(
|
|
new MulExpr(
|
|
TL,
|
|
new ConstExpr(2)
|
|
),
|
|
TQ
|
|
)
|
|
),
|
|
new ConstExpr(100)
|
|
)
|
|
);
|
|
this.addOutput(VR);
|
|
var MAVR = new OutputExpr("MAVR",
|
|
new MaExpr(VR, M)
|
|
);
|
|
this.addOutput(MAVR);
|
|
};
|
|
VRIndicator.prototype.getName = function () {
|
|
return "VR";
|
|
};
|
|
var OBVIndicator = create_class(Indicator);
|
|
OBVIndicator.prototype.__construct = function () {
|
|
OBVIndicator.__super.__construct.call(this);
|
|
var M = new ParameterExpr("M", 2, 100, 30);
|
|
this.addParameter(M);
|
|
var REF_CLOSE_1 = new AssignExpr("REF_CLOSE_1",
|
|
new RefExpr(new CloseExpr(), new ConstExpr(1))
|
|
);
|
|
this.addAssign(REF_CLOSE_1);
|
|
var VA = new AssignExpr("VA",
|
|
new IfExpr(
|
|
new GtExpr(new CloseExpr(), REF_CLOSE_1),
|
|
new VolumeExpr(),
|
|
new NegExpr(new VolumeExpr())
|
|
)
|
|
);
|
|
this.addAssign(VA);
|
|
var OBV = new OutputExpr("OBV",
|
|
new SumExpr(
|
|
new IfExpr(
|
|
new EqExpr(new CloseExpr(), REF_CLOSE_1),
|
|
new ConstExpr(0),
|
|
VA
|
|
),
|
|
new ConstExpr(0)
|
|
)
|
|
);
|
|
this.addOutput(OBV);
|
|
var MAOBV = new OutputExpr("MAOBV",
|
|
new MaExpr(OBV, M)
|
|
);
|
|
this.addOutput(MAOBV);
|
|
};
|
|
OBVIndicator.prototype.getName = function () {
|
|
return "OBV";
|
|
};
|
|
var EMVIndicator = create_class(Indicator);
|
|
EMVIndicator.prototype.__construct = function () {
|
|
EMVIndicator.__super.__construct.call(this);
|
|
var N = new ParameterExpr("N", 2, 90, 14);
|
|
var M = new ParameterExpr("M", 2, 60, 9);
|
|
this.addParameter(N);
|
|
this.addParameter(M);
|
|
var VOLUME = new AssignExpr("VOLUME",
|
|
new DivExpr(
|
|
new MaExpr(new VolumeExpr(), N),
|
|
new VolumeExpr()
|
|
)
|
|
);
|
|
this.addAssign(VOLUME);
|
|
var MID = new AssignExpr("MID",
|
|
new MulExpr(
|
|
new DivExpr(
|
|
new SubExpr(
|
|
new AddExpr(new HighExpr(), new LowExpr()),
|
|
new RefExpr(
|
|
new AddExpr(new HighExpr(), new LowExpr()),
|
|
new ConstExpr(1)
|
|
)
|
|
),
|
|
new AddExpr(new HighExpr(), new LowExpr())
|
|
),
|
|
new ConstExpr(100)
|
|
)
|
|
);
|
|
this.addAssign(MID);
|
|
var EMV = new OutputExpr("EMV",
|
|
new MaExpr(
|
|
new DivExpr(
|
|
new MulExpr(
|
|
MID,
|
|
new MulExpr(
|
|
VOLUME,
|
|
new SubExpr(new HighExpr(), new LowExpr())
|
|
)
|
|
),
|
|
new MaExpr(
|
|
new SubExpr(new HighExpr(), new LowExpr()),
|
|
N
|
|
)
|
|
),
|
|
N
|
|
)
|
|
);
|
|
this.addOutput(EMV);
|
|
var MAEMV = new OutputExpr("MAEMV",
|
|
new MaExpr(EMV, M)
|
|
);
|
|
this.addOutput(MAEMV);
|
|
};
|
|
EMVIndicator.prototype.getName = function () {
|
|
return "EMV";
|
|
};
|
|
var RSIIndicator = create_class(Indicator);
|
|
RSIIndicator.prototype.__construct = function () {
|
|
RSIIndicator.__super.__construct.call(this);
|
|
var N1 = new ParameterExpr("N1", 2, 120, 6);
|
|
var N2 = new ParameterExpr("N2", 2, 250, 12);
|
|
var N3 = new ParameterExpr("N3", 2, 500, 24);
|
|
this.addParameter(N1);
|
|
this.addParameter(N2);
|
|
this.addParameter(N3);
|
|
var LC = new AssignExpr("LC",
|
|
new RefExpr(new CloseExpr(), new ConstExpr(1))
|
|
);
|
|
this.addAssign(LC);
|
|
var CLOSE_LC = new AssignExpr("CLOSE_LC",
|
|
new SubExpr(new CloseExpr(), LC)
|
|
);
|
|
this.addAssign(CLOSE_LC);
|
|
this.addOutput(new OutputExpr("RSI1",
|
|
new MulExpr(
|
|
new DivExpr(
|
|
new SmaExpr(new MaxExpr(CLOSE_LC, new ConstExpr(0)), N1, new ConstExpr(1)),
|
|
new SmaExpr(new AbsExpr(CLOSE_LC), N1, new ConstExpr(1))
|
|
),
|
|
new ConstExpr(100)
|
|
)
|
|
));
|
|
this.addOutput(new OutputExpr("RSI2",
|
|
new MulExpr(
|
|
new DivExpr(
|
|
new SmaExpr(new MaxExpr(CLOSE_LC, new ConstExpr(0)), N2, new ConstExpr(1)),
|
|
new SmaExpr(new AbsExpr(CLOSE_LC), N2, new ConstExpr(1))
|
|
),
|
|
new ConstExpr(100)
|
|
)
|
|
));
|
|
this.addOutput(new OutputExpr("RSI3",
|
|
new MulExpr(
|
|
new DivExpr(
|
|
new SmaExpr(new MaxExpr(CLOSE_LC, new ConstExpr(0)), N3, new ConstExpr(1)),
|
|
new SmaExpr(new AbsExpr(CLOSE_LC), N3, new ConstExpr(1))
|
|
),
|
|
new ConstExpr(100)
|
|
)
|
|
));
|
|
};
|
|
RSIIndicator.prototype.getName = function () {
|
|
return "RSI";
|
|
};
|
|
var WRIndicator = create_class(Indicator);
|
|
WRIndicator.prototype.__construct = function () {
|
|
WRIndicator.__super.__construct.call(this);
|
|
var N = new ParameterExpr("N", 2, 100, 10);
|
|
var N1 = new ParameterExpr("N1", 2, 100, 6);
|
|
this.addParameter(N);
|
|
this.addParameter(N1);
|
|
var HHV = new AssignExpr("HHV",
|
|
new HhvExpr(new HighExpr(), N)
|
|
);
|
|
this.addAssign(HHV);
|
|
var HHV1 = new AssignExpr("HHV1",
|
|
new HhvExpr(new HighExpr(), N1)
|
|
);
|
|
this.addAssign(HHV1);
|
|
var LLV = new AssignExpr("LLV",
|
|
new LlvExpr(new LowExpr(), N)
|
|
);
|
|
this.addAssign(LLV);
|
|
var LLV1 = new AssignExpr("LLV1",
|
|
new LlvExpr(new LowExpr(), N1)
|
|
);
|
|
this.addAssign(LLV1);
|
|
var WR1 = new OutputExpr("WR1",
|
|
new MulExpr(
|
|
new DivExpr(
|
|
new SubExpr(
|
|
HHV,
|
|
new CloseExpr()
|
|
),
|
|
new SubExpr(
|
|
HHV,
|
|
LLV
|
|
)
|
|
),
|
|
new ConstExpr(100)
|
|
)
|
|
);
|
|
this.addOutput(WR1);
|
|
var WR2 = new OutputExpr("WR2",
|
|
new MulExpr(
|
|
new DivExpr(
|
|
new SubExpr(
|
|
HHV1,
|
|
new CloseExpr()
|
|
),
|
|
new SubExpr(
|
|
HHV1,
|
|
LLV1
|
|
)
|
|
),
|
|
new ConstExpr(100)
|
|
)
|
|
);
|
|
this.addOutput(WR2);
|
|
};
|
|
WRIndicator.prototype.getName = function () {
|
|
return "WR";
|
|
};
|
|
var SARIndicator = create_class(Indicator);
|
|
SARIndicator.prototype.__construct = function () {
|
|
SARIndicator.__super.__construct.call(this);
|
|
var N = new ConstExpr(4);
|
|
var MIN = new ConstExpr(2);
|
|
var STEP = new ConstExpr(2);
|
|
var MAX = new ConstExpr(20);
|
|
this.addOutput(new OutputExpr("SAR",
|
|
new SarExpr(N, MIN, STEP, MAX),
|
|
OutputStyle.SARPoint
|
|
));
|
|
};
|
|
SARIndicator.prototype.getName = function () {
|
|
return "SAR";
|
|
};
|
|
var KDJIndicator = create_class(Indicator);
|
|
KDJIndicator.prototype.__construct = function () {
|
|
KDJIndicator.__super.__construct.call(this);
|
|
var N = new ParameterExpr("N", 2, 90, 9);
|
|
var M1 = new ParameterExpr("M1", 2, 30, 3);
|
|
var M2 = new ParameterExpr("M2", 2, 30, 3);
|
|
this.addParameter(N);
|
|
this.addParameter(M1);
|
|
this.addParameter(M2);
|
|
var HHV = new AssignExpr("HHV",
|
|
new HhvExpr(new HighExpr(), N)
|
|
);
|
|
this.addAssign(HHV);
|
|
var LLV = new AssignExpr("LLV",
|
|
new LlvExpr(new LowExpr(), N)
|
|
);
|
|
this.addAssign(LLV);
|
|
var RSV = new AssignExpr("RSV",
|
|
new MulExpr(
|
|
new DivExpr(
|
|
new SubExpr(
|
|
new CloseExpr(),
|
|
LLV
|
|
),
|
|
new SubExpr(
|
|
HHV,
|
|
LLV
|
|
)
|
|
),
|
|
new ConstExpr(100)
|
|
)
|
|
);
|
|
this.addAssign(RSV);
|
|
var K = new OutputExpr("K",
|
|
new SmaExpr(RSV, M1, new ConstExpr(1))
|
|
);
|
|
this.addOutput(K);
|
|
var D = new OutputExpr("D",
|
|
new SmaExpr(K, M2, new ConstExpr(1))
|
|
);
|
|
this.addOutput(D);
|
|
var J = new OutputExpr("J",
|
|
new SubExpr(
|
|
new MulExpr(
|
|
K,
|
|
new ConstExpr(3)
|
|
),
|
|
new MulExpr(
|
|
D,
|
|
new ConstExpr(2)
|
|
)
|
|
)
|
|
);
|
|
this.addOutput(J);
|
|
};
|
|
KDJIndicator.prototype.getName = function () {
|
|
return "KDJ";
|
|
};
|
|
var ROCIndicator = create_class(Indicator);
|
|
ROCIndicator.prototype.__construct = function () {
|
|
ROCIndicator.__super.__construct.call(this);
|
|
var N = new ParameterExpr("N", 2, 120, 12);
|
|
var M = new ParameterExpr("M", 2, 60, 6);
|
|
this.addParameter(N);
|
|
this.addParameter(M);
|
|
var REF_CLOSE_N = new AssignExpr("REF_CLOSE_N",
|
|
new RefExpr(new CloseExpr(), N)
|
|
);
|
|
this.addAssign(REF_CLOSE_N);
|
|
var ROC = new OutputExpr("ROC",
|
|
new MulExpr(
|
|
new DivExpr(
|
|
new SubExpr(
|
|
new CloseExpr(),
|
|
REF_CLOSE_N
|
|
),
|
|
REF_CLOSE_N
|
|
),
|
|
new ConstExpr(100)
|
|
)
|
|
);
|
|
this.addOutput(ROC);
|
|
var MAROC = new OutputExpr("MAROC",
|
|
new MaExpr(ROC, M)
|
|
);
|
|
this.addOutput(MAROC);
|
|
};
|
|
ROCIndicator.prototype.getName = function () {
|
|
return "ROC";
|
|
};
|
|
var MTMIndicator = create_class(Indicator);
|
|
MTMIndicator.prototype.__construct = function () {
|
|
MTMIndicator.__super.__construct.call(this);
|
|
var N = new ParameterExpr("N", 2, 120, 12);
|
|
var M = new ParameterExpr("M", 2, 60, 6);
|
|
this.addParameter(N);
|
|
this.addParameter(M);
|
|
var MTM = new OutputExpr("MTM",
|
|
new SubExpr(
|
|
new CloseExpr(),
|
|
new RefExpr(new CloseExpr(), N)
|
|
)
|
|
);
|
|
this.addOutput(MTM);
|
|
var MTMMA = new OutputExpr("MTMMA",
|
|
new MaExpr(MTM, M)
|
|
);
|
|
this.addOutput(MTMMA);
|
|
};
|
|
MTMIndicator.prototype.getName = function () {
|
|
return "MTM";
|
|
};
|
|
var BOLLIndicator = create_class(Indicator);
|
|
BOLLIndicator.prototype.__construct = function () {
|
|
BOLLIndicator.__super.__construct.call(this);
|
|
var N = new ParameterExpr("N", 2, 120, 20);
|
|
this.addParameter(N);
|
|
var STD_CLOSE_N = new AssignExpr("STD_CLOSE_N",
|
|
new StdExpr(new CloseExpr(), N)
|
|
);
|
|
this.addAssign(STD_CLOSE_N);
|
|
var BOLL = new OutputExpr("BOLL",
|
|
new MaExpr(new CloseExpr(), N)
|
|
);
|
|
this.addOutput(BOLL);
|
|
var UB = new OutputExpr("UB",
|
|
new AddExpr(
|
|
BOLL,
|
|
new MulExpr(
|
|
new ConstExpr(2),
|
|
STD_CLOSE_N
|
|
)
|
|
)
|
|
);
|
|
this.addOutput(UB);
|
|
var LB = new OutputExpr("LB",
|
|
new SubExpr(
|
|
BOLL,
|
|
new MulExpr(
|
|
new ConstExpr(2),
|
|
STD_CLOSE_N
|
|
)
|
|
)
|
|
);
|
|
this.addOutput(LB);
|
|
};
|
|
BOLLIndicator.prototype.getName = function () {
|
|
return "BOLL";
|
|
};
|
|
var PSYIndicator = create_class(Indicator);
|
|
PSYIndicator.prototype.__construct = function () {
|
|
PSYIndicator.__super.__construct.call(this);
|
|
var N = new ParameterExpr("N", 2, 100, 12);
|
|
var M = new ParameterExpr("M", 2, 100, 6);
|
|
this.addParameter(N);
|
|
this.addParameter(M);
|
|
var PSY = new OutputExpr("PSY",
|
|
new MulExpr(
|
|
new DivExpr(
|
|
new CountExpr(
|
|
new GtExpr(
|
|
new CloseExpr(),
|
|
new RefExpr(new CloseExpr(), new ConstExpr(1))
|
|
),
|
|
N
|
|
),
|
|
N
|
|
),
|
|
new ConstExpr(100)
|
|
)
|
|
);
|
|
this.addOutput(PSY);
|
|
var PSYMA = new OutputExpr("PSYMA",
|
|
new MaExpr(PSY, M)
|
|
);
|
|
this.addOutput(PSYMA);
|
|
};
|
|
PSYIndicator.prototype.getName = function () {
|
|
return "PSY";
|
|
};
|
|
var STOCHRSIIndicator = create_class(Indicator);
|
|
STOCHRSIIndicator.prototype.__construct = function () {
|
|
STOCHRSIIndicator.__super.__construct.call(this);
|
|
var N = new ParameterExpr("N", 3, 100, 14);
|
|
var M = new ParameterExpr("M", 3, 100, 14);
|
|
var P1 = new ParameterExpr("P1", 2, 50, 3);
|
|
var P2 = new ParameterExpr("P2", 2, 50, 3);
|
|
this.addParameter(N);
|
|
this.addParameter(M);
|
|
this.addParameter(P1);
|
|
this.addParameter(P2);
|
|
var LC = new AssignExpr("LC",
|
|
new RefExpr(new CloseExpr(), new ConstExpr(1))
|
|
);
|
|
this.addAssign(LC);
|
|
var CLOSE_LC = new AssignExpr("CLOSE_LC",
|
|
new SubExpr(new CloseExpr(), LC)
|
|
);
|
|
this.addAssign(CLOSE_LC);
|
|
var RSI = new AssignExpr("RSI",
|
|
new MulExpr(
|
|
new DivExpr(
|
|
new SmaExpr(new MaxExpr(CLOSE_LC, new ConstExpr(0)), N, new ConstExpr(1)),
|
|
new SmaExpr(new AbsExpr(CLOSE_LC), N, new ConstExpr(1))
|
|
),
|
|
new ConstExpr(100)
|
|
)
|
|
);
|
|
this.addAssign(RSI);
|
|
var STOCHRSI = new OutputExpr("STOCHRSI",
|
|
new MulExpr(
|
|
new DivExpr(
|
|
new MaExpr(
|
|
new SubExpr(
|
|
RSI,
|
|
new LlvExpr(RSI, M)
|
|
),
|
|
P1
|
|
),
|
|
new MaExpr(
|
|
new SubExpr(
|
|
new HhvExpr(RSI, M),
|
|
new LlvExpr(RSI, M)
|
|
),
|
|
P1
|
|
)
|
|
),
|
|
new ConstExpr(100)
|
|
)
|
|
);
|
|
this.addOutput(STOCHRSI);
|
|
this.addOutput(new RangeOutputExpr("MA",
|
|
new MaExpr(STOCHRSI, P2)
|
|
));
|
|
};
|
|
STOCHRSIIndicator.prototype.getName = function () {
|
|
return "StochRSI";
|
|
};
|
|
/**
|
|
* Created by Administrator on 2014/11/19.
|
|
*/
|
|
var Chart = create_class();
|
|
Chart.strPeriod = {
|
|
'zh-cn': {
|
|
'line': '(分时)',
|
|
'1min': '(1分钟)',
|
|
'5min': '(5分钟)',
|
|
'15min': '(15分钟)',
|
|
'30min': '(30分钟)',
|
|
'1hour': '(1小时)',
|
|
'1day': '(日线)',
|
|
'1week': '(周线)',
|
|
'3min': '(3分钟)',
|
|
'2hour': '(2小时)',
|
|
'4hour': '(4小时)',
|
|
'6hour': '(6小时)',
|
|
'12hour': '(12小时)',
|
|
'3day': '(3天)'
|
|
},
|
|
'en-us': {
|
|
'line': '(Line)',
|
|
'1min': '(1m)',
|
|
'5min': '(5m)',
|
|
'15min': '(15m)',
|
|
'30min': '(30m)',
|
|
'1hour': '(1h)',
|
|
'1day': '(1d)',
|
|
'1week': '(1w)',
|
|
'3min': '(3m)',
|
|
'2hour': '(2h)',
|
|
'4hour': '(4h)',
|
|
'6hour': '(6h)',
|
|
'12hour': '(12h)',
|
|
'3day': '(3d)'
|
|
},
|
|
'zh-tw': {
|
|
'line': '(分時)',
|
|
'1min': '(1分钟)',
|
|
'5min': '(5分钟)',
|
|
'15min': '(15分钟)',
|
|
'30min': '(30分钟)',
|
|
'1hour': '(1小時)',
|
|
'1day': '(日线)',
|
|
'1week': '(周线)',
|
|
'3min': '(3分钟)',
|
|
'2hour': '(2小時)',
|
|
'4hour': '(4小時)',
|
|
'6hour': '(6小時)',
|
|
'12hour': '(12小時)',
|
|
'3day': '(3天)'
|
|
}
|
|
};
|
|
Chart.prototype.__construct = function () {
|
|
this._data = null;
|
|
this._charStyle = "CandleStick";
|
|
this._depthData = {
|
|
array: null,
|
|
asks_count: 0,
|
|
bids_count: 0,
|
|
asks_si: 0,
|
|
asks_ei: 0,
|
|
bids_si: 0,
|
|
bids_ei: 0
|
|
};
|
|
this._range = KlineIns.range;
|
|
this._symbol = KlineIns.symbol;
|
|
};
|
|
Chart.prototype.setTitle = function () {
|
|
var lang = ChartManager.getInstance().getLanguage();
|
|
var title = KlineIns.symbolName;
|
|
title += ' ';
|
|
title += this.strIsLine ? Chart.strPeriod[lang]['line'] : Chart.strPeriod[lang][this._range];
|
|
title += (this._contract_unit + '/' + this._money_type).toUpperCase();
|
|
ChartManager.getInstance().setTitle('frame0.k0', title);
|
|
};
|
|
Chart.prototype.setSymbol = function (symbol) {
|
|
this._symbol = symbol;
|
|
this.updateDataAndDisplay();
|
|
};
|
|
|
|
Chart.prototype.updateDataAndDisplay = function () {
|
|
KlineIns.symbol = this._symbol;
|
|
KlineIns.range = this._range;
|
|
ChartManager.getInstance().setCurrentDataSource('frame0.k0', this._symbol + '.' + this._range);
|
|
ChartManager.getInstance().setNormalMode();
|
|
var f = KlineIns.chartMgr.getDataSource("frame0.k0").getLastDate();
|
|
|
|
$('.symbol-title>a').text(KlineIns.symbolName);
|
|
|
|
if (f == -1) {
|
|
KlineIns.requestParam = setHttpRequestParam(KlineIns.symbol, KlineIns.range, KlineIns.limit, null);
|
|
RequestData(true);
|
|
} else {
|
|
KlineIns.requestParam = setHttpRequestParam(KlineIns.symbol, KlineIns.range, null, f.toString());
|
|
RequestData();
|
|
}
|
|
ChartManager.getInstance().redraw('All', false);
|
|
};
|
|
Chart.prototype.setCurrentContractUnit = function (contractUnit) {
|
|
this._contract_unit = contractUnit;
|
|
this.updateDataAndDisplay();
|
|
};
|
|
Chart.prototype.setCurrentMoneyType = function (moneyType) {
|
|
this._money_type = moneyType;
|
|
this.updateDataAndDisplay();
|
|
};
|
|
Chart.prototype.setCurrentPeriod = function (period) {
|
|
this._range = KlineIns.periodMap[period];
|
|
this.updateDataAndDisplay();
|
|
KlineIns.onRangeChange(this._range);
|
|
};
|
|
Chart.prototype.updateDataSource = function (data) {
|
|
this._data = data;
|
|
ChartManager.getInstance().updateData("frame0.k0", this._data);
|
|
};
|
|
Chart.prototype.updateDepth = function (array) {
|
|
if (array == null) {
|
|
this._depthData.array = [];
|
|
ChartManager.getInstance().redraw('All', false);
|
|
return;
|
|
}
|
|
if (!array.asks || !array.bids || array.asks == '' || array.bids == '')
|
|
return;
|
|
var _data = this._depthData;
|
|
_data.array = [];
|
|
for (var i = 0; i < array.asks.length; i++) {
|
|
var data = {};
|
|
data.rate = array.asks[i][0];
|
|
data.amount = array.asks[i][1];
|
|
_data.array.push(data);
|
|
}
|
|
for (var i = 0; i < array.bids.length; i++) {
|
|
var data = {};
|
|
data.rate = array.bids[i][0];
|
|
data.amount = array.bids[i][1];
|
|
_data.array.push(data);
|
|
}
|
|
_data.asks_count = array.asks.length;
|
|
_data.bids_count = array.bids.length;
|
|
_data.asks_si = _data.asks_count - 1;
|
|
_data.asks_ei = 0;
|
|
_data.bids_si = _data.asks_count;
|
|
_data.bids_ei = _data.asks_count + _data.bids_count - 1;
|
|
for (var i = _data.asks_si; i >= _data.asks_ei; i--) {
|
|
if (i == _data.asks_si) {
|
|
_data.array[i].amounts = _data.array[i].amount;
|
|
} else {
|
|
_data.array[i].amounts = _data.array[i + 1].amounts + _data.array[i].amount;
|
|
}
|
|
}
|
|
for (var i = _data.bids_si; i <= _data.bids_ei; i++) {
|
|
if (i == _data.bids_si) {
|
|
_data.array[i].amounts = _data.array[i].amount;
|
|
} else {
|
|
_data.array[i].amounts = _data.array[i - 1].amounts + _data.array[i].amount;
|
|
}
|
|
}
|
|
ChartManager.getInstance().redraw('All', false);
|
|
};
|
|
Chart.prototype.setMainIndicator = function (indicName) {
|
|
this._mainIndicator = indicName;
|
|
if (indicName == 'NONE') {
|
|
ChartManager.getInstance().removeMainIndicator('frame0.k0');
|
|
} else {
|
|
ChartManager.getInstance().setMainIndicator('frame0.k0', indicName);
|
|
}
|
|
ChartManager.getInstance().redraw('All', true);
|
|
};
|
|
Chart.prototype.setIndicator = function (index, indicName) {
|
|
if (indicName == 'NONE') {
|
|
var index = 2;
|
|
if (Template.displayVolume == false)
|
|
index = 1;
|
|
var areaName = ChartManager.getInstance().getIndicatorAreaName('frame0.k0', index);
|
|
if (areaName != '')
|
|
ChartManager.getInstance().removeIndicator(areaName);
|
|
} else {
|
|
var index = 2;
|
|
if (Template.displayVolume == false)
|
|
index = 1;
|
|
var areaName = ChartManager.getInstance().getIndicatorAreaName('frame0.k0', index);
|
|
if (areaName == '') {
|
|
Template.createIndicatorChartComps('frame0.k0', indicName);
|
|
} else {
|
|
ChartManager.getInstance().setIndicator(areaName, indicName);
|
|
}
|
|
}
|
|
ChartManager.getInstance().redraw('All', true);
|
|
};
|
|
Chart.prototype.addIndicator = function (indicName) {
|
|
ChartManager.getInstance().addIndicator(indicName);
|
|
ChartManager.getInstance().redraw('All', true);
|
|
};
|
|
Chart.prototype.removeIndicator = function (indicName) {
|
|
var areaName = ChartManager.getInstance().getIndicatorAreaName(2);
|
|
ChartManager.getInstance().removeIndicator(areaName);
|
|
ChartManager.getInstance().redraw('All', true);
|
|
};
|
|
var CName = create_class();
|
|
CName.prototype.__construct = function (name) {
|
|
this._names = [];
|
|
this._comps = [];
|
|
if (name instanceof CName) {
|
|
this._names = name._names;
|
|
this._comps = name._comps;
|
|
} else {
|
|
var comps = name.split(".");
|
|
var dotNum = comps.length - 1;
|
|
if (dotNum > 0) {
|
|
this._comps = comps;
|
|
this._names.push(comps[0]);
|
|
for (var i = 1; i <= dotNum; i++) {
|
|
this._names.push(this._names[i - 1] + "." + comps[i]);
|
|
}
|
|
} else {
|
|
this._comps.push(name);
|
|
this._names.push(name);
|
|
}
|
|
}
|
|
};
|
|
CName.prototype.getCompAt = function (index) {
|
|
if (index >= 0 && index < this._comps.length)
|
|
return this._comps[index];
|
|
return "";
|
|
};
|
|
CName.prototype.getName = function (index) {
|
|
if (index < 0) {
|
|
if (this._names.length > 0)
|
|
return this._names[this._names.length - 1];
|
|
} else if (index < this._names.length) {
|
|
return this._names[index];
|
|
}
|
|
return "";
|
|
};
|
|
var NamedObject = create_class();
|
|
NamedObject.prototype.__construct = function (name) {
|
|
this._name = name;
|
|
this._nameObj = new CName(name);
|
|
};
|
|
NamedObject.prototype.getFrameName = function () {
|
|
return this._nameObj.getName(0);
|
|
};
|
|
NamedObject.prototype.getDataSourceName = function () {
|
|
return this._nameObj.getName(1);
|
|
};
|
|
NamedObject.prototype.getAreaName = function () {
|
|
return this._nameObj.getName(2);
|
|
};
|
|
NamedObject.prototype.getName = function () {
|
|
return this._nameObj.getName(-1);
|
|
};
|
|
NamedObject.prototype.getNameObject = function () {
|
|
return this._nameObj;
|
|
};
|
|
var ChartArea = create_class(NamedObject);
|
|
ChartArea.prototype.__construct = function (name) {
|
|
ChartArea.__super.__construct.call(this, name);
|
|
this._left = 0;
|
|
this._top = 0;
|
|
this._right = 0;
|
|
this._bottom = 0;
|
|
this._changed = false;
|
|
this._highlighted = false;
|
|
this._pressed = false;
|
|
this._selected = false;
|
|
this.Measuring = new MEvent();
|
|
};
|
|
ChartArea.DockStyle = {Left: 0, Top: 1, Right: 2, Bottom: 3, Fill: 4};
|
|
ChartArea.prototype.getDockStyle = function () {
|
|
return this._dockStyle;
|
|
};
|
|
ChartArea.prototype.setDockStyle = function (dockStyle) {
|
|
this._dockStyle = dockStyle;
|
|
};
|
|
ChartArea.prototype.getLeft = function () {
|
|
return this._left;
|
|
};
|
|
ChartArea.prototype.getTop = function () {
|
|
return this._top;
|
|
};
|
|
ChartArea.prototype.setTop = function (v) {
|
|
if (this._top != v) {
|
|
this._top = v;
|
|
this._changed = true;
|
|
}
|
|
};
|
|
ChartArea.prototype.getRight = function () {
|
|
return this._right;
|
|
};
|
|
ChartArea.prototype.getBottom = function () {
|
|
return this._bottom;
|
|
};
|
|
ChartArea.prototype.setBottom = function (v) {
|
|
if (this._bottom != v) {
|
|
this._bottom = v;
|
|
this._changed = true;
|
|
}
|
|
};
|
|
ChartArea.prototype.getCenter = function () {
|
|
return (this._left + this._right) >> 1;
|
|
};
|
|
ChartArea.prototype.getMiddle = function () {
|
|
return (this._top + this._bottom) >> 1;
|
|
};
|
|
ChartArea.prototype.getWidth = function () {
|
|
return this._right - this._left;
|
|
};
|
|
ChartArea.prototype.getHeight = function () {
|
|
return this._bottom - this._top;
|
|
};
|
|
ChartArea.prototype.getRect = function () {
|
|
return {
|
|
X: this._left,
|
|
Y: this._top,
|
|
Width: this._right - this._left,
|
|
Height: this._bottom - this._top
|
|
};
|
|
};
|
|
ChartArea.prototype.contains = function (x, y) {
|
|
if (x >= this._left && x < this._right)
|
|
if (y >= this._top && y < this._bottom)
|
|
return [this];
|
|
return null;
|
|
};
|
|
ChartArea.prototype.getMeasuredWidth = function () {
|
|
return this._measuredWidth;
|
|
};
|
|
ChartArea.prototype.getMeasuredHeight = function () {
|
|
return this._measuredHeight;
|
|
};
|
|
ChartArea.prototype.setMeasuredDimension = function (width, height) {
|
|
this._measuredWidth = width;
|
|
this._measuredHeight = height;
|
|
};
|
|
ChartArea.prototype.measure = function (context, width, height) {
|
|
this._measuredWidth = 0;
|
|
this._measuredHeight = 0;
|
|
this.Measuring.raise(this, {Width: width, Height: height});
|
|
if (this._measuredWidth == 0 && this._measuredHeight == 0)
|
|
this.setMeasuredDimension(width, height);
|
|
};
|
|
ChartArea.prototype.layout = function (left, top, right, bottom, forceChange) {
|
|
left <<= 0;
|
|
if (this._left != left) {
|
|
this._left = left;
|
|
this._changed = true;
|
|
}
|
|
top <<= 0;
|
|
if (this._top != top) {
|
|
this._top = top;
|
|
this._changed = true;
|
|
}
|
|
right <<= 0;
|
|
if (this._right != right) {
|
|
this._right = right;
|
|
this._changed = true;
|
|
}
|
|
bottom <<= 0;
|
|
if (this._bottom != bottom) {
|
|
this._bottom = bottom;
|
|
this._changed = true;
|
|
}
|
|
if (forceChange)
|
|
this._changed = true;
|
|
};
|
|
ChartArea.prototype.isChanged = function () {
|
|
return this._changed;
|
|
};
|
|
ChartArea.prototype.setChanged = function (v) {
|
|
this._changed = v;
|
|
};
|
|
ChartArea.prototype.isHighlighted = function () {
|
|
return this._highlighted;
|
|
};
|
|
ChartArea.prototype.getHighlightedArea = function () {
|
|
return this._highlighted ? this : null;
|
|
};
|
|
ChartArea.prototype.highlight = function (area) {
|
|
this._highlighted = (this == area);
|
|
return this._highlighted ? this : null;
|
|
};
|
|
ChartArea.prototype.isPressed = function () {
|
|
return this._pressed;
|
|
};
|
|
ChartArea.prototype.setPressed = function (v) {
|
|
this._pressed = v;
|
|
};
|
|
ChartArea.prototype.isSelected = function () {
|
|
return this._selected;
|
|
};
|
|
ChartArea.prototype.getSelectedArea = function () {
|
|
return this._selected ? this : null;
|
|
};
|
|
ChartArea.prototype.select = function (area) {
|
|
this._selected = (this == area);
|
|
return this._selected ? this : null;
|
|
};
|
|
ChartArea.prototype.onMouseMove = function (x, y) {
|
|
return null;
|
|
};
|
|
ChartArea.prototype.onMouseLeave = function (x, y) {
|
|
};
|
|
ChartArea.prototype.onMouseDown = function (x, y) {
|
|
return null;
|
|
};
|
|
ChartArea.prototype.onMouseUp = function (x, y) {
|
|
return null;
|
|
};
|
|
var MainArea = create_class(ChartArea);
|
|
MainArea.prototype.__construct = function (name) {
|
|
MainArea.__super.__construct.call(this, name);
|
|
this._dragStarted = false;
|
|
this._oldX = 0;
|
|
this._oldY = 0;
|
|
this._passMoveEventToToolManager = true;
|
|
};
|
|
MainArea.prototype.onMouseMove = function (x, y) {
|
|
var mgr = ChartManager.getInstance();
|
|
if (mgr._capturingMouseArea == this)
|
|
if (this._dragStarted == false)
|
|
if (Math.abs(this._oldX - x) > 1 || Math.abs(this._oldY - y) > 1)
|
|
this._dragStarted = true;
|
|
if (this._dragStarted) {
|
|
mgr.hideCursor();
|
|
if (mgr.onToolMouseDrag(this.getFrameName(), x, y))
|
|
return this;
|
|
mgr.getTimeline(this.getDataSourceName()).move(x - this._oldX);
|
|
return this;
|
|
}
|
|
if (this._passMoveEventToToolManager && mgr.onToolMouseMove(this.getFrameName(), x, y)) {
|
|
mgr.hideCursor();
|
|
return this;
|
|
}
|
|
switch (mgr._drawingTool) {
|
|
case ChartManager.DrawingTool.Cursor:
|
|
mgr.showCursor();
|
|
break;
|
|
case ChartManager.DrawingTool.CrossCursor:
|
|
if (mgr.showCrossCursor(this, x, y))
|
|
mgr.hideCursor();
|
|
else
|
|
mgr.showCursor();
|
|
break;
|
|
default:
|
|
mgr.hideCursor();
|
|
break;
|
|
}
|
|
return this;
|
|
};
|
|
MainArea.prototype.onMouseLeave = function (x, y) {
|
|
this._dragStarted = false;
|
|
this._passMoveEventToToolManager = true;
|
|
};
|
|
MainArea.prototype.onMouseDown = function (x, y) {
|
|
var mgr = ChartManager.getInstance();
|
|
mgr.getTimeline(this.getDataSourceName()).startMove();
|
|
this._oldX = x;
|
|
this._oldY = y;
|
|
this._dragStarted = false;
|
|
if (mgr.onToolMouseDown(this.getFrameName(), x, y))
|
|
this._passMoveEventToToolManager = false;
|
|
return this;
|
|
};
|
|
MainArea.prototype.onMouseUp = function (x, y) {
|
|
var mgr = ChartManager.getInstance();
|
|
var ret = null;
|
|
if (this._dragStarted) {
|
|
this._dragStarted = false;
|
|
ret = this;
|
|
}
|
|
if (mgr.onToolMouseUp(this.getFrameName(), x, y))
|
|
ret = this;
|
|
this._passMoveEventToToolManager = true;
|
|
return ret;
|
|
};
|
|
var IndicatorArea = create_class(ChartArea);
|
|
IndicatorArea.prototype.__construct = function (name) {
|
|
IndicatorArea.__super.__construct.call(this, name);
|
|
this._dragStarted = false;
|
|
this._oldX = 0;
|
|
this._oldY = 0;
|
|
};
|
|
IndicatorArea.prototype.onMouseMove = function (x, y) {
|
|
var mgr = ChartManager.getInstance();
|
|
if (mgr._capturingMouseArea == this)
|
|
if (this._dragStarted == false)
|
|
if (this._oldX != x || this._oldY != y)
|
|
this._dragStarted = true;
|
|
if (this._dragStarted) {
|
|
mgr.hideCursor();
|
|
mgr.getTimeline(this.getDataSourceName()).move(x - this._oldX);
|
|
return this;
|
|
}
|
|
switch (mgr._drawingTool) {
|
|
case ChartManager.DrawingTool.CrossCursor:
|
|
if (mgr.showCrossCursor(this, x, y))
|
|
mgr.hideCursor();
|
|
else
|
|
mgr.showCursor();
|
|
break;
|
|
default:
|
|
mgr.showCursor();
|
|
break;
|
|
}
|
|
return this;
|
|
};
|
|
IndicatorArea.prototype.onMouseLeave = function (x, y) {
|
|
this._dragStarted = false;
|
|
};
|
|
IndicatorArea.prototype.onMouseDown = function (x, y) {
|
|
var mgr = ChartManager.getInstance();
|
|
mgr.getTimeline(this.getDataSourceName()).startMove();
|
|
this._oldX = x;
|
|
this._oldY = y;
|
|
this._dragStarted = false;
|
|
return this;
|
|
};
|
|
IndicatorArea.prototype.onMouseUp = function (x, y) {
|
|
if (this._dragStarted) {
|
|
this._dragStarted = false;
|
|
return this;
|
|
}
|
|
return null;
|
|
};
|
|
var MainRangeArea = create_class(ChartArea);
|
|
MainRangeArea.prototype.__construct = function (name) {
|
|
MainRangeArea.__super.__construct.call(this, name);
|
|
};
|
|
MainRangeArea.prototype.onMouseMove = function (x, y) {
|
|
ChartManager.getInstance().showCursor();
|
|
return this;
|
|
};
|
|
var IndicatorRangeArea = create_class(ChartArea);
|
|
IndicatorRangeArea.prototype.__construct = function (name) {
|
|
IndicatorRangeArea.__super.__construct.call(this, name);
|
|
};
|
|
IndicatorRangeArea.prototype.onMouseMove = function (x, y) {
|
|
ChartManager.getInstance().showCursor();
|
|
return this;
|
|
};
|
|
var TimelineArea = create_class(ChartArea);
|
|
TimelineArea.prototype.__construct = function (name) {
|
|
TimelineArea.__super.__construct.call(this, name);
|
|
};
|
|
TimelineArea.prototype.onMouseMove = function (x, y) {
|
|
ChartManager.getInstance().showCursor();
|
|
return this;
|
|
};
|
|
var ChartAreaGroup = create_class(ChartArea);
|
|
ChartAreaGroup.prototype.__construct = function (name) {
|
|
ChartAreaGroup.__super.__construct.call(this, name);
|
|
this._areas = [];
|
|
this._highlightedArea = null;
|
|
this._selectedArea = null;
|
|
};
|
|
ChartAreaGroup.prototype.contains = function (x, y) {
|
|
var areas;
|
|
var a, i, cnt = this._areas.length;
|
|
for (i = 0; i < cnt; i++) {
|
|
a = this._areas[i];
|
|
areas = a.contains(x, y);
|
|
if (areas != null) {
|
|
areas.push(this);
|
|
return areas;
|
|
}
|
|
}
|
|
return ChartAreaGroup.__super.contains(x, y);
|
|
};
|
|
ChartAreaGroup.prototype.getAreaCount = function () {
|
|
return this._areas.length;
|
|
};
|
|
ChartAreaGroup.prototype.getAreaAt = function (index) {
|
|
if (index < 0 || index >= this._areas.length)
|
|
return null;
|
|
return this._areas[index];
|
|
};
|
|
ChartAreaGroup.prototype.addArea = function (area) {
|
|
this._areas.push(area);
|
|
};
|
|
ChartAreaGroup.prototype.removeArea = function (area) {
|
|
var i, cnt = this._areas.length;
|
|
for (i = 0; i < cnt; i++) {
|
|
if (area == this._areas[i]) {
|
|
this._areas.splice(i);
|
|
this.setChanged(true);
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
ChartAreaGroup.prototype.getGridColor = function () {
|
|
return this._gridColor;
|
|
};
|
|
ChartAreaGroup.prototype.setGridColor = function (c) {
|
|
this._gridColor = c;
|
|
};
|
|
ChartAreaGroup.prototype.getHighlightedArea = function () {
|
|
if (this._highlightedArea != null)
|
|
return this._highlightedArea.getHighlightedArea();
|
|
return null;
|
|
};
|
|
ChartAreaGroup.prototype.highlight = function (area) {
|
|
this._highlightedArea = null;
|
|
var e, i, cnt = this._areas.length;
|
|
for (i = 0; i < cnt; i++) {
|
|
e = this._areas[i].highlight(area);
|
|
if (e != null) {
|
|
this._highlightedArea = e;
|
|
return this;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
ChartAreaGroup.prototype.getSelectedArea = function () {
|
|
if (this._selectedArea != null)
|
|
return this._selectedArea.getSelectedArea();
|
|
return null;
|
|
};
|
|
ChartAreaGroup.prototype.select = function (area) {
|
|
this._selectedArea = null;
|
|
var e, i, cnt = this._areas.length;
|
|
for (i = 0; i < cnt; i++) {
|
|
e = this._areas[i].select(area);
|
|
if (e != null) {
|
|
this._selectedArea = e;
|
|
return this;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
ChartAreaGroup.prototype.onMouseLeave = function (x, y) {
|
|
var i, cnt = this._areas.length;
|
|
for (i = 0; i < cnt; i++)
|
|
this._areas[i].onMouseLeave(x, y);
|
|
};
|
|
ChartAreaGroup.prototype.onMouseUp = function (x, y) {
|
|
var a, i, cnt = this._areas.length;
|
|
for (i = 0; i < cnt; i++) {
|
|
a = this._areas[i].onMouseUp(x, y);
|
|
if (a != null)
|
|
return a;
|
|
}
|
|
return null;
|
|
};
|
|
var TableLayout = create_class(ChartAreaGroup);
|
|
TableLayout.prototype.__construct = function (name) {
|
|
TableLayout.__super.__construct.call(this, name);
|
|
this._nextRowId = 0;
|
|
this._focusedRowIndex = -1;
|
|
};
|
|
TableLayout.prototype.getNextRowId = function () {
|
|
return this._nextRowId++;
|
|
};
|
|
TableLayout.prototype.measure = function (context, width, height) {
|
|
this.setMeasuredDimension(width, height);
|
|
var rowH, prevH = 0,
|
|
totalH = 0;
|
|
var h, rows;
|
|
var rh = [];
|
|
var i, cnt = this._areas.length;
|
|
for (i = 0; i < cnt; i += 2) {
|
|
rowH = this._areas[i].getHeight();
|
|
if (rowH == 0) {
|
|
if (i == 0) {
|
|
rows = (cnt + 1) >> 1;
|
|
var n = (rows * 2) + 5;
|
|
var nh = ((height / n) * 2) << 0;
|
|
h = height;
|
|
for (i = rows - 1; i > 0; i--) {
|
|
rh.unshift(nh);
|
|
h -= nh;
|
|
}
|
|
rh.unshift(h);
|
|
break;
|
|
} else if (i == 2) {
|
|
rowH = prevH / 3;
|
|
} else {
|
|
rowH = prevH;
|
|
}
|
|
}
|
|
totalH += rowH;
|
|
prevH = rowH;
|
|
rh.push(rowH);
|
|
}
|
|
if (totalH > 0) {
|
|
var rate = height / totalH;
|
|
rows = (cnt + 1) >> 1;
|
|
h = height;
|
|
for (i = rows - 1; i > 0; i--) {
|
|
rh[i] *= rate;
|
|
h -= rh[i];
|
|
}
|
|
rh[0] = h;
|
|
}
|
|
var nw = 8;
|
|
// chart depths sidebar
|
|
var minRW = 64;
|
|
var maxRW = Math.min(240, width >> 1);
|
|
var rw = minRW;
|
|
var mgr = ChartManager.getInstance();
|
|
var timeline = mgr.getTimeline(this.getDataSourceName());
|
|
if (timeline.getFirstIndex() >= 0) {
|
|
var firstIndexes = [];
|
|
for (rw = minRW; rw < maxRW; rw += nw)
|
|
firstIndexes.push(
|
|
timeline.calcFirstIndex(timeline.calcColumnCount(width - rw)));
|
|
var lastIndex = timeline.getLastIndex();
|
|
var dpNames = [".main", ".secondary"];
|
|
var minmaxes = new Array(firstIndexes.length);
|
|
var iArea, iIndex;
|
|
for (iArea = 0, iIndex = 0, rw = minRW; iArea < this._areas.length && iIndex < firstIndexes.length; iArea += 2) {
|
|
var area = this._areas[iArea];
|
|
var plotter = mgr.getPlotter(area.getName() + "Range.main");
|
|
for (var iDp in dpNames) {
|
|
var dp = mgr.getDataProvider(area.getName() + dpNames[iDp]);
|
|
if (dp == undefined)
|
|
continue;
|
|
dp.calcRange(firstIndexes, lastIndex, minmaxes, null);
|
|
while (iIndex < firstIndexes.length) {
|
|
var minW = plotter.getRequiredWidth(context, minmaxes[iIndex].min);
|
|
var maxW = plotter.getRequiredWidth(context, minmaxes[iIndex].max);
|
|
if (Math.max(minW, maxW) < rw)
|
|
break;
|
|
iIndex++;
|
|
rw += nw;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
for (i = 1; i < this._areas.length; i += 2) {
|
|
this._areas[i].measure(context, rw, rh[i >> 1]);
|
|
}
|
|
var lw = width - rw;
|
|
for (i = 0; i < this._areas.length; i += 2) {
|
|
this._areas[i].measure(context, lw, rh[i >> 1]);
|
|
}
|
|
};
|
|
TableLayout.prototype.layout = function (left, top, right, bottom, forceChange) {
|
|
TableLayout.__super.layout.call(this, left, top, right, bottom, forceChange);
|
|
if (this._areas.length < 1)
|
|
return;
|
|
var area;
|
|
var center = left + this._areas[0].getMeasuredWidth();
|
|
var t = top,
|
|
b;
|
|
if (!forceChange)
|
|
forceChange = this.isChanged();
|
|
var i, cnt = this._areas.length;
|
|
for (i = 0; i < cnt; i++) {
|
|
area = this._areas[i];
|
|
b = t + area.getMeasuredHeight();
|
|
area.layout(left, t, center, b, forceChange);
|
|
i++;
|
|
area = this._areas[i];
|
|
area.layout(center, t, this.getRight(), b, forceChange);
|
|
t = b;
|
|
}
|
|
this.setChanged(false);
|
|
};
|
|
TableLayout.prototype.drawGrid = function (context) {
|
|
if (this._areas.length < 1)
|
|
return;
|
|
var mgr = ChartManager.getInstance();
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
context.fillStyle = theme.getColor(Theme.Color.Grid1);
|
|
context.fillRect(this._areas[0].getRight(), this.getTop(), 1, this.getHeight());
|
|
var i, cnt = this._areas.length - 2;
|
|
for (i = 0; i < cnt; i += 2)
|
|
context.fillRect(this.getLeft(), this._areas[i].getBottom(), this.getWidth(), 1);
|
|
if (!mgr.getCaptureMouseWheelDirectly()) {
|
|
for (i = 0, cnt += 2; i < cnt; i += 2) {
|
|
if (this._areas[i].isSelected()) {
|
|
context.strokeStyle = theme.getColor(Theme.Color.Indicator1);
|
|
context.strokeRect(
|
|
this.getLeft() + 0.5, this.getTop() + 0.5,
|
|
this.getWidth() - 1, this.getHeight() - 1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
TableLayout.prototype.highlight = function (area) {
|
|
this._highlightedArea = null;
|
|
var e, i, cnt = this._areas.length;
|
|
for (i = 0; i < cnt; i++) {
|
|
e = this._areas[i];
|
|
if (e == area) {
|
|
i &= ~1;
|
|
e = this._areas[i];
|
|
e.highlight(e);
|
|
this._highlightedArea = e;
|
|
i++;
|
|
e = this._areas[i];
|
|
e.highlight(null);
|
|
e.highlight(e);
|
|
} else {
|
|
e.highlight(null);
|
|
}
|
|
}
|
|
return this._highlightedArea != null ? this : null;
|
|
};
|
|
TableLayout.prototype.select = function (area) {
|
|
this._selectedArea = null;
|
|
var e, i, cnt = this._areas.length;
|
|
for (i = 0; i < cnt; i++) {
|
|
e = this._areas[i];
|
|
if (e == area) {
|
|
i &= ~1;
|
|
e = this._areas[i];
|
|
e.select(e);
|
|
this._selectedArea = e;
|
|
i++;
|
|
e = this._areas[i];
|
|
e.select(e);
|
|
} else {
|
|
e.select(null);
|
|
}
|
|
}
|
|
return this._selectedArea != null ? this : null;
|
|
};
|
|
TableLayout.prototype.onMouseMove = function (x, y) {
|
|
if (this._focusedRowIndex >= 0) {
|
|
var upper = this._areas[this._focusedRowIndex];
|
|
var lower = this._areas[this._focusedRowIndex + 2];
|
|
var d = y - this._oldY;
|
|
if (d == 0)
|
|
return this;
|
|
var upperBottom = this._oldUpperBottom + d;
|
|
var lowerTop = this._oldLowerTop + d;
|
|
if (upperBottom - upper.getTop() >= 60 && lower.getBottom() - lowerTop >= 60) {
|
|
upper.setBottom(upperBottom);
|
|
lower.setTop(lowerTop);
|
|
}
|
|
return this;
|
|
}
|
|
var i, cnt = this._areas.length - 2;
|
|
for (i = 0; i < cnt; i += 2) {
|
|
var b = this._areas[i].getBottom();
|
|
if (y >= b - 4 && y < b + 4) {
|
|
ChartManager.getInstance().showCursor('n-resize');
|
|
return this;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
TableLayout.prototype.onMouseLeave = function (x, y) {
|
|
this._focusedRowIndex = -1;
|
|
};
|
|
TableLayout.prototype.onMouseDown = function (x, y) {
|
|
var i, cnt = this._areas.length - 2;
|
|
for (i = 0; i < cnt; i += 2) {
|
|
var b = this._areas[i].getBottom();
|
|
if (y >= b - 4 && y < b + 4) {
|
|
this._focusedRowIndex = i;
|
|
this._oldY = y;
|
|
this._oldUpperBottom = b;
|
|
this._oldLowerTop = this._areas[i + 2].getTop();
|
|
return this;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
TableLayout.prototype.onMouseUp = function (x, y) {
|
|
if (this._focusedRowIndex >= 0) {
|
|
this._focusedRowIndex = -1;
|
|
var i, cnt = this._areas.length;
|
|
var height = [];
|
|
for (i = 0; i < cnt; i += 2) {
|
|
height.push(this._areas[i].getHeight());
|
|
}
|
|
ChartSettings.get().charts.areaHeight = height;
|
|
ChartSettings.save();
|
|
}
|
|
return this;
|
|
};
|
|
var DockableLayout = create_class(ChartAreaGroup);
|
|
DockableLayout.prototype.__construct = function (name) {
|
|
DockableLayout.__super.__construct.call(this, name);
|
|
};
|
|
DockableLayout.prototype.measure = function (context, width, height) {
|
|
DockableLayout.__super.measure.call(this, context, width, height);
|
|
width = this.getMeasuredWidth();
|
|
height = this.getMeasuredHeight();
|
|
for (var i in this._areas) {
|
|
var area = this._areas[i];
|
|
area.measure(context, width, height);
|
|
switch (area.getDockStyle()) {
|
|
case ChartArea.DockStyle.left:
|
|
case ChartArea.DockStyle.Right:
|
|
width -= area.getMeasuredWidth();
|
|
break;
|
|
case ChartArea.DockStyle.Top:
|
|
case ChartArea.DockStyle.Bottom:
|
|
height -= area.getMeasuredHeight();
|
|
break;
|
|
case ChartArea.DockStyle.Fill:
|
|
width = 0;
|
|
height = 0;
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
DockableLayout.prototype.layout = function (left, top, right, bottom, forceChange) {
|
|
DockableLayout.__super.layout.call(this, left, top, right, bottom, forceChange);
|
|
left = this.getLeft();
|
|
top = this.getTop();
|
|
right = this.getRight();
|
|
bottom = this.getBottom();
|
|
var w, h;
|
|
if (!forceChange)
|
|
forceChange = this.isChanged();
|
|
for (var i in this._areas) {
|
|
var area = this._areas[i];
|
|
switch (area.getDockStyle()) {
|
|
case ChartArea.DockStyle.left:
|
|
w = area.getMeasuredWidth();
|
|
area.layout(left, top, left + w, bottom, forceChange);
|
|
left += w;
|
|
break;
|
|
case ChartArea.DockStyle.Top:
|
|
h = area.getMeasuredHeight();
|
|
area.layout(left, top, right, top + h, forceChange);
|
|
top += h;
|
|
break;
|
|
case ChartArea.DockStyle.Right:
|
|
w = area.getMeasuredWidth();
|
|
area.layout(right - w, top, right, bottom, forceChange);
|
|
right -= w;
|
|
break;
|
|
case ChartArea.DockStyle.Bottom:
|
|
h = area.getMeasuredHeight();
|
|
area.layout(left, bottom - h, right, bottom, forceChange);
|
|
bottom -= h;
|
|
break;
|
|
case ChartArea.DockStyle.Fill:
|
|
area.layout(left, top, right, bottom, forceChange);
|
|
left = right;
|
|
top = bottom;
|
|
break;
|
|
}
|
|
}
|
|
this.setChanged(false);
|
|
};
|
|
DockableLayout.prototype.drawGrid = function (context) {
|
|
var mgr = ChartManager.getInstance();
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
var left = this.getLeft();
|
|
var top = this.getTop();
|
|
var right = this.getRight();
|
|
var bottom = this.getBottom();
|
|
context.fillStyle = theme.getColor(this._gridColor);
|
|
for (var i in this._areas) {
|
|
var area = this._areas[i];
|
|
switch (area.getDockStyle()) {
|
|
case ChartArea.DockStyle.Left:
|
|
context.fillRect(area.getRight(), top, 1, bottom - top);
|
|
left += area.getWidth();
|
|
break;
|
|
case ChartArea.DockStyle.Top:
|
|
context.fillRect(left, area.getBottom(), right - left, 1);
|
|
top += area.getHeight();
|
|
break;
|
|
case ChartArea.DockStyle.Right:
|
|
context.fillRect(area.getLeft(), top, 1, bottom - top);
|
|
right -= area.getWidth();
|
|
break;
|
|
case ChartArea.DockStyle.Bottom:
|
|
context.fillRect(left, area.getTop(), right - left, 1);
|
|
bottom -= area.getHeight();
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
var ChartManager = create_class();
|
|
ChartManager.DrawingTool = {
|
|
Cursor: 0,
|
|
CrossCursor: 1,
|
|
DrawLines: 2,
|
|
DrawFibRetrace: 3,
|
|
DrawFibFans: 4,
|
|
SegLine: 5,
|
|
StraightLine: 6,
|
|
ArrowLine: 7,
|
|
RayLine: 8,
|
|
HoriStraightLine: 9,
|
|
HoriRayLine: 10,
|
|
HoriSegLine: 11,
|
|
VertiStraightLine: 12,
|
|
PriceLine: 13,
|
|
BiParallelLine: 14,
|
|
BiParallelRayLine: 15,
|
|
TriParallelLine: 16,
|
|
BandLine: 17
|
|
};
|
|
ChartManager._instance = null;
|
|
ChartManager.getInstance = function () {
|
|
if (ChartManager._instance == null)
|
|
ChartManager._instance = new ChartManager();
|
|
return ChartManager._instance;
|
|
};
|
|
ChartManager.prototype.__construct = function () {
|
|
this._dataSources = {};
|
|
this._dataSourceCache = {};
|
|
this._dataProviders = {};
|
|
this._frames = {};
|
|
this._areas = {};
|
|
this._timelines = {};
|
|
this._ranges = {};
|
|
this._plotters = {};
|
|
this._themes = {};
|
|
this._titles = {};
|
|
this._frameMousePos = {};
|
|
this._dsChartStyle = {};
|
|
this._dragStarted = false;
|
|
this._oldX = 0;
|
|
this._fakeIndicators = {};
|
|
this._captureMouseWheelDirectly = true;
|
|
this._chart = {};
|
|
this._chart.defaultFrame = new Chart();
|
|
this._drawingTool = ChartManager.DrawingTool["CrossCursor"];
|
|
this._beforeDrawingTool = this._drawingTool;
|
|
this._language = "zh-cn";
|
|
this._mainCanvas = null;
|
|
this._overlayCanvas = null;
|
|
this._mainContext = null;
|
|
this._overlayContext = null;
|
|
};
|
|
/**
|
|
* redraw.
|
|
* @param layer
|
|
* "all", "main", "overlay"
|
|
*/
|
|
ChartManager.prototype.redraw = function (layer, refresh) {
|
|
if (layer == undefined || refresh)
|
|
layer = "All";
|
|
if (layer == "All" || layer == "MainCanvas") {
|
|
if (refresh)
|
|
this.getFrame("frame0").setChanged(true);
|
|
this.layout(this._mainContext, "frame0",
|
|
0, 0, this._mainCanvas.width, this._mainCanvas.height);
|
|
this.drawMain("frame0", this._mainContext);
|
|
}
|
|
if (layer == "All" || layer == "OverlayCanvas") {
|
|
this._overlayContext.clearRect(
|
|
0, 0, this._overlayCanvas.width, this._overlayCanvas.height);
|
|
this.drawOverlay("frame0", this._overlayContext);
|
|
}
|
|
};
|
|
/**
|
|
* bindCanvas.
|
|
* @param layer
|
|
* "main", "overlay"
|
|
*/
|
|
ChartManager.prototype.bindCanvas = function (layer, canvas) {
|
|
if (layer == "main") {
|
|
this._mainCanvas = canvas;
|
|
this._mainContext = canvas.getContext("2d");
|
|
} else if (layer == "overlay") {
|
|
this._overlayCanvas = canvas;
|
|
this._overlayContext = canvas.getContext("2d");
|
|
if (this._captureMouseWheelDirectly)
|
|
$(this._overlayCanvas).bind('mousewheel', mouseWheel);
|
|
}
|
|
};
|
|
ChartManager.prototype.getCaptureMouseWheelDirectly = function () {
|
|
return this._captureMouseWheelDirectly;
|
|
};
|
|
ChartManager.prototype.setCaptureMouseWheelDirectly = function (v) {
|
|
this._captureMouseWheelDirectly = v;
|
|
if (v)
|
|
$(this._overlayCanvas).bind('mousewheel', mouseWheel);
|
|
else
|
|
$(this._overlayCanvas).unbind('mousewheel');
|
|
};
|
|
ChartManager.prototype.getChart = function (nouseParam) {
|
|
return this._chart["defaultFrame"];
|
|
};
|
|
ChartManager.prototype.init = function () {
|
|
delete this._ranges['frame0.k0.indic1'];
|
|
delete this._ranges['frame0.k0.indic1Range'];
|
|
delete this._areas['frame0.k0.indic1'];
|
|
delete this._areas['frame0.k0.indic1Range'];
|
|
DefaultTemplate.loadTemplate("frame0.k0", "");
|
|
this.redraw('All', true);
|
|
};
|
|
ChartManager.prototype.setCurrentDrawingTool = function (paramTool) {
|
|
this._drawingTool = ChartManager.DrawingTool[paramTool];
|
|
this.setRunningMode(this._drawingTool);
|
|
};
|
|
/**
|
|
* Property: Language.
|
|
* @param lang:
|
|
* "en-us" "zh-cn" "zh-tw"
|
|
*/
|
|
ChartManager.prototype.getLanguage = function () {
|
|
return this._language;
|
|
};
|
|
ChartManager.prototype.setLanguage = function (lang) {
|
|
this._language = lang;
|
|
};
|
|
/**
|
|
* Property: ThemeName.
|
|
* @param lang:
|
|
* "Dark" "Light"
|
|
*/
|
|
ChartManager.prototype.setThemeName = function (frameName, themeName) {
|
|
if (themeName == undefined)
|
|
themeName = "Dark";
|
|
var theme;
|
|
switch (themeName) {
|
|
case "Light":
|
|
theme = new LightTheme();
|
|
break;
|
|
default:
|
|
themeName = "Dark";
|
|
theme = new DarkTheme();
|
|
break;
|
|
}
|
|
this._themeName = themeName;
|
|
this.setTheme(frameName, theme);
|
|
this.getFrame(frameName).setChanged(true);
|
|
};
|
|
/**
|
|
* Property: ChartStyle.
|
|
* @param style:
|
|
* "CandleStick" "CandleStickHLC" "OHLC"
|
|
*/
|
|
ChartManager.prototype.getChartStyle = function (dsName) {
|
|
var chartStyle = this._dsChartStyle[dsName];
|
|
if (chartStyle == undefined)
|
|
return "CandleStick";
|
|
return chartStyle;
|
|
};
|
|
ChartManager.prototype.setChartStyle = function (dsName, style) {
|
|
if (this._dsChartStyle[dsName] == style)
|
|
return;
|
|
var areaName = dsName + ".main";
|
|
var dpName = areaName + ".main";
|
|
var plotterName = areaName + ".main";
|
|
var dp, plotter;
|
|
switch (style) {
|
|
case "CandleStick":
|
|
case "CandleStickHLC":
|
|
case "OHLC":
|
|
dp = this.getDataProvider(dpName);
|
|
if (dp == undefined || !is_instance(dp, MainDataProvider)) {
|
|
dp = new MainDataProvider(dpName);
|
|
this.setDataProvider(dpName, dp);
|
|
dp.updateData();
|
|
}
|
|
this.setMainIndicator(dsName, ChartSettings.get().charts.mIndic);
|
|
switch (style) {
|
|
case "CandleStick":
|
|
plotter = new CandlestickPlotter(plotterName);
|
|
break;
|
|
case "CandleStickHLC":
|
|
plotter = new CandlestickHLCPlotter(plotterName);
|
|
break;
|
|
case "OHLC":
|
|
plotter = new OHLCPlotter(plotterName);
|
|
break;
|
|
}
|
|
this.setPlotter(plotterName, plotter);
|
|
plotter = new MinMaxPlotter(areaName + ".decoration");
|
|
this.setPlotter(plotter.getName(), plotter);
|
|
break;
|
|
case "Line":
|
|
dp = new IndicatorDataProvider(dpName);
|
|
this.setDataProvider(dp.getName(), dp);
|
|
dp.setIndicator(new HLCIndicator());
|
|
this.removeMainIndicator(dsName);
|
|
plotter = new IndicatorPlotter(plotterName);
|
|
this.setPlotter(plotterName, plotter);
|
|
this.removePlotter(areaName + ".decoration");
|
|
break;
|
|
}
|
|
this.getArea(plotter.getAreaName()).setChanged(true);
|
|
this._dsChartStyle[dsName] = style;
|
|
};
|
|
ChartManager.prototype.setNormalMode = function () {
|
|
this._drawingTool = this._beforeDrawingTool;
|
|
$(".chart_dropdown_data").removeClass("chart_dropdown-hover");
|
|
$("#chart_toolpanel .chart_toolpanel_button").removeClass("selected");
|
|
$("#chart_CrossCursor").parent().addClass("selected");
|
|
if (this._drawingTool == ChartManager.DrawingTool.Cursor) {
|
|
this.showCursor();
|
|
$("#mode a").removeClass("selected");
|
|
$("#chart_toolpanel .chart_toolpanel_button").removeClass("selected");
|
|
$("#chart_Cursor").parent().addClass("selected");
|
|
} else {
|
|
this.hideCursor();
|
|
}
|
|
};
|
|
ChartManager.prototype.setRunningMode = function (mode) {
|
|
var pds = this.getDataSource("frame0.k0");
|
|
var curr_o = pds.getCurrentToolObject();
|
|
if (curr_o != null && curr_o.state != CToolObject.state.AfterDraw) {
|
|
pds.delToolObject();
|
|
}
|
|
if (pds.getToolObjectCount() > 10) {
|
|
this.setNormalMode();
|
|
return;
|
|
}
|
|
this._drawingTool = mode;
|
|
if (mode == ChartManager.DrawingTool.Cursor) {
|
|
this.showCursor();
|
|
} else {
|
|
}
|
|
switch (mode) {
|
|
case ChartManager.DrawingTool.Cursor: {
|
|
this._beforeDrawingTool = mode;
|
|
break;
|
|
}
|
|
case ChartManager.DrawingTool.ArrowLine: {
|
|
pds.addToolObject(new CArrowLineObject("frame0.k0"));
|
|
break;
|
|
}
|
|
case ChartManager.DrawingTool.BandLine: {
|
|
pds.addToolObject(new CBandLineObject("frame0.k0"));
|
|
break;
|
|
}
|
|
case ChartManager.DrawingTool.BiParallelLine: {
|
|
pds.addToolObject(new CBiParallelLineObject("frame0.k0"));
|
|
break;
|
|
}
|
|
case ChartManager.DrawingTool.BiParallelRayLine: {
|
|
pds.addToolObject(new CBiParallelRayLineObject("frame0.k0"));
|
|
break;
|
|
}
|
|
case ChartManager.DrawingTool.CrossCursor: {
|
|
this._beforeDrawingTool = mode;
|
|
break;
|
|
}
|
|
case ChartManager.DrawingTool.DrawFibFans: {
|
|
pds.addToolObject(new CFibFansObject("frame0.k0"));
|
|
break;
|
|
}
|
|
case ChartManager.DrawingTool.DrawFibRetrace: {
|
|
pds.addToolObject(new CFibRetraceObject("frame0.k0"));
|
|
break;
|
|
}
|
|
case ChartManager.DrawingTool.DrawLines: {
|
|
pds.addToolObject(new CStraightLineObject("frame0.k0"));
|
|
break;
|
|
}
|
|
case ChartManager.DrawingTool.HoriRayLine: {
|
|
pds.addToolObject(new CHoriRayLineObject("frame0.k0"));
|
|
break;
|
|
}
|
|
case ChartManager.DrawingTool.HoriSegLine: {
|
|
pds.addToolObject(new CHoriSegLineObject("frame0.k0"));
|
|
break;
|
|
}
|
|
case ChartManager.DrawingTool.HoriStraightLine: {
|
|
pds.addToolObject(new CHoriStraightLineObject("frame0.k0"));
|
|
break;
|
|
}
|
|
case ChartManager.DrawingTool.PriceLine: {
|
|
pds.addToolObject(new CPriceLineObject("frame0.k0"));
|
|
break;
|
|
}
|
|
case ChartManager.DrawingTool.RayLine: {
|
|
pds.addToolObject(new CRayLineObject("frame0.k0"));
|
|
break;
|
|
}
|
|
case ChartManager.DrawingTool.SegLine: {
|
|
pds.addToolObject(new CSegLineObject("frame0.k0"));
|
|
break;
|
|
}
|
|
case ChartManager.DrawingTool.StraightLine: {
|
|
pds.addToolObject(new CStraightLineObject("frame0.k0"));
|
|
break;
|
|
}
|
|
case ChartManager.DrawingTool.TriParallelLine: {
|
|
pds.addToolObject(new CTriParallelLineObject("frame0.k0"));
|
|
break;
|
|
}
|
|
case ChartManager.DrawingTool.VertiStraightLine: {
|
|
pds.addToolObject(new CVertiStraightLineObject("frame0.k0"));
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
ChartManager.prototype.getTitle = function (dsName) {
|
|
return this._titles[dsName];
|
|
};
|
|
ChartManager.prototype.setTitle = function (dsName, title) {
|
|
this._titles[dsName] = title;
|
|
};
|
|
ChartManager.prototype.setCurrentDataSource = function (dsName, dsAlias) {
|
|
var cached = this.getCachedDataSource(dsAlias);
|
|
if (cached != null) {
|
|
this.setDataSource(dsName, cached, true);
|
|
} else {
|
|
var ds = this.getDataSource(dsName);
|
|
if (ds != null) {
|
|
if (is_instance(ds, MainDataSource)) {
|
|
cached = new MainDataSource(dsAlias);
|
|
} else if (is_instance(ds, CLiveOrderDataSource)) {
|
|
cached = new CLiveOrderDataSource(dsAlias);
|
|
} else if (is_instance(ds, CLiveTradeDataSource)) {
|
|
cached = new CLiveTradeDataSource(dsAlias);
|
|
}
|
|
this.setDataSource(dsName, cached, true);
|
|
this.setCachedDataSource(dsAlias, cached);
|
|
}
|
|
}
|
|
};
|
|
ChartManager.prototype.getDataSource = function (name) {
|
|
return this._dataSources[name];
|
|
};
|
|
ChartManager.prototype.setDataSource = function (name, ds, forceRefresh) {
|
|
this._dataSources[name] = ds;
|
|
if (forceRefresh)
|
|
this.updateData(name, null);
|
|
};
|
|
ChartManager.prototype.getCachedDataSource = function (name) {
|
|
return this._dataSourceCache[name];
|
|
};
|
|
ChartManager.prototype.setCachedDataSource = function (name, ds) {
|
|
this._dataSourceCache[name] = ds;
|
|
};
|
|
ChartManager.prototype.getDataProvider = function (name) {
|
|
return this._dataProviders[name];
|
|
};
|
|
ChartManager.prototype.setDataProvider = function (name, dp) {
|
|
this._dataProviders[name] = dp;
|
|
};
|
|
ChartManager.prototype.removeDataProvider = function (name) {
|
|
delete this._dataProviders[name];
|
|
};
|
|
ChartManager.prototype.getFrame = function (name) {
|
|
return this._frames[name];
|
|
};
|
|
ChartManager.prototype.setFrame = function (name, frame) {
|
|
this._frames[name] = frame;
|
|
};
|
|
ChartManager.prototype.removeFrame = function (name) {
|
|
delete this._frames[name];
|
|
};
|
|
ChartManager.prototype.getArea = function (name) {
|
|
return this._areas[name];
|
|
};
|
|
ChartManager.prototype.setArea = function (name, area) {
|
|
this._areas[name] = area;
|
|
};
|
|
ChartManager.prototype.removeArea = function (name) {
|
|
delete this._areas[name];
|
|
};
|
|
ChartManager.prototype.getTimeline = function (name) {
|
|
return this._timelines[name];
|
|
};
|
|
ChartManager.prototype.setTimeline = function (name, timeline) {
|
|
this._timelines[name] = timeline;
|
|
};
|
|
ChartManager.prototype.removeTimeline = function (name) {
|
|
delete this._timelines[name];
|
|
};
|
|
ChartManager.prototype.getRange = function (name) {
|
|
return this._ranges[name];
|
|
};
|
|
ChartManager.prototype.setRange = function (name, range) {
|
|
this._ranges[name] = range;
|
|
};
|
|
ChartManager.prototype.removeRange = function (name) {
|
|
delete this._ranges[name];
|
|
};
|
|
ChartManager.prototype.getPlotter = function (name) {
|
|
return this._plotters[name];
|
|
};
|
|
ChartManager.prototype.setPlotter = function (name, plotter) {
|
|
this._plotters[name] = plotter;
|
|
};
|
|
ChartManager.prototype.removePlotter = function (name) {
|
|
delete this._plotters[name];
|
|
};
|
|
ChartManager.prototype.getTheme = function (name) {
|
|
return this._themes[name];
|
|
};
|
|
ChartManager.prototype.setTheme = function (name, theme) {
|
|
this._themes[name] = theme;
|
|
};
|
|
ChartManager.prototype.getFrameMousePos = function (name, point) {
|
|
if (this._frameMousePos[name] != undefined) {
|
|
point.x = this._frameMousePos[name].x;
|
|
point.y = this._frameMousePos[name].y;
|
|
} else {
|
|
point.x = -1;
|
|
point.y = -1;
|
|
}
|
|
};
|
|
ChartManager.prototype.setFrameMousePos = function (name, px, py) {
|
|
this._frameMousePos[name] = {x: px, y: py};
|
|
};
|
|
ChartManager.prototype.drawArea = function (context, area, plotterNames) {
|
|
var areaName = area.getNameObject().getCompAt(2);
|
|
if (areaName == "timeline") {
|
|
if (area.getHeight() < 20)
|
|
return;
|
|
} else {
|
|
if (area.getHeight() < 30)
|
|
return;
|
|
}
|
|
if (area.getWidth() < 30)
|
|
return;
|
|
areaName = area.getName();
|
|
var plotter;
|
|
var i, cnt = plotterNames.length;
|
|
for (i = 0; i < cnt; i++) {
|
|
plotter = this._plotters[areaName + plotterNames[i]];
|
|
if (plotter != undefined)
|
|
plotter.Draw(context);
|
|
}
|
|
};
|
|
ChartManager.prototype.drawAreaMain = function (context, area) {
|
|
var ds = this._dataSources[area.getDataSourceName()];
|
|
var plotterNames;
|
|
if (ds.getDataCount() < 1)
|
|
plotterNames = [".background"];
|
|
else
|
|
plotterNames = [".background", ".grid", ".main", ".secondary"];
|
|
this.drawArea(context, area, plotterNames);
|
|
area.setChanged(false);
|
|
};
|
|
ChartManager.prototype.drawAreaOverlay = function (context, area) {
|
|
var ds = this._dataSources[area.getDataSourceName()];
|
|
var plotterNames;
|
|
if (ds.getDataCount() < 1)
|
|
plotterNames = [".selection"];
|
|
else
|
|
plotterNames = [".decoration", ".selection", ".info", ".tool"];
|
|
this.drawArea(context, area, plotterNames);
|
|
};
|
|
ChartManager.prototype.drawMain = function (frameName, context) {
|
|
var drawn = false;
|
|
|
|
if (!drawn) {
|
|
for (var it in this._areas) {
|
|
if (this._areas[it].getFrameName() == frameName && !is_instance(this._areas[it], ChartAreaGroup))
|
|
this.drawAreaMain(context, this._areas[it]);
|
|
}
|
|
}
|
|
var e;
|
|
for (var i in this._timelines) {
|
|
e = this._timelines[i];
|
|
if (e.getFrameName() == frameName)
|
|
e.setUpdated(false);
|
|
}
|
|
for (var i in this._ranges) {
|
|
e = this._ranges[i];
|
|
if (e.getFrameName() == frameName)
|
|
e.setUpdated(false);
|
|
}
|
|
for (var i in this._areas) {
|
|
e = this._areas[i];
|
|
if (e.getFrameName() == frameName)
|
|
e.setChanged(false);
|
|
}
|
|
};
|
|
ChartManager.prototype.drawOverlay = function (frameName, context) {
|
|
for (var n in this._areas) {
|
|
var area = this._areas[n];
|
|
if (is_instance(area, ChartAreaGroup))
|
|
if (area.getFrameName() == frameName)
|
|
area.drawGrid(context);
|
|
}
|
|
for (var n in this._areas) {
|
|
var area = this._areas[n];
|
|
if (is_instance(area, ChartAreaGroup) == false)
|
|
if (area.getFrameName() == frameName)
|
|
this.drawAreaOverlay(context, area);
|
|
}
|
|
};
|
|
ChartManager.prototype.updateData = function (dsName, data) {
|
|
var ds = this.getDataSource(dsName);
|
|
if (ds == undefined)
|
|
return;
|
|
if (data != null) {
|
|
if (!ds.update(data))
|
|
return false;
|
|
if (ds.getUpdateMode() == DataSource.UpdateMode.DoNothing)
|
|
return true;
|
|
} else {
|
|
ds.setUpdateMode(DataSource.UpdateMode.Refresh);
|
|
}
|
|
var timeline = this.getTimeline(dsName);
|
|
if (timeline != undefined)
|
|
timeline.update();
|
|
if (ds.getDataCount() < 1)
|
|
return true;
|
|
var dpNames = [".main", ".secondary"];
|
|
var area, areaName;
|
|
for (var n in this._areas) {
|
|
area = this._areas[n];
|
|
if (is_instance(area, ChartAreaGroup))
|
|
continue;
|
|
if (area.getDataSourceName() != dsName)
|
|
continue;
|
|
areaName = area.getName();
|
|
for (var i = 0; i < dpNames.length; i++) {
|
|
var dp = this.getDataProvider(areaName + dpNames[i]);
|
|
if (dp != undefined)
|
|
dp.updateData();
|
|
}
|
|
}
|
|
return true;
|
|
};
|
|
ChartManager.prototype.updateRange = function (dsName) {
|
|
var ds = this.getDataSource(dsName);
|
|
if (ds.getDataCount() < 1)
|
|
return;
|
|
var dpNames = [".main", ".secondary"];
|
|
var area, areaName;
|
|
for (var n in this._areas) {
|
|
area = this._areas[n];
|
|
if (is_instance(area, ChartAreaGroup))
|
|
continue;
|
|
if (area.getDataSourceName() != dsName)
|
|
continue;
|
|
areaName = area.getName();
|
|
for (var i = 0; i < dpNames.length; i++) {
|
|
var dp = this.getDataProvider(areaName + dpNames[i]);
|
|
if (dp != undefined)
|
|
dp.updateRange();
|
|
}
|
|
var timeline = this.getTimeline(dsName);
|
|
if (timeline != undefined && timeline.getMaxItemCount() > 0) {
|
|
var range = this.getRange(areaName);
|
|
if (range != undefined)
|
|
range.update();
|
|
}
|
|
}
|
|
};
|
|
ChartManager.prototype.layout = function (context, frameName, left, top, right, bottom) {
|
|
var frame = this.getFrame(frameName);
|
|
frame.measure(context, right - left, bottom - top);
|
|
frame.layout(left, top, right, bottom);
|
|
for (var n in this._timelines) {
|
|
var e = this._timelines[n];
|
|
if (e.getFrameName() == frameName)
|
|
e.onLayout();
|
|
}
|
|
for (var n in this._dataSources) {
|
|
if (n.substring(0, frameName.length) == frameName)
|
|
this.updateRange(n);
|
|
}
|
|
};
|
|
ChartManager.prototype.SelectRange = function (pArea, y) {
|
|
var it;
|
|
for (var ee in this._ranges) {
|
|
var _1 = this._ranges[ee].getAreaName();
|
|
var _2 = pArea.getName();
|
|
if (_1 == _2)
|
|
this._ranges[ee].selectAt(y);
|
|
else
|
|
this._ranges[ee].unselect();
|
|
}
|
|
};
|
|
ChartManager.prototype.scale = function (s) {
|
|
if (this._highlightedFrame == null)
|
|
return;
|
|
var hiArea = this._highlightedFrame.getHighlightedArea();
|
|
if (this.getRange(hiArea.getName()) != undefined) {
|
|
var dsName = hiArea.getDataSourceName();
|
|
var timeline = this.getTimeline(dsName);
|
|
if (timeline != null) {
|
|
timeline.scale(s);
|
|
this.updateRange(dsName);
|
|
}
|
|
}
|
|
};
|
|
ChartManager.prototype.showCursor = function (cursor) {
|
|
if (cursor === undefined)
|
|
cursor = 'default';
|
|
this._mainCanvas.style.cursor = cursor;
|
|
this._overlayCanvas.style.cursor = cursor;
|
|
};
|
|
ChartManager.prototype.hideCursor = function () {
|
|
this._mainCanvas.style.cursor = 'none';
|
|
this._overlayCanvas.style.cursor = 'none';
|
|
};
|
|
ChartManager.prototype.showCrossCursor = function (area, x, y) {
|
|
var e = this.getRange(area.getName());
|
|
if (e != undefined) {
|
|
e.selectAt(y);
|
|
e = this.getTimeline(area.getDataSourceName());
|
|
if (e != undefined)
|
|
if (e.selectAt(x))
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
ChartManager.prototype.hideCrossCursor = function (exceptTimeline) {
|
|
if (exceptTimeline != null) {
|
|
for (var n in this._timelines) {
|
|
var e = this._timelines[n];
|
|
if (e != exceptTimeline)
|
|
e.unselect();
|
|
}
|
|
} else {
|
|
for (var n in this._timelines)
|
|
this._timelines[n].unselect();
|
|
}
|
|
for (var n in this._ranges)
|
|
this._ranges[n].unselect();
|
|
};
|
|
ChartManager.prototype.clearHighlight = function () {
|
|
if (this._highlightedFrame != null) {
|
|
this._highlightedFrame.highlight(null);
|
|
this._highlightedFrame = null;
|
|
}
|
|
};
|
|
ChartManager.prototype.onToolMouseMove = function (frameName, x, y) {
|
|
var ret = false;
|
|
frameName += ".";
|
|
for (var n in this._dataSources) {
|
|
if (n.indexOf(frameName) == 0) {
|
|
var ds = this._dataSources[n];
|
|
if (is_instance(ds, MainDataSource))
|
|
if (ds.toolManager.acceptMouseMoveEvent(x, y))
|
|
ret = true;
|
|
}
|
|
}
|
|
return ret;
|
|
};
|
|
ChartManager.prototype.onToolMouseDown = function (frameName, x, y) {
|
|
var ret = false;
|
|
frameName += ".";
|
|
for (var n in this._dataSources) {
|
|
if (n.indexOf(frameName) == 0) {
|
|
var ds = this._dataSources[n];
|
|
if (is_instance(ds, MainDataSource))
|
|
if (ds.toolManager.acceptMouseDownEvent(x, y))
|
|
ret = true;
|
|
}
|
|
}
|
|
return ret;
|
|
};
|
|
ChartManager.prototype.onToolMouseUp = function (frameName, x, y) {
|
|
var ret = false;
|
|
frameName += ".";
|
|
for (var n in this._dataSources) {
|
|
if (n.indexOf(frameName) == 0) {
|
|
var ds = this._dataSources[n];
|
|
if (is_instance(ds, MainDataSource))
|
|
if (ds.toolManager.acceptMouseUpEvent(x, y))
|
|
ret = true;
|
|
}
|
|
}
|
|
return ret;
|
|
};
|
|
ChartManager.prototype.onToolMouseDrag = function (frameName, x, y) {
|
|
var ret = false;
|
|
frameName += ".";
|
|
for (var n in this._dataSources) {
|
|
if (n.indexOf(frameName) == 0) {
|
|
var ds = this._dataSources[n];
|
|
if (is_instance(ds, MainDataSource))
|
|
if (ds.toolManager.acceptMouseDownMoveEvent(x, y))
|
|
ret = true;
|
|
}
|
|
}
|
|
return ret;
|
|
};
|
|
ChartManager.prototype.onMouseMove = function (frameName, x, y, drag) {
|
|
var frame = this.getFrame(frameName);
|
|
if (frame === undefined)
|
|
return;
|
|
this.setFrameMousePos(frameName, x, y);
|
|
this.hideCrossCursor();
|
|
if (this._highlightedFrame != frame)
|
|
this.clearHighlight();
|
|
if (this._capturingMouseArea != null) {
|
|
this._capturingMouseArea.onMouseMove(x, y);
|
|
return;
|
|
}
|
|
var areas = frame.contains(x, y);
|
|
if (areas == null)
|
|
return;
|
|
var a, i, cnt = areas.length;
|
|
for (i = cnt - 1; i >= 0; i--) {
|
|
a = areas[i];
|
|
a = a.onMouseMove(x, y);
|
|
if (a != null) {
|
|
if (!is_instance(a, ChartAreaGroup)) {
|
|
frame.highlight(a);
|
|
this._highlightedFrame = frame;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
};
|
|
ChartManager.prototype.onMouseLeave = function (frameName, x, y, move) {
|
|
var frame = this.getFrame(frameName);
|
|
if (frame == undefined)
|
|
return;
|
|
this.setFrameMousePos(frameName, x, y);
|
|
this.hideCrossCursor();
|
|
this.clearHighlight();
|
|
if (this._capturingMouseArea != null) {
|
|
this._capturingMouseArea.onMouseLeave(x, y);
|
|
this._capturingMouseArea = null;
|
|
}
|
|
this._dragStarted = false;
|
|
};
|
|
ChartManager.prototype.onMouseDown = function (frameName, x, y) {
|
|
var frame = this.getFrame(frameName);
|
|
if (frame == undefined)
|
|
return;
|
|
var areas = frame.contains(x, y);
|
|
if (areas == null)
|
|
return;
|
|
var a, i, cnt = areas.length;
|
|
for (i = cnt - 1; i >= 0; i--) {
|
|
a = areas[i];
|
|
a = a.onMouseDown(x, y);
|
|
if (a != null) {
|
|
this._capturingMouseArea = a;
|
|
return;
|
|
}
|
|
}
|
|
};
|
|
ChartManager.prototype.onMouseUp = function (frameName, x, y) {
|
|
var frame = this.getFrame(frameName);
|
|
if (frame == undefined)
|
|
return;
|
|
if (this._capturingMouseArea) {
|
|
if (this._capturingMouseArea.onMouseUp(x, y) == null && this._dragStarted == false) {
|
|
if (this._selectedFrame != null && this._selectedFrame != frame)
|
|
this._selectedFrame.select(null);
|
|
if (this._capturingMouseArea.isSelected()) {
|
|
if (!this._captureMouseWheelDirectly)
|
|
$(this._overlayCanvas).unbind('mousewheel');
|
|
frame.select(null);
|
|
this._selectedFrame = null;
|
|
} else {
|
|
if (this._selectedFrame != frame)
|
|
if (!this._captureMouseWheelDirectly)
|
|
$(this._overlayCanvas).bind('mousewheel', mouseWheel);
|
|
frame.select(this._capturingMouseArea);
|
|
this._selectedFrame = frame;
|
|
}
|
|
}
|
|
this._capturingMouseArea = null;
|
|
this._dragStarted = false;
|
|
}
|
|
};
|
|
ChartManager.prototype.deleteToolObject = function () {
|
|
var pDPTool = this.getDataSource("frame0.k0");
|
|
var selectObject = pDPTool.getSelectToolObjcet();
|
|
if (selectObject != null)
|
|
pDPTool.delSelectToolObject();
|
|
var currentObject = pDPTool.getCurrentToolObject();
|
|
if (currentObject != null && currentObject.getState() != CToolObject.state.AfterDraw) {
|
|
pDPTool.delToolObject();
|
|
}
|
|
this.setNormalMode();
|
|
};
|
|
ChartManager.prototype.unloadTemplate = function (frameName) {
|
|
var frame = this.getFrame(frameName);
|
|
if (frame == undefined)
|
|
return;
|
|
for (var n in this._dataSources) {
|
|
if (n.match(frameName + "."))
|
|
delete this._dataSources[n];
|
|
}
|
|
for (var n in this._dataProviders) {
|
|
if (this._dataProviders[n].getFrameName() == frameName)
|
|
delete this._dataProviders[n];
|
|
}
|
|
delete this._frames[frameName];
|
|
for (var n in this._areas) {
|
|
if (this._areas[n].getFrameName() == frameName)
|
|
delete this._areas[n];
|
|
}
|
|
for (var n in this._timelines) {
|
|
if (this._timelines[n].getFrameName() == frameName)
|
|
delete this._timelines[n];
|
|
}
|
|
for (var n in this._ranges) {
|
|
if (this._ranges[n].getFrameName() == frameName)
|
|
delete this._ranges[n];
|
|
}
|
|
for (var n in this._plotters) {
|
|
if (this._plotters[n].getFrameName() == frameName)
|
|
delete this._plotters[n];
|
|
}
|
|
delete this._themes[frameName];
|
|
delete this._frameMousePos[frameName];
|
|
};
|
|
ChartManager.prototype.createIndicatorAndRange = function (areaName, indicName, notLoadSettings) {
|
|
var indic, range;
|
|
switch (indicName) {
|
|
case "MA":
|
|
indic = new MAIndicator();
|
|
range = new PositiveRange(areaName);
|
|
break;
|
|
case "EMA":
|
|
indic = new EMAIndicator();
|
|
range = new PositiveRange(areaName);
|
|
break;
|
|
case "VOLUME":
|
|
indic = new VOLUMEIndicator();
|
|
range = new ZeroBasedPositiveRange(areaName);
|
|
break;
|
|
case "MACD":
|
|
indic = new MACDIndicator();
|
|
range = new ZeroCenteredRange(areaName);
|
|
break;
|
|
case "DMI":
|
|
indic = new DMIIndicator();
|
|
range = new PercentageRange(areaName);
|
|
break;
|
|
case "DMA":
|
|
indic = new DMAIndicator();
|
|
range = new Range(areaName);
|
|
break;
|
|
case "TRIX":
|
|
indic = new TRIXIndicator();
|
|
range = new Range(areaName);
|
|
break;
|
|
case "BRAR":
|
|
indic = new BRARIndicator();
|
|
range = new Range(areaName);
|
|
break;
|
|
case "VR":
|
|
indic = new VRIndicator();
|
|
range = new Range(areaName);
|
|
break;
|
|
case "OBV":
|
|
indic = new OBVIndicator();
|
|
range = new Range(areaName);
|
|
break;
|
|
case "EMV":
|
|
indic = new EMVIndicator();
|
|
range = new Range(areaName);
|
|
break;
|
|
case "RSI":
|
|
indic = new RSIIndicator();
|
|
range = new PercentageRange(areaName);
|
|
break;
|
|
case "WR":
|
|
indic = new WRIndicator();
|
|
range = new PercentageRange(areaName);
|
|
break;
|
|
case "SAR":
|
|
indic = new SARIndicator();
|
|
range = new PositiveRange(areaName);
|
|
break;
|
|
case "KDJ":
|
|
indic = new KDJIndicator();
|
|
range = new PercentageRange(areaName);
|
|
break;
|
|
case "ROC":
|
|
indic = new ROCIndicator();
|
|
range = new Range(areaName);
|
|
break;
|
|
case "MTM":
|
|
indic = new MTMIndicator();
|
|
range = new Range(areaName);
|
|
break;
|
|
case "BOLL":
|
|
indic = new BOLLIndicator();
|
|
range = new Range(areaName);
|
|
break;
|
|
case "PSY":
|
|
indic = new PSYIndicator();
|
|
range = new Range(areaName);
|
|
break;
|
|
case "StochRSI":
|
|
indic = new STOCHRSIIndicator();
|
|
range = new PercentageRange(areaName);
|
|
break;
|
|
default:
|
|
return null;
|
|
}
|
|
if (!notLoadSettings)
|
|
indic.setParameters(ChartSettings.get().indics[indicName]);
|
|
return {"indic": indic, "range": range};
|
|
};
|
|
ChartManager.prototype.setMainIndicator = function (dsName, indicName) {
|
|
var areaName = dsName + ".main";
|
|
var dp = this.getDataProvider(areaName + ".main");
|
|
if (dp == undefined || !is_instance(dp, MainDataProvider))
|
|
return false;
|
|
var indic;
|
|
switch (indicName) {
|
|
case "MA":
|
|
indic = new MAIndicator();
|
|
break;
|
|
case "EMA":
|
|
indic = new EMAIndicator();
|
|
break;
|
|
case "BOLL":
|
|
indic = new BOLLIndicator();
|
|
break;
|
|
case "SAR":
|
|
indic = new SARIndicator();
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
indic.setParameters(ChartSettings.get().indics[indicName]);
|
|
var indicDpName = areaName + ".secondary";
|
|
var indicDp = this.getDataProvider(indicDpName);
|
|
if (indicDp == undefined) {
|
|
indicDp = new IndicatorDataProvider(indicDpName);
|
|
this.setDataProvider(indicDp.getName(), indicDp);
|
|
}
|
|
indicDp.setIndicator(indic);
|
|
var plotter = this.getPlotter(indicDpName);
|
|
if (plotter == undefined) {
|
|
plotter = new IndicatorPlotter(indicDpName);
|
|
this.setPlotter(plotter.getName(), plotter);
|
|
}
|
|
this.getArea(areaName).setChanged(true);
|
|
return true;
|
|
};
|
|
ChartManager.prototype.setIndicator = function (areaName, indicName) {
|
|
var area = this.getArea(areaName);
|
|
if (area == undefined || area.getNameObject().getCompAt(2) == "main")
|
|
return false;
|
|
var dp = this.getDataProvider(areaName + ".secondary");
|
|
if (dp == undefined || !is_instance(dp, IndicatorDataProvider))
|
|
return false;
|
|
var ret = this.createIndicatorAndRange(areaName, indicName);
|
|
if (ret == null)
|
|
return false;
|
|
var indic = ret.indic;
|
|
var range = ret.range;
|
|
this.removeDataProvider(areaName + ".main");
|
|
this.removePlotter(areaName + ".main");
|
|
this.removeRange(areaName);
|
|
this.removePlotter(areaName + "Range.decoration");
|
|
dp.setIndicator(indic);
|
|
this.setRange(areaName, range);
|
|
range.setPaddingTop(20);
|
|
range.setPaddingBottom(4);
|
|
range.setMinInterval(20);
|
|
if (is_instance(indic, VOLUMEIndicator)) {
|
|
var plotter = new LastVolumePlotter(areaName + "Range.decoration");
|
|
this.setPlotter(plotter.getName(), plotter);
|
|
} else if (is_instance(indic, BOLLIndicator) || is_instance(indic, SARIndicator)) {
|
|
var dp = new MainDataProvider(areaName + ".main");
|
|
this.setDataProvider(dp.getName(), dp);
|
|
dp.updateData();
|
|
var plotter = new OHLCPlotter(areaName + ".main");
|
|
this.setPlotter(plotter.getName(), plotter);
|
|
}
|
|
return true;
|
|
};
|
|
ChartManager.prototype.removeMainIndicator = function (dsName) {
|
|
var areaName = dsName + ".main";
|
|
var indicDpName = areaName + ".secondary";
|
|
var indicDp = this.getDataProvider(indicDpName);
|
|
if (indicDp == undefined || !is_instance(indicDp, IndicatorDataProvider))
|
|
return;
|
|
this.removeDataProvider(indicDpName);
|
|
this.removePlotter(indicDpName);
|
|
this.getArea(areaName).setChanged(true);
|
|
};
|
|
ChartManager.prototype.removeIndicator = function (areaName) {
|
|
var area = this.getArea(areaName);
|
|
if (area == undefined || area.getNameObject().getCompAt(2) == "main")
|
|
return;
|
|
var dp = this.getDataProvider(areaName + ".secondary");
|
|
if (dp == undefined || !is_instance(dp, IndicatorDataProvider))
|
|
return;
|
|
var rangeAreaName = areaName + "Range";
|
|
var rangeArea = this.getArea(rangeAreaName);
|
|
if (rangeArea == undefined)
|
|
return;
|
|
var tableLayout = this.getArea(area.getDataSourceName() + ".charts");
|
|
if (tableLayout == undefined)
|
|
return;
|
|
tableLayout.removeArea(area);
|
|
this.removeArea(areaName);
|
|
tableLayout.removeArea(rangeArea);
|
|
this.removeArea(rangeAreaName);
|
|
for (var n in this._dataProviders) {
|
|
if (this._dataProviders[n].getAreaName() == areaName)
|
|
this.removeDataProvider(n);
|
|
}
|
|
for (var n in this._ranges) {
|
|
if (this._ranges[n].getAreaName() == areaName)
|
|
this.removeRange(n);
|
|
}
|
|
for (var n in this._plotters) {
|
|
if (this._plotters[n].getAreaName() == areaName)
|
|
this.removePlotter(n);
|
|
}
|
|
for (var n in this._plotters) {
|
|
if (this._plotters[n].getAreaName() == rangeAreaName)
|
|
this.removePlotter(n);
|
|
}
|
|
};
|
|
/**
|
|
* getIndicatorParameters
|
|
* 获取指标的ParamExpr数组
|
|
* @param indicName
|
|
* @returns {*}
|
|
*/
|
|
ChartManager.prototype.getIndicatorParameters = function (indicName) {
|
|
var indic = this._fakeIndicators[indicName];
|
|
if (indic == undefined) {
|
|
var ret = this.createIndicatorAndRange("", indicName);
|
|
if (ret == null)
|
|
return null;
|
|
this._fakeIndicators[indicName] = indic = ret.indic;
|
|
}
|
|
var params = [];
|
|
var i, cnt = indic.getParameterCount();
|
|
for (i = 0; i < cnt; i++)
|
|
params.push(indic.getParameterAt(i));
|
|
return params;
|
|
};
|
|
ChartManager.prototype.setIndicatorParameters = function (indicName, params) {
|
|
var n, indic;
|
|
for (n in this._dataProviders) {
|
|
var dp = this._dataProviders[n];
|
|
if (is_instance(dp, IndicatorDataProvider) == false)
|
|
continue;
|
|
indic = dp.getIndicator();
|
|
if (indic.getName() == indicName) {
|
|
indic.setParameters(params);
|
|
dp.refresh();
|
|
this.getArea(dp.getAreaName()).setChanged(true);
|
|
}
|
|
}
|
|
indic = this._fakeIndicators[indicName];
|
|
if (indic == undefined) {
|
|
var ret = this.createIndicatorAndRange("", indicName, true);
|
|
if (ret == null)
|
|
return;
|
|
this._fakeIndicators[indicName] = indic = ret.indic;
|
|
}
|
|
indic.setParameters(params);
|
|
};
|
|
ChartManager.prototype.getIndicatorAreaName = function (dsName, index) {
|
|
var tableLayout = this.getArea(dsName + ".charts");
|
|
var cnt = tableLayout.getAreaCount() >> 1;
|
|
if (index < 0 || index >= cnt)
|
|
return "";
|
|
return tableLayout.getAreaAt(index << 1).getName();
|
|
};
|
|
var Timeline = create_class(NamedObject);
|
|
Timeline._ItemWidth = [1, 3, 3, 5, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29];
|
|
Timeline._SpaceWidth = [1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 7, 7, 7];
|
|
Timeline.PADDING_LEFT = 4;
|
|
Timeline.PADDING_RIGHT = 8;
|
|
Timeline.prototype.__construct = function (name) {
|
|
Timeline.__super.__construct.call(this, name);
|
|
this._updated = false;
|
|
this._innerLeft = 0;
|
|
this._innerWidth = 0;
|
|
this._firstColumnLeft = 0;
|
|
this._scale = 3;
|
|
this._lastScale = -1;
|
|
this._maxItemCount = 0;
|
|
this._maxIndex = 0;
|
|
this._firstIndex = -1;
|
|
this._selectedIndex = -1;
|
|
this._savedFirstIndex = -1;
|
|
};
|
|
Timeline.prototype.isLatestShown = function () {
|
|
return this.getLastIndex() == this._maxIndex;
|
|
};
|
|
Timeline.prototype.isUpdated = function () {
|
|
return this._updated;
|
|
};
|
|
Timeline.prototype.setUpdated = function (v) {
|
|
this._updated = v;
|
|
};
|
|
Timeline.prototype.getItemWidth = function () {
|
|
return Timeline._ItemWidth[this._scale];
|
|
};
|
|
Timeline.prototype.getSpaceWidth = function () {
|
|
return Timeline._SpaceWidth[this._scale];
|
|
};
|
|
Timeline.prototype.getColumnWidth = function () {
|
|
return this.getSpaceWidth() + this.getItemWidth();
|
|
};
|
|
Timeline.prototype.getInnerWidth = function () {
|
|
return this._innerWidth;
|
|
};
|
|
Timeline.prototype.getItemLeftOffset = function () {
|
|
return this.getSpaceWidth();
|
|
};
|
|
Timeline.prototype.getItemCenterOffset = function () {
|
|
return this.getSpaceWidth() + (this.getItemWidth() >> 1);
|
|
};
|
|
Timeline.prototype.getFirstColumnLeft = function () {
|
|
return this._firstColumnLeft;
|
|
};
|
|
Timeline.prototype.getMaxItemCount = function () {
|
|
return this._maxItemCount;
|
|
};
|
|
Timeline.prototype.getFirstIndex = function () {
|
|
return this._firstIndex;
|
|
};
|
|
Timeline.prototype.getLastIndex = function () {
|
|
return Math.min(this._firstIndex + this._maxItemCount, this._maxIndex);
|
|
};
|
|
Timeline.prototype.getSelectedIndex = function () {
|
|
return this._selectedIndex;
|
|
};
|
|
Timeline.prototype.getMaxIndex = function () {
|
|
return this._maxIndex;
|
|
};
|
|
Timeline.prototype.calcColumnCount = function (w) {
|
|
return Math.floor(w / this.getColumnWidth()) << 0;
|
|
};
|
|
Timeline.prototype.calcFirstColumnLeft = function (maxItemCount) {
|
|
return this._innerLeft + this._innerWidth - (this.getColumnWidth() * maxItemCount);
|
|
};
|
|
Timeline.prototype.calcFirstIndexAlignRight = function (oldFirstIndex, oldMaxItemCount, newMaxItemCount) {
|
|
return Math.max(0, oldFirstIndex + Math.max(oldMaxItemCount, 1) - Math.max(newMaxItemCount, 1));
|
|
};
|
|
Timeline.prototype.calcFirstIndex = function (newMaxItemCount) {
|
|
return this.validateFirstIndex(
|
|
this.calcFirstIndexAlignRight(this._firstIndex, this._maxItemCount,
|
|
newMaxItemCount), newMaxItemCount);
|
|
};
|
|
Timeline.prototype.updateMaxItemCount = function () {
|
|
var newMaxItemCount = this.calcColumnCount(this._innerWidth);
|
|
var newFirstIndex;
|
|
if (this._maxItemCount < 1) {
|
|
newFirstIndex = this.calcFirstIndex(newMaxItemCount);
|
|
} else if (this._lastScale == this._scale) {
|
|
newFirstIndex = this.validateFirstIndex(this._firstIndex - (newMaxItemCount - this._maxItemCount));
|
|
} else {
|
|
var focusedIndex = (this._selectedIndex >= 0) ? this._selectedIndex : this.getLastIndex() - 1;
|
|
newFirstIndex = this.validateFirstIndex(focusedIndex -
|
|
Math.round((focusedIndex - this._firstIndex) * newMaxItemCount / this._maxItemCount));
|
|
}
|
|
this._lastScale = this._scale;
|
|
if (this._firstIndex != newFirstIndex) {
|
|
if (this._selectedIndex == this._firstIndex)
|
|
this._selectedIndex = newFirstIndex;
|
|
this._firstIndex = newFirstIndex;
|
|
this._updated = true;
|
|
}
|
|
if (this._maxItemCount != newMaxItemCount) {
|
|
this._maxItemCount = newMaxItemCount;
|
|
this._updated = true;
|
|
}
|
|
this._firstColumnLeft = this.calcFirstColumnLeft(newMaxItemCount);
|
|
};
|
|
Timeline.prototype.validateFirstIndex = function (firstIndex, maxItemCount) {
|
|
if (this._maxIndex < 1)
|
|
return -1;
|
|
if (firstIndex < 0)
|
|
return 0;
|
|
var lastFirst = Math.max(0, this._maxIndex - 1 /*maxItemCount*/);
|
|
if (firstIndex > lastFirst)
|
|
return lastFirst;
|
|
return firstIndex;
|
|
};
|
|
Timeline.prototype.validateSelectedIndex = function () {
|
|
if (this._selectedIndex < this._firstIndex)
|
|
this._selectedIndex = -1;
|
|
else if (this._selectedIndex >= this.getLastIndex())
|
|
this._selectedIndex = -1;
|
|
};
|
|
Timeline.prototype.onLayout = function () {
|
|
var mgr = ChartManager.getInstance();
|
|
var area = mgr.getArea(this.getDataSourceName() + ".main");
|
|
if (area != null) {
|
|
this._innerLeft = area.getLeft() + Timeline.PADDING_LEFT;
|
|
var w = Math.max(0, area.getWidth() - (Timeline.PADDING_LEFT + Timeline.PADDING_RIGHT));
|
|
if (this._innerWidth != w) {
|
|
this._innerWidth = w;
|
|
this.updateMaxItemCount();
|
|
}
|
|
}
|
|
};
|
|
Timeline.prototype.toIndex = function (x) {
|
|
return this._firstIndex + this.calcColumnCount(x - this._firstColumnLeft);
|
|
};
|
|
Timeline.prototype.toColumnLeft = function (index) {
|
|
return this._firstColumnLeft + (this.getColumnWidth() * (index - this._firstIndex));
|
|
};
|
|
Timeline.prototype.toItemLeft = function (index) {
|
|
return this.toColumnLeft(index) + this.getItemLeftOffset();
|
|
};
|
|
Timeline.prototype.toItemCenter = function (index) {
|
|
return this.toColumnLeft(index) + this.getItemCenterOffset();
|
|
};
|
|
Timeline.prototype.selectAt = function (x) {
|
|
this._selectedIndex = this.toIndex(x);
|
|
this.validateSelectedIndex();
|
|
return (this._selectedIndex >= 0);
|
|
};
|
|
Timeline.prototype.unselect = function () {
|
|
this._selectedIndex = -1;
|
|
};
|
|
Timeline.prototype.update = function () {
|
|
var mgr = ChartManager.getInstance();
|
|
var ds = mgr.getDataSource(this.getDataSourceName());
|
|
var oldMaxIndex = this._maxIndex;
|
|
this._maxIndex = ds.getDataCount();
|
|
switch (ds.getUpdateMode()) {
|
|
case DataSource.UpdateMode.Refresh:
|
|
if (this._maxIndex < 1)
|
|
this._firstIndex = -1;
|
|
else
|
|
this._firstIndex = Math.max(this._maxIndex - this._maxItemCount, 0);
|
|
this._selectedIndex = -1;
|
|
this._updated = true;
|
|
break;
|
|
case DataSource.UpdateMode.Append:
|
|
var lastIndex = this.getLastIndex();
|
|
var erasedCount = ds.getErasedCount();
|
|
if (lastIndex < oldMaxIndex) {
|
|
if (erasedCount > 0) {
|
|
this._firstIndex = Math.max(this._firstIndex - erasedCount, 0);
|
|
if (this._selectedIndex >= 0) {
|
|
this._selectedIndex -= erasedCount;
|
|
this.validateSelectedIndex();
|
|
}
|
|
this._updated = true;
|
|
}
|
|
} else if (lastIndex == oldMaxIndex) {
|
|
this._firstIndex += (this._maxIndex - oldMaxIndex);
|
|
if (this._selectedIndex >= 0) {
|
|
this._selectedIndex -= erasedCount;
|
|
this.validateSelectedIndex();
|
|
}
|
|
this._updated = true;
|
|
}
|
|
break;
|
|
}
|
|
};
|
|
Timeline.prototype.move = function (x) {
|
|
if (this.isLatestShown())
|
|
ChartManager.getInstance().getArea(
|
|
this.getDataSourceName() + ".mainRange").setChanged(true);
|
|
this._firstIndex = this.validateFirstIndex(
|
|
this._savedFirstIndex - this.calcColumnCount(x), this._maxItemCount);
|
|
this._updated = true;
|
|
if (this._selectedIndex >= 0)
|
|
this.validateSelectedIndex();
|
|
};
|
|
Timeline.prototype.startMove = function () {
|
|
this._savedFirstIndex = this._firstIndex;
|
|
};
|
|
Timeline.prototype.scale = function (s) {
|
|
this._scale += s;
|
|
if (this._scale < 0)
|
|
this._scale = 0;
|
|
else if (this._scale >= Timeline._ItemWidth.length)
|
|
this._scale = Timeline._ItemWidth.length - 1;
|
|
this.updateMaxItemCount();
|
|
if (this._selectedIndex >= 0)
|
|
this.validateSelectedIndex();
|
|
};
|
|
var Range = create_class(NamedObject);
|
|
Range.prototype.__construct = function (name) {
|
|
Range.__super.__construct.call(this, name);
|
|
this._updated = true;
|
|
this._minValue = Number.MAX_VALUE;
|
|
this._maxValue = -Number.MAX_VALUE;
|
|
this._outerMinValue = Number.MAX_VALUE;
|
|
this._outerMaxValue = -Number.MAX_VALUE;
|
|
this._ratio = 0;
|
|
this._top = 0;
|
|
this._bottom = 0;
|
|
this._paddingTop = 0;
|
|
this._paddingBottom = 0;
|
|
this._minInterval = 36;
|
|
this._selectedPosition = -1;
|
|
this._selectedValue = -Number.MAX_VALUE;
|
|
this._gradations = [];
|
|
};
|
|
Range.prototype.isUpdated = function () {
|
|
return this._updated;
|
|
};
|
|
Range.prototype.setUpdated = function (v) {
|
|
this._updated = v;
|
|
};
|
|
Range.prototype.getMinValue = function () {
|
|
return this._minValue;
|
|
};
|
|
Range.prototype.getMaxValue = function () {
|
|
return this._maxValue;
|
|
};
|
|
Range.prototype.getRange = function () {
|
|
return this._maxValue - this._minValue;
|
|
};
|
|
Range.prototype.getOuterMinValue = function () {
|
|
return this._outerMinValue;
|
|
};
|
|
Range.prototype.getOuterMaxValue = function () {
|
|
return this._outerMaxValue;
|
|
};
|
|
Range.prototype.getOuterRange = function () {
|
|
return this._outerMaxValue - this._outerMinValue;
|
|
};
|
|
Range.prototype.getHeight = function () {
|
|
return Math.max(0, this._bottom - this._top);
|
|
};
|
|
Range.prototype.getGradations = function () {
|
|
return this._gradations;
|
|
};
|
|
Range.prototype.getMinInterval = function () {
|
|
return this._minInterval;
|
|
};
|
|
Range.prototype.setMinInterval = function (v) {
|
|
this._minInterval = v;
|
|
};
|
|
Range.prototype.getSelectedPosition = function () {
|
|
if (this._selectedPosition >= 0)
|
|
return this._selectedPosition;
|
|
if (this._selectedValue > -Number.MAX_VALUE)
|
|
return this.toY(this._selectedValue);
|
|
return -1;
|
|
};
|
|
Range.prototype.getSelectedValue = function () {
|
|
if (this._selectedValue > -Number.MAX_VALUE)
|
|
return this._selectedValue;
|
|
var mgr = ChartManager.getInstance();
|
|
var area = mgr.getArea(this.getAreaName());
|
|
if (area == null)
|
|
return -Number.MAX_VALUE;
|
|
if (this._selectedPosition < area.getTop() + 12 || this._selectedPosition >= area.getBottom() - 4)
|
|
return -Number.MAX_VALUE;
|
|
return this.toValue(this._selectedPosition);
|
|
};
|
|
Range.prototype.setPaddingTop = function (p) {
|
|
this._paddingTop = p;
|
|
};
|
|
Range.prototype.setPaddingBottom = function (p) {
|
|
this._paddingBottom = p;
|
|
};
|
|
Range.prototype.toValue = function (y) {
|
|
return this._maxValue - (y - this._top) / this._ratio;
|
|
};
|
|
Range.prototype.toY = function (value) {
|
|
if (this._ratio > 0)
|
|
return this._top + Math.floor((this._maxValue - value) * this._ratio + 0.5);
|
|
return this._top;
|
|
};
|
|
Range.prototype.toHeight = function (value) {
|
|
return Math.floor(value * this._ratio + 1.5);
|
|
};
|
|
Range.prototype.update = function () {
|
|
var min = Number.MAX_VALUE;
|
|
var max = -Number.MAX_VALUE;
|
|
var mgr = ChartManager.getInstance();
|
|
var dp, dpNames = [".main", ".secondary"];
|
|
for (var i = 0; i < dpNames.length; i++) {
|
|
dp = mgr.getDataProvider(this.getName() + dpNames[i]);
|
|
if (dp != null) {
|
|
min = Math.min(min, dp.getMinValue());
|
|
max = Math.max(max, dp.getMaxValue());
|
|
}
|
|
}
|
|
var r = {"min": min, "max": max};
|
|
this.preSetRange(r);
|
|
this.setRange(r.min, r.max);
|
|
};
|
|
Range.prototype.select = function (v) {
|
|
this._selectedValue = v;
|
|
this._selectedPosition = -1;
|
|
};
|
|
Range.prototype.selectAt = function (y) {
|
|
this._selectedPosition = y;
|
|
this._selectedValue = -Number.MAX_VALUE;
|
|
};
|
|
Range.prototype.unselect = function () {
|
|
this._selectedPosition = -1;
|
|
this._selectedValue = -Number.MAX_VALUE;
|
|
};
|
|
Range.prototype.preSetRange = function (r) {
|
|
if (r.min == r.max) {
|
|
r.min = -1.0;
|
|
r.max = 1.0;
|
|
}
|
|
};
|
|
Range.prototype.setRange = function (minValue, maxValue) {
|
|
var mgr = ChartManager.getInstance();
|
|
var area = mgr.getArea(this.getAreaName());
|
|
if (this._minValue == minValue && this._maxValue == maxValue && !area.isChanged())
|
|
return;
|
|
this._updated = true;
|
|
this._minValue = minValue;
|
|
this._maxValue = maxValue;
|
|
this._gradations = [];
|
|
var top = area.getTop() + this._paddingTop;
|
|
var bottom = area.getBottom() - (this._paddingBottom + 1);
|
|
if (top >= bottom) {
|
|
this._minValue = this._maxValue;
|
|
return;
|
|
}
|
|
this._top = top;
|
|
this._bottom = bottom;
|
|
if (this._maxValue > this._minValue)
|
|
this._ratio = (bottom - top) / (this._maxValue - this._minValue);
|
|
else {
|
|
this._ratio = 1;
|
|
}
|
|
this._outerMinValue = this.toValue(area.getBottom());
|
|
this._outerMaxValue = this.toValue(area.getTop());
|
|
this.updateGradations();
|
|
};
|
|
Range.prototype.calcInterval = function () {
|
|
var H = this.getHeight();
|
|
var h = this.getMinInterval();
|
|
if ((H / h) <= 1)
|
|
h = H >> 1;
|
|
var d = this.getRange();
|
|
var i = 0;
|
|
while (i > -2 && Math.floor(d) < d) {
|
|
d *= 10.0;
|
|
i--;
|
|
}
|
|
var m, c;
|
|
for (; ; i++) {
|
|
c = Math.pow(10.0, i);
|
|
m = c;
|
|
if (this.toHeight(m) > h)
|
|
break;
|
|
m = 2.0 * c;
|
|
if (this.toHeight(m) > h)
|
|
break;
|
|
m = 5.0 * c;
|
|
if (this.toHeight(m) > h)
|
|
break;
|
|
}
|
|
return m;
|
|
};
|
|
Range.prototype.updateGradations = function () {
|
|
this._gradations = [];
|
|
var interval = this.calcInterval();
|
|
if (interval <= 0.0)
|
|
return;
|
|
var v = Math.floor(this.getMaxValue() / interval) * interval;
|
|
do {
|
|
this._gradations.push(v);
|
|
v -= interval;
|
|
} while (v > this.getMinValue());
|
|
};
|
|
var PositiveRange = create_class(Range);
|
|
PositiveRange.prototype.__construct = function (name) {
|
|
PositiveRange.__super.__construct.call(this, name);
|
|
};
|
|
PositiveRange.prototype.preSetRange = function (r) {
|
|
if (r.min < 0) r.min = 0;
|
|
if (r.max < 0) r.max = 0;
|
|
};
|
|
var ZeroBasedPositiveRange = create_class(Range);
|
|
ZeroBasedPositiveRange.prototype.__construct = function (name) {
|
|
ZeroBasedPositiveRange.__super.__construct.call(this, name);
|
|
};
|
|
ZeroBasedPositiveRange.prototype.preSetRange = function (r) {
|
|
r.min = 0;
|
|
if (r.max < 0) r.max = 0;
|
|
};
|
|
var MainRange = create_class(Range);
|
|
MainRange.prototype.__construct = function (name) {
|
|
MainRange.__super.__construct.call(this, name);
|
|
};
|
|
MainRange.prototype.preSetRange = function (r) {
|
|
var mgr = ChartManager.getInstance();
|
|
|
|
var timeline = mgr.getTimeline(this.getDataSourceName());
|
|
var dIndex = timeline.getMaxIndex() - timeline.getLastIndex();
|
|
if (dIndex < 25) {
|
|
var ds = mgr.getDataSource(this.getDataSourceName());
|
|
|
|
var data = ds.getDataAt(ds.getDataCount() - 1);
|
|
var d = ((r.max - r.min) / 4) * (1 - (dIndex / 25));
|
|
|
|
r.min = Math.min(r.min, Math.max(data.low - d, 0));
|
|
r.max = Math.max(r.max, data.high + d);
|
|
}
|
|
|
|
if (r.min > 0) {
|
|
var a = r.max / r.min;
|
|
|
|
if (a < 1.016) {
|
|
var m = (r.max + r.min) / 2.0;
|
|
var c = (a - 1.0) * 1.5;
|
|
r.max = m * (1.0 + c);
|
|
r.min = m * (1.0 - c);
|
|
} else if (a < 1.048) {
|
|
var m = (r.max + r.min) / 2.0;
|
|
r.max = m * 1.024;
|
|
r.min = m * 0.976;
|
|
}
|
|
}
|
|
if (r.min < 0) r.min = 0;
|
|
if (r.max < 0) r.max = 0;
|
|
};
|
|
|
|
var ZeroCenteredRange = create_class(Range);
|
|
ZeroCenteredRange.prototype.__construct = function (name) {
|
|
ZeroCenteredRange.__super.__construct.call(this, name);
|
|
};
|
|
ZeroCenteredRange.prototype.calcInterval = function (area) {
|
|
var h = this.getMinInterval();
|
|
if (area.getHeight() / h < 2)
|
|
return 0.0;
|
|
var r = this.getRange();
|
|
var i;
|
|
for (i = 3; ; i += 2) {
|
|
if (this.toHeight(r / i) <= h)
|
|
break;
|
|
}
|
|
i -= 2;
|
|
return r / i;
|
|
};
|
|
ZeroCenteredRange.prototype.updateGradations = function () {
|
|
this._gradations = [];
|
|
var mgr = ChartManager.getInstance();
|
|
var area = mgr.getArea(this.getAreaName());
|
|
var interval = this.calcInterval(area);
|
|
if (interval <= 0.0)
|
|
return;
|
|
var v = interval / 2.0;
|
|
do {
|
|
this._gradations.push(v);
|
|
this._gradations.push(-v);
|
|
v += interval;
|
|
} while (v <= this.getMaxValue());
|
|
};
|
|
ZeroCenteredRange.prototype.preSetRange = function (r) {
|
|
var abs = Math.max(Math.abs(r.min), Math.abs(r.max));
|
|
r.min = -abs;
|
|
r.max = abs;
|
|
};
|
|
var PercentageRange = create_class(Range);
|
|
PercentageRange.prototype.__construct = function (name) {
|
|
PercentageRange.__super.__construct.call(this, name);
|
|
};
|
|
PercentageRange.prototype.updateGradations = function () {
|
|
this._gradations = [];
|
|
var mgr = ChartManager.getInstance();
|
|
var area = mgr.getArea(this.getAreaName());
|
|
var interval = 10.0;
|
|
var h = Math.floor(this.toHeight(interval));
|
|
if ((h << 2) > area.getHeight())
|
|
return;
|
|
var v = Math.ceil(this.getMinValue() / interval) * interval;
|
|
if (v == 0.0)
|
|
v = 0;
|
|
if ((h << 2) < 24) {
|
|
if ((h << 1) < 8)
|
|
return;
|
|
do {
|
|
if (v == 20.0 || v == 80.0)
|
|
this._gradations.push(v);
|
|
v += interval;
|
|
} while (v < this.getMaxValue());
|
|
} else {
|
|
do {
|
|
if (h < 8) {
|
|
if (v == 20.0 || v == 50.0 || v == 80.0)
|
|
this._gradations.push(v);
|
|
} else {
|
|
if (v == 0.0 || v == 20.0 || v == 50.0 || v == 80.0 || v == 100.0)
|
|
this._gradations.push(v);
|
|
}
|
|
v += interval;
|
|
} while (v < this.getMaxValue());
|
|
}
|
|
};
|
|
var DataSource = create_class(NamedObject);
|
|
DataSource.prototype.__construct = function (name) {
|
|
DataSource.__super.__construct.call(this, name);
|
|
};
|
|
DataSource.UpdateMode = {
|
|
DoNothing: 0,
|
|
Refresh: 1,
|
|
Update: 2,
|
|
Append: 3
|
|
};
|
|
DataSource.prototype.getUpdateMode = function () {
|
|
return this._updateMode;
|
|
};
|
|
DataSource.prototype.setUpdateMode = function (mode) {
|
|
this._updateMode = mode;
|
|
};
|
|
DataSource.prototype.getCacheSize = function () {
|
|
return 0;
|
|
};
|
|
DataSource.prototype.getDataCount = function () {
|
|
return 0;
|
|
};
|
|
var MainDataSource = create_class(DataSource);
|
|
MainDataSource.prototype.__construct = function (name) {
|
|
MainDataSource.__super.__construct.call(this, name);
|
|
this._erasedCount = 0;
|
|
this._dataItems = [];
|
|
this._decimalDigits = 0;
|
|
this.toolManager = new CToolManager(name);
|
|
};
|
|
MainDataSource.prototype.getCacheSize = function () {
|
|
return this._dataItems.length;
|
|
};
|
|
MainDataSource.prototype.getDataCount = function () {
|
|
return this._dataItems.length;
|
|
};
|
|
MainDataSource.prototype.getUpdatedCount = function () {
|
|
return this._updatedCount;
|
|
};
|
|
MainDataSource.prototype.getAppendedCount = function () {
|
|
return this._appendedCount;
|
|
};
|
|
MainDataSource.prototype.getErasedCount = function () {
|
|
return this._erasedCount;
|
|
};
|
|
MainDataSource.prototype.getDecimalDigits = function () {
|
|
return this._decimalDigits;
|
|
};
|
|
MainDataSource.prototype.calcDecimalDigits = function (v) {
|
|
var str = "" + v;
|
|
var i = str.indexOf('.');
|
|
if (i < 0)
|
|
return 0;
|
|
return (str.length - 1) - i;
|
|
};
|
|
MainDataSource.prototype.getLastDate = function () {
|
|
|
|
var count = this.getDataCount();
|
|
if (count < 1)
|
|
return -1;
|
|
return this.getDataAt(count - 1).date;
|
|
};
|
|
MainDataSource.prototype.getDataAt = function (index) {
|
|
return this._dataItems[index];
|
|
};
|
|
MainDataSource.prototype.update = function (data) {
|
|
|
|
this._updatedCount = 0;
|
|
this._appendedCount = 0;
|
|
this._erasedCount = 0;
|
|
var len = this._dataItems.length;
|
|
if (len > 0) {
|
|
var lastIndex = len - 1;
|
|
var lastItem = this._dataItems[lastIndex];
|
|
var e, i, cnt = data.length;
|
|
for (i = 0; i < cnt; i++) {
|
|
e = data[i];
|
|
if (e[0] == lastItem.date) {
|
|
if (lastItem.open == e[1] &&
|
|
lastItem.high == e[2] &&
|
|
lastItem.low == e[3] &&
|
|
lastItem.close == e[4] &&
|
|
lastItem.volume == e[5]) {
|
|
this.setUpdateMode(DataSource.UpdateMode.DoNothing);
|
|
} else {
|
|
this.setUpdateMode(DataSource.UpdateMode.Update);
|
|
this._dataItems[lastIndex] = {
|
|
date: e[0],
|
|
open: e[1],
|
|
high: e[2],
|
|
low: e[3],
|
|
close: e[4],
|
|
volume: e[5]
|
|
};
|
|
this._updatedCount++;
|
|
}
|
|
i++;
|
|
if (i < cnt) {
|
|
this.setUpdateMode(DataSource.UpdateMode.Append);
|
|
for (; i < cnt; i++, this._appendedCount++) {
|
|
e = data[i];
|
|
this._dataItems.push({
|
|
date: e[0],
|
|
open: e[1],
|
|
high: e[2],
|
|
low: e[3],
|
|
close: e[4],
|
|
volume: e[5]
|
|
});
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
if (cnt < KlineIns.limit) {
|
|
this.setUpdateMode(DataSource.UpdateMode.DoNothing);
|
|
return false;
|
|
}
|
|
}
|
|
this.setUpdateMode(DataSource.UpdateMode.Refresh);
|
|
this._dataItems = [];
|
|
var d, n, e, i, cnt = data.length;
|
|
for (i = 0; i < cnt; i++) {
|
|
e = data[i];
|
|
for (n = 1; n <= 4; n++) {
|
|
d = this.calcDecimalDigits(e[n]);
|
|
if (this._decimalDigits < d)
|
|
this._decimalDigits = d;
|
|
}
|
|
this._dataItems.push({
|
|
date: e[0],
|
|
open: e[1],
|
|
high: e[2],
|
|
low: e[3],
|
|
close: e[4],
|
|
volume: e[5]
|
|
});
|
|
}
|
|
return true;
|
|
};
|
|
MainDataSource.prototype.select = function (id) {
|
|
this.toolManager.selecedObject = id;
|
|
};
|
|
MainDataSource.prototype.unselect = function () {
|
|
this.toolManager.selecedObject = -1;
|
|
};
|
|
MainDataSource.prototype.addToolObject = function (toolObject) {
|
|
this.toolManager.addToolObject(toolObject);
|
|
};
|
|
MainDataSource.prototype.delToolObject = function () {
|
|
this.toolManager.delCurrentObject();
|
|
};
|
|
MainDataSource.prototype.getToolObject = function (index) {
|
|
return this.toolManager.getToolObject(index);
|
|
};
|
|
MainDataSource.prototype.getToolObjectCount = function () {
|
|
return this.toolManager.toolObjects.length;
|
|
};
|
|
MainDataSource.prototype.getCurrentToolObject = function () {
|
|
return this.toolManager.getCurrentObject();
|
|
};
|
|
MainDataSource.prototype.getSelectToolObjcet = function () {
|
|
return this.toolManager.getSelectedObject();
|
|
};
|
|
MainDataSource.prototype.delSelectToolObject = function () {
|
|
this.toolManager.delSelectedObject();
|
|
};
|
|
var DataProvider = create_class(NamedObject);
|
|
DataProvider.prototype.__construct = function (name) {
|
|
DataProvider.__super.__construct.call(this, name);
|
|
this._minValue = 0;
|
|
this._maxValue = 0;
|
|
this._minValueIndex = -1;
|
|
this._maxValueIndex = -1;
|
|
};
|
|
DataProvider.prototype.getMinValue = function () {
|
|
return this._minValue;
|
|
};
|
|
DataProvider.prototype.getMaxValue = function () {
|
|
return this._maxValue;
|
|
};
|
|
DataProvider.prototype.getMinValueIndex = function () {
|
|
return this._minValueIndex;
|
|
};
|
|
DataProvider.prototype.getMaxValueIndex = function () {
|
|
return this._maxValueIndex;
|
|
};
|
|
DataProvider.prototype.calcRange = function (firstIndexes, lastIndex, minmaxes, indexes) {
|
|
var min = Number.MAX_VALUE;
|
|
var max = -Number.MAX_VALUE;
|
|
var minIndex = -1;
|
|
var maxIndex = -1;
|
|
var minmax = {};
|
|
var i = lastIndex - 1;
|
|
var n = firstIndexes.length - 1;
|
|
for (; n >= 0; n--) {
|
|
var first = firstIndexes[n];
|
|
if (i < first) {
|
|
minmaxes[n] = {"min": min, "max": max};
|
|
} else {
|
|
for (; i >= first; i--) {
|
|
if (this.getMinMaxAt(i, minmax) == false)
|
|
continue;
|
|
if (min > minmax.min) {
|
|
min = minmax.min;
|
|
minIndex = i;
|
|
}
|
|
if (max < minmax.max) {
|
|
max = minmax.max;
|
|
maxIndex = i;
|
|
}
|
|
}
|
|
minmaxes[n] = {"min": min, "max": max};
|
|
}
|
|
if (indexes != null) {
|
|
indexes[n] = {"minIndex": minIndex, "maxIndex": maxIndex};
|
|
}
|
|
}
|
|
};
|
|
DataProvider.prototype.updateRange = function () {
|
|
var mgr = ChartManager.getInstance();
|
|
var timeline = mgr.getTimeline(this.getDataSourceName());
|
|
var firstIndexes = [timeline.getFirstIndex()];
|
|
var minmaxes = [{}];
|
|
var indexes = [{}];
|
|
this.calcRange(firstIndexes, timeline.getLastIndex(), minmaxes, indexes);
|
|
this._minValue = minmaxes[0].min;
|
|
this._maxValue = minmaxes[0].max;
|
|
this._minValueIndex = indexes[0].minIndex;
|
|
this._maxValueIndex = indexes[0].maxIndex;
|
|
};
|
|
var MainDataProvider = create_class(DataProvider);
|
|
MainDataProvider.prototype.__construct = function (name) {
|
|
MainDataProvider.__super.__construct.call(this, name);
|
|
this._candlestickDS = null;
|
|
};
|
|
MainDataProvider.prototype.updateData = function () {
|
|
var mgr = ChartManager.getInstance();
|
|
var ds = mgr.getDataSource(this.getDataSourceName());
|
|
if (!is_instance(ds, MainDataSource))
|
|
return;
|
|
this._candlestickDS = ds;
|
|
};
|
|
MainDataProvider.prototype.getMinMaxAt = function (index, minmax) {
|
|
var data = this._candlestickDS.getDataAt(index);
|
|
minmax.min = data.low;
|
|
minmax.max = data.high;
|
|
return true;
|
|
};
|
|
var IndicatorDataProvider = create_class(DataProvider);
|
|
IndicatorDataProvider.prototype.getIndicator = function () {
|
|
return this._indicator;
|
|
};
|
|
IndicatorDataProvider.prototype.setIndicator = function (v) {
|
|
this._indicator = v;
|
|
this.refresh();
|
|
};
|
|
IndicatorDataProvider.prototype.refresh = function () {
|
|
var mgr = ChartManager.getInstance();
|
|
var ds = mgr.getDataSource(this.getDataSourceName());
|
|
if (ds.getDataCount() < 1)
|
|
return;
|
|
var indic = this._indicator;
|
|
var i, last = ds.getDataCount();
|
|
indic.clear();
|
|
indic.reserve(last);
|
|
for (i = 0; i < last; i++)
|
|
indic.execute(ds, i);
|
|
};
|
|
IndicatorDataProvider.prototype.updateData = function () {
|
|
var mgr = ChartManager.getInstance();
|
|
var ds = mgr.getDataSource(this.getDataSourceName());
|
|
if (ds.getDataCount() < 1)
|
|
return;
|
|
var indic = this._indicator;
|
|
var mode = ds.getUpdateMode();
|
|
switch (mode) {
|
|
case DataSource.UpdateMode.Refresh: {
|
|
this.refresh();
|
|
break;
|
|
}
|
|
case DataSource.UpdateMode.Append: {
|
|
indic.reserve(ds.getAppendedCount());
|
|
}
|
|
case DataSource.UpdateMode.Update: {
|
|
var i, last = ds.getDataCount();
|
|
var cnt = ds.getUpdatedCount() + ds.getAppendedCount();
|
|
for (i = last - cnt; i < last; i++)
|
|
indic.execute(ds, i);
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
IndicatorDataProvider.prototype.getMinMaxAt = function (index, minmax) {
|
|
minmax.min = Number.MAX_VALUE;
|
|
minmax.max = -Number.MAX_VALUE;
|
|
var result, valid = false;
|
|
var i, cnt = this._indicator.getOutputCount();
|
|
for (i = 0; i < cnt; i++) {
|
|
result = this._indicator.getOutputAt(i).execute(index);
|
|
if (isNaN(result) == false) {
|
|
valid = true;
|
|
if (minmax.min > result)
|
|
minmax.min = result;
|
|
if (minmax.max < result)
|
|
minmax.max = result;
|
|
}
|
|
}
|
|
return valid;
|
|
};
|
|
var theme_color_id = 0;
|
|
var theme_font_id = 0;
|
|
var Theme = create_class();
|
|
Theme.prototype.getColor = function (which) {
|
|
return this._colors[which];
|
|
};
|
|
Theme.prototype.getFont = function (which) {
|
|
return this._fonts[which];
|
|
};
|
|
Theme.Color = {
|
|
Positive: theme_color_id++,
|
|
Negative: theme_color_id++,
|
|
PositiveDark: theme_color_id++,
|
|
NegativeDark: theme_color_id++,
|
|
Unchanged: theme_color_id++,
|
|
Background: theme_color_id++,
|
|
Cursor: theme_color_id++,
|
|
RangeMark: theme_color_id++,
|
|
Indicator0: theme_color_id++,
|
|
Indicator1: theme_color_id++,
|
|
Indicator2: theme_color_id++,
|
|
Indicator3: theme_color_id++,
|
|
Indicator4: theme_color_id++,
|
|
Indicator5: theme_color_id++,
|
|
Grid0: theme_color_id++,
|
|
Grid1: theme_color_id++,
|
|
Grid2: theme_color_id++,
|
|
Grid3: theme_color_id++,
|
|
Grid4: theme_color_id++,
|
|
TextPositive: theme_color_id++,
|
|
TextNegative: theme_color_id++,
|
|
Text0: theme_color_id++,
|
|
Text1: theme_color_id++,
|
|
Text2: theme_color_id++,
|
|
Text3: theme_color_id++,
|
|
Text4: theme_color_id++,
|
|
LineColorNormal: theme_color_id++,
|
|
LineColorSelected: theme_color_id++,
|
|
CircleColorFill: theme_color_id++,
|
|
CircleColorStroke: theme_color_id++
|
|
};
|
|
Theme.Font = {
|
|
Default: theme_font_id++
|
|
};
|
|
var DarkTheme = create_class(Theme);
|
|
DarkTheme.prototype.__construct = function () {
|
|
this._colors = [];
|
|
|
|
if (KlineIns.reverseColor) {
|
|
this._colors[Theme.Color.Positive] = "#990e0e";
|
|
this._colors[Theme.Color.Negative] = "#19b34c";
|
|
this._colors[Theme.Color.PositiveDark] = "#3b0e08";
|
|
this._colors[Theme.Color.NegativeDark] = "#004718";
|
|
} else {
|
|
this._colors[Theme.Color.Positive] = "#19b34c";
|
|
this._colors[Theme.Color.Negative] = "#990e0e";
|
|
this._colors[Theme.Color.PositiveDark] = "#004718";
|
|
this._colors[Theme.Color.NegativeDark] = "#3b0e08";
|
|
}
|
|
this._colors[Theme.Color.Unchanged] = "#fff";
|
|
this._colors[Theme.Color.Background] = "#0a0a0a";
|
|
this._colors[Theme.Color.Cursor] = "#aaa";
|
|
this._colors[Theme.Color.RangeMark] = "#f9ee30";
|
|
this._colors[Theme.Color.Indicator0] = "#ddd";
|
|
this._colors[Theme.Color.Indicator1] = "#f9ee30";
|
|
this._colors[Theme.Color.Indicator2] = "#f600ff";
|
|
this._colors[Theme.Color.Indicator3] = "#6bf";
|
|
this._colors[Theme.Color.Indicator4] = "#a5cf81";
|
|
this._colors[Theme.Color.Indicator5] = "#e18b89";
|
|
this._colors[Theme.Color.Grid0] = "#333";
|
|
this._colors[Theme.Color.Grid1] = "#444";
|
|
this._colors[Theme.Color.Grid2] = "#666";
|
|
this._colors[Theme.Color.Grid3] = "#888";
|
|
this._colors[Theme.Color.Grid4] = "#aaa";
|
|
this._colors[Theme.Color.TextPositive] = "#1bd357";
|
|
this._colors[Theme.Color.TextNegative] = "#ff6f5e";
|
|
this._colors[Theme.Color.Text0] = "#444";
|
|
this._colors[Theme.Color.Text1] = "#666";
|
|
this._colors[Theme.Color.Text2] = "#888";
|
|
this._colors[Theme.Color.Text3] = "#aaa";
|
|
this._colors[Theme.Color.Text4] = "#ccc";
|
|
this._colors[Theme.Color.LineColorNormal] = "#a6a6a6";
|
|
this._colors[Theme.Color.LineColorSelected] = "#ffffff";
|
|
this._colors[Theme.Color.CircleColorFill] = "#000000";
|
|
this._colors[Theme.Color.CircleColorStroke] = "#ffffff";
|
|
this._fonts = [];
|
|
this._fonts[Theme.Font.Default] = "12px Tahoma";
|
|
};
|
|
var LightTheme = create_class(Theme);
|
|
LightTheme.prototype.__construct = function () {
|
|
this._colors = [];
|
|
|
|
if (KlineIns.reverseColor) {
|
|
this._colors[Theme.Color.Positive] = "#db5542";
|
|
this._colors[Theme.Color.Negative] = "#53b37b";
|
|
this._colors[Theme.Color.PositiveDark] = "#ffadaa";
|
|
this._colors[Theme.Color.NegativeDark] = "#66d293";
|
|
} else {
|
|
this._colors[Theme.Color.Positive] = "#53b37b";
|
|
this._colors[Theme.Color.Negative] = "#db5542";
|
|
this._colors[Theme.Color.PositiveDark] = "#66d293";
|
|
this._colors[Theme.Color.NegativeDark] = "#ffadaa";
|
|
}
|
|
this._colors[Theme.Color.Unchanged] = "#fff";
|
|
this._colors[Theme.Color.Background] = "#fff";
|
|
this._colors[Theme.Color.Cursor] = "#aaa";
|
|
this._colors[Theme.Color.RangeMark] = "#f27935";
|
|
this._colors[Theme.Color.Indicator0] = "#2fd2b2";
|
|
this._colors[Theme.Color.Indicator1] = "#ffb400";
|
|
this._colors[Theme.Color.Indicator2] = "#e849b9";
|
|
this._colors[Theme.Color.Indicator3] = "#1478c8";
|
|
this._colors[Theme.Color.Grid0] = "#eee";
|
|
this._colors[Theme.Color.Grid1] = "#afb1b3";
|
|
this._colors[Theme.Color.Grid2] = "#ccc";
|
|
this._colors[Theme.Color.Grid3] = "#bbb";
|
|
this._colors[Theme.Color.Grid4] = "#aaa";
|
|
this._colors[Theme.Color.TextPositive] = "#53b37b";
|
|
this._colors[Theme.Color.TextNegative] = "#db5542";
|
|
this._colors[Theme.Color.Text0] = "#ccc";
|
|
this._colors[Theme.Color.Text1] = "#aaa";
|
|
this._colors[Theme.Color.Text2] = "#888";
|
|
this._colors[Theme.Color.Text3] = "#666";
|
|
this._colors[Theme.Color.Text4] = "#444";
|
|
this._colors[Theme.Color.LineColorNormal] = "#8c8c8c";
|
|
this._colors[Theme.Color.LineColorSelected] = "#393c40";
|
|
this._colors[Theme.Color.CircleColorFill] = "#ffffff";
|
|
this._colors[Theme.Color.CircleColorStroke] = "#393c40";
|
|
this._fonts = [];
|
|
this._fonts[Theme.Font.Default] = "12px Tahoma";
|
|
};
|
|
var TemplateMeasuringHandler = create_class();
|
|
TemplateMeasuringHandler.onMeasuring = function (sender, args) {
|
|
var width = args.Width;
|
|
var height = args.Height;
|
|
var areaName = sender.getNameObject().getCompAt(2);
|
|
if (areaName == "timeline")
|
|
sender.setMeasuredDimension(width, 22);
|
|
};
|
|
var Template = create_class();
|
|
Template.displayVolume = true;
|
|
Template.createCandlestickDataSource = function (dsAlias) {
|
|
return new MainDataSource(dsAlias);
|
|
};
|
|
Template.createLiveOrderDataSource = function (dsAlias) {
|
|
return new CLiveOrderDataSource(dsAlias);
|
|
};
|
|
Template.createLiveTradeDataSource = function (dsAlias) {
|
|
return new CLiveTradeDataSource(dsAlias);
|
|
};
|
|
Template.createDataSource = function (dsName, dsAlias, createFunc) {
|
|
var mgr = ChartManager.getInstance();
|
|
if (mgr.getCachedDataSource(dsAlias) == null)
|
|
mgr.setCachedDataSource(dsAlias, createFunc(dsAlias));
|
|
mgr.setCurrentDataSource(dsName, dsAlias);
|
|
mgr.updateData(dsName, null);
|
|
};
|
|
Template.createTableComps = function (dsName) {
|
|
Template.createMainChartComps(dsName);
|
|
if (Template.displayVolume)
|
|
Template.createIndicatorChartComps(dsName, "VOLUME");
|
|
Template.createTimelineComps(dsName);
|
|
};
|
|
Template.createMainChartComps = function (dsName) {
|
|
var mgr = ChartManager.getInstance();
|
|
var tableLayout = mgr.getArea(dsName + ".charts");
|
|
var areaName = dsName + ".main";
|
|
var rangeAreaName = areaName + "Range";
|
|
var area = new MainArea(areaName);
|
|
mgr.setArea(areaName, area);
|
|
tableLayout.addArea(area);
|
|
var rangeArea = new MainRangeArea(rangeAreaName);
|
|
mgr.setArea(rangeAreaName, rangeArea);
|
|
tableLayout.addArea(rangeArea);
|
|
var dp = new MainDataProvider(areaName + ".main");
|
|
mgr.setDataProvider(dp.getName(), dp);
|
|
mgr.setMainIndicator(dsName, "MA");
|
|
var range = new MainRange(areaName);
|
|
mgr.setRange(range.getName(), range);
|
|
range.setPaddingTop(28);
|
|
range.setPaddingBottom(12);
|
|
var plotter = new MainAreaBackgroundPlotter(areaName + ".background");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
plotter = new CGridPlotter(areaName + ".grid");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
plotter = new CandlestickPlotter(areaName + ".main");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
plotter = new MinMaxPlotter(areaName + ".decoration");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
plotter = new MainInfoPlotter(areaName + ".info");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
plotter = new SelectionPlotter(areaName + ".selection");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
plotter = new CDynamicLinePlotter(areaName + ".tool");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
plotter = new RangeAreaBackgroundPlotter(areaName + "Range.background");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
plotter = new COrderGraphPlotter(areaName + "Range.grid");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
plotter = new RangePlotter(areaName + "Range.main");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
plotter = new RangeSelectionPlotter(areaName + "Range.selection");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
plotter = new LastClosePlotter(areaName + "Range.decoration");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
};
|
|
Template.createIndicatorChartComps = function (dsName, indicName) {
|
|
var mgr = ChartManager.getInstance();
|
|
var tableLayout = mgr.getArea(dsName + ".charts");
|
|
var areaName = dsName + ".indic" + tableLayout.getNextRowId();
|
|
var rangeAreaName = areaName + "Range";
|
|
var area = new IndicatorArea(areaName);
|
|
mgr.setArea(areaName, area);
|
|
tableLayout.addArea(area);
|
|
var rowIndex = tableLayout.getAreaCount() >> 1;
|
|
var heights = ChartSettings.get().charts.areaHeight;
|
|
if (heights.length > rowIndex) {
|
|
var a, i;
|
|
for (i = 0; i < rowIndex; i++) {
|
|
a = tableLayout.getAreaAt(i << 1);
|
|
a.setTop(0);
|
|
a.setBottom(heights[i]);
|
|
}
|
|
area.setTop(0);
|
|
area.setBottom(heights[rowIndex]);
|
|
}
|
|
var rangeArea = new IndicatorRangeArea(rangeAreaName);
|
|
mgr.setArea(rangeAreaName, rangeArea);
|
|
tableLayout.addArea(rangeArea);
|
|
var dp = new IndicatorDataProvider(areaName + ".secondary");
|
|
mgr.setDataProvider(dp.getName(), dp);
|
|
if (mgr.setIndicator(areaName, indicName) == false) {
|
|
mgr.removeIndicator(areaName);
|
|
return;
|
|
}
|
|
var plotter = new MainAreaBackgroundPlotter(areaName + ".background");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
plotter = new CGridPlotter(areaName + ".grid");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
plotter = new IndicatorPlotter(areaName + ".secondary");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
plotter = new IndicatorInfoPlotter(areaName + ".info");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
plotter = new SelectionPlotter(areaName + ".selection");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
plotter = new RangeAreaBackgroundPlotter(areaName + "Range.background");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
plotter = new RangePlotter(areaName + "Range.main");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
plotter = new RangeSelectionPlotter(areaName + "Range.selection");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
};
|
|
Template.createTimelineComps = function (dsName) {
|
|
var mgr = ChartManager.getInstance();
|
|
var plotter;
|
|
var timeline = new Timeline(dsName);
|
|
mgr.setTimeline(timeline.getName(), timeline);
|
|
plotter = new TimelineAreaBackgroundPlotter(dsName + ".timeline.background");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
plotter = new TimelinePlotter(dsName + ".timeline.main");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
plotter = new TimelineSelectionPlotter(dsName + ".timeline.selection");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
};
|
|
Template.createLiveOrderComps = function (dsName) {
|
|
var mgr = ChartManager.getInstance();
|
|
var plotter;
|
|
plotter = new BackgroundPlotter(dsName + ".main.background");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
plotter = new CLiveOrderPlotter(dsName + ".main.main");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
};
|
|
Template.createLiveTradeComps = function (dsName) {
|
|
var mgr = ChartManager.getInstance();
|
|
var plotter;
|
|
plotter = new BackgroundPlotter(dsName + ".main.background");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
plotter = new CLiveTradePlotter(dsName + ".main.main");
|
|
mgr.setPlotter(plotter.getName(), plotter);
|
|
};
|
|
var DefaultTemplate = create_class(Template);
|
|
DefaultTemplate.loadTemplate = function (dsName, dsAlias) {
|
|
var mgr = ChartManager.getInstance();
|
|
var settings = ChartSettings.get();
|
|
var frameName = (new CName(dsName)).getCompAt(0);
|
|
mgr.unloadTemplate(frameName);
|
|
Template.createDataSource(dsName, dsAlias, Template.createCandlestickDataSource);
|
|
var frame = new DockableLayout(frameName);
|
|
mgr.setFrame(frame.getName(), frame);
|
|
mgr.setArea(frame.getName(), frame);
|
|
frame.setGridColor(Theme.Color.Grid1);
|
|
var area = new TimelineArea(dsName + ".timeline");
|
|
mgr.setArea(area.getName(), area);
|
|
frame.addArea(area);
|
|
area.setDockStyle(ChartArea.DockStyle.Bottom);
|
|
area.Measuring.addHandler(area, TemplateMeasuringHandler.onMeasuring);
|
|
var tableLayout = new TableLayout(dsName + ".charts");
|
|
mgr.setArea(tableLayout.getName(), tableLayout);
|
|
tableLayout.setDockStyle(ChartArea.DockStyle.Fill);
|
|
frame.addArea(tableLayout);
|
|
Template.createTableComps(dsName);
|
|
mgr.setThemeName(frameName, settings.theme);
|
|
return mgr;
|
|
};
|
|
var Plotter = create_class(NamedObject);
|
|
Plotter.prototype.__construct = function (name) {
|
|
Plotter.__super.__construct.call(this, name);
|
|
};
|
|
Plotter.isChrome = (navigator.userAgent.toLowerCase().match(/chrome/) != null);
|
|
Plotter.drawLine = function (context, x1, y1, x2, y2) {
|
|
context.beginPath();
|
|
context.moveTo((x1 << 0) + 0.5, (y1 << 0) + 0.5);
|
|
context.lineTo((x2 << 0) + 0.5, (y2 << 0) + 0.5);
|
|
context.stroke();
|
|
};
|
|
Plotter.drawLines = function (context, points) {
|
|
var i, cnt = points.length;
|
|
context.beginPath();
|
|
context.moveTo(points[0].x, points[0].y);
|
|
for (i = 1; i < cnt; i++)
|
|
context.lineTo(points[i].x, points[i].y);
|
|
if (Plotter.isChrome) {
|
|
context.moveTo(points[0].x, points[0].y);
|
|
for (i = 1; i < cnt; i++)
|
|
context.lineTo(points[i].x, points[i].y);
|
|
}
|
|
context.stroke();
|
|
};
|
|
Plotter.drawDashedLine = function (context, x1, y1, x2, y2, dashLen, dashSolid) {
|
|
if (dashLen < 2)
|
|
dashLen = 2;
|
|
var dX = x2 - x1;
|
|
var dY = y2 - y1;
|
|
context.beginPath();
|
|
if (dY == 0) {
|
|
var count = (dX / dashLen + 0.5) << 0;
|
|
for (var i = 0; i < count; i++) {
|
|
context.rect(x1, y1, dashSolid, 1);
|
|
x1 += dashLen;
|
|
}
|
|
context.fill();
|
|
} else {
|
|
var count = (Math.sqrt(dX * dX + dY * dY) / dashLen + 0.5) << 0;
|
|
dX = dX / count;
|
|
dY = dY / count;
|
|
var dashX = dX * dashSolid / dashLen;
|
|
var dashY = dY * dashSolid / dashLen;
|
|
for (var i = 0; i < count; i++) {
|
|
context.moveTo(x1 + 0.5, y1 + 0.5);
|
|
context.lineTo(x1 + 0.5 + dashX, y1 + 0.5 + dashY);
|
|
x1 += dX;
|
|
y1 += dY;
|
|
}
|
|
context.stroke();
|
|
}
|
|
};
|
|
Plotter.createHorzDashedLine = function (context, x1, x2, y, dashLen, dashSolid) {
|
|
if (dashLen < 2)
|
|
dashLen = 2;
|
|
var dX = x2 - x1;
|
|
var count = (dX / dashLen + 0.5) << 0;
|
|
for (var i = 0; i < count; i++) {
|
|
context.rect(x1, y, dashSolid, 1);
|
|
x1 += dashLen;
|
|
}
|
|
};
|
|
Plotter.createRectangles = function (context, rects) {
|
|
context.beginPath();
|
|
var e, i, cnt = rects.length;
|
|
for (i = 0; i < cnt; i++) {
|
|
e = rects[i];
|
|
context.rect(e.x, e.y, e.w, e.h);
|
|
}
|
|
};
|
|
Plotter.createPolygon = function (context, points) {
|
|
context.beginPath();
|
|
context.moveTo(points[0].x + 0.5, points[0].y + 0.5);
|
|
var i, cnt = points.length;
|
|
for (i = 1; i < cnt; i++)
|
|
context.lineTo(points[i].x + 0.5, points[i].y + 0.5);
|
|
context.closePath();
|
|
};
|
|
Plotter.drawString = function (context, str, rect) {
|
|
var w = context.measureText(str).width;
|
|
if (rect.w < w)
|
|
return false;
|
|
context.fillText(str, rect.x, rect.y);
|
|
rect.x += w;
|
|
rect.w -= w;
|
|
return true;
|
|
};
|
|
var BackgroundPlotter = create_class(Plotter);
|
|
BackgroundPlotter.prototype.__construct = function (name) {
|
|
BackgroundPlotter.__super.__construct.call(this, name);
|
|
this._color = Theme.Color.Background;
|
|
};
|
|
BackgroundPlotter.prototype.getColor = function () {
|
|
return this._color;
|
|
};
|
|
BackgroundPlotter.prototype.setColor = function (c) {
|
|
this._color = c;
|
|
};
|
|
BackgroundPlotter.prototype.Draw = function (context) {
|
|
var mgr = ChartManager.getInstance();
|
|
var area = mgr.getArea(this.getAreaName());
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
context.fillStyle = theme.getColor(this._color);
|
|
context.fillRect(area.getLeft(), area.getTop(), area.getWidth(), area.getHeight());
|
|
};
|
|
var MainAreaBackgroundPlotter = create_class(BackgroundPlotter);
|
|
MainAreaBackgroundPlotter.prototype.__construct = function (name) {
|
|
MainAreaBackgroundPlotter.__super.__construct.call(this, name);
|
|
};
|
|
MainAreaBackgroundPlotter.prototype.Draw = function (context) {
|
|
var mgr = ChartManager.getInstance();
|
|
var area = mgr.getArea(this.getAreaName());
|
|
var timeline = mgr.getTimeline(this.getDataSourceName());
|
|
var range = mgr.getRange(this.getAreaName());
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
var rect = area.getRect();
|
|
if (!area.isChanged() && !timeline.isUpdated() && !range.isUpdated()) {
|
|
var first = timeline.getFirstIndex();
|
|
var last = timeline.getLastIndex() - 2;
|
|
var start = Math.max(first, last);
|
|
rect.X = timeline.toColumnLeft(start);
|
|
rect.Width = area.getRight() - rect.X;
|
|
}
|
|
context.fillStyle = theme.getColor(this._color);
|
|
context.fillRect(rect.X, rect.Y, rect.Width, rect.Height);
|
|
};
|
|
var RangeAreaBackgroundPlotter = create_class(BackgroundPlotter);
|
|
RangeAreaBackgroundPlotter.prototype.__construct = function (name) {
|
|
RangeAreaBackgroundPlotter.__super.__construct.call(this, name);
|
|
};
|
|
RangeAreaBackgroundPlotter.prototype.Draw = function (context) {
|
|
var mgr = ChartManager.getInstance();
|
|
var areaName = this.getAreaName();
|
|
var area = mgr.getArea(areaName);
|
|
var range = mgr.getRange(areaName.substring(0, areaName.lastIndexOf("Range")));
|
|
var isMainRange = range.getNameObject().getCompAt(2) == "main";
|
|
if (isMainRange) {
|
|
} else {
|
|
if (!area.isChanged() && !range.isUpdated())
|
|
return;
|
|
}
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
context.fillStyle = theme.getColor(this._color);
|
|
context.fillRect(area.getLeft(), area.getTop(), area.getWidth(), area.getHeight());
|
|
};
|
|
var TimelineAreaBackgroundPlotter = create_class(BackgroundPlotter);
|
|
TimelineAreaBackgroundPlotter.prototype.__construct = function (name) {
|
|
TimelineAreaBackgroundPlotter.__super.__construct.call(this, name);
|
|
};
|
|
TimelineAreaBackgroundPlotter.prototype.Draw = function (context) {
|
|
var mgr = ChartManager.getInstance();
|
|
var area = mgr.getArea(this.getAreaName());
|
|
var timeline = mgr.getTimeline(this.getDataSourceName());
|
|
if (!area.isChanged() && !timeline.isUpdated())
|
|
return;
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
context.fillStyle = theme.getColor(this._color);
|
|
context.fillRect(area.getLeft(), area.getTop(), area.getWidth(), area.getHeight());
|
|
};
|
|
var CGridPlotter = create_class(NamedObject);
|
|
CGridPlotter.prototype.__construct = function (name) {
|
|
CGridPlotter.__super.__construct.call(this, name);
|
|
};
|
|
CGridPlotter.prototype.Draw = function (context) {
|
|
//return;//去掉背景价格虚线
|
|
var mgr = ChartManager.getInstance();
|
|
var area = mgr.getArea(this.getAreaName());
|
|
var timeline = mgr.getTimeline(this.getDataSourceName());
|
|
var range = mgr.getRange(this.getAreaName());
|
|
var clipped = false;
|
|
if (!area.isChanged() && !timeline.isUpdated() && !range.isUpdated()) {
|
|
var first = timeline.getFirstIndex();
|
|
var last = timeline.getLastIndex();
|
|
var start = Math.max(first, last - 2);
|
|
var left = timeline.toColumnLeft(start);
|
|
context.save();
|
|
context.rect(left, area.getTop(), area.getRight() - left, area.getHeight());
|
|
context.clip();
|
|
clipped = true;
|
|
}
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
context.fillStyle = theme.getColor(Theme.Color.Grid0);
|
|
context.beginPath();
|
|
var dashLen = 4,
|
|
dashSolid = 1;
|
|
if (Plotter.isChrome) {
|
|
dashLen = 4;
|
|
dashSolid = 1;
|
|
}
|
|
var gradations = range.getGradations();
|
|
for (var n in gradations)
|
|
Plotter.createHorzDashedLine(context,
|
|
area.getLeft(), area.getRight(), range.toY(gradations[n]), dashLen, dashSolid);
|
|
context.fill();
|
|
if (clipped)
|
|
context.restore();
|
|
};
|
|
var CandlestickPlotter = create_class(NamedObject);
|
|
CandlestickPlotter.prototype.__construct = function (name) {
|
|
CandlestickPlotter.__super.__construct.call(this, name);
|
|
};
|
|
CandlestickPlotter.prototype.Draw = function (context) {
|
|
var mgr = ChartManager.getInstance();
|
|
var ds = mgr.getDataSource(this.getDataSourceName());
|
|
if (ds.getDataCount() < 1)
|
|
return;
|
|
var area = mgr.getArea(this.getAreaName());
|
|
var timeline = mgr.getTimeline(this.getDataSourceName());
|
|
var range = mgr.getRange(this.getAreaName());
|
|
if (range.getRange() == 0.0)
|
|
return;
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
var dark = is_instance(theme, DarkTheme);
|
|
var first = timeline.getFirstIndex();
|
|
var last = timeline.getLastIndex();
|
|
var start;
|
|
if (area.isChanged() || timeline.isUpdated() || range.isUpdated())
|
|
start = first;
|
|
else
|
|
start = Math.max(first, last - 2);
|
|
var cW = timeline.getColumnWidth();
|
|
var iW = timeline.getItemWidth();
|
|
var left = timeline.toItemLeft(start);
|
|
var center = timeline.toItemCenter(start);
|
|
var strokePosRects = [];
|
|
var fillPosRects = [];
|
|
var fillUchRects = [];
|
|
var fillNegRects = [];
|
|
for (var i = start; i < last; i++) {
|
|
var data = ds.getDataAt(i);
|
|
var high = range.toY(data.high);
|
|
var low = range.toY(data.low);
|
|
var open = data.open;
|
|
var close = data.close;
|
|
if (close > open) {
|
|
var top = range.toY(close);
|
|
var bottom = range.toY(open);
|
|
var iH = Math.max(bottom - top, 1);
|
|
if (iH > 1 && iW > 1 && dark)
|
|
strokePosRects.push({x: left + 0.5, y: top + 0.5, w: iW - 1, h: iH - 1});
|
|
else
|
|
fillPosRects.push({x: left, y: top, w: Math.max(iW, 1), h: Math.max(iH, 1)});
|
|
if (data.high > close) {
|
|
high = Math.min(high, top - 1);
|
|
fillPosRects.push({x: center, y: high, w: 1, h: top - high});
|
|
}
|
|
if (open > data.low) {
|
|
low = Math.max(low, bottom + 1);
|
|
fillPosRects.push({x: center, y: bottom, w: 1, h: low - bottom});
|
|
}
|
|
} else if (close == open) {
|
|
var top = range.toY(close);
|
|
fillUchRects.push({x: left, y: top, w: Math.max(iW, 1), h: 1});
|
|
if (data.high > close)
|
|
high = Math.min(high, top - 1);
|
|
if (open > data.low)
|
|
low = Math.max(low, top + 1);
|
|
if (high < low)
|
|
fillUchRects.push({x: center, y: high, w: 1, h: low - high});
|
|
} else {
|
|
var top = range.toY(open);
|
|
var bottom = range.toY(close);
|
|
var iH = Math.max(bottom - top, 1);
|
|
fillNegRects.push({x: left, y: top, w: Math.max(iW, 1), h: Math.max(iH, 1)});
|
|
if (data.high > open)
|
|
high = Math.min(high, top - 1);
|
|
if (close > data.low)
|
|
low = Math.max(low, bottom + 1);
|
|
if (high < low)
|
|
fillNegRects.push({x: center, y: high, w: 1, h: low - high});
|
|
}
|
|
left += cW;
|
|
center += cW;
|
|
}
|
|
if (strokePosRects.length > 0) {
|
|
context.strokeStyle = theme.getColor(Theme.Color.Positive);
|
|
Plotter.createRectangles(context, strokePosRects);
|
|
context.stroke();
|
|
}
|
|
if (fillPosRects.length > 0) {
|
|
context.fillStyle = theme.getColor(Theme.Color.Positive);
|
|
Plotter.createRectangles(context, fillPosRects);
|
|
context.fill();
|
|
}
|
|
if (fillUchRects.length > 0) {
|
|
context.fillStyle = theme.getColor(Theme.Color.Negative);
|
|
Plotter.createRectangles(context, fillUchRects);
|
|
context.fill();
|
|
}
|
|
if (fillNegRects.length > 0) {
|
|
context.fillStyle = theme.getColor(Theme.Color.Negative);
|
|
Plotter.createRectangles(context, fillNegRects);
|
|
context.fill();
|
|
}
|
|
};
|
|
var CandlestickHLCPlotter = create_class(Plotter);
|
|
CandlestickHLCPlotter.prototype.__construct = function (name) {
|
|
CandlestickHLCPlotter.__super.__construct.call(this, name);
|
|
};
|
|
CandlestickHLCPlotter.prototype.Draw = function (context) {
|
|
var mgr = ChartManager.getInstance();
|
|
var ds = mgr.getDataSource(this.getDataSourceName());
|
|
if (!is_instance(ds, MainDataSource) || ds.getDataCount() < 1)
|
|
return;
|
|
var area = mgr.getArea(this.getAreaName());
|
|
var timeline = mgr.getTimeline(this.getDataSourceName());
|
|
var range = mgr.getRange(this.getAreaName());
|
|
if (range.getRange() == 0.0)
|
|
return;
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
var dark = is_instance(theme, DarkTheme);
|
|
var first = timeline.getFirstIndex();
|
|
var last = timeline.getLastIndex();
|
|
var start;
|
|
if (area.isChanged() || timeline.isUpdated() || range.isUpdated())
|
|
start = first;
|
|
else
|
|
start = Math.max(first, last - 2);
|
|
var cW = timeline.getColumnWidth();
|
|
var iW = timeline.getItemWidth();
|
|
var left = timeline.toItemLeft(start);
|
|
var center = timeline.toItemCenter(start);
|
|
var strokePosRects = [];
|
|
var fillPosRects = [];
|
|
var fillUchRects = [];
|
|
var fillNegRects = [];
|
|
for (var i = start; i < last; i++) {
|
|
var data = ds.getDataAt(i);
|
|
var high = range.toY(data.high);
|
|
var low = range.toY(data.low);
|
|
var open = data.open;
|
|
if (i > 0)
|
|
open = ds.getDataAt(i - 1).close;
|
|
var close = data.close;
|
|
if (close > open) {
|
|
var top = range.toY(close);
|
|
var bottom = range.toY(open);
|
|
var iH = Math.max(bottom - top, 1);
|
|
if (iH > 1 && iW > 1 && dark)
|
|
strokePosRects.push({x: left + 0.5, y: top + 0.5, w: iW - 1, h: iH - 1});
|
|
else
|
|
fillPosRects.push({x: left, y: top, w: Math.max(iW, 1), h: Math.max(iH, 1)});
|
|
if (data.high > close) {
|
|
high = Math.min(high, top - 1);
|
|
fillPosRects.push({x: center, y: high, w: 1, h: top - high});
|
|
}
|
|
if (open > data.low) {
|
|
low = Math.max(low, bottom + 1);
|
|
fillPosRects.push({x: center, y: bottom, w: 1, h: low - bottom});
|
|
}
|
|
} else if (close == open) {
|
|
var top = range.toY(close);
|
|
fillUchRects.push({x: left, y: top, w: Math.max(iW, 1), h: 1});
|
|
if (data.high > close)
|
|
high = Math.min(high, top - 1);
|
|
if (open > data.low)
|
|
low = Math.max(low, top + 1);
|
|
if (high < low)
|
|
fillUchRects.push({x: center, y: high, w: 1, h: low - high});
|
|
} else {
|
|
var top = range.toY(open);
|
|
var bottom = range.toY(close);
|
|
var iH = Math.max(bottom - top, 1);
|
|
fillNegRects.push({x: left, y: top, w: Math.max(iW, 1), h: Math.max(iH, 1)});
|
|
if (data.high > open)
|
|
high = Math.min(high, top - 1);
|
|
if (close > data.low)
|
|
low = Math.max(low, bottom + 1);
|
|
if (high < low)
|
|
fillNegRects.push({x: center, y: high, w: 1, h: low - high});
|
|
}
|
|
left += cW;
|
|
center += cW;
|
|
}
|
|
if (strokePosRects.length > 0) {
|
|
context.strokeStyle = theme.getColor(Theme.Color.Positive);
|
|
Plotter.createRectangles(context, strokePosRects);
|
|
context.stroke();
|
|
}
|
|
if (fillPosRects.length > 0) {
|
|
context.fillStyle = theme.getColor(Theme.Color.Positive);
|
|
Plotter.createRectangles(context, fillPosRects);
|
|
context.fill();
|
|
}
|
|
if (fillUchRects.length > 0) {
|
|
context.fillStyle = theme.getColor(Theme.Color.Negative);
|
|
Plotter.createRectangles(context, fillUchRects);
|
|
context.fill();
|
|
}
|
|
if (fillNegRects.length > 0) {
|
|
context.fillStyle = theme.getColor(Theme.Color.Negative);
|
|
Plotter.createRectangles(context, fillNegRects);
|
|
context.fill();
|
|
}
|
|
};
|
|
var OHLCPlotter = create_class(Plotter);
|
|
OHLCPlotter.prototype.__construct = function (name) {
|
|
OHLCPlotter.__super.__construct.call(this, name);
|
|
};
|
|
OHLCPlotter.prototype.Draw = function (context) {
|
|
var mgr = ChartManager.getInstance();
|
|
var ds = mgr.getDataSource(this.getDataSourceName());
|
|
if (!is_instance(ds, MainDataSource) || ds.getDataCount() < 1)
|
|
return;
|
|
var area = mgr.getArea(this.getAreaName());
|
|
var timeline = mgr.getTimeline(this.getDataSourceName());
|
|
var range = mgr.getRange(this.getAreaName());
|
|
if (range.getRange() == 0.0)
|
|
return;
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
var first = timeline.getFirstIndex();
|
|
var last = timeline.getLastIndex();
|
|
var start;
|
|
if (area.isChanged() || timeline.isUpdated() || range.isUpdated())
|
|
start = first;
|
|
else
|
|
start = Math.max(first, last - 2);
|
|
var cW = timeline.getColumnWidth();
|
|
var iW = timeline.getItemWidth() >> 1;
|
|
var left = timeline.toItemLeft(start);
|
|
var center = timeline.toItemCenter(start);
|
|
var right = left + timeline.getItemWidth();
|
|
var fillPosRects = [];
|
|
var fillUchRects = [];
|
|
var fillNegRects = [];
|
|
for (var i = start; i < last; i++) {
|
|
var data = ds.getDataAt(i);
|
|
var high = range.toY(data.high);
|
|
var low = range.toY(data.low);
|
|
var iH = Math.max(low - high, 1);
|
|
if (data.close > data.open) {
|
|
var top = range.toY(data.close);
|
|
var bottom = range.toY(data.open);
|
|
fillPosRects.push({x: center, y: high, w: 1, h: iH});
|
|
fillPosRects.push({x: left, y: top, w: iW, h: 1});
|
|
fillPosRects.push({x: center, y: bottom, w: iW, h: 1});
|
|
} else if (data.close == data.open) {
|
|
var y = range.toY(data.close);
|
|
fillUchRects.push({x: center, y: high, w: 1, h: iH});
|
|
fillUchRects.push({x: left, y: y, w: iW, h: 1});
|
|
fillUchRects.push({x: center, y: y, w: iW, h: 1});
|
|
} else {
|
|
var top = range.toY(data.open);
|
|
var bottom = range.toY(data.close);
|
|
fillNegRects.push({x: center, y: high, w: 1, h: iH});
|
|
fillNegRects.push({x: left, y: top, w: iW, h: 1});
|
|
fillNegRects.push({x: center, y: bottom, w: iW, h: 1});
|
|
}
|
|
left += cW;
|
|
center += cW;
|
|
right += cW;
|
|
}
|
|
if (fillPosRects.length > 0) {
|
|
context.fillStyle = theme.getColor(Theme.Color.Positive);
|
|
Plotter.createRectangles(context, fillPosRects);
|
|
context.fill();
|
|
}
|
|
if (fillUchRects.length > 0) {
|
|
context.fillStyle = theme.getColor(Theme.Color.Negative);
|
|
Plotter.createRectangles(context, fillUchRects);
|
|
context.fill();
|
|
}
|
|
if (fillNegRects.length > 0) {
|
|
context.fillStyle = theme.getColor(Theme.Color.Negative);
|
|
Plotter.createRectangles(context, fillNegRects);
|
|
context.fill();
|
|
}
|
|
};
|
|
var MainInfoPlotter = create_class(Plotter);
|
|
MainInfoPlotter.prototype.__construct = function (name) {
|
|
MainInfoPlotter.__super.__construct.call(this, name);
|
|
};
|
|
|
|
function format_time(v) {
|
|
return (v < 10) ? "0" + v.toString() : v.toString();
|
|
}
|
|
|
|
MainInfoPlotter.prototype.Draw = function (context) {
|
|
var mgr = ChartManager.getInstance();
|
|
var area = mgr.getArea(this.getAreaName());
|
|
var timeline = mgr.getTimeline(this.getDataSourceName());
|
|
var ds = mgr.getDataSource(this.getDataSourceName());
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
context.font = theme.getFont(Theme.Font.Default);
|
|
context.textAlign = "left";
|
|
context.textBaseline = "top";
|
|
context.fillStyle = theme.getColor(Theme.Color.Text4);
|
|
var rect = {
|
|
x: area.getLeft() + 4,
|
|
y: area.getTop() + 2,
|
|
w: area.getWidth() - 8,
|
|
h: 20
|
|
};
|
|
var selIndex = timeline.getSelectedIndex();
|
|
if (selIndex < 0)
|
|
return;
|
|
var data = ds.getDataAt(selIndex);
|
|
var digits = ds.getDecimalDigits();
|
|
var time = new Date(data.date);
|
|
var year = time.getFullYear();
|
|
var month = format_time(time.getMonth() + 1);
|
|
var date = format_time(time.getDate());
|
|
var hour = format_time(time.getHours());
|
|
var minute = format_time(time.getMinutes());
|
|
var lang = mgr.getLanguage();
|
|
if (lang == "zh-cn") {
|
|
if (!Plotter.drawString(context, '时间: ' +
|
|
year + '-' + month + '-' + date + ' ' + hour + ':' + minute, rect))
|
|
return;
|
|
if (!Plotter.drawString(context, ' 开: ' + data.open.toFixed(digits), rect))
|
|
return;
|
|
if (!Plotter.drawString(context, ' 高: ' + data.high.toFixed(digits), rect))
|
|
return;
|
|
if (!Plotter.drawString(context, ' 低: ' + data.low.toFixed(digits), rect))
|
|
return;
|
|
if (!Plotter.drawString(context, ' 收: ' + data.close.toFixed(digits), rect))
|
|
return;
|
|
} else if (lang == "en-us") {
|
|
if (!Plotter.drawString(context, 'DATE: ' +
|
|
year + '-' + month + '-' + date + ' ' + hour + ':' + minute, rect))
|
|
return;
|
|
if (!Plotter.drawString(context, ' O: ' + data.open.toFixed(digits), rect))
|
|
return;
|
|
if (!Plotter.drawString(context, ' H: ' + data.high.toFixed(digits), rect))
|
|
return;
|
|
if (!Plotter.drawString(context, ' L: ' + data.low.toFixed(digits), rect))
|
|
return;
|
|
if (!Plotter.drawString(context, ' C: ' + data.close.toFixed(digits), rect))
|
|
return;
|
|
} else if (lang == "zh-tw") {
|
|
if (!Plotter.drawString(context, '時間: ' +
|
|
year + '-' + month + '-' + date + ' ' + hour + ':' + minute, rect))
|
|
return;
|
|
if (!Plotter.drawString(context, ' 開: ' + data.open.toFixed(digits), rect))
|
|
return;
|
|
if (!Plotter.drawString(context, ' 高: ' + data.high.toFixed(digits), rect))
|
|
return;
|
|
if (!Plotter.drawString(context, ' 低: ' + data.low.toFixed(digits), rect))
|
|
return;
|
|
if (!Plotter.drawString(context, ' 收: ' + data.close.toFixed(digits), rect))
|
|
return;
|
|
}
|
|
if (selIndex > 0) {
|
|
if (lang == "zh-cn") {
|
|
if (!Plotter.drawString(context, ' 涨幅: ', rect))
|
|
return;
|
|
} else if (lang == "en-us") {
|
|
if (!Plotter.drawString(context, ' CHANGE: ', rect))
|
|
return;
|
|
} else if (lang == "zh-tw") {
|
|
if (!Plotter.drawString(context, ' 漲幅: ', rect))
|
|
return;
|
|
}
|
|
var prev = ds.getDataAt(selIndex - 1);
|
|
if ((data.close - prev.close) / prev.close * 100.0) {
|
|
var change = (data.close - prev.close) / prev.close * 100.0;
|
|
} else {
|
|
var change = 0.00;
|
|
}
|
|
|
|
|
|
if (change >= 0) {
|
|
change = ' ' + change.toFixed(2);
|
|
context.fillStyle = theme.getColor(Theme.Color.TextPositive);
|
|
} else {
|
|
change = change.toFixed(2);
|
|
context.fillStyle = theme.getColor(Theme.Color.TextNegative);
|
|
}
|
|
if (!Plotter.drawString(context, change, rect))
|
|
return;
|
|
context.fillStyle = theme.getColor(Theme.Color.Text4);
|
|
if (!Plotter.drawString(context, ' %', rect))
|
|
return;
|
|
}
|
|
// debugger;
|
|
if ((data.high - data.low) / data.low * 100.0) {
|
|
var amplitude = (data.high - data.low) / data.low * 100.0;
|
|
} else {
|
|
var amplitude = 0.00;
|
|
}
|
|
|
|
|
|
if (lang == "zh-cn") {
|
|
if (!Plotter.drawString(context, ' 振幅: ' + amplitude.toFixed(2) + ' %', rect))
|
|
return;
|
|
if (!Plotter.drawString(context, ' 量: ' + data.volume.toFixed(2), rect))
|
|
return;
|
|
} else if (lang == "en-us") {
|
|
if (!Plotter.drawString(context, ' AMPLITUDE: ' + amplitude.toFixed(2) + ' %', rect))
|
|
return;
|
|
if (!Plotter.drawString(context, ' V: ' + data.volume.toFixed(2), rect))
|
|
return;
|
|
} else if (lang == "zh-tw") {
|
|
if (!Plotter.drawString(context, ' 振幅: ' + amplitude.toFixed(2) + ' %', rect))
|
|
return;
|
|
if (!Plotter.drawString(context, ' 量: ' + data.volume.toFixed(2), rect))
|
|
return;
|
|
}
|
|
var dp = mgr.getDataProvider(this.getAreaName() + ".secondary");
|
|
if (dp == undefined)
|
|
return;
|
|
var indic = dp.getIndicator();
|
|
var n, cnt = indic.getOutputCount();
|
|
for (n = 0; n < cnt; n++) {
|
|
var out = indic.getOutputAt(n);
|
|
var v = out.execute(selIndex);
|
|
if (isNaN(v))
|
|
continue;
|
|
var info = " " + out.getName() + ": " + v.toFixed(digits);
|
|
var color = out.getColor();
|
|
if (color === undefined)
|
|
color = Theme.Color.Indicator0 + n;
|
|
context.fillStyle = theme.getColor(color);
|
|
if (!Plotter.drawString(context, info, rect))
|
|
return;
|
|
}
|
|
};
|
|
var IndicatorPlotter = create_class(NamedObject);
|
|
IndicatorPlotter.prototype.__construct = function (name) {
|
|
IndicatorPlotter.__super.__construct.call(this, name);
|
|
};
|
|
IndicatorPlotter.prototype.Draw = function (context) {
|
|
var mgr = ChartManager.getInstance();
|
|
var area = mgr.getArea(this.getAreaName());
|
|
var timeline = mgr.getTimeline(this.getDataSourceName());
|
|
var range = mgr.getRange(this.getAreaName());
|
|
if (range.getRange() == 0.0)
|
|
return;
|
|
var dp = mgr.getDataProvider(this.getName());
|
|
if (!is_instance(dp, IndicatorDataProvider))
|
|
return;
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
var cW = timeline.getColumnWidth();
|
|
var first = timeline.getFirstIndex();
|
|
var last = timeline.getLastIndex();
|
|
var start;
|
|
if (area.isChanged() || timeline.isUpdated() || range.isUpdated())
|
|
start = first;
|
|
else
|
|
start = Math.max(first, last - 2);
|
|
var indic = dp.getIndicator();
|
|
var out, n, outCount = indic.getOutputCount();
|
|
for (n = 0; n < outCount; n++) {
|
|
out = indic.getOutputAt(n);
|
|
var style = out.getStyle();
|
|
if (style == OutputStyle.VolumeStick) {
|
|
this.drawVolumeStick(context, theme,
|
|
mgr.getDataSource(this.getDataSourceName()), start, last,
|
|
timeline.toItemLeft(start), cW, timeline.getItemWidth(), range);
|
|
} else if (style == OutputStyle.MACDStick) {
|
|
this.drawMACDStick(context, theme,
|
|
out, start, last,
|
|
timeline.toItemLeft(start), cW, timeline.getItemWidth(), range);
|
|
} else if (style == OutputStyle.SARPoint) {
|
|
this.drawSARPoint(context, theme,
|
|
out, start, last,
|
|
timeline.toItemCenter(start), cW, timeline.getItemWidth(), range);
|
|
}
|
|
}
|
|
var left = timeline.toColumnLeft(start);
|
|
var center = timeline.toItemCenter(start);
|
|
context.save();
|
|
context.rect(left, area.getTop(), area.getRight() - left, area.getHeight());
|
|
context.clip();
|
|
context.translate(0.5, 0.5);
|
|
for (n = 0; n < outCount; n++) {
|
|
var x = center;
|
|
out = indic.getOutputAt(n);
|
|
if (out.getStyle() == OutputStyle.Line) {
|
|
var v, points = [];
|
|
if (start > first) {
|
|
v = out.execute(start - 1);
|
|
if (isNaN(v) == false)
|
|
points.push({"x": x - cW, "y": range.toY(v)});
|
|
}
|
|
for (var i = start; i < last; i++, x += cW) {
|
|
v = out.execute(i);
|
|
if (isNaN(v) == false)
|
|
points.push({"x": x, "y": range.toY(v)});
|
|
}
|
|
if (points.length > 0) {
|
|
var color = out.getColor();
|
|
if (color == undefined)
|
|
color = Theme.Color.Indicator0 + n;
|
|
context.strokeStyle = theme.getColor(color);
|
|
Plotter.drawLines(context, points);
|
|
}
|
|
}
|
|
}
|
|
context.restore();
|
|
};
|
|
IndicatorPlotter.prototype.drawVolumeStick =
|
|
function (context, theme, ds, first, last, startX, cW, iW, range) {
|
|
var dark = is_instance(theme, DarkTheme);
|
|
var left = startX;
|
|
var bottom = range.toY(0);
|
|
var strokePosRects = [];
|
|
var fillPosRects = [];
|
|
var fillNegRects = [];
|
|
for (var i = first; i < last; i++) {
|
|
var data = ds.getDataAt(i);
|
|
var top = range.toY(data.volume);
|
|
var iH = range.toHeight(data.volume);
|
|
if (data.close > data.open) {
|
|
if (iH > 1 && iW > 1 && dark) {
|
|
strokePosRects.push({x: left + 0.5, y: top + 0.5, w: iW - 1, h: iH - 1});
|
|
} else {
|
|
fillPosRects.push({x: left, y: top, w: Math.max(iW, 1), h: Math.max(iH, 1)});
|
|
}
|
|
} else if (data.close == data.open) {
|
|
if (i > 0 && data.close >= ds.getDataAt(i - 1).close) {
|
|
if (iH > 1 && iW > 1 && dark) {
|
|
strokePosRects.push({x: left + 0.5, y: top + 0.5, w: iW - 1, h: iH - 1});
|
|
} else {
|
|
fillPosRects.push({x: left, y: top, w: Math.max(iW, 1), h: Math.max(iH, 1)});
|
|
}
|
|
} else {
|
|
fillNegRects.push({x: left, y: top, w: Math.max(iW, 1), h: Math.max(iH, 1)});
|
|
}
|
|
} else {
|
|
fillNegRects.push({x: left, y: top, w: Math.max(iW, 1), h: Math.max(iH, 1)});
|
|
}
|
|
left += cW;
|
|
}
|
|
if (strokePosRects.length > 0) {
|
|
context.strokeStyle = theme.getColor(Theme.Color.Positive);
|
|
Plotter.createRectangles(context, strokePosRects);
|
|
context.stroke();
|
|
}
|
|
if (fillPosRects.length > 0) {
|
|
context.fillStyle = theme.getColor(Theme.Color.Positive);
|
|
Plotter.createRectangles(context, fillPosRects);
|
|
context.fill();
|
|
}
|
|
if (fillNegRects.length > 0) {
|
|
context.fillStyle = theme.getColor(Theme.Color.Negative);
|
|
Plotter.createRectangles(context, fillNegRects);
|
|
context.fill();
|
|
}
|
|
};
|
|
IndicatorPlotter.prototype.drawMACDStick =
|
|
function (context, theme, output, first, last, startX, cW, iW, range) {
|
|
var left = startX;
|
|
var middle = range.toY(0);
|
|
var strokePosRects = [];
|
|
var strokeNegRects = [];
|
|
var fillPosRects = [];
|
|
var fillNegRects = [];
|
|
var prevMACD = (first > 0) ? output.execute(first - 1) : NaN;
|
|
for (var i = first; i < last; i++) {
|
|
var MACD = output.execute(i);
|
|
if (MACD >= 0) {
|
|
var iH = range.toHeight(MACD);
|
|
if ((i == 0 || MACD >= prevMACD) && iH > 1 && iW > 1)
|
|
strokePosRects.push({x: left + 0.5, y: middle - iH + 0.5, w: iW - 1, h: iH - 1});
|
|
else
|
|
fillPosRects.push({x: left, y: middle - iH, w: Math.max(iW, 1), h: Math.max(iH, 1)});
|
|
} else {
|
|
var iH = range.toHeight(-MACD);
|
|
if ((i == 0 || MACD >= prevMACD) && iH > 1 && iW > 1)
|
|
strokeNegRects.push({x: left + 0.5, y: middle + 0.5, w: iW - 1, h: iH - 1});
|
|
else
|
|
fillNegRects.push({x: left, y: middle, w: Math.max(iW, 1), h: Math.max(iH, 1)});
|
|
}
|
|
prevMACD = MACD;
|
|
left += cW;
|
|
}
|
|
if (strokePosRects.length > 0) {
|
|
context.strokeStyle = theme.getColor(Theme.Color.Positive);
|
|
Plotter.createRectangles(context, strokePosRects);
|
|
context.stroke();
|
|
}
|
|
if (strokeNegRects.length > 0) {
|
|
context.strokeStyle = theme.getColor(Theme.Color.Negative);
|
|
Plotter.createRectangles(context, strokeNegRects);
|
|
context.stroke();
|
|
}
|
|
if (fillPosRects.length > 0) {
|
|
context.fillStyle = theme.getColor(Theme.Color.Positive);
|
|
Plotter.createRectangles(context, fillPosRects);
|
|
context.fill();
|
|
}
|
|
if (fillNegRects.length > 0) {
|
|
context.fillStyle = theme.getColor(Theme.Color.Negative);
|
|
Plotter.createRectangles(context, fillNegRects);
|
|
context.fill();
|
|
}
|
|
};
|
|
IndicatorPlotter.prototype.drawSARPoint =
|
|
function (context, theme, output, first, last, startX, cW, iW, range) {
|
|
var r = iW >> 1;
|
|
if (r < 0.5) r = 0.5;
|
|
if (r > 4) r = 4;
|
|
var center = startX;
|
|
var right = center + r;
|
|
var endAngle = 2 * Math.PI;
|
|
context.save();
|
|
context.translate(0.5, 0.5);
|
|
context.strokeStyle = theme.getColor(Theme.Color.Indicator3);
|
|
context.beginPath();
|
|
for (var i = first; i < last; i++) {
|
|
var y = range.toY(output.execute(i));
|
|
context.moveTo(right, y);
|
|
context.arc(center, y, r, 0, endAngle);
|
|
center += cW;
|
|
right += cW;
|
|
}
|
|
context.stroke();
|
|
context.restore();
|
|
};
|
|
var IndicatorInfoPlotter = create_class(Plotter);
|
|
IndicatorInfoPlotter.prototype.__construct = function (name) {
|
|
IndicatorInfoPlotter.__super.__construct.call(this, name);
|
|
};
|
|
IndicatorInfoPlotter.prototype.Draw = function (context) {
|
|
var mgr = ChartManager.getInstance();
|
|
var area = mgr.getArea(this.getAreaName());
|
|
var timeline = mgr.getTimeline(this.getDataSourceName());
|
|
var dp = mgr.getDataProvider(this.getAreaName() + ".secondary");
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
context.font = theme.getFont(Theme.Font.Default);
|
|
context.textAlign = "left";
|
|
context.textBaseline = "top";
|
|
context.fillStyle = theme.getColor(Theme.Color.Text4);
|
|
var rect = {
|
|
x: area.getLeft() + 4,
|
|
y: area.getTop() + 2,
|
|
w: area.getWidth() - 8,
|
|
h: 20
|
|
};
|
|
var indic = dp.getIndicator();
|
|
var title;
|
|
switch (indic.getParameterCount()) {
|
|
case 0:
|
|
title = indic.getName();
|
|
break;
|
|
case 1:
|
|
title = indic.getName() + "(" +
|
|
indic.getParameterAt(0).getValue() +
|
|
")";
|
|
break;
|
|
case 2:
|
|
title = indic.getName() + "(" +
|
|
indic.getParameterAt(0).getValue() + "," +
|
|
indic.getParameterAt(1).getValue() +
|
|
")";
|
|
break;
|
|
case 3:
|
|
title = indic.getName() + "(" +
|
|
indic.getParameterAt(0).getValue() + "," +
|
|
indic.getParameterAt(1).getValue() + "," +
|
|
indic.getParameterAt(2).getValue() +
|
|
")";
|
|
break;
|
|
case 4:
|
|
title = indic.getName() + "(" +
|
|
indic.getParameterAt(0).getValue() + "," +
|
|
indic.getParameterAt(1).getValue() + "," +
|
|
indic.getParameterAt(2).getValue() + "," +
|
|
indic.getParameterAt(3).getValue() +
|
|
")";
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
if (!Plotter.drawString(context, title, rect))
|
|
return;
|
|
var selIndex = timeline.getSelectedIndex();
|
|
if (selIndex < 0)
|
|
return;
|
|
var out, v, info, color;
|
|
var n, cnt = indic.getOutputCount();
|
|
for (n = 0; n < cnt; n++) {
|
|
out = indic.getOutputAt(n);
|
|
v = out.execute(selIndex);
|
|
if (isNaN(v))
|
|
continue;
|
|
info = " " + out.getName() + ": " + v.toFixed(2);
|
|
color = out.getColor();
|
|
if (color === undefined)
|
|
color = Theme.Color.Indicator0 + n;
|
|
context.fillStyle = theme.getColor(color);
|
|
if (!Plotter.drawString(context, info, rect))
|
|
return;
|
|
}
|
|
};
|
|
var MinMaxPlotter = create_class(NamedObject);
|
|
MinMaxPlotter.prototype.__construct = function (name) {
|
|
MinMaxPlotter.__super.__construct.call(this, name);
|
|
};
|
|
MinMaxPlotter.prototype.Draw = function (context) {
|
|
var mgr = ChartManager.getInstance();
|
|
var ds = mgr.getDataSource(this.getDataSourceName());
|
|
if (ds.getDataCount() < 1)
|
|
return;
|
|
var timeline = mgr.getTimeline(this.getDataSourceName());
|
|
if (timeline.getInnerWidth() < timeline.getColumnWidth())
|
|
return;
|
|
var range = mgr.getRange(this.getAreaName());
|
|
if (range.getRange() == 0)
|
|
return;
|
|
var dp = mgr.getDataProvider(this.getAreaName() + ".main");
|
|
var first = timeline.getFirstIndex();
|
|
var center = (first + timeline.getLastIndex()) >> 1;
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
context.font = theme.getFont(Theme.Font.Default);
|
|
context.textBaseline = "middle";
|
|
context.fillStyle = theme.getColor(Theme.Color.Text4);
|
|
context.strokeStyle = theme.getColor(Theme.Color.Text4);
|
|
var digits = ds.getDecimalDigits();
|
|
this.drawMark(context, dp.getMinValue(), digits, range.toY(dp.getMinValue()),
|
|
first, center, dp.getMinValueIndex(), timeline);
|
|
this.drawMark(context, dp.getMaxValue(), digits, range.toY(dp.getMaxValue()),
|
|
first, center, dp.getMaxValueIndex(), timeline);
|
|
};
|
|
MinMaxPlotter.prototype.drawMark = function (context, v, digits, y, first, center, index, timeline) {
|
|
var arrowStart, arrowStop, _arrowStop;
|
|
var textStart;
|
|
if (index > center) {
|
|
context.textAlign = "right";
|
|
arrowStart = timeline.toItemCenter(index) - 4;
|
|
arrowStop = arrowStart - 7;
|
|
_arrowStop = arrowStart - 3;
|
|
textStart = arrowStop - 4;
|
|
} else {
|
|
context.textAlign = "left";
|
|
arrowStart = timeline.toItemCenter(index) + 4;
|
|
arrowStop = arrowStart + 7;
|
|
_arrowStop = arrowStart + 3;
|
|
textStart = arrowStop + 4;
|
|
}
|
|
Plotter.drawLine(context, arrowStart, y, arrowStop, y);
|
|
Plotter.drawLine(context, arrowStart, y, _arrowStop, y + 2);
|
|
Plotter.drawLine(context, arrowStart, y, _arrowStop, y - 2);
|
|
context.fillText(String.fromFloat(v, digits), textStart, y);
|
|
};
|
|
var TimelinePlotter = create_class(Plotter);
|
|
TimelinePlotter.prototype.__construct = function (name) {
|
|
TimelinePlotter.__super.__construct.call(this, name);
|
|
};
|
|
TimelinePlotter.TP_MINUTE = 60 * 1000;
|
|
TimelinePlotter.TP_HOUR = 60 * TimelinePlotter.TP_MINUTE;
|
|
TimelinePlotter.TP_DAY = 24 * TimelinePlotter.TP_HOUR;
|
|
TimelinePlotter.TIME_INTERVAL = [
|
|
5 * TimelinePlotter.TP_MINUTE,
|
|
10 * TimelinePlotter.TP_MINUTE,
|
|
15 * TimelinePlotter.TP_MINUTE,
|
|
30 * TimelinePlotter.TP_MINUTE,
|
|
TimelinePlotter.TP_HOUR,
|
|
2 * TimelinePlotter.TP_HOUR,
|
|
3 * TimelinePlotter.TP_HOUR,
|
|
6 * TimelinePlotter.TP_HOUR,
|
|
12 * TimelinePlotter.TP_HOUR,
|
|
TimelinePlotter.TP_DAY,
|
|
2 * TimelinePlotter.TP_DAY
|
|
];
|
|
TimelinePlotter.MonthConvert = {
|
|
1: "Jan.",
|
|
2: "Feb.",
|
|
3: "Mar.",
|
|
4: "Apr.",
|
|
5: "May.",
|
|
6: "Jun.",
|
|
7: "Jul.",
|
|
8: "Aug.",
|
|
9: "Sep.",
|
|
10: "Oct.",
|
|
11: "Nov.",
|
|
12: "Dec."
|
|
};
|
|
TimelinePlotter.prototype.Draw = function (context) {
|
|
|
|
|
|
var mgr = ChartManager.getInstance();
|
|
var area = mgr.getArea(this.getAreaName());
|
|
var timeline = mgr.getTimeline(this.getDataSourceName());
|
|
if (!area.isChanged() && !timeline.isUpdated())
|
|
return;
|
|
var ds = mgr.getDataSource(this.getDataSourceName());
|
|
if (ds.getDataCount() < 2)
|
|
return;
|
|
var timeInterval = ds.getDataAt(1).date - ds.getDataAt(0).date;
|
|
var n, cnt = TimelinePlotter.TIME_INTERVAL.length;
|
|
for (n = 0; n < cnt; n++) {
|
|
if (timeInterval < TimelinePlotter.TIME_INTERVAL[n])
|
|
break;
|
|
}
|
|
for (; n < cnt; n++) {
|
|
if (TimelinePlotter.TIME_INTERVAL[n] % timeInterval == 0)
|
|
if ((TimelinePlotter.TIME_INTERVAL[n] / timeInterval) * timeline.getColumnWidth() > 60)
|
|
break;
|
|
}
|
|
var first = timeline.getFirstIndex();
|
|
var last = timeline.getLastIndex();
|
|
var d = new Date();
|
|
var local_utc_diff = d.getTimezoneOffset() * 60 * 1000;
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
context.font = theme.getFont(Theme.Font.Default);
|
|
context.textAlign = "center";
|
|
context.textBaseline = "middle";
|
|
var lang = mgr.getLanguage();
|
|
var gridRects = [];
|
|
var top = area.getTop();
|
|
var middle = area.getMiddle();
|
|
for (var i = first; i < last; i++) {
|
|
var utcDate = ds.getDataAt(i).date;
|
|
var localDate = utcDate - local_utc_diff;
|
|
var time = new Date(utcDate);
|
|
var year = time.getFullYear();
|
|
var month = time.getMonth() + 1;
|
|
var date = time.getDate();
|
|
var hour = time.getHours();
|
|
var minute = time.getMinutes();
|
|
var text = "";
|
|
if (n < cnt) {
|
|
var m = Math.max(
|
|
TimelinePlotter.TP_DAY,
|
|
TimelinePlotter.TIME_INTERVAL[n]);
|
|
if (localDate % m == 0) {
|
|
if (lang == "zh-cn")
|
|
text = month.toString() + "月" + date.toString() + "日";
|
|
else if (lang == "zh-tw")
|
|
text = month.toString() + "月" + date.toString() + "日";
|
|
else if (lang == "en-us")
|
|
text = TimelinePlotter.MonthConvert[month] + " " + date.toString();
|
|
context.fillStyle = theme.getColor(Theme.Color.Text4);
|
|
} else if (localDate % TimelinePlotter.TIME_INTERVAL[n] == 0) {
|
|
var strMinute = minute.toString();
|
|
if (minute < 10)
|
|
strMinute = "0" + strMinute;
|
|
text = hour.toString() + ":" + strMinute;
|
|
context.fillStyle = theme.getColor(Theme.Color.Text2);
|
|
}
|
|
} else if (date == 1 && (hour < (timeInterval / TimelinePlotter.TP_HOUR))) {
|
|
if (month == 1) {
|
|
text = year.toString();
|
|
if (lang == "zh-cn")
|
|
text += "年";
|
|
else if (lang == "zh-tw")
|
|
text += "年";
|
|
} else {
|
|
if (lang == "zh-cn")
|
|
text = month.toString() + "月";
|
|
else if (lang == "zh-tw")
|
|
text = month.toString() + "月";
|
|
else if (lang == "en-us")
|
|
text = TimelinePlotter.MonthConvert[month];
|
|
}
|
|
context.fillStyle = theme.getColor(Theme.Color.Text4);
|
|
}
|
|
if (text.length > 0) {
|
|
var x = timeline.toItemCenter(i);
|
|
gridRects.push({x: x, y: top, w: 1, h: 4});
|
|
context.fillText(text, x, middle);
|
|
}
|
|
}
|
|
if (gridRects.length > 0) {
|
|
context.fillStyle = theme.getColor(Theme.Color.Grid1);
|
|
Plotter.createRectangles(context, gridRects);
|
|
context.fill();
|
|
}
|
|
};
|
|
var RangePlotter = create_class(NamedObject);
|
|
RangePlotter.prototype.__construct = function (name) {
|
|
RangePlotter.__super.__construct.call(this, name);
|
|
};
|
|
RangePlotter.prototype.getRequiredWidth = function (context, v) {
|
|
var mgr = ChartManager.getInstance();
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
context.font = theme.getFont(Theme.Font.Default);
|
|
return context.measureText((Math.floor(v) + 0.88).toString()).width + 16;
|
|
};
|
|
RangePlotter.prototype.Draw = function (context) {
|
|
var mgr = ChartManager.getInstance();
|
|
var areaName = this.getAreaName();
|
|
var area = mgr.getArea(areaName);
|
|
var rangeName = areaName.substring(0, areaName.lastIndexOf("Range"));
|
|
var range = mgr.getRange(rangeName);
|
|
if (range.getRange() == 0.0)
|
|
return;
|
|
var isMainRange = range.getNameObject().getCompAt(2) == "main";
|
|
if (isMainRange) {
|
|
} else {
|
|
if (!area.isChanged() && !range.isUpdated())
|
|
return;
|
|
}
|
|
var gradations = range.getGradations();
|
|
if (gradations.length == 0)
|
|
return;
|
|
var left = area.getLeft();
|
|
var right = area.getRight();
|
|
var center = area.getCenter();
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
context.font = theme.getFont(Theme.Font.Default);
|
|
context.textAlign = "center";
|
|
context.textBaseline = "middle";
|
|
context.fillStyle = theme.getColor(Theme.Color.Text2);
|
|
var gridRects = [];
|
|
for (var n in gradations) {
|
|
var y = range.toY(gradations[n]);
|
|
gridRects.push({x: left, y: y, w: 6, h: 1});
|
|
gridRects.push({x: right - 6, y: y, w: 6, h: 1});
|
|
context.fillText(String.fromFloat(gradations[n], 2), center, y);
|
|
}
|
|
if (gridRects.length > 0) {
|
|
context.fillStyle = theme.getColor(Theme.Color.Grid1);
|
|
Plotter.createRectangles(context, gridRects);
|
|
context.fill();
|
|
}
|
|
};
|
|
|
|
var COrderGraphPlotter = create_class(NamedObject);
|
|
COrderGraphPlotter.prototype.__construct = function (name) {
|
|
COrderGraphPlotter.__super.__construct.call(this, name);
|
|
};
|
|
COrderGraphPlotter.prototype.Draw = function (context) {
|
|
return this._Draw_(context);
|
|
};
|
|
COrderGraphPlotter.prototype._Draw_ = function (context) {
|
|
if (this.Update() == false) return;
|
|
if (this.updateData() == false) return;
|
|
this.m_top = this.m_pArea.getTop();
|
|
this.m_bottom = this.m_pArea.getBottom();
|
|
this.m_left = this.m_pArea.getLeft();
|
|
this.m_right = this.m_pArea.getRight();
|
|
context.save();
|
|
context.rect(this.m_left, this.m_top, this.m_right - this.m_left, this.m_bottom - this.m_top);
|
|
context.clip();
|
|
var all = ChartManager.getInstance().getChart()._depthData;
|
|
this.x_offset = 0;
|
|
this.y_offset = 0;
|
|
var ask_tmp = {};
|
|
var bid_tmp = {};
|
|
ask_tmp.x = this.m_left + all.array[this.m_ask_si].amounts * this.m_Step;
|
|
ask_tmp.y = this.m_pRange.toY(all.array[this.m_ask_si].rate);
|
|
bid_tmp.x = this.m_left + all.array[this.m_bid_si].amounts * this.m_Step;
|
|
bid_tmp.y = this.m_pRange.toY(all.array[this.m_bid_si].rate);
|
|
if (Math.abs(ask_tmp.y - bid_tmp.y) < 1) {
|
|
this.y_offset = 1;
|
|
}
|
|
this.x_offset = 1;
|
|
this.DrawBackground(context);
|
|
this.UpdatePoints();
|
|
this.FillBlack(context);
|
|
this.DrawGradations(context);
|
|
this.DrawLine(context);
|
|
context.restore();
|
|
};
|
|
COrderGraphPlotter.prototype.DrawBackground = function (context) {
|
|
context.fillStyle = this.m_pTheme.getColor(Theme.Color.Background);
|
|
context.fillRect(this.m_left, this.m_top, this.m_right - this.m_left, this.m_bottom - this.m_top);
|
|
var all = ChartManager.getInstance().getChart()._depthData;
|
|
if (this.m_mode == 0) {
|
|
var ask_bottom = this.m_pRange.toY(all.array[this.m_ask_si].rate) - this.y_offset;
|
|
var bid_top = this.m_pRange.toY(all.array[this.m_bid_si].rate) + this.y_offset;
|
|
var ask_gradient = context.createLinearGradient(this.m_left, 0, this.m_right, 0);
|
|
ask_gradient.addColorStop(0, this.m_pTheme.getColor(Theme.Color.Background));
|
|
ask_gradient.addColorStop(1, this.m_pTheme.getColor(Theme.Color.PositiveDark));
|
|
context.fillStyle = ask_gradient;
|
|
context.fillRect(this.m_left, this.m_top, this.m_right - this.m_left, ask_bottom - this.m_top);
|
|
var bid_gradient = context.createLinearGradient(this.m_left, 0, this.m_right, 0);
|
|
bid_gradient.addColorStop(0, this.m_pTheme.getColor(Theme.Color.Background));
|
|
bid_gradient.addColorStop(1, this.m_pTheme.getColor(Theme.Color.NegativeDark));
|
|
context.fillStyle = bid_gradient;
|
|
context.fillRect(this.m_left, bid_top, this.m_right - this.m_left, this.m_bottom - bid_top);
|
|
} else if (this.m_mode == 1) {
|
|
var ask_gradient = context.createLinearGradient(this.m_left, 0, this.m_right, 0);
|
|
ask_gradient.addColorStop(0, this.m_pTheme.getColor(Theme.Color.Background));
|
|
ask_gradient.addColorStop(1, this.m_pTheme.getColor(Theme.Color.PositiveDark));
|
|
context.fillStyle = ask_gradient;
|
|
context.fillRect(this.m_left, this.m_top, this.m_right - this.m_left, this.m_bottom - this.m_top);
|
|
} else if (this.m_mode == 2) {
|
|
var bid_gradient = context.createLinearGradient(this.m_left, 0, this.m_right, 0);
|
|
bid_gradient.addColorStop(0, this.m_pTheme.getColor(Theme.Color.Background));
|
|
bid_gradient.addColorStop(1, this.m_pTheme.getColor(Theme.Color.NegativeDark));
|
|
context.fillStyle = bid_gradient;
|
|
context.fillRect(this.m_left, this.m_top, this.m_right - this.m_left, this.m_bottom - this.m_top);
|
|
}
|
|
};
|
|
COrderGraphPlotter.prototype.DrawLine = function (context) {
|
|
if (this.m_mode == 0 || this.m_mode == 1) {
|
|
context.strokeStyle = this.m_pTheme.getColor(Theme.Color.Positive);
|
|
context.beginPath();
|
|
context.moveTo(Math.floor(this.m_ask_points[0].x) + 0.5, Math.floor(this.m_ask_points[0].y) + 0.5);
|
|
for (var i = 1; i < this.m_ask_points.length; i++) {
|
|
context.lineTo(Math.floor(this.m_ask_points[i].x) + 0.5, Math.floor(this.m_ask_points[i].y) + 0.5);
|
|
}
|
|
context.stroke();
|
|
}
|
|
if (this.m_mode == 0 || this.m_mode == 2) {
|
|
context.strokeStyle = this.m_pTheme.getColor(Theme.Color.Negative);
|
|
context.beginPath();
|
|
context.moveTo(this.m_bid_points[0].x + 0.5, this.m_bid_points[0].y + 0.5);
|
|
for (var i = 1; i < this.m_bid_points.length; i++) {
|
|
context.lineTo(this.m_bid_points[i].x + 0.5, this.m_bid_points[i].y + 0.5);
|
|
}
|
|
context.stroke();
|
|
}
|
|
};
|
|
COrderGraphPlotter.prototype.UpdatePoints = function () {
|
|
var all = ChartManager.getInstance().getChart()._depthData;
|
|
this.m_ask_points = [];
|
|
var index_ask = {};
|
|
index_ask.x = Math.floor(this.m_left);
|
|
index_ask.y = Math.floor(this.m_pRange.toY(all.array[this.m_ask_si].rate) - this.y_offset);
|
|
this.m_ask_points.push(index_ask);
|
|
var ask_p_i = 0;
|
|
for (var i = this.m_ask_si; i >= this.m_ask_ei; i--) {
|
|
var index0 = {};
|
|
var index1 = {};
|
|
if (i == this.m_ask_si) {
|
|
index0.x = Math.floor(this.m_left + all.array[i].amounts * this.m_Step + this.x_offset);
|
|
index0.y = Math.floor(this.m_pRange.toY(all.array[i].rate) - this.y_offset);
|
|
this.m_ask_points.push(index0);
|
|
ask_p_i = 1;
|
|
} else {
|
|
index0.x = Math.floor(this.m_left + all.array[i].amounts * this.m_Step + this.x_offset);
|
|
index0.y = Math.floor(this.m_ask_points[ask_p_i].y);
|
|
index1.x = Math.floor(index0.x);
|
|
index1.y = Math.floor(this.m_pRange.toY(all.array[i].rate) - this.y_offset);
|
|
this.m_ask_points.push(index0);
|
|
ask_p_i++;
|
|
this.m_ask_points.push(index1);
|
|
ask_p_i++;
|
|
}
|
|
}
|
|
this.m_bid_points = [];
|
|
var index_bid = {};
|
|
index_bid.x = Math.floor(this.m_left);
|
|
index_bid.y = Math.ceil(this.m_pRange.toY(all.array[this.m_bid_si].rate) + this.y_offset);
|
|
this.m_bid_points.push(index_bid);
|
|
var bid_p_i = 0;
|
|
for (var i = this.m_bid_si; i <= this.m_bid_ei; i++) {
|
|
var index0 = {};
|
|
var index1 = {};
|
|
if (i == this.m_bid_si) {
|
|
index0.x = Math.floor(this.m_left + all.array[i].amounts * this.m_Step + this.x_offset);
|
|
index0.y = Math.ceil(this.m_pRange.toY(all.array[i].rate) + this.y_offset);
|
|
this.m_bid_points.push(index0);
|
|
bid_p_i = 1;
|
|
} else {
|
|
index0.x = Math.floor(this.m_left + all.array[i].amounts * this.m_Step + this.x_offset);
|
|
index0.y = Math.ceil(this.m_bid_points[bid_p_i].y);
|
|
index1.x = Math.floor(index0.x);
|
|
index1.y = Math.ceil(this.m_pRange.toY(all.array[i].rate) + this.x_offset);
|
|
this.m_bid_points.push(index0);
|
|
bid_p_i++;
|
|
this.m_bid_points.push(index1);
|
|
bid_p_i++;
|
|
}
|
|
}
|
|
};
|
|
COrderGraphPlotter.prototype.updateData = function () {
|
|
var all = ChartManager.getInstance().getChart()._depthData;
|
|
if (all.array == null) return false;
|
|
if (all.array.length <= 50) return false;
|
|
var minRange = this.m_pRange.getOuterMinValue();
|
|
var maxRange = this.m_pRange.getOuterMaxValue();
|
|
this.m_ask_si = all.asks_si;
|
|
this.m_ask_ei = all.asks_si;
|
|
for (var i = all.asks_si; i >= all.asks_ei; i--) {
|
|
if (all.array[i].rate < maxRange)
|
|
this.m_ask_ei = i;
|
|
else
|
|
break;
|
|
}
|
|
this.m_bid_si = all.bids_si;
|
|
this.m_bid_ei = all.bids_si;
|
|
for (var i = all.bids_si; i <= all.bids_ei; i++) {
|
|
if (all.array[i].rate > minRange)
|
|
this.m_bid_ei = i;
|
|
else
|
|
break;
|
|
}
|
|
if (this.m_ask_ei == this.m_ask_si)
|
|
this.m_mode = 2;
|
|
else if (this.m_bid_ei == this.m_bid_si)
|
|
this.m_mode = 1;
|
|
else
|
|
this.m_mode = 0;
|
|
this.m_Step = this.m_pArea.getWidth();
|
|
if (this.m_mode == 0) {
|
|
/*
|
|
* View: B -------- T
|
|
* Data: Lo ----- Hi
|
|
*/
|
|
if (this.m_ask_ei == all.asks_ei && this.m_bid_ei == all.bids_ei) {
|
|
this.m_Step /= Math.min(all.array[this.m_ask_ei].amounts,
|
|
all.array[this.m_bid_ei].amounts);
|
|
}
|
|
/*
|
|
* View: B -------- T
|
|
* Data: Lo ----- Hi
|
|
*/
|
|
else if (this.m_ask_ei != all.asks_ei && this.m_bid_ei == all.bids_ei) {
|
|
this.m_Step /= all.array[this.m_bid_ei].amounts;
|
|
}
|
|
/*
|
|
* View: B -------- T
|
|
* Data: Lo ----- Hi
|
|
*/
|
|
else if (this.m_ask_ei == all.asks_ei && this.m_bid_ei != all.bids_ei) {
|
|
this.m_Step /= all.array[this.m_ask_ei].amounts;
|
|
}
|
|
/*
|
|
* View: B -------- T
|
|
* Data: Lo ------------ Hi
|
|
*/
|
|
else if (this.m_ask_ei != all.asks_ei && this.m_bid_ei != all.bids_ei) {
|
|
this.m_Step /= Math.max(all.array[this.m_ask_ei].amounts,
|
|
all.array[this.m_bid_ei].amounts);
|
|
}
|
|
} else if (this.m_mode == 1) {
|
|
this.m_Step /= all.array[this.m_ask_ei].amounts;
|
|
} else if (this.m_mode == 2) {
|
|
this.m_Step /= all.array[this.m_bid_ei].amounts;
|
|
}
|
|
return true;
|
|
};
|
|
COrderGraphPlotter.prototype.Update = function () {
|
|
this.m_pMgr = ChartManager.getInstance();
|
|
var areaName = this.getAreaName();
|
|
this.m_pArea = this.m_pMgr.getArea(areaName);
|
|
if (this.m_pArea == null)
|
|
return false;
|
|
var rangeName = areaName.substring(0, areaName.lastIndexOf("Range"));
|
|
this.m_pRange = this.m_pMgr.getRange(rangeName);
|
|
if (this.m_pRange == null || this.m_pRange.getRange() == 0.0)
|
|
return false;
|
|
this.m_pTheme = this.m_pMgr.getTheme(this.getFrameName());
|
|
if (this.m_pTheme == null)
|
|
return false;
|
|
return true;
|
|
};
|
|
COrderGraphPlotter.prototype.DrawGradations = function (context) {
|
|
var mgr = ChartManager.getInstance();
|
|
var areaName = this.getAreaName();
|
|
var area = mgr.getArea(areaName);
|
|
var rangeName = areaName.substring(0, areaName.lastIndexOf("Range"));
|
|
var range = mgr.getRange(rangeName);
|
|
if (range.getRange() == 0.0)
|
|
return;
|
|
var gradations = range.getGradations();
|
|
if (gradations.length == 0)
|
|
return;
|
|
var left = area.getLeft();
|
|
var right = area.getRight();
|
|
var gridRects = [];
|
|
for (var n in gradations) {
|
|
var y = range.toY(gradations[n]);
|
|
gridRects.push({x: left, y: y, w: 6, h: 1});
|
|
gridRects.push({x: right - 6, y: y, w: 6, h: 1});
|
|
}
|
|
if (gridRects.length > 0) {
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
context.fillStyle = theme.getColor(Theme.Color.Grid1);
|
|
Plotter.createRectangles(context, gridRects);
|
|
context.fill();
|
|
}
|
|
};
|
|
COrderGraphPlotter.prototype.FillBlack = function (context) {
|
|
var ask_point = this.m_ask_points;
|
|
var bid_point = this.m_bid_points;
|
|
var ask_first_add = {};
|
|
var ask_last_add = {};
|
|
ask_first_add.x = this.m_right;
|
|
ask_first_add.y = ask_point[0].y;
|
|
ask_last_add.x = this.m_right;
|
|
ask_last_add.y = ask_point[ask_point.length - 1].y;
|
|
var bid_first_add = {};
|
|
var bid_last_add = {};
|
|
bid_first_add.x = this.m_right;
|
|
bid_first_add.y = bid_point[0].y - 1;
|
|
bid_last_add.x = this.m_right;
|
|
bid_last_add.y = bid_point[bid_point.length - 1].y;
|
|
ask_point.unshift(ask_first_add);
|
|
ask_point.push(ask_last_add);
|
|
bid_point.unshift(bid_first_add);
|
|
bid_point.push(bid_last_add);
|
|
context.fillStyle = this.m_pTheme.getColor(Theme.Color.Background);
|
|
context.beginPath();
|
|
context.moveTo(Math.floor(ask_point[0].x) + 0.5, Math.floor(ask_point[0].y) + 0.5);
|
|
for (var i = 1; i < ask_point.length; i++) {
|
|
context.lineTo(Math.floor(ask_point[i].x) + 0.5, Math.floor(ask_point[i].y) + 0.5);
|
|
}
|
|
context.fill();
|
|
context.beginPath();
|
|
context.moveTo(Math.floor(bid_point[0].x) + 0.5, Math.floor(bid_point[0].y) + 0.5);
|
|
for (var i = 1; i < bid_point.length; i++) {
|
|
context.lineTo(Math.floor(bid_point[i].x) + 0.5, Math.floor(bid_point[i].y) + 0.5);
|
|
}
|
|
context.fill();
|
|
ask_point.shift();
|
|
ask_point.pop();
|
|
bid_point.shift();
|
|
bid_point.pop();
|
|
};
|
|
COrderGraphPlotter.prototype.DrawTickerGraph = function (context) {
|
|
return;
|
|
var mgr = ChartManager.getInstance();
|
|
var ds = mgr.getDataSource(this.getDataSourceName());
|
|
var ticker = ds._dataItems[ds._dataItems.length - 1].close;
|
|
var p1x = this.m_left + 1;
|
|
var p1y = this.m_pRange.toY(ticker);
|
|
var p2x = p1x + 5;
|
|
var p2y = p1y + 2.5;
|
|
var p3x = p1x + 5;
|
|
var p3y = p1y - 2.5;
|
|
context.fillStyle = this.m_pTheme.getColor(Theme.Color.Mark);
|
|
context.strokeStyle = this.m_pTheme.getColor(Theme.Color.Mark);
|
|
};
|
|
var LastVolumePlotter = create_class(Plotter);
|
|
LastVolumePlotter.prototype.__construct = function (name) {
|
|
LastVolumePlotter.__super.__construct.call(this, name);
|
|
};
|
|
LastVolumePlotter.prototype.Draw = function (context) {
|
|
var mgr = ChartManager.getInstance();
|
|
var timeline = mgr.getTimeline(this.getDataSourceName());
|
|
var areaName = this.getAreaName();
|
|
var area = mgr.getArea(areaName);
|
|
var rangeName = areaName.substring(0, areaName.lastIndexOf("Range"));
|
|
var range = mgr.getRange(rangeName);
|
|
if (range.getRange() == 0.0)
|
|
return;
|
|
var ds = mgr.getDataSource(this.getDataSourceName());
|
|
if (ds.getDataCount() < 1)
|
|
return;
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
context.font = theme.getFont(Theme.Font.Default);
|
|
context.textAlign = "left";
|
|
context.textBaseline = "middle";
|
|
context.fillStyle = theme.getColor(Theme.Color.RangeMark);
|
|
context.strokeStyle = theme.getColor(Theme.Color.RangeMark);
|
|
var v = ds.getDataAt(ds.getDataCount() - 1).volume;
|
|
var y = range.toY(v);
|
|
var left = area.getLeft() + 1;
|
|
Plotter.drawLine(context, left, y, left + 7, y);
|
|
Plotter.drawLine(context, left, y, left + 3, y + 2);
|
|
Plotter.drawLine(context, left, y, left + 3, y - 2);
|
|
context.fillText(String.fromFloat(v, 2), left + 10, y);
|
|
};
|
|
/**
|
|
* Created by Administrator on 2014/11/28.
|
|
*/
|
|
var LastClosePlotter = create_class(Plotter);
|
|
LastClosePlotter.prototype.__construct = function (name) {
|
|
LastClosePlotter.__super.__construct.call(this, name);
|
|
};
|
|
LastClosePlotter.prototype.Draw = function (context) {
|
|
var mgr = ChartManager.getInstance();
|
|
var timeline = mgr.getTimeline(this.getDataSourceName());
|
|
var areaName = this.getAreaName();
|
|
var area = mgr.getArea(areaName);
|
|
var rangeName = areaName.substring(0, areaName.lastIndexOf("Range"));
|
|
var range = mgr.getRange(rangeName);
|
|
if (range.getRange() == 0.0)
|
|
return;
|
|
var ds = mgr.getDataSource(this.getDataSourceName());
|
|
if (ds.getDataCount() < 1)
|
|
return;
|
|
var v = ds._dataItems[ds._dataItems.length - 1].close;
|
|
if (v <= range.getMinValue() || v >= range.getMaxValue())
|
|
return;
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
context.font = theme.getFont(Theme.Font.Default);
|
|
context.textAlign = "left";
|
|
context.textBaseline = "middle";
|
|
context.fillStyle = theme.getColor(Theme.Color.RangeMark);
|
|
context.strokeStyle = theme.getColor(Theme.Color.RangeMark);
|
|
var y = range.toY(v);
|
|
var left = area.getLeft() + 1;
|
|
Plotter.drawLine(context, left, y, left + 7, y);
|
|
Plotter.drawLine(context, left, y, left + 3, y + 2);
|
|
Plotter.drawLine(context, left, y, left + 3, y - 2);
|
|
context.fillText(String.fromFloat(v, ds.getDecimalDigits()), left + 10, y);
|
|
};
|
|
var SelectionPlotter = create_class(Plotter);
|
|
SelectionPlotter.prototype.__construct = function (name) {
|
|
SelectionPlotter.__super.__construct.call(this, name);
|
|
};
|
|
SelectionPlotter.prototype.Draw = function (context) {
|
|
var mgr = ChartManager.getInstance();
|
|
if (mgr._drawingTool != ChartManager.DrawingTool.CrossCursor)
|
|
return;
|
|
var area = mgr.getArea(this.getAreaName());
|
|
var timeline = mgr.getTimeline(this.getDataSourceName());
|
|
if (timeline.getSelectedIndex() < 0) {
|
|
return;
|
|
}
|
|
var range = mgr.getRange(this.getAreaName());
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
context.strokeStyle = theme.getColor(Theme.Color.Cursor);
|
|
var x = timeline.toItemCenter(timeline.getSelectedIndex());
|
|
Plotter.drawLine(context, x, area.getTop() - 1, x, area.getBottom());
|
|
var pos = range.getSelectedPosition();
|
|
if (pos >= 0)
|
|
Plotter.drawLine(context, area.getLeft(), pos, area.getRight(), pos);
|
|
};
|
|
var TimelineSelectionPlotter = create_class(NamedObject);
|
|
TimelineSelectionPlotter.MonthConvert = {
|
|
1: "Jan.",
|
|
2: "Feb.",
|
|
3: "Mar.",
|
|
4: "Apr.",
|
|
5: "May.",
|
|
6: "Jun.",
|
|
7: "Jul.",
|
|
8: "Aug.",
|
|
9: "Sep.",
|
|
10: "Oct.",
|
|
11: "Nov.",
|
|
12: "Dec."
|
|
};
|
|
TimelineSelectionPlotter.prototype.__construct = function (name) {
|
|
TimelineSelectionPlotter.__super.__construct.call(this, name);
|
|
};
|
|
TimelineSelectionPlotter.prototype.Draw = function (context) {
|
|
var mgr = ChartManager.getInstance();
|
|
var area = mgr.getArea(this.getAreaName());
|
|
var timeline = mgr.getTimeline(this.getDataSourceName());
|
|
if (timeline.getSelectedIndex() < 0)
|
|
return;
|
|
var ds = mgr.getDataSource(this.getDataSourceName());
|
|
if (!is_instance(ds, MainDataSource))
|
|
return;
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
var lang = mgr.getLanguage();
|
|
var x = timeline.toItemCenter(timeline.getSelectedIndex());
|
|
context.fillStyle = theme.getColor(Theme.Color.Background);
|
|
context.fillRect(x - 52.5, area.getTop() + 2.5, 106, 18);
|
|
context.strokeStyle = theme.getColor(Theme.Color.Grid3);
|
|
context.strokeRect(x - 52.5, area.getTop() + 2.5, 106, 18);
|
|
context.font = theme.getFont(Theme.Font.Default);
|
|
context.textAlign = "center";
|
|
context.textBaseline = "middle";
|
|
context.fillStyle = theme.getColor(Theme.Color.Text4);
|
|
var time = new Date(ds.getDataAt(timeline.getSelectedIndex()).date);
|
|
var month = time.getMonth() + 1;
|
|
var date = time.getDate();
|
|
var hour = time.getHours();
|
|
var minute = time.getMinutes();
|
|
var second = time.getSeconds();
|
|
var strMonth = month.toString();
|
|
var strDate = date.toString();
|
|
var strHour = hour.toString();
|
|
var strMinute = minute.toString();
|
|
var strSecond = second.toString();
|
|
if (minute < 10)
|
|
strMinute = "0" + strMinute;
|
|
if (second < 10)
|
|
strSecond = "0" + strSecond;
|
|
var text = "";
|
|
if (lang == "zh-cn") {
|
|
text = strMonth + "月" + strDate + "日 " +
|
|
strHour + ":" + strMinute;
|
|
} else if (lang == "zh-tw") {
|
|
text = strMonth + "月" + strDate + "日 " +
|
|
strHour + ":" + strMinute;
|
|
} else if (lang == "en-us") {
|
|
text = TimelineSelectionPlotter.MonthConvert[month] + " " + strDate + " " +
|
|
strHour + ":" + strMinute;
|
|
}
|
|
if (KlineIns.range < 60000) {
|
|
text += ":" + strSecond;
|
|
}
|
|
context.fillText(text, x, area.getMiddle());
|
|
};
|
|
var RangeSelectionPlotter = create_class(NamedObject);
|
|
RangeSelectionPlotter.prototype.__construct = function (name) {
|
|
RangeSelectionPlotter.__super.__construct.call(this, name);
|
|
};
|
|
RangeSelectionPlotter.prototype.Draw = function (context) {
|
|
var mgr = ChartManager.getInstance();
|
|
var areaName = this.getAreaName();
|
|
var area = mgr.getArea(areaName);
|
|
var timeline = mgr.getTimeline(this.getDataSourceName());
|
|
if (timeline.getSelectedIndex() < 0)
|
|
return;
|
|
var rangeName = areaName.substring(0, areaName.lastIndexOf("Range"));
|
|
var range = mgr.getRange(rangeName);
|
|
if (range.getRange() == 0.0 || range.getSelectedPosition() < 0)
|
|
return;
|
|
var v = range.getSelectedValue();
|
|
if (v == -Number.MAX_VALUE)
|
|
return;
|
|
var y = range.getSelectedPosition();
|
|
Plotter.createPolygon(context, [
|
|
{"x": area.getLeft(), "y": y},
|
|
{"x": area.getLeft() + 5, "y": y + 10},
|
|
{"x": area.getRight() - 3, "y": y + 10},
|
|
{"x": area.getRight() - 3, "y": y - 10},
|
|
{"x": area.getLeft() + 5, "y": y - 10}
|
|
]);
|
|
var theme = mgr.getTheme(this.getFrameName());
|
|
context.fillStyle = theme.getColor(Theme.Color.Background);
|
|
context.fill();
|
|
context.strokeStyle = theme.getColor(Theme.Color.Grid4);
|
|
context.stroke();
|
|
context.font = theme.getFont(Theme.Font.Default);
|
|
context.textAlign = "center";
|
|
context.textBaseline = "middle";
|
|
context.fillStyle = theme.getColor(Theme.Color.Text3);
|
|
var digits = 2;
|
|
if (range.getNameObject().getCompAt(2) == "main")
|
|
digits = mgr.getDataSource(this.getDataSourceName()).getDecimalDigits();
|
|
context.fillText(String.fromFloat(v, digits), area.getCenter(), y);
|
|
};
|
|
var ChartSettings = {};
|
|
ChartSettings.checkVersion = function () {
|
|
if (ChartSettings._data.ver < 2) {
|
|
ChartSettings._data.ver = 2;
|
|
var charts = ChartSettings._data.charts;
|
|
charts.period_weight = {};
|
|
charts.period_weight['line'] = 8;
|
|
charts.period_weight['1min'] = 7;
|
|
charts.period_weight['5min'] = 6;
|
|
charts.period_weight['15min'] = 5;
|
|
charts.period_weight['30min'] = 4;
|
|
charts.period_weight['1hour'] = 3;
|
|
charts.period_weight['1day'] = 2;
|
|
charts.period_weight['1week'] = 1;
|
|
charts.period_weight['3min'] = 0;
|
|
charts.period_weight['2hour'] = 0;
|
|
charts.period_weight['4hour'] = 0;
|
|
charts.period_weight['6hour'] = 0;
|
|
charts.period_weight['12hour'] = 0;
|
|
charts.period_weight['3day'] = 0;
|
|
}
|
|
if (ChartSettings._data.ver < 3) {
|
|
ChartSettings._data.ver = 3;
|
|
var charts = ChartSettings._data.charts;
|
|
charts.areaHeight = [];
|
|
}
|
|
};
|
|
ChartSettings.get = function () {
|
|
if (ChartSettings._data == undefined) {
|
|
ChartSettings.init();
|
|
ChartSettings.load();
|
|
ChartSettings.checkVersion();
|
|
}
|
|
return ChartSettings._data;
|
|
};
|
|
ChartSettings.init = function () {
|
|
var _indic_param = {};
|
|
var _name = new Array('MA', 'EMA', 'VOLUME', 'MACD', 'KDJ', 'StochRSI', 'RSI', 'DMI', 'OBV', 'BOLL', 'DMA', 'TRIX', 'BRAR', 'VR', 'EMV', 'WR', 'ROC', 'MTM', 'PSY');
|
|
for (var i = 0; i < _name.length; i++) {
|
|
var _value = ChartManager.getInstance().createIndicatorAndRange('', _name[i], true);
|
|
if (_value == null) continue;
|
|
_indic_param[_name[i]] = [];
|
|
var param = _value.indic.getParameters();
|
|
for (var j = 0; j < param.length; j++) {
|
|
_indic_param[_name[i]].push(param[j]);
|
|
}
|
|
}
|
|
var _chart_style = 'CandleStick';
|
|
var _m_indic = 'MA';
|
|
var _indic = new Array('VOLUME', 'MACD');
|
|
var _range = '15m';
|
|
var _frame = {};
|
|
_frame.chartStyle = _chart_style;
|
|
_frame.mIndic = _m_indic;
|
|
_frame.indics = _indic;
|
|
_frame.indicsStatus = 'open';
|
|
_frame.period = _range;
|
|
ChartSettings._data = {
|
|
ver: 1,
|
|
charts: _frame,
|
|
indics: _indic_param,
|
|
theme: "Dark"
|
|
};
|
|
ChartSettings.checkVersion();
|
|
};
|
|
ChartSettings.load = function () {
|
|
if (document.cookie.length <= 0)
|
|
return;
|
|
var start = document.cookie.indexOf("chartSettings=");
|
|
if (start < 0)
|
|
return;
|
|
start += "chartSettings=".length;
|
|
var end = document.cookie.indexOf(";", start);
|
|
if (end < 0)
|
|
end = document.cookie.length;
|
|
var json = unescape(document.cookie.substring(start, end));
|
|
ChartSettings._data = JSON.parse(json);
|
|
};
|
|
ChartSettings.save = function () {
|
|
var exdate = new Date();
|
|
exdate.setDate(exdate.getDate() + 2);
|
|
document.cookie = "chartSettings=" + escape(JSON.stringify(ChartSettings._data)) +
|
|
";expires=" + exdate.toGMTString();
|
|
};
|
|
var CPoint = create_class(NamedObject);
|
|
CPoint.state = {
|
|
Hide: 0,
|
|
Show: 1,
|
|
Highlight: 2
|
|
};
|
|
CPoint.prototype.__construct = function (name) {
|
|
CPoint.__super.__construct.call(this, name);
|
|
this.pos = {index: -1, value: -1};
|
|
this.state = CPoint.state.Hide;
|
|
};
|
|
CPoint.prototype.getChartObjects = function () {
|
|
var ppMgr = ChartManager.getInstance();
|
|
var ppCDS = ppMgr.getDataSource("frame0.k0");
|
|
if (ppCDS == null || !is_instance(ppCDS, MainDataSource))
|
|
return null;
|
|
var ppTimeline = ppMgr.getTimeline("frame0.k0");
|
|
if (ppTimeline == null)
|
|
return null;
|
|
var ppRange = ppMgr.getRange("frame0.k0.main");
|
|
if (ppRange == null)
|
|
return null;
|
|
return {pMgr: ppMgr, pCDS: ppCDS, pTimeline: ppTimeline, pRange: ppRange};
|
|
};
|
|
CPoint.prototype.setPosXY = function (x, y) {
|
|
var pObj = this.getChartObjects();
|
|
var i = pObj.pTimeline.toIndex(x);
|
|
var v = pObj.pRange.toValue(y);
|
|
var result = this.snapValue(i, v);
|
|
if (result != null)
|
|
v = result;
|
|
this.setPosIV(i, v);
|
|
};
|
|
CPoint.prototype.setPosXYNoSnap = function (x, y) {
|
|
var pObj = this.getChartObjects();
|
|
var i = pObj.pTimeline.toIndex(x);
|
|
var v = pObj.pRange.toValue(y);
|
|
this.setPosIV(i, v);
|
|
};
|
|
CPoint.prototype.setPosIV = function (i, v) {
|
|
this.pos = {index: i, value: v};
|
|
};
|
|
CPoint.prototype.getPosXY = function () {
|
|
var pObj = this.getChartObjects();
|
|
var _x = pObj.pTimeline.toItemCenter(this.pos.index);
|
|
var _y = pObj.pRange.toY(this.pos.value);
|
|
return {x: _x, y: _y};
|
|
};
|
|
CPoint.prototype.getPosIV = function () {
|
|
return {i: this.pos.index, v: this.pos.value};
|
|
};
|
|
CPoint.prototype.setState = function (s) {
|
|
this.state = s;
|
|
};
|
|
CPoint.prototype.getState = function () {
|
|
return this.state;
|
|
};
|
|
CPoint.prototype.isSelected = function (x, y) {
|
|
var xy = this.getPosXY();
|
|
if (x < xy.x - 4 || x > xy.x + 4 || y < xy.y - 4 || y > xy.y + 4)
|
|
return false;
|
|
this.setState(CPoint.state.Highlight);
|
|
return true;
|
|
};
|
|
CPoint.prototype.snapValue = function (i, v) {
|
|
var pObj = this.getChartObjects();
|
|
var result = null;
|
|
var first = Math.floor(pObj.pTimeline.getFirstIndex());
|
|
var last = Math.floor(pObj.pTimeline.getLastIndex());
|
|
if (i < first || i > last)
|
|
return result;
|
|
var y = pObj.pRange.toY(v);
|
|
var pData = pObj.pCDS.getDataAt(i);
|
|
if (pData == null || pData == undefined)
|
|
return result;
|
|
var pDataPre = null;
|
|
if (i > 0)
|
|
pDataPre = pObj.pCDS.getDataAt(i - 1);
|
|
else
|
|
pDataPre = pObj.pCDS.getDataAt(i);
|
|
var candleStickStyle = pObj.pMgr.getChartStyle(pObj.pCDS.getFrameName());
|
|
var open = pObj.pRange.toY(pData.open);
|
|
var high = pObj.pRange.toY(pData.high);
|
|
var low = pObj.pRange.toY(pData.low);
|
|
var close = pObj.pRange.toY(pData.close);
|
|
if (candleStickStyle === "CandleStickHLC") {
|
|
open = pObj.pRange.toY(pDataPre.close);
|
|
}
|
|
var dif_open = Math.abs(open - y);
|
|
var dif_high = Math.abs(high - y);
|
|
var dif_low = Math.abs(low - y);
|
|
var dif_close = Math.abs(close - y);
|
|
if (dif_open <= dif_high && dif_open <= dif_low && dif_open <= dif_close) {
|
|
if (dif_open < 6)
|
|
result = pData.open;
|
|
}
|
|
if (dif_high <= dif_open && dif_high <= dif_low && dif_high <= dif_close) {
|
|
if (dif_high < 6)
|
|
result = pData.high;
|
|
}
|
|
if (dif_low <= dif_open && dif_low <= dif_high && dif_low <= dif_close) {
|
|
if (dif_low < 6)
|
|
result = pData.low;
|
|
}
|
|
if (dif_close <= dif_open && dif_close <= dif_high && dif_close <= dif_low) {
|
|
if (dif_close < 6)
|
|
result = pData.close;
|
|
}
|
|
return result;
|
|
};
|
|
var CToolObject = create_class(NamedObject);
|
|
CToolObject.state = {
|
|
BeforeDraw: 0,
|
|
Draw: 1,
|
|
AfterDraw: 2
|
|
};
|
|
CToolObject.prototype.__construct = function (name) {
|
|
CToolObject.__super.__construct.call(this, name);
|
|
this.drawer = null;
|
|
this.state = CToolObject.state.BeforeDraw;
|
|
this.points = [];
|
|
this.step = 0;
|
|
};
|
|
CToolObject.prototype.getChartObjects = function () {
|
|
var ppMgr = ChartManager.getInstance();
|
|
var ppCDS = ppMgr.getDataSource("frame0.k0");
|
|
if (ppCDS == null || !is_instance(ppCDS, MainDataSource))
|
|
return null;
|
|
var ppTimeline = ppMgr.getTimeline("frame0.k0");
|
|
if (ppTimeline == null)
|
|
return null;
|
|
var ppArea = ppMgr.getArea('frame0.k0.main');
|
|
if (ppArea == null)
|
|
return null;
|
|
var ppRange = ppMgr.getRange("frame0.k0.main");
|
|
if (ppRange == null)
|
|
return null;
|
|
return {pMgr: ppMgr, pCDS: ppCDS, pTimeline: ppTimeline, pArea: ppArea, pRange: ppRange};
|
|
};
|
|
CToolObject.prototype.isValidMouseXY = function (x, y) {
|
|
var pObj = this.getChartObjects();
|
|
var areaPos = {
|
|
left: pObj.pArea.getLeft(),
|
|
top: pObj.pArea.getTop(),
|
|
right: pObj.pArea.getRight(),
|
|
bottom: pObj.pArea.getBottom()
|
|
};
|
|
if (x < areaPos.left || x > areaPos.right ||
|
|
y < areaPos.top || y > areaPos.bottom)
|
|
return false;
|
|
return true;
|
|
};
|
|
CToolObject.prototype.getPlotter = function () {
|
|
return this.drawer;
|
|
};
|
|
CToolObject.prototype.setState = function (s) {
|
|
this.state = s;
|
|
};
|
|
CToolObject.prototype.getState = function () {
|
|
return this.state;
|
|
};
|
|
CToolObject.prototype.addPoint = function (point) {
|
|
this.points.push(point);
|
|
};
|
|
CToolObject.prototype.getPoint = function (i) {
|
|
return this.points[i];
|
|
};
|
|
CToolObject.prototype.acceptMouseMoveEvent = function (x, y) {
|
|
if (this.isValidMouseXY(x, y) == false)
|
|
return false;
|
|
if (this.state == CToolObject.state.BeforeDraw) {
|
|
this.setBeforeDrawPos(x, y);
|
|
} else if (this.state == CToolObject.state.Draw) {
|
|
this.setDrawPos(x, y);
|
|
} else if (this.state == CToolObject.state.AfterDraw) {
|
|
this.setAfterDrawPos(x, y);
|
|
}
|
|
return true;
|
|
};
|
|
CToolObject.prototype.acceptMouseDownEvent = function (x, y) {
|
|
if (this.isValidMouseXY(x, y) == false)
|
|
return false;
|
|
if (this.state == CToolObject.state.BeforeDraw) {
|
|
this.setDrawPos(x, y);
|
|
this.setState(CToolObject.state.Draw);
|
|
} else if (this.state == CToolObject.state.Draw) {
|
|
this.setAfterDrawPos(x, y);
|
|
if (this.step == 0)
|
|
this.setState(CToolObject.state.AfterDraw);
|
|
} else if (this.state == CToolObject.state.AfterDraw) {
|
|
if (CToolObject.prototype.isSelected.call(this, x, y)) {
|
|
this.setDrawPos(x, y);
|
|
this.setState(CToolObject.state.Draw);
|
|
} else {
|
|
this.oldx = x;
|
|
this.oldy = y;
|
|
}
|
|
}
|
|
return true;
|
|
};
|
|
CToolObject.prototype.acceptMouseDownMoveEvent = function (x, y) {
|
|
if (this.isValidMouseXY(x, y) == false)
|
|
return false;
|
|
if (this.state == CToolObject.state.Draw) {
|
|
this.setDrawPos(x, y);
|
|
} else if (this.state == CToolObject.state.AfterDraw) {
|
|
var pObj = this.getChartObjects();
|
|
var _width = pObj.pTimeline.getItemWidth();
|
|
var _height = pObj.pRange;
|
|
if (Math.abs(x - this.oldx) < _width && Math.abs(y - this.oldy) == 0)
|
|
return true;
|
|
var _old_x = pObj.pTimeline.toIndex(this.oldx);
|
|
var _old_y = pObj.pRange.toValue(this.oldy);
|
|
var _new_x = pObj.pTimeline.toIndex(x);
|
|
var _new_y = pObj.pRange.toValue(y);
|
|
this.oldx = x;
|
|
this.oldy = y;
|
|
var _dif_x = _new_x - _old_x;
|
|
var _dif_y = _new_y - _old_y;
|
|
for (var index in this.points) {
|
|
this.points[index].pos.index += _dif_x;
|
|
this.points[index].pos.value += _dif_y;
|
|
}
|
|
}
|
|
return true;
|
|
};
|
|
CToolObject.prototype.acceptMouseUpEvent = function (x, y) {
|
|
if (this.isValidMouseXY(x, y) == false)
|
|
return false;
|
|
if (this.state == CToolObject.state.Draw) {
|
|
this.setAfterDrawPos(x, y);
|
|
if (this.step == 0)
|
|
this.setState(CToolObject.state.AfterDraw);
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
CToolObject.prototype.setBeforeDrawPos = function (x, y) {
|
|
for (var index in this.points) {
|
|
this.points[index].setPosXY(x, y);
|
|
this.points[index].setState(CPoint.state.Show);
|
|
}
|
|
};
|
|
CToolObject.prototype.setDrawPos = function (x, y) {
|
|
for (var index in this.points) {
|
|
if (this.points[index].getState() == CPoint.state.Highlight) {
|
|
this.points[index].setPosXY(x, y);
|
|
}
|
|
}
|
|
};
|
|
CToolObject.prototype.setAfterDrawPos = function (x, y) {
|
|
if (this.step != 0)
|
|
this.step -= 1;
|
|
for (var index in this.points) {
|
|
this.points[index].setState(CPoint.state.Hide);
|
|
}
|
|
if (this.step == 0) {
|
|
var pObj = this.getChartObjects();
|
|
pObj.pMgr.setNormalMode();
|
|
}
|
|
};
|
|
CToolObject.prototype.isSelected = function (x, y) {
|
|
var isFind = false;
|
|
for (var index in this.points) {
|
|
if (this.points[index].isSelected(x, y)) {
|
|
this.points[index].setState(CPoint.state.Highlight);
|
|
isFind = true;
|
|
break;
|
|
}
|
|
}
|
|
if (isFind == true) {
|
|
this.select();
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
CToolObject.prototype.select = function () {
|
|
for (var index in this.points) {
|
|
if (this.points[index].getState() == CPoint.state.Hide) {
|
|
this.points[index].setState(CPoint.state.Show);
|
|
}
|
|
}
|
|
};
|
|
CToolObject.prototype.unselect = function () {
|
|
for (var index in this.points) {
|
|
if (this.points[index].getState() != CPoint.state.Hide) {
|
|
this.points[index].setState(CPoint.state.Hide);
|
|
}
|
|
}
|
|
};
|
|
CToolObject.prototype.calcDistance = function (point1, point2, point3) {
|
|
var xa = point1.getPosXY().x;
|
|
var ya = point1.getPosXY().y;
|
|
var xb = point2.getPosXY().x;
|
|
var yb = point2.getPosXY().y;
|
|
var xc = point3.getPosXY().x;
|
|
var yc = point3.getPosXY().y;
|
|
var a1 = xa - xc;
|
|
var a2 = ya - yc;
|
|
var b1 = xb - xc;
|
|
var b2 = yb - yc;
|
|
var area = Math.abs(a1 * b2 - a2 * b1);
|
|
var len = Math.sqrt(Math.pow((xb - xa), 2) + Math.pow((yb - ya), 2));
|
|
return area / len;
|
|
};
|
|
CToolObject.prototype.calcGap = function (r, x, y) {
|
|
var xa = r.sx;
|
|
var ya = r.sy;
|
|
var xb = r.ex;
|
|
var yb = r.ey;
|
|
var xc = x;
|
|
var yc = y;
|
|
var a1 = xa - xc;
|
|
var a2 = ya - yc;
|
|
var b1 = xb - xc;
|
|
var b2 = yb - yc;
|
|
var area = Math.abs(a1 * b2 - a2 * b1);
|
|
var len = Math.sqrt(Math.pow((xb - xa), 2) + Math.pow((yb - ya), 2));
|
|
return area / len;
|
|
};
|
|
CToolObject.prototype.isWithRect = function (point1, point2, point3) {
|
|
var sx = point1.getPosXY().x;
|
|
var sy = point1.getPosXY().y;
|
|
var ex = point2.getPosXY().x;
|
|
var ey = point2.getPosXY().y;
|
|
var x = point3.getPosXY().x;
|
|
var y = point3.getPosXY().y;
|
|
if (sx > ex) {
|
|
sx += 4;
|
|
ex -= 4;
|
|
} else {
|
|
sx -= 4;
|
|
ex += 4;
|
|
}
|
|
if (sy > ey) {
|
|
sy += 4;
|
|
ey -= 4;
|
|
} else {
|
|
sy -= 4;
|
|
ey += 4;
|
|
}
|
|
if (sx <= x && ex >= x && sy <= y && ey >= y)
|
|
return true;
|
|
if (sx >= x && ex <= x && sy <= y && ey >= y)
|
|
return true;
|
|
if (sx <= x && ex >= x && sy >= y && ey <= y)
|
|
return true;
|
|
if (sx >= x && ex <= x && sy >= y && ey <= y)
|
|
return true;
|
|
return false;
|
|
};
|
|
var CBiToolObject = create_class(CToolObject);
|
|
CBiToolObject.prototype.__construct = function (name) {
|
|
CBiToolObject.__super.__construct.call(this, name);
|
|
this.addPoint(new CPoint(name));
|
|
this.addPoint(new CPoint(name));
|
|
};
|
|
CBiToolObject.prototype.setBeforeDrawPos = function (x, y) {
|
|
this.step = 1;
|
|
CBiToolObject.__super.setBeforeDrawPos.call(this, x, y);
|
|
this.getPoint(0).setState(CPoint.state.Show);
|
|
this.getPoint(1).setState(CPoint.state.Highlight);
|
|
};
|
|
var CTriToolObject = create_class(CToolObject);
|
|
CTriToolObject.prototype.__construct = function (name) {
|
|
CTriToolObject.__super.__construct.call(this, name);
|
|
this.addPoint(new CPoint(name));
|
|
this.addPoint(new CPoint(name));
|
|
this.addPoint(new CPoint(name));
|
|
};
|
|
CTriToolObject.prototype.setBeforeDrawPos = function (x, y) {
|
|
this.step = 2;
|
|
CBiToolObject.__super.setBeforeDrawPos.call(this, x, y);
|
|
this.getPoint(0).setState(CPoint.state.Show);
|
|
this.getPoint(1).setState(CPoint.state.Show);
|
|
this.getPoint(2).setState(CPoint.state.Highlight);
|
|
};
|
|
CTriToolObject.prototype.setAfterDrawPos = function (x, y) {
|
|
if (this.step != 0)
|
|
this.step -= 1;
|
|
if (this.step == 0) {
|
|
for (var index in this.points) {
|
|
this.points[index].setState(CPoint.state.Hide);
|
|
}
|
|
} else {
|
|
this.getPoint(0).setState(CPoint.state.Show);
|
|
this.getPoint(1).setState(CPoint.state.Highlight);
|
|
this.getPoint(2).setState(CPoint.state.Show);
|
|
}
|
|
if (this.step == 0) {
|
|
var pObj = this.getChartObjects();
|
|
pObj.pMgr.setNormalMode();
|
|
}
|
|
};
|
|
var CBandLineObject = create_class(CBiToolObject);
|
|
CBandLineObject.prototype.__construct = function (name) {
|
|
CBandLineObject.__super.__construct.call(this, name);
|
|
this.drawer = new DrawBandLinesPlotter(name, this);
|
|
};
|
|
CBandLineObject.prototype.isSelected = function (x, y) {
|
|
if (CBandLineObject.__super.isSelected.call(this, x, y) == true)
|
|
return true;
|
|
var c = new CPoint("frame0.k0");
|
|
c.setPosXY(x, y);
|
|
var sx = this.getPoint(0).getPosXY().x;
|
|
var sy = this.getPoint(0).getPosXY().y;
|
|
var ex = this.getPoint(1).getPosXY().x;
|
|
var ey = this.getPoint(1).getPosXY().y;
|
|
var fibSequence = [100.0, 87.5, 75.0, 62.5, 50.0, 37.5, 25.0, 12.5, 0.0];
|
|
for (var i = 0; i < fibSequence.length; i++) {
|
|
var stage_y = sy + (100 - fibSequence[i]) / 100 * (ey - sy);
|
|
if (stage_y < y + 4 && stage_y > y - 4) {
|
|
this.select();
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
var CBiParallelLineObject = create_class(CTriToolObject);
|
|
CBiParallelLineObject.prototype.__construct = function (name) {
|
|
CBiParallelLineObject.__super.__construct.call(this, name);
|
|
this.drawer = new DrawBiParallelLinesPlotter(name, this);
|
|
};
|
|
CBiParallelLineObject.prototype.isSelected = function (x, y) {
|
|
if (CTriParallelLineObject.__super.isSelected.call(this, x, y) == true)
|
|
return true;
|
|
var _0x = this.getPoint(0).getPosXY().x;
|
|
var _0y = this.getPoint(0).getPosXY().y;
|
|
var _1x = this.getPoint(1).getPosXY().x;
|
|
var _1y = this.getPoint(1).getPosXY().y;
|
|
var _2x = this.getPoint(2).getPosXY().x;
|
|
var _2y = this.getPoint(2).getPosXY().y;
|
|
var _a = {x: _0x - _1x, y: _0y - _1y};
|
|
var _b = {x: _0x - _2x, y: _0y - _2y};
|
|
var _c = {x: _a.x + _b.x, y: _a.y + _b.y};
|
|
var _3x = _0x - _c.x;
|
|
var _3y = _0y - _c.y;
|
|
var r1 = {sx: _0x, sy: _0y, ex: _2x, ey: _2y};
|
|
var r2 = {sx: _1x, sy: _1y, ex: _3x, ey: _3y};
|
|
if (this.calcGap(r1, x, y) > 4 && this.calcGap(r2, x, y) > 4)
|
|
return false;
|
|
return true;
|
|
};
|
|
var CBiParallelRayLineObject = create_class(CTriToolObject);
|
|
CBiParallelRayLineObject.prototype.__construct = function (name) {
|
|
CBiParallelRayLineObject.__super.__construct.call(this, name);
|
|
this.drawer = new DrawBiParallelRayLinesPlotter(name, this);
|
|
};
|
|
CBiParallelRayLineObject.prototype.isSelected = function (x, y) {
|
|
if (CTriParallelLineObject.__super.isSelected.call(this, x, y) == true)
|
|
return true;
|
|
var _0x = this.getPoint(0).getPosXY().x;
|
|
var _0y = this.getPoint(0).getPosXY().y;
|
|
var _1x = this.getPoint(1).getPosXY().x;
|
|
var _1y = this.getPoint(1).getPosXY().y;
|
|
var _2x = this.getPoint(2).getPosXY().x;
|
|
var _2y = this.getPoint(2).getPosXY().y;
|
|
var _a = {x: _0x - _1x, y: _0y - _1y};
|
|
var _b = {x: _0x - _2x, y: _0y - _2y};
|
|
var _c = {x: _a.x + _b.x, y: _a.y + _b.y};
|
|
var _3x = _0x - _c.x;
|
|
var _3y = _0y - _c.y;
|
|
var r1 = {sx: _0x, sy: _0y, ex: _2x, ey: _2y};
|
|
var r2 = {sx: _1x, sy: _1y, ex: _3x, ey: _3y};
|
|
if ((r1.ex > r1.sx && x > r1.sx - 4) || (r1.ex < r1.sx && x < r1.sx + 4) ||
|
|
(r2.ex > r2.sx && x > r2.sx - 4) || (r2.ex < r2.sx && x < r2.sx + 4)) {
|
|
if (this.calcGap(r1, x, y) > 4 && this.calcGap(r2, x, y) > 4) {
|
|
return false;
|
|
}
|
|
} else {
|
|
return false;
|
|
}
|
|
this.select();
|
|
return true;
|
|
};
|
|
var CFibFansObject = create_class(CBiToolObject);
|
|
CFibFansObject.prototype.__construct = function (name) {
|
|
CFibFansObject.__super.__construct.call(this, name);
|
|
this.drawer = new DrawFibFansPlotter(name, this);
|
|
};
|
|
CFibFansObject.prototype.isSelected = function (x, y) {
|
|
if (CFibFansObject.__super.isSelected.call(this, x, y) == true)
|
|
return true;
|
|
var c = new CPoint("frame0.k0");
|
|
c.setPosXY(x, y);
|
|
var sx = this.getPoint(0).getPosXY().x;
|
|
var sy = this.getPoint(0).getPosXY().y;
|
|
var ex = this.getPoint(1).getPosXY().x;
|
|
var ey = this.getPoint(1).getPosXY().y;
|
|
var pObj = this.getChartObjects();
|
|
var areaPos = {
|
|
left: pObj.pArea.getLeft(),
|
|
top: pObj.pArea.getTop(),
|
|
right: pObj.pArea.getRight(),
|
|
bottom: pObj.pArea.getBottom()
|
|
};
|
|
var fibFansSequence = [0, 38.2, 50, 61.8];
|
|
for (var i = 0; i < fibFansSequence.length; i++) {
|
|
var stageY = sy + (100 - fibFansSequence[i]) / 100 * (ey - sy);
|
|
var tempStartPt = {x: sx, y: sy};
|
|
var tempEndPt = {x: ex, y: stageY};
|
|
var crossPt = getRectCrossPt(areaPos, tempStartPt, tempEndPt);
|
|
var lenToStartPt = Math.pow((crossPt[0].x - sx), 2) + Math.pow((crossPt[0].y - sy), 2);
|
|
var lenToEndPt = Math.pow((crossPt[0].x - ex), 2) + Math.pow((crossPt[0].y - ey), 2);
|
|
var tempCrossPt = lenToStartPt > lenToEndPt ? {x: crossPt[0].x, y: crossPt[0].y} : {
|
|
x: crossPt[1].x,
|
|
y: crossPt[1].y
|
|
};
|
|
if (tempCrossPt.x > sx && x < sx)
|
|
continue;
|
|
if (tempCrossPt.x < sx && x > sx)
|
|
continue;
|
|
var a = new CPoint("frame0.k0");
|
|
a.setPosXY(sx, sy);
|
|
var b = new CPoint("frame0.k0");
|
|
b.setPosXY(tempCrossPt.x, tempCrossPt.y);
|
|
if (this.calcDistance(a, b, c) > 4)
|
|
continue;
|
|
this.select();
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
var CFibRetraceObject = create_class(CBiToolObject);
|
|
CFibRetraceObject.prototype.__construct = function (name) {
|
|
CFibRetraceObject.__super.__construct.call(this, name);
|
|
this.drawer = new DrawFibRetracePlotter(name, this);
|
|
};
|
|
CFibRetraceObject.prototype.isSelected = function (x, y) {
|
|
if (CFibRetraceObject.__super.isSelected.call(this, x, y) == true)
|
|
return true;
|
|
var c = new CPoint("frame0.k0");
|
|
c.setPosXY(x, y);
|
|
var sx = this.getPoint(0).getPosXY().x;
|
|
var sy = this.getPoint(0).getPosXY().y;
|
|
var ex = this.getPoint(1).getPosXY().x;
|
|
var ey = this.getPoint(1).getPosXY().y;
|
|
var fibSequence = [100.0, 78.6, 61.8, 50.0, 38.2, 23.6, 0.0];
|
|
for (var i = 0; i < fibSequence.length; i++) {
|
|
var stage_y = sy + (100 - fibSequence[i]) / 100 * (ey - sy);
|
|
if (stage_y < y + 4 && stage_y > y - 4) {
|
|
this.select();
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
var CHoriRayLineObject = create_class(CBiToolObject);
|
|
CHoriRayLineObject.prototype.__construct = function (name) {
|
|
CHoriRayLineObject.__super.__construct.call(this, name);
|
|
this.drawer = new DrawHoriRayLinesPlotter(name, this);
|
|
};
|
|
CHoriRayLineObject.prototype.setDrawPos = function (x, y) {
|
|
if (this.points[0].getState() == CPoint.state.Highlight) {
|
|
this.points[0].setPosXY(x, y);
|
|
this.points[1].setPosXYNoSnap(this.points[1].getPosXY().x, this.points[0].getPosXY().y);
|
|
return;
|
|
}
|
|
if (this.points[1].getState() == CPoint.state.Highlight) {
|
|
this.points[1].setPosXY(x, y);
|
|
this.points[0].setPosXYNoSnap(this.points[0].getPosXY().x, this.points[1].getPosXY().y);
|
|
}
|
|
};
|
|
CHoriRayLineObject.prototype.isSelected = function (x, y) {
|
|
if (CHoriRayLineObject.__super.isSelected.call(this, x, y) == true)
|
|
return true;
|
|
var c = new CPoint("frame0.k0");
|
|
c.setPosXY(x, y);
|
|
var sy = this.getPoint(0).getPosXY().y;
|
|
var sx = this.getPoint(0).getPosXY().x;
|
|
var ex = this.getPoint(1).getPosXY().x;
|
|
if (y > sy + 4 || y < sy - 4)
|
|
return false;
|
|
if (ex > sx && x < sx - 4)
|
|
return false;
|
|
if (ex < sx && x > sx + 4)
|
|
return false;
|
|
this.select();
|
|
return true;
|
|
};
|
|
var CHoriSegLineObject = create_class(CBiToolObject);
|
|
CHoriSegLineObject.prototype.__construct = function (name) {
|
|
CHoriSegLineObject.__super.__construct.call(this, name);
|
|
this.drawer = new DrawHoriSegLinesPlotter(name, this);
|
|
};
|
|
CHoriSegLineObject.prototype.setDrawPos = function (x, y) {
|
|
if (this.points[0].getState() == CPoint.state.Highlight) {
|
|
this.points[0].setPosXY(x, y);
|
|
this.points[1].setPosXYNoSnap(this.points[1].getPosXY().x, this.points[0].getPosXY().y);
|
|
return;
|
|
}
|
|
if (this.points[1].getState() == CPoint.state.Highlight) {
|
|
this.points[1].setPosXY(x, y);
|
|
this.points[0].setPosXYNoSnap(this.points[0].getPosXY().x, this.points[1].getPosXY().y);
|
|
}
|
|
};
|
|
CHoriSegLineObject.prototype.isSelected = function (x, y) {
|
|
if (CHoriSegLineObject.__super.isSelected.call(this, x, y) == true)
|
|
return true;
|
|
var c = new CPoint("frame0.k0");
|
|
c.setPosXY(x, y);
|
|
var sy = this.getPoint(0).getPosXY().y;
|
|
var sx = this.getPoint(0).getPosXY().x;
|
|
var ex = this.getPoint(1).getPosXY().x;
|
|
if (y > sy + 4 || y < sy - 4)
|
|
return false;
|
|
if (sx > ex && (x > sx + 4 || x < ex - 4))
|
|
return false;
|
|
if (sx < ex && (x < sx - 4 || x > ex + 4))
|
|
return false;
|
|
this.select();
|
|
return true;
|
|
};
|
|
var CHoriStraightLineObject = create_class(CBiToolObject);
|
|
CHoriStraightLineObject.prototype.__construct = function (name) {
|
|
CHoriStraightLineObject.__super.__construct.call(this, name);
|
|
this.drawer = new DrawHoriStraightLinesPlotter(name, this);
|
|
};
|
|
CHoriStraightLineObject.prototype.setDrawPos = function (x, y) {
|
|
for (var index in this.points) {
|
|
this.points[index].setPosXY(x, y);
|
|
}
|
|
};
|
|
CHoriStraightLineObject.prototype.isSelected = function (x, y) {
|
|
if (CHoriStraightLineObject.__super.isSelected.call(this, x, y) == true)
|
|
return true;
|
|
var c = new CPoint("frame0.k0");
|
|
c.setPosXY(x, y);
|
|
var sy = this.getPoint(0).getPosXY().y;
|
|
if (y > sy + 4 || y < sy - 4)
|
|
return false;
|
|
this.select();
|
|
return true;
|
|
};
|
|
var CRayLineObject = create_class(CBiToolObject);
|
|
CRayLineObject.prototype.__construct = function (name) {
|
|
CRayLineObject.__super.__construct.call(this, name);
|
|
this.drawer = new DrawRayLinesPlotter(name, this);
|
|
};
|
|
CRayLineObject.prototype.isSelected = function (x, y) {
|
|
if (CRayLineObject.__super.isSelected.call(this, x, y) == true)
|
|
return true;
|
|
var c = new CPoint("frame0.k0");
|
|
c.setPosXY(x, y);
|
|
var sx = this.getPoint(0).getPosXY().x;
|
|
var ex = this.getPoint(1).getPosXY().x;
|
|
if (ex > sx && x < sx - 4)
|
|
return false;
|
|
if (ex < sx && x > sx + 4)
|
|
return false;
|
|
if (this.calcDistance(this.getPoint(0), this.getPoint(1), c) < 4) {
|
|
this.select();
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
var CSegLineObject = create_class(CBiToolObject);
|
|
CSegLineObject.prototype.__construct = function (name) {
|
|
CSegLineObject.__super.__construct.call(this, name);
|
|
this.drawer = new DrawSegLinesPlotter(name, this);
|
|
};
|
|
CSegLineObject.prototype.isSelected = function (x, y) {
|
|
if (CSegLineObject.__super.isSelected.call(this, x, y) == true)
|
|
return true;
|
|
var c = new CPoint("frame0.k0");
|
|
c.setPosXY(x, y);
|
|
if (this.isWithRect(this.getPoint(0), this.getPoint(1), c) == false)
|
|
return false;
|
|
if (this.calcDistance(this.getPoint(0), this.getPoint(1), c) < 4) {
|
|
this.select();
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
var CStraightLineObject = create_class(CBiToolObject);
|
|
CStraightLineObject.prototype.__construct = function (name) {
|
|
CStraightLineObject.__super.__construct.call(this, name);
|
|
this.drawer = new DrawStraightLinesPlotter(name, this);
|
|
};
|
|
CStraightLineObject.prototype.isSelected = function (x, y) {
|
|
if (CStraightLineObject.__super.isSelected.call(this, x, y) == true)
|
|
return true;
|
|
var c = new CPoint("frame0.k0");
|
|
c.setPosXY(x, y);
|
|
if (this.calcDistance(this.getPoint(0), this.getPoint(1), c) < 4) {
|
|
this.select();
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
var CTriParallelLineObject = create_class(CTriToolObject);
|
|
CTriParallelLineObject.prototype.__construct = function (name) {
|
|
CTriParallelLineObject.__super.__construct.call(this, name);
|
|
this.drawer = new DrawTriParallelLinesPlotter(name, this);
|
|
};
|
|
CTriParallelLineObject.prototype.isSelected = function (x, y) {
|
|
if (CTriParallelLineObject.__super.isSelected.call(this, x, y) == true)
|
|
return true;
|
|
var pObj = this.getChartObjects();
|
|
var _0x = this.getPoint(0).getPosXY().x;
|
|
var _0y = this.getPoint(0).getPosXY().y;
|
|
var _1x = this.getPoint(1).getPosXY().x;
|
|
var _1y = this.getPoint(1).getPosXY().y;
|
|
var _2x = this.getPoint(2).getPosXY().x;
|
|
var _2y = this.getPoint(2).getPosXY().y;
|
|
var _a = {x: _0x - _1x, y: _0y - _1y};
|
|
var _b = {x: _0x - _2x, y: _0y - _2y};
|
|
var _c = {x: _a.x + _b.x, y: _a.y + _b.y};
|
|
var _3x = _0x - _c.x;
|
|
var _3y = _0y - _c.y;
|
|
var r1 = {sx: _0x, sy: _0y, ex: _2x, ey: _2y};
|
|
var r2 = {sx: _1x, sy: _1y, ex: _3x, ey: _3y};
|
|
var _i = {x: _0x - _1x, y: _0y - _1y};
|
|
var _j = {x: _2x - _3x, y: _2y - _3y};
|
|
var _ri = {x: _1x - _0x, y: _1y - _0y};
|
|
var _rj = {x: _3x - _2x, y: _3y - _2y};
|
|
var _4x = Math.abs(_ri.x - _0x);
|
|
var _4y = Math.abs(_ri.y - _0y);
|
|
var _5x = Math.abs(_rj.x - _2x);
|
|
var _5y = Math.abs(_rj.y - _2y);
|
|
var r3 = {sx: _4x, sy: _4y, ex: _5x, ey: _5y};
|
|
if (this.calcGap(r1, x, y) > 4 &&
|
|
this.calcGap(r2, x, y) > 4 &&
|
|
this.calcGap(r3, x, y) > 4)
|
|
return false;
|
|
this.select();
|
|
return true;
|
|
};
|
|
var CVertiStraightLineObject = create_class(CBiToolObject);
|
|
CVertiStraightLineObject.prototype.__construct = function (name) {
|
|
CVertiStraightLineObject.__super.__construct.call(this, name);
|
|
this.drawer = new DrawVertiStraightLinesPlotter(name, this);
|
|
};
|
|
CVertiStraightLineObject.prototype.setDrawPos = function (x, y) {
|
|
for (var index in this.points) {
|
|
this.points[index].setPosXY(x, y);
|
|
}
|
|
};
|
|
CVertiStraightLineObject.prototype.isSelected = function (x, y) {
|
|
if (CVertiStraightLineObject.__super.isSelected.call(this, x, y) == true)
|
|
return true;
|
|
var c = new CPoint("frame0.k0");
|
|
c.setPosXY(x, y);
|
|
var sx = this.getPoint(0).getPosXY().x;
|
|
if (x > sx + 4 || x < sx - 4)
|
|
return false;
|
|
this.select();
|
|
return true;
|
|
};
|
|
var CPriceLineObject = create_class(CSegLineObject);
|
|
CPriceLineObject.prototype.__construct = function (name) {
|
|
CPriceLineObject.__super.__construct.call(this, name);
|
|
this.drawer = new DrawPriceLinesPlotter(name, this);
|
|
};
|
|
CPriceLineObject.prototype.setDrawPos = function (x, y) {
|
|
for (var index in this.points) {
|
|
this.points[index].setPosXY(x, y);
|
|
}
|
|
};
|
|
CPriceLineObject.prototype.isSelected = function (x, y) {
|
|
if (CFibRetraceObject.__super.isSelected.call(this, x, y) == true)
|
|
return true;
|
|
var c = new CPoint("frame0.k0");
|
|
c.setPosXY(x, y);
|
|
var sx = this.getPoint(0).getPosXY().x;
|
|
var sy = this.getPoint(0).getPosXY().y;
|
|
var ex = this.getPoint(1).getPosXY().x;
|
|
var ey = this.getPoint(1).getPosXY().y;
|
|
if (x < sx - 4)
|
|
return false;
|
|
if (y >= sy + 4 || y <= sy - 4)
|
|
return false;
|
|
this.select();
|
|
return true;
|
|
};
|
|
var CArrowLineObject = create_class(CSegLineObject);
|
|
CArrowLineObject.prototype.__construct = function (name) {
|
|
CArrowLineObject.__super.__construct.call(this, name);
|
|
this.drawer = new DrawArrowLinesPlotter(name, this);
|
|
};
|
|
var CToolManager = create_class(NamedObject);
|
|
CToolManager.prototype.__construct = function (name) {
|
|
CToolManager.__super.__construct.call(this, name);
|
|
this.selectedObject = -1;
|
|
this.toolObjects = [];
|
|
};
|
|
CToolManager.prototype.getToolObjectCount = function () {
|
|
return this.toolObjects.length;
|
|
};
|
|
CToolManager.prototype.addToolObject = function (o) {
|
|
this.toolObjects.push(o);
|
|
};
|
|
CToolManager.prototype.getToolObject = function (i) {
|
|
if (i < this.toolObjects.length && i >= 0)
|
|
return this.toolObjects[i];
|
|
return null;
|
|
};
|
|
CToolManager.prototype.getCurrentObject = function () {
|
|
return this.getToolObject(this.getToolObjectCount() - 1);
|
|
};
|
|
CToolManager.prototype.getSelectedObject = function () {
|
|
return this.getToolObject(this.selectedObject);
|
|
};
|
|
CToolManager.prototype.delCurrentObject = function () {
|
|
this.toolObjects.splice(this.getToolObjectCount() - 1, 1);
|
|
};
|
|
CToolManager.prototype.delSelectedObject = function () {
|
|
this.toolObjects.splice(this.selectedObject, 1);
|
|
this.selectedObject = -1;
|
|
};
|
|
CToolManager.prototype.acceptMouseMoveEvent = function (x, y) {
|
|
if (this.selectedObject == -1) {
|
|
var curr = this.toolObjects[this.getToolObjectCount() - 1];
|
|
if (curr != null && curr.getState() != CToolObject.state.AfterDraw)
|
|
return curr.acceptMouseMoveEvent(x, y);
|
|
} else {
|
|
var sel = this.toolObjects[this.selectedObject];
|
|
if (sel.getState() == CToolObject.state.Draw)
|
|
return sel.acceptMouseMoveEvent(x, y);
|
|
sel.unselect();
|
|
this.selectedObject = -1;
|
|
}
|
|
for (var index in this.toolObjects) {
|
|
if (this.toolObjects[index].isSelected(x, y)) {
|
|
this.selectedObject = index;
|
|
return false;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
CToolManager.prototype.acceptMouseDownEvent = function (x, y) {
|
|
this.mouseDownMove = false;
|
|
if (this.selectedObject == -1) {
|
|
var curr = this.toolObjects[this.getToolObjectCount() - 1];
|
|
if (curr != null && curr.getState() != CToolObject.state.AfterDraw)
|
|
return curr.acceptMouseDownEvent(x, y);
|
|
} else {
|
|
var sel = this.toolObjects[this.selectedObject];
|
|
if (sel.getState() != CToolObject.state.BeforeDraw)
|
|
return sel.acceptMouseDownEvent(x, y);
|
|
}
|
|
return false;
|
|
};
|
|
CToolManager.prototype.acceptMouseDownMoveEvent = function (x, y) {
|
|
this.mouseDownMove = true;
|
|
if (this.selectedObject == -1) {
|
|
var curr = this.toolObjects[this.getToolObjectCount() - 1];
|
|
if (curr != null && curr.getState() == CToolObject.state.Draw)
|
|
return curr.acceptMouseDownMoveEvent(x, y);
|
|
return false;
|
|
} else {
|
|
var sel = this.toolObjects[this.selectedObject];
|
|
if (sel.getState() != CToolObject.state.BeforeDraw) {
|
|
if (sel.acceptMouseDownMoveEvent(x, y) == true) {
|
|
var point = this.toolObjects[this.selectedObject].points;
|
|
for (var i = 0; i < point.length; i++) {
|
|
if (point[i].state == CPoint.state.Highlight || point[i].state == CPoint.state.Show) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
};
|
|
CToolManager.prototype.acceptMouseUpEvent = function (x, y) {
|
|
if (this.mouseDownMove == true) {
|
|
if (this.selectedObject == -1) {
|
|
var curr = this.toolObjects[this.getToolObjectCount() - 1];
|
|
if (curr != null && curr.getState() == CToolObject.state.Draw)
|
|
return curr.acceptMouseUpEvent(x, y);
|
|
return true;
|
|
} else {
|
|
var sel = this.toolObjects[this.selectedObject];
|
|
if (sel.getState() != CToolObject.state.BeforeDraw)
|
|
return sel.acceptMouseUpEvent(x, y);
|
|
}
|
|
}
|
|
if (this.selectedObject != -1) {
|
|
return true;
|
|
}
|
|
var curr = this.toolObjects[this.getToolObjectCount() - 1];
|
|
if (curr != null) {
|
|
if (curr.getState() == CToolObject.state.Draw)
|
|
return true;
|
|
if (!curr.isValidMouseXY(x, y)) {
|
|
return false;
|
|
}
|
|
if (curr.isSelected(x, y)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
var CToolPlotter = create_class(NamedObject);
|
|
CToolPlotter.prototype.__construct = function (name, toolObject) {
|
|
CToolPlotter.__super.__construct.call(this, name);
|
|
this.toolObject = toolObject;
|
|
var pMgr = ChartManager.getInstance();
|
|
var pArea = pMgr.getArea('frame0.k0.main');
|
|
if (pArea == null) {
|
|
this.areaPos = {
|
|
left: 0,
|
|
top: 0,
|
|
right: 0,
|
|
bottom: 0
|
|
};
|
|
return;
|
|
}
|
|
this.areaPos = {
|
|
left: pArea.getLeft(),
|
|
top: pArea.getTop(),
|
|
right: pArea.getRight(),
|
|
bottom: pArea.getBottom()
|
|
};
|
|
this.crossPt = {};
|
|
this.normalSize = 4;
|
|
this.selectedSize = 6;
|
|
this.cursorLen = 4;
|
|
this.cursorGapLen = 3;
|
|
this.theme = ChartManager.getInstance().getTheme(this.getFrameName());
|
|
};
|
|
CToolPlotter.prototype.drawCursor = function (context) {
|
|
this.drawCrossCursor(context);
|
|
};
|
|
CToolPlotter.prototype.drawCrossCursor = function (context) {
|
|
context.strokeStyle = this.theme.getColor(Theme.Color.LineColorNormal);
|
|
context.fillStyle = this.theme.getColor(Theme.Color.LineColorNormal);
|
|
var tempPt = this.toolObject.getPoint(0).getPosXY();
|
|
if (tempPt == null) {
|
|
return;
|
|
}
|
|
var x = tempPt.x;
|
|
var y = tempPt.y;
|
|
var cursorLen = this.cursorLen;
|
|
var cursorGapLen = this.cursorGapLen;
|
|
context.fillRect(x, y, 1, 1);
|
|
Plotter.drawLine(context, x - cursorLen - cursorGapLen, y, x - cursorGapLen, y);
|
|
Plotter.drawLine(context, x + cursorLen + cursorGapLen, y, x + cursorGapLen, y);
|
|
Plotter.drawLine(context, x, y - cursorLen - cursorGapLen, x, y - cursorGapLen);
|
|
Plotter.drawLine(context, x, y + cursorLen + cursorGapLen, x, y + cursorGapLen);
|
|
};
|
|
CToolPlotter.prototype.drawCircle = function (context, center, radius) {
|
|
var centerX = center.x;
|
|
var centerY = center.y;
|
|
context.beginPath();
|
|
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
|
|
context.fillStyle = this.theme.getColor(Theme.Color.CircleColorFill);
|
|
context.fill();
|
|
context.stroke();
|
|
};
|
|
CToolPlotter.prototype.drawCtrlPt = function (context) {
|
|
context.strokeStyle = this.theme.getColor(Theme.Color.CircleColorStroke);
|
|
for (var i = 0; i < this.ctrlPtsNum; i++) {
|
|
this.drawCircle(context, this.ctrlPts[1][i], this.normalSize);
|
|
}
|
|
};
|
|
CToolPlotter.prototype.highlightCtrlPt = function (context) {
|
|
context.strokeStyle = this.theme.getColor(Theme.Color.CircleColorStroke);
|
|
for (var i = 0; i < this.ctrlPtsNum; i++) {
|
|
if (this.toolObject.getPoint(i).getState() == CPoint.state.Highlight)
|
|
this.drawCircle(context, this.ctrlPts[1][i], this.selectedSize);
|
|
}
|
|
};
|
|
CToolPlotter.prototype.drawFibRayLines = function (context, startPoint, endPoint) {
|
|
for (var i = 0; i < this.fiboFansSequence.length; i++) {
|
|
var stageY = startPoint.y + (100 - this.fiboFansSequence[i]) / 100 * (endPoint.y - startPoint.y);
|
|
var tempStartPt = {x: startPoint.x, y: startPoint.y};
|
|
var tempEndPt = {x: endPoint.x, y: stageY};
|
|
this.drawRayLines(context, tempStartPt, tempEndPt);
|
|
}
|
|
};
|
|
CToolPlotter.prototype.drawRayLines = function (context, startPoint, endPoint) {
|
|
this.getAreaPos();
|
|
var tempStartPt = {x: startPoint.x, y: startPoint.y};
|
|
var tempEndPt = {x: endPoint.x, y: endPoint.y};
|
|
var crossPt = getRectCrossPt(this.areaPos, tempStartPt, tempEndPt);
|
|
var tempCrossPt;
|
|
if (endPoint.x == startPoint.x) {
|
|
if (endPoint.y == startPoint.y) {
|
|
tempCrossPt = endPoint;
|
|
} else {
|
|
tempCrossPt = endPoint.y > startPoint.y ? {x: crossPt[1].x, y: crossPt[1].y} : {
|
|
x: crossPt[0].x,
|
|
y: crossPt[0].y
|
|
};
|
|
}
|
|
} else {
|
|
tempCrossPt = endPoint.x > startPoint.x ? {x: crossPt[1].x, y: crossPt[1].y} : {
|
|
x: crossPt[0].x,
|
|
y: crossPt[0].y
|
|
};
|
|
}
|
|
Plotter.drawLine(context, startPoint.x, startPoint.y, tempCrossPt.x, tempCrossPt.y);
|
|
};
|
|
CToolPlotter.prototype.lenBetweenPts = function (pt1, pt2) {
|
|
return Math.sqrt(Math.pow((pt2.x - pt1.x), 2) + Math.pow((pt2.y - pt1.y), 2));
|
|
};
|
|
CToolPlotter.prototype.getCtrlPts = function () {
|
|
for (var i = 0; i < this.ctrlPtsNum; i++) {
|
|
this.ctrlPts[0][i] = this.toolObject.getPoint(i);
|
|
}
|
|
};
|
|
CToolPlotter.prototype.updateCtrlPtPos = function () {
|
|
for (var i = 0; i < this.ctrlPtsNum; i++) {
|
|
this.ctrlPts[1][i] = this.ctrlPts[0][i].getPosXY();
|
|
}
|
|
};
|
|
CToolPlotter.prototype.getAreaPos = function () {
|
|
var pMgr = ChartManager.getInstance();
|
|
var pArea = pMgr.getArea('frame0.k0.main');
|
|
if (pArea == null) {
|
|
this.areaPos = {
|
|
left: 0,
|
|
top: 0,
|
|
right: 0,
|
|
bottom: 0
|
|
};
|
|
return;
|
|
}
|
|
this.areaPos = {
|
|
left: Math.floor(pArea.getLeft()),
|
|
top: Math.floor(pArea.getTop()),
|
|
right: Math.floor(pArea.getRight()),
|
|
bottom: Math.floor(pArea.getBottom())
|
|
};
|
|
};
|
|
CToolPlotter.prototype.updateDraw = function (context) {
|
|
context.strokeStyle = this.theme.getColor(Theme.Color.LineColorNormal);
|
|
this.draw(context);
|
|
this.drawCtrlPt(context);
|
|
};
|
|
CToolPlotter.prototype.finishDraw = function (context) {
|
|
context.strokeStyle = this.theme.getColor(Theme.Color.LineColorNormal);
|
|
this.draw(context);
|
|
};
|
|
CToolPlotter.prototype.highlight = function (context) {
|
|
context.strokeStyle = this.theme.getColor(Theme.Color.LineColorSelected);
|
|
this.draw(context);
|
|
this.drawCtrlPt(context);
|
|
this.highlightCtrlPt(context);
|
|
};
|
|
var DrawStraightLinesPlotter = create_class(CToolPlotter);
|
|
DrawStraightLinesPlotter.prototype.__construct = function (name, toolObject) {
|
|
DrawStraightLinesPlotter.__super.__construct.call(this, name, toolObject);
|
|
this.toolObject = toolObject;
|
|
this.ctrlPtsNum = 2;
|
|
this.ctrlPts = new Array(new Array(this.ctrlPtsNum), new Array(2));
|
|
this.getCtrlPts();
|
|
};
|
|
DrawStraightLinesPlotter.prototype.draw = function (context) {
|
|
this.updateCtrlPtPos();
|
|
this.getAreaPos();
|
|
this.startPoint = this.ctrlPts[1][0];
|
|
this.endPoint = this.ctrlPts[1][1];
|
|
if (this.startPoint.x == this.endPoint.x && this.startPoint.y == this.endPoint.y) {
|
|
Plotter.drawLine(context, this.areaPos.left, this.startPoint.y, this.areaPos.right, this.startPoint.y);
|
|
} else {
|
|
this.crossPt = getRectCrossPt(this.areaPos, this.startPoint, this.endPoint);
|
|
Plotter.drawLine(context, this.crossPt[0].x, this.crossPt[0].y, this.crossPt[1].x, this.crossPt[1].y);
|
|
}
|
|
};
|
|
var DrawSegLinesPlotter = create_class(CToolPlotter);
|
|
DrawSegLinesPlotter.prototype.__construct = function (name, toolObject) {
|
|
DrawSegLinesPlotter.__super.__construct.call(this, name, toolObject);
|
|
this.toolObject = toolObject;
|
|
this.ctrlPtsNum = 2;
|
|
this.ctrlPts = new Array(new Array(this.ctrlPtsNum), new Array(2));
|
|
this.getCtrlPts();
|
|
};
|
|
DrawSegLinesPlotter.prototype.draw = function (context) {
|
|
this.updateCtrlPtPos();
|
|
this.startPoint = this.ctrlPts[1][0];
|
|
this.endPoint = this.ctrlPts[1][1];
|
|
if (this.startPoint.x == this.endPoint.x && this.startPoint.y == this.endPoint.y) {
|
|
this.endPoint.x += 1;
|
|
}
|
|
Plotter.drawLine(context, this.startPoint.x, this.startPoint.y, this.endPoint.x, this.endPoint.y);
|
|
};
|
|
var DrawRayLinesPlotter = create_class(CToolPlotter);
|
|
DrawRayLinesPlotter.prototype.__construct = function (name, toolObject) {
|
|
DrawRayLinesPlotter.__super.__construct.call(this, name);
|
|
this.toolObject = toolObject;
|
|
this.ctrlPtsNum = 2;
|
|
this.ctrlPts = new Array(new Array(this.ctrlPtsNum), new Array(2));
|
|
this.getCtrlPts();
|
|
};
|
|
DrawRayLinesPlotter.prototype.draw = function (context) {
|
|
this.updateCtrlPtPos();
|
|
this.getAreaPos();
|
|
this.startPoint = this.ctrlPts[1][0];
|
|
this.endPoint = this.ctrlPts[1][1];
|
|
if (this.startPoint.x == this.endPoint.x && this.startPoint.y == this.endPoint.y) {
|
|
this.endPoint.x += 1;
|
|
}
|
|
this.drawRayLines(context, this.startPoint, this.endPoint);
|
|
};
|
|
var DrawArrowLinesPlotter = create_class(CToolPlotter);
|
|
DrawArrowLinesPlotter.prototype.__construct = function (name, toolObject) {
|
|
DrawArrowLinesPlotter.__super.__construct.call(this, name, toolObject);
|
|
this.toolObject = toolObject;
|
|
this.arrowSizeRatio = 0.03;
|
|
this.arrowSize = 4;
|
|
this.crossPt = {x: -1, y: -1};
|
|
this.ctrlPtsNum = 2;
|
|
this.ctrlPts = new Array(new Array(this.ctrlPtsNum), new Array(2));
|
|
this.getCtrlPts();
|
|
};
|
|
DrawArrowLinesPlotter.prototype.drawArrow = function (context, startPoint, endPoint) {
|
|
var len = this.lenBetweenPts(startPoint, endPoint);
|
|
var vectorA = [endPoint.x - startPoint.x, endPoint.y - startPoint.y];
|
|
this.crossPt.x = startPoint.x + (1 - this.arrowSize / len) * vectorA[0];
|
|
this.crossPt.y = startPoint.y + (1 - this.arrowSize / len) * vectorA[1];
|
|
var vectorAautho = [-vectorA[1], vectorA[0]];
|
|
var Aautho = {x: vectorAautho[0], y: vectorAautho[1]};
|
|
var origin = {x: 0, y: 0};
|
|
vectorAautho[0] = this.arrowSize * Aautho.x / this.lenBetweenPts(Aautho, origin);
|
|
vectorAautho[1] = this.arrowSize * Aautho.y / this.lenBetweenPts(Aautho, origin);
|
|
var arrowEndPt = [this.crossPt.x + vectorAautho[0], this.crossPt.y + vectorAautho[1]];
|
|
Plotter.drawLine(context, endPoint.x, endPoint.y, arrowEndPt[0], arrowEndPt[1]);
|
|
arrowEndPt = [this.crossPt.x - vectorAautho[0], this.crossPt.y - vectorAautho[1]];
|
|
Plotter.drawLine(context, endPoint.x, endPoint.y, arrowEndPt[0], arrowEndPt[1]);
|
|
};
|
|
DrawArrowLinesPlotter.prototype.draw = function (context) {
|
|
this.updateCtrlPtPos();
|
|
this.startPoint = this.ctrlPts[1][0];
|
|
this.endPoint = this.ctrlPts[1][1];
|
|
if (this.startPoint.x == this.endPoint.x && this.startPoint.y == this.endPoint.y) {
|
|
this.endPoint.x += 1;
|
|
}
|
|
Plotter.drawLine(context, this.startPoint.x, this.startPoint.y, this.endPoint.x, this.endPoint.y);
|
|
this.drawArrow(context, this.startPoint, this.endPoint);
|
|
};
|
|
var DrawHoriStraightLinesPlotter = create_class(CToolPlotter);
|
|
DrawHoriStraightLinesPlotter.prototype.__construct = function (name, toolObject) {
|
|
DrawHoriStraightLinesPlotter.__super.__construct.call(this, name);
|
|
this.toolObject = toolObject;
|
|
this.ctrlPtsNum = 1;
|
|
this.ctrlPts = new Array(new Array(this.ctrlPtsNum), new Array(2));
|
|
this.getCtrlPts();
|
|
};
|
|
DrawHoriStraightLinesPlotter.prototype.draw = function (context) {
|
|
this.updateCtrlPtPos();
|
|
this.getAreaPos();
|
|
this.startPoint = this.ctrlPts[1][0];
|
|
Plotter.drawLine(context, this.areaPos.left, this.startPoint.y, this.areaPos.right, this.startPoint.y);
|
|
};
|
|
var DrawHoriRayLinesPlotter = create_class(CToolPlotter);
|
|
DrawHoriRayLinesPlotter.prototype.__construct = function (name, toolObject) {
|
|
DrawHoriRayLinesPlotter.__super.__construct.call(this, name);
|
|
this.toolObject = toolObject;
|
|
this.ctrlPtsNum = 2;
|
|
this.ctrlPts = new Array(new Array(this.ctrlPtsNum), new Array(2));
|
|
this.getCtrlPts();
|
|
};
|
|
DrawHoriRayLinesPlotter.prototype.draw = function (context) {
|
|
this.updateCtrlPtPos();
|
|
this.getAreaPos();
|
|
this.startPoint = this.ctrlPts[1][0];
|
|
this.endPoint = this.ctrlPts[1][1];
|
|
if (this.startPoint.x == this.endPoint.x) {
|
|
Plotter.drawLine(context, this.startPoint.x, this.startPoint.y, this.areaPos.right, this.startPoint.y);
|
|
} else {
|
|
var tempEndPt = {x: this.endPoint.x, y: this.startPoint.y};
|
|
this.drawRayLines(context, this.startPoint, tempEndPt);
|
|
}
|
|
};
|
|
var DrawHoriSegLinesPlotter = create_class(CToolPlotter);
|
|
DrawHoriSegLinesPlotter.prototype.__construct = function (name, toolObject) {
|
|
DrawHoriSegLinesPlotter.__super.__construct.call(this, name, toolObject);
|
|
this.toolObject = toolObject;
|
|
this.ctrlPtsNum = 2;
|
|
this.ctrlPts = new Array(new Array(this.ctrlPtsNum), new Array(2));
|
|
this.getCtrlPts();
|
|
};
|
|
DrawHoriSegLinesPlotter.prototype.draw = function (context) {
|
|
this.updateCtrlPtPos();
|
|
this.startPoint = this.ctrlPts[1][0];
|
|
this.endPoint = this.ctrlPts[1][1];
|
|
this.endPoint.y = this.startPoint.y;
|
|
if (this.startPoint.x == this.endPoint.x && this.startPoint.y == this.endPoint.y) {
|
|
Plotter.drawLine(context, this.startPoint.x, this.startPoint.y, this.endPoint.x + 1, this.startPoint.y);
|
|
} else {
|
|
Plotter.drawLine(context, this.startPoint.x, this.startPoint.y, this.endPoint.x, this.startPoint.y);
|
|
}
|
|
};
|
|
var DrawVertiStraightLinesPlotter = create_class(CToolPlotter);
|
|
DrawVertiStraightLinesPlotter.prototype.__construct = function (name, toolObject) {
|
|
DrawVertiStraightLinesPlotter.__super.__construct.call(this, name);
|
|
this.toolObject = toolObject;
|
|
this.ctrlPtsNum = 1;
|
|
this.ctrlPts = new Array(new Array(this.ctrlPtsNum), new Array(2));
|
|
this.getCtrlPts();
|
|
};
|
|
DrawVertiStraightLinesPlotter.prototype.draw = function (context) {
|
|
this.updateCtrlPtPos();
|
|
this.getAreaPos();
|
|
this.startPoint = this.ctrlPts[1][0];
|
|
Plotter.drawLine(context, this.startPoint.x, this.areaPos.top, this.startPoint.x, this.areaPos.bottom);
|
|
};
|
|
var DrawPriceLinesPlotter = create_class(CToolPlotter);
|
|
DrawPriceLinesPlotter.prototype.__construct = function (name, toolObject) {
|
|
DrawPriceLinesPlotter.__super.__construct.call(this, name);
|
|
this.toolObject = toolObject;
|
|
this.ctrlPtsNum = 1;
|
|
this.ctrlPts = new Array(new Array(this.ctrlPtsNum), new Array(2));
|
|
this.getCtrlPts();
|
|
};
|
|
DrawPriceLinesPlotter.prototype.draw = function (context) {
|
|
context.font = "12px Tahoma";
|
|
context.textAlign = "left";
|
|
context.fillStyle = this.theme.getColor(Theme.Color.LineColorNormal);
|
|
this.updateCtrlPtPos();
|
|
this.getAreaPos();
|
|
this.startPoint = this.ctrlPts[1][0];
|
|
var text = this.ctrlPts[0][0].getPosIV().v;
|
|
Plotter.drawLine(context, this.startPoint.x, this.startPoint.y, this.areaPos.right, this.startPoint.y);
|
|
context.fillText(text.toFixed(2), this.startPoint.x + 2, this.startPoint.y - 15);
|
|
};
|
|
var ParallelLinesPlotter = create_class(CToolPlotter);
|
|
ParallelLinesPlotter.prototype.__construct = function (name, toolObject) {
|
|
ParallelLinesPlotter.__super.__construct.call(this, name);
|
|
this.toolObject = toolObject;
|
|
};
|
|
ParallelLinesPlotter.prototype.getParaPt = function () {
|
|
var vectorA = [];
|
|
vectorA[0] = this.endPoint.x - this.startPoint.x;
|
|
vectorA[1] = this.endPoint.y - this.startPoint.y;
|
|
var vectorB = [];
|
|
vectorB[0] = this.paraStartPoint.x - this.startPoint.x;
|
|
vectorB[1] = this.paraStartPoint.y - this.startPoint.y;
|
|
this.paraEndPoint = {x: -1, y: -1};
|
|
this.paraEndPoint.x = vectorA[0] + vectorB[0] + this.startPoint.x;
|
|
this.paraEndPoint.y = vectorA[1] + vectorB[1] + this.startPoint.y;
|
|
};
|
|
var DrawBiParallelLinesPlotter = create_class(ParallelLinesPlotter);
|
|
DrawBiParallelLinesPlotter.prototype.__construct = function (name, toolObject) {
|
|
DrawBiParallelLinesPlotter.__super.__construct.call(this, name, toolObject);
|
|
this.toolObject = toolObject;
|
|
this.ctrlPtsNum = 3;
|
|
this.ctrlPts = new Array(new Array(this.ctrlPtsNum), new Array(2));
|
|
this.getCtrlPts();
|
|
};
|
|
DrawBiParallelLinesPlotter.prototype.draw = function (context) {
|
|
this.updateCtrlPtPos();
|
|
this.getAreaPos();
|
|
this.startPoint = this.ctrlPts[1][0];
|
|
this.paraStartPoint = this.ctrlPts[1][1];
|
|
this.endPoint = this.ctrlPts[1][2];
|
|
this.getParaPt();
|
|
this.getAreaPos();
|
|
this.crossPt0 = getRectCrossPt(this.areaPos, this.startPoint, this.endPoint);
|
|
Plotter.drawLine(context, this.crossPt0[0].x, this.crossPt0[0].y, this.crossPt0[1].x, this.crossPt0[1].y);
|
|
this.crossPt1 = getRectCrossPt(this.areaPos, this.paraStartPoint, this.paraEndPoint);
|
|
Plotter.drawLine(context, this.crossPt1[0].x, this.crossPt1[0].y, this.crossPt1[1].x, this.crossPt1[1].y);
|
|
};
|
|
var DrawBiParallelRayLinesPlotter = create_class(ParallelLinesPlotter);
|
|
DrawBiParallelRayLinesPlotter.prototype.__construct = function (name, toolObject) {
|
|
DrawBiParallelRayLinesPlotter.__super.__construct.call(this, name, toolObject);
|
|
this.toolObject = toolObject;
|
|
this.ctrlPtsNum = 3;
|
|
this.ctrlPts = new Array(new Array(this.ctrlPtsNum), new Array(2));
|
|
this.getCtrlPts();
|
|
};
|
|
DrawBiParallelRayLinesPlotter.prototype.draw = function (context) {
|
|
this.updateCtrlPtPos();
|
|
this.getAreaPos();
|
|
this.startPoint = this.ctrlPts[1][0];
|
|
this.paraStartPoint = this.ctrlPts[1][1];
|
|
this.endPoint = this.ctrlPts[1][2];
|
|
if (this.startPoint.x == this.endPoint.x && this.startPoint.y == this.endPoint.y) {
|
|
this.endPoint.x += 1;
|
|
}
|
|
this.getParaPt();
|
|
this.drawRayLines(context, this.startPoint, this.endPoint);
|
|
this.drawRayLines(context, this.paraStartPoint, this.paraEndPoint);
|
|
};
|
|
var DrawTriParallelLinesPlotter = create_class(ParallelLinesPlotter);
|
|
DrawTriParallelLinesPlotter.prototype.__construct = function (name, toolObject) {
|
|
DrawTriParallelLinesPlotter.__super.__construct.call(this, name, toolObject);
|
|
this.toolObject = toolObject;
|
|
this.ctrlPtsNum = 3;
|
|
this.ctrlPts = new Array(new Array(this.ctrlPtsNum), new Array(2));
|
|
this.getCtrlPts();
|
|
};
|
|
DrawTriParallelLinesPlotter.prototype.draw = function (context) {
|
|
this.updateCtrlPtPos();
|
|
this.getAreaPos();
|
|
this.startPoint = this.ctrlPts[1][0];
|
|
this.paraStartPoint = this.ctrlPts[1][1];
|
|
this.endPoint = this.ctrlPts[1][2];
|
|
var vectorA = [];
|
|
vectorA[0] = this.endPoint.x - this.startPoint.x;
|
|
vectorA[1] = this.endPoint.y - this.startPoint.y;
|
|
var vectorB = [];
|
|
vectorB[0] = this.paraStartPoint.x - this.startPoint.x;
|
|
vectorB[1] = this.paraStartPoint.y - this.startPoint.y;
|
|
this.para1EndPoint = {x: -1, y: -1};
|
|
this.para2EndPoint = {x: -1, y: -1};
|
|
this.para2StartPoint = {x: -1, y: -1};
|
|
this.para1EndPoint.x = vectorA[0] + vectorB[0] + this.startPoint.x;
|
|
this.para1EndPoint.y = vectorA[1] + vectorB[1] + this.startPoint.y;
|
|
this.para2StartPoint.x = this.startPoint.x - vectorB[0];
|
|
this.para2StartPoint.y = this.startPoint.y - vectorB[1];
|
|
this.para2EndPoint.x = this.endPoint.x - vectorB[0];
|
|
this.para2EndPoint.y = this.endPoint.y - vectorB[1];
|
|
this.getAreaPos();
|
|
this.crossPt0 = getRectCrossPt(this.areaPos, this.startPoint, this.endPoint);
|
|
Plotter.drawLine(context, this.crossPt0[0].x, this.crossPt0[0].y, this.crossPt0[1].x, this.crossPt0[1].y);
|
|
this.crossPt1 = getRectCrossPt(this.areaPos, this.paraStartPoint, this.para1EndPoint);
|
|
Plotter.drawLine(context, this.crossPt1[0].x, this.crossPt1[0].y, this.crossPt1[1].x, this.crossPt1[1].y);
|
|
this.crossPt2 = getRectCrossPt(this.areaPos, this.para2StartPoint, this.para2EndPoint);
|
|
Plotter.drawLine(context, this.crossPt2[0].x, this.crossPt2[0].y, this.crossPt2[1].x, this.crossPt2[1].y);
|
|
};
|
|
var BandLinesPlotter = create_class(CToolPlotter);
|
|
BandLinesPlotter.prototype.__construct = function (name, toolObject) {
|
|
BandLinesPlotter.__super.__construct.call(this, name);
|
|
this.toolObject = toolObject;
|
|
this.ctrlPtsNum = 2;
|
|
this.ctrlPts = new Array(new Array(this.ctrlPtsNum), new Array(2));
|
|
this.getCtrlPts();
|
|
};
|
|
BandLinesPlotter.prototype.drawLinesAndInfo = function (context, startPoint, endPoint) {
|
|
context.font = "12px Tahoma";
|
|
context.textAlign = "left";
|
|
context.fillStyle = this.theme.getColor(Theme.Color.LineColorNormal);
|
|
var text;
|
|
if (this.toolObject.state == CToolObject.state.Draw) {
|
|
this.startPtValue = this.toolObject.getPoint(0).getPosIV().v;
|
|
this.endPtValue = this.toolObject.getPoint(1).getPosIV().v;
|
|
}
|
|
this.getAreaPos();
|
|
for (var i = 0; i < this.fiboSequence.length; i++) {
|
|
var stageY = startPoint.y + (100 - this.fiboSequence[i]) / 100 * (endPoint.y - startPoint.y);
|
|
if (stageY > this.areaPos.bottom)
|
|
continue;
|
|
var stageYvalue = this.startPtValue + (100 - this.fiboSequence[i]) / 100 * (this.endPtValue - this.startPtValue);
|
|
Plotter.drawLine(context, this.areaPos.left, stageY, this.areaPos.right, stageY);
|
|
text = this.fiboSequence[i].toFixed(1) + '% ' + stageYvalue.toFixed(1);
|
|
context.fillText(text, this.areaPos.left + 2, stageY - 15);
|
|
}
|
|
};
|
|
BandLinesPlotter.prototype.draw = function (context) {
|
|
this.updateCtrlPtPos();
|
|
this.getAreaPos();
|
|
this.startPoint = this.ctrlPts[1][0];
|
|
this.endPoint = this.ctrlPts[1][1];
|
|
this.drawLinesAndInfo(context, this.startPoint, this.endPoint);
|
|
};
|
|
var DrawFibRetracePlotter = create_class(BandLinesPlotter);
|
|
DrawFibRetracePlotter.prototype.__construct = function (name, toolObject) {
|
|
DrawFibRetracePlotter.__super.__construct.call(this, name, toolObject);
|
|
this.toolObject = toolObject;
|
|
this.fiboSequence = [100.0, 78.6, 61.8, 50.0, 38.2, 23.6, 0.0];
|
|
};
|
|
var DrawBandLinesPlotter = create_class(BandLinesPlotter);
|
|
DrawBandLinesPlotter.prototype.__construct = function (name, toolObject) {
|
|
DrawBandLinesPlotter.__super.__construct.call(this, name, toolObject);
|
|
this.toolObject = toolObject;
|
|
this.fiboSequence = [0, 12.5, 25, 37.5, 50, 62.5, 75, 87.5, 100];
|
|
};
|
|
var DrawFibFansPlotter = create_class(CToolPlotter);
|
|
DrawFibFansPlotter.prototype.__construct = function (name, toolObject) {
|
|
DrawFibFansPlotter.__super.__construct.call(this, name);
|
|
this.toolObject = toolObject;
|
|
this.fiboFansSequence = [0, 38.2, 50, 61.8];
|
|
this.ctrlPtsNum = 2;
|
|
this.ctrlPts = new Array(new Array(this.ctrlPtsNum), new Array(2));
|
|
this.getCtrlPts();
|
|
};
|
|
DrawFibFansPlotter.prototype.drawLinesAndInfo = function (context, startPoint, endPoint) {
|
|
this.drawFibRayLines(context, startPoint, endPoint);
|
|
};
|
|
DrawFibFansPlotter.prototype.draw = function (context) {
|
|
this.updateCtrlPtPos();
|
|
this.getAreaPos();
|
|
this.startPoint = this.ctrlPts[1][0];
|
|
this.endPoint = this.ctrlPts[1][1];
|
|
if (this.startPoint.x == this.endPoint.x && this.startPoint.y == this.endPoint.y) {
|
|
this.endPoint.x += 1;
|
|
}
|
|
this.drawLinesAndInfo(context, this.startPoint, this.endPoint);
|
|
};
|
|
var CDynamicLinePlotter = create_class(NamedObject);
|
|
CDynamicLinePlotter.prototype.__construct = function (name) {
|
|
CDynamicLinePlotter.__super.__construct.call(this, name);
|
|
this.flag = true;
|
|
this.context = ChartManager.getInstance()._overlayContext;
|
|
};
|
|
CDynamicLinePlotter.prototype.getAreaPos = function () {
|
|
var pMgr = ChartManager.getInstance();
|
|
var pArea = pMgr.getArea('frame0.k0.main');
|
|
if (pArea == null) {
|
|
this.areaPos = {
|
|
left: 0,
|
|
top: 0,
|
|
right: 0,
|
|
bottom: 0
|
|
};
|
|
return;
|
|
}
|
|
this.areaPos = {
|
|
left: Math.floor(pArea.getLeft()),
|
|
top: Math.floor(pArea.getTop()),
|
|
right: Math.floor(pArea.getRight()),
|
|
bottom: Math.floor(pArea.getBottom())
|
|
};
|
|
};
|
|
CDynamicLinePlotter.prototype.Draw = function (context) {
|
|
this.getAreaPos();
|
|
var pMgr = ChartManager.getInstance();
|
|
var pTDP = pMgr.getDataSource(this.getDataSourceName());
|
|
if (pTDP == null || !is_instance(pTDP, MainDataSource))
|
|
return;
|
|
this.context.save();
|
|
this.context.rect(this.areaPos.left, this.areaPos.top, this.areaPos.right - this.areaPos.left, this.areaPos.bottom - this.areaPos.top);
|
|
this.context.clip();
|
|
var count = pTDP.getToolObjectCount();
|
|
for (var i = 0; i < count; i++) {
|
|
var toolObject = pTDP.getToolObject(i);
|
|
var state = toolObject.getState();
|
|
switch (state) {
|
|
case CToolObject.state.BeforeDraw:
|
|
toolObject.getPlotter().theme = ChartManager.getInstance().getTheme(this.getFrameName());
|
|
toolObject.getPlotter().drawCursor(this.context);
|
|
break;
|
|
case CToolObject.state.Draw:
|
|
toolObject.getPlotter().theme = ChartManager.getInstance().getTheme(this.getFrameName());
|
|
toolObject.getPlotter().updateDraw(this.context);
|
|
break;
|
|
case CToolObject.state.AfterDraw:
|
|
toolObject.getPlotter().theme = ChartManager.getInstance().getTheme(this.getFrameName());
|
|
toolObject.getPlotter().finishDraw(this.context);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
var sel = pTDP.getSelectToolObjcet();
|
|
if (sel != null && sel != CToolObject.state.Draw)
|
|
sel.getPlotter().highlight(this.context);
|
|
this.context.restore();
|
|
return;
|
|
};
|
|
|
|
var isSize = false;
|
|
$('body').on('click', '#sizeIcon', function () {
|
|
isSize = !isSize;
|
|
if (isSize) {
|
|
$(KlineIns.element).css({
|
|
position: 'fixed',
|
|
left: '0',
|
|
right: '0',
|
|
top: '0',
|
|
bottom: '0',
|
|
width: '100%',
|
|
height: '100%',
|
|
zIndex: '10000'
|
|
});
|
|
on_size();
|
|
$('html,body').css({width: '100%', height: '100%', overflow: 'hidden'});
|
|
} else {
|
|
$(KlineIns.element).attr('style', '');
|
|
|
|
$('html,body').attr('style', '');
|
|
|
|
on_size(KlineIns.width, KlineIns.height);
|
|
$(KlineIns.element).css({visibility: 'visible', height: KlineIns.height + 'px'});
|
|
}
|
|
});
|
|
|
|
function KLineMouseEvent() {
|
|
$(document).ready(function () {
|
|
function __resize() {
|
|
if (navigator.userAgent.indexOf('Firefox') >= 0) {
|
|
setTimeout(function () {
|
|
on_size(KlineIns.width, KlineIns.height)
|
|
}, 200);
|
|
} else {
|
|
on_size(KlineIns.width, KlineIns.height);
|
|
}
|
|
}
|
|
|
|
$('#chart_overlayCanvas').bind("contextmenu", function (e) {
|
|
e.cancelBubble = true;
|
|
e.returnValue = false;
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
return false;
|
|
});
|
|
$(".chart_container .chart_dropdown .chart_dropdown_t")
|
|
.mouseover(function () {
|
|
var container = $(".chart_container");
|
|
var title = $(this);
|
|
var dropdown = title.next();
|
|
var containerLeft = container.offset().left;
|
|
var titleLeft = title.offset().left;
|
|
var containerWidth = container.width();
|
|
var titleWidth = title.width();
|
|
var dropdownWidth = dropdown.width();
|
|
var d = ((dropdownWidth - titleWidth) / 2) << 0;
|
|
if (titleLeft - d < containerLeft + 4) {
|
|
d = titleLeft - containerLeft - 4;
|
|
} else if (titleLeft + titleWidth + d > containerLeft + containerWidth - 4) {
|
|
d += titleLeft + titleWidth + d - (containerLeft + containerWidth - 4) + 19;
|
|
} else {
|
|
d += 4;
|
|
}
|
|
dropdown.css({"margin-left": -d});
|
|
title.addClass("chart_dropdown-hover");
|
|
dropdown.addClass("chart_dropdown-hover");
|
|
})
|
|
.mouseout(function () {
|
|
$(this).next().removeClass("chart_dropdown-hover");
|
|
$(this).removeClass("chart_dropdown-hover");
|
|
});
|
|
$(".chart_dropdown_data")
|
|
.mouseover(function () {
|
|
$(this).addClass("chart_dropdown-hover");
|
|
$(this).prev().addClass("chart_dropdown-hover");
|
|
})
|
|
.mouseout(function () {
|
|
$(this).prev().removeClass("chart_dropdown-hover");
|
|
$(this).removeClass("chart_dropdown-hover");
|
|
});
|
|
$("#chart_btn_parameter_settings").click(function () {
|
|
$('#chart_parameter_settings').addClass("clicked");
|
|
$(".chart_dropdown_data").removeClass("chart_dropdown-hover");
|
|
$("#chart_parameter_settings").find("th").each(function () {
|
|
var name = $(this).html();
|
|
var index = 0;
|
|
var tmp = ChartSettings.get();
|
|
var value = tmp.indics[name];
|
|
$(this.nextElementSibling).find("input").each(function () {
|
|
if (value != null && index < value.length) {
|
|
$(this).val(value[index]);
|
|
}
|
|
index++;
|
|
});
|
|
});
|
|
});
|
|
$("#close_settings").click(function () {
|
|
$('#chart_parameter_settings').removeClass("clicked");
|
|
});
|
|
$(".chart_container .chart_toolbar_tabgroup a")
|
|
.click(function () {
|
|
switch_period($(this).parent().attr('name'));
|
|
|
|
});
|
|
$("#chart_toolbar_periods_vert ul a").click(function () {
|
|
|
|
switch_period($(this).parent().attr('name'));
|
|
|
|
});
|
|
|
|
$(".market_chooser ul a").click(function () {
|
|
switch_symbol($(this).attr('name'));
|
|
});
|
|
|
|
$('#chart_show_tools')
|
|
.click(function () {
|
|
if ($(this).hasClass('selected')) {
|
|
switch_tools('off');
|
|
} else {
|
|
switch_tools('on');
|
|
}
|
|
});
|
|
$("#chart_toolpanel .chart_toolpanel_button")
|
|
.click(function () {
|
|
$(".chart_dropdown_data").removeClass("chart_dropdown-hover");
|
|
$("#chart_toolpanel .chart_toolpanel_button").removeClass("selected");
|
|
$(this).addClass("selected");
|
|
var name = $(this).children().attr('name');
|
|
KlineIns.chartMgr.setRunningMode(ChartManager.DrawingTool[name]);
|
|
});
|
|
$('#chart_show_indicator')
|
|
.click(function () {
|
|
if ($(this).hasClass('selected')) {
|
|
switch_indic('off');
|
|
} else {
|
|
switch_indic('on');
|
|
}
|
|
});
|
|
$("#chart_tabbar li a")
|
|
.click(function () {
|
|
$("#chart_tabbar li a").removeClass('selected');
|
|
$(this).addClass('selected');
|
|
var name = $(this).attr('name');
|
|
var tmp = ChartSettings.get();
|
|
tmp.charts.indics[1] = name;
|
|
ChartSettings.save();
|
|
if (Template.displayVolume == false)
|
|
ChartManager.getInstance().getChart().setIndicator(1, name);
|
|
else
|
|
ChartManager.getInstance().getChart().setIndicator(2, name);
|
|
});
|
|
$("#chart_select_chart_style a")
|
|
.click(function () {
|
|
$("#chart_select_chart_style a").removeClass('selected');
|
|
$(this).addClass("selected");
|
|
var tmp = ChartSettings.get();
|
|
tmp.charts.chartStyle = $(this)[0].innerHTML;
|
|
ChartSettings.save();
|
|
var mgr = ChartManager.getInstance();
|
|
mgr.setChartStyle("frame0.k0", $(this).html());
|
|
mgr.redraw();
|
|
});
|
|
$('#chart_dropdown_themes li').click(function () {
|
|
$('#chart_dropdown_themes li a').removeClass('selected');
|
|
var name = $(this).attr('name');
|
|
if (name == 'chart_themes_dark') {
|
|
switch_theme('dark');
|
|
} else if (name == 'chart_themes_light') {
|
|
switch_theme('light');
|
|
}
|
|
});
|
|
$("#chart_select_main_indicator a")
|
|
.click(function () {
|
|
$("#chart_select_main_indicator a").removeClass('selected');
|
|
$(this).addClass("selected");
|
|
var name = $(this).attr('name');
|
|
var tmp = ChartSettings.get();
|
|
tmp.charts.mIndic = name;
|
|
ChartSettings.save();
|
|
var mgr = ChartManager.getInstance();
|
|
if (!mgr.setMainIndicator("frame0.k0", name))
|
|
mgr.removeMainIndicator("frame0.k0");
|
|
mgr.redraw();
|
|
});
|
|
$('#chart_toolbar_theme a').click(function () {
|
|
$('#chart_toolbar_theme a').removeClass('selected');
|
|
if ($(this).attr('name') == 'dark') {
|
|
switch_theme('dark');
|
|
} else if ($(this).attr('name') == 'light') {
|
|
switch_theme('light');
|
|
}
|
|
});
|
|
$('#chart_select_theme li a').click(function () {
|
|
$('#chart_select_theme a').removeClass('selected');
|
|
if ($(this).attr('name') == 'dark') {
|
|
switch_theme('dark');
|
|
} else if ($(this).attr('name') == 'light') {
|
|
switch_theme('light');
|
|
}
|
|
});
|
|
$('#chart_enable_tools li a').click(function () {
|
|
$('#chart_enable_tools a').removeClass('selected');
|
|
if ($(this).attr('name') == 'on') {
|
|
switch_tools('on');
|
|
} else if ($(this).attr('name') == 'off') {
|
|
switch_tools('off');
|
|
}
|
|
});
|
|
$('#chart_enable_indicator li a').click(function () {
|
|
$('#chart_enable_indicator a').removeClass('selected');
|
|
if ($(this).attr('name') == 'on') {
|
|
switch_indic('on');
|
|
} else if ($(this).attr('name') == 'off') {
|
|
switch_indic('off');
|
|
}
|
|
});
|
|
$('#chart_language_setting_div li a').click(function () {
|
|
|
|
$('#chart_language_setting_div a').removeClass('selected');
|
|
if ($(this).attr('name') == 'zh-cn') {
|
|
chart_switch_language('zh-cn');
|
|
} else if ($(this).attr('name') == 'en-us') {
|
|
|
|
chart_switch_language('en-us');
|
|
} else if ($(this).attr('name') == 'zh-tw') {
|
|
chart_switch_language('zh-tw');
|
|
}
|
|
});
|
|
$(document).keyup(function (e) {
|
|
if (e.keyCode == 46) {
|
|
ChartManager.getInstance().deleteToolObject();
|
|
ChartManager.getInstance().redraw('OverlayCanvas', false);
|
|
}
|
|
});
|
|
$("#clearCanvas").click(function () {
|
|
var pDPTool = ChartManager.getInstance().getDataSource("frame0.k0");
|
|
var len = pDPTool.getToolObjectCount();
|
|
for (var i = 0; i < len; i++) {
|
|
pDPTool.delToolObject();
|
|
}
|
|
ChartManager.getInstance().redraw('OverlayCanvas', false);
|
|
});
|
|
$("#chart_overlayCanvas")
|
|
.mousemove(function (e) {
|
|
var r = e.target.getBoundingClientRect();
|
|
var x = e.clientX - r.left;
|
|
var y = e.clientY - r.top;
|
|
var mgr = ChartManager.getInstance();
|
|
if (KlineIns.buttonDown == true) {
|
|
mgr.onMouseMove("frame0", x, y, true);
|
|
mgr.redraw("All", false);
|
|
} else {
|
|
mgr.onMouseMove("frame0", x, y, false);
|
|
mgr.redraw("OverlayCanvas");
|
|
}
|
|
})
|
|
.mouseleave(function (e) {
|
|
var r = e.target.getBoundingClientRect();
|
|
var x = e.clientX - r.left;
|
|
var y = e.clientY - r.top;
|
|
var mgr = ChartManager.getInstance();
|
|
mgr.onMouseLeave("frame0", x, y, false);
|
|
mgr.redraw("OverlayCanvas");
|
|
})
|
|
.mouseup(function (e) {
|
|
if (e.which != 1) {
|
|
return;
|
|
}
|
|
KlineIns.buttonDown = false;
|
|
var r = e.target.getBoundingClientRect();
|
|
var x = e.clientX - r.left;
|
|
var y = e.clientY - r.top;
|
|
var mgr = ChartManager.getInstance();
|
|
mgr.onMouseUp("frame0", x, y);
|
|
mgr.redraw("All");
|
|
})
|
|
.mousedown(function (e) {
|
|
if (e.which != 1) {
|
|
ChartManager.getInstance().deleteToolObject();
|
|
ChartManager.getInstance().redraw('OverlayCanvas', false);
|
|
return;
|
|
}
|
|
KlineIns.buttonDown = true;
|
|
var r = e.target.getBoundingClientRect();
|
|
var x = e.clientX - r.left;
|
|
var y = e.clientY - r.top;
|
|
ChartManager.getInstance().onMouseDown("frame0", x, y);
|
|
});
|
|
$("#chart_parameter_settings :input").change(function () {
|
|
var name = $(this).attr("name");
|
|
var index = 0;
|
|
var valueArray = [];
|
|
var mgr = ChartManager.getInstance();
|
|
$("#chart_parameter_settings :input").each(function () {
|
|
if ($(this).attr("name") == name) {
|
|
if ($(this).val() != "" && $(this).val() != null && $(this).val() != undefined) {
|
|
var i = parseInt($(this).val());
|
|
valueArray.push(i);
|
|
}
|
|
index++;
|
|
}
|
|
});
|
|
if (valueArray.length != 0) {
|
|
mgr.setIndicatorParameters(name, valueArray);
|
|
var value = mgr.getIndicatorParameters(name);
|
|
var cookieArray = [];
|
|
index = 0;
|
|
$("#chart_parameter_settings :input").each(function () {
|
|
if ($(this).attr("name") == name) {
|
|
if ($(this).val() != "" && $(this).val() != null && $(this).val() != undefined) {
|
|
$(this).val(value[index].getValue());
|
|
cookieArray.push(value[index].getValue());
|
|
}
|
|
index++;
|
|
}
|
|
});
|
|
var tmp = ChartSettings.get();
|
|
tmp.indics[name] = cookieArray;
|
|
ChartSettings.save();
|
|
mgr.redraw('All', false);
|
|
}
|
|
});
|
|
$("#chart_parameter_settings button").click(function () {
|
|
var name = $(this).parents("tr").children("th").html();
|
|
var index = 0;
|
|
var value = ChartManager.getInstance().getIndicatorParameters(name);
|
|
var valueArray = [];
|
|
$(this).parent().prev().children('input').each(function () {
|
|
if (value != null && index < value.length) {
|
|
$(this).val(value[index].getDefaultValue());
|
|
valueArray.push(value[index].getDefaultValue());
|
|
}
|
|
index++;
|
|
});
|
|
ChartManager.getInstance().setIndicatorParameters(name, valueArray);
|
|
var tmp = ChartSettings.get();
|
|
tmp.indics[name] = valueArray;
|
|
ChartSettings.save();
|
|
ChartManager.getInstance().redraw('All', false);
|
|
});
|
|
});
|
|
}
|
|
|
|
var refresh_counter = 0;
|
|
var refresh_handler = null;
|
|
|
|
function refresh_function() {
|
|
refresh_counter++;
|
|
var lang = ChartManager.getInstance().getLanguage();
|
|
if (refresh_counter > 3600) {
|
|
var num = new Number(refresh_counter / 3600);
|
|
if (lang == "en-us") {
|
|
$("#chart_updated_time_text").html(num.toFixed(0) + "h");
|
|
} else {
|
|
$("#chart_updated_time_text").html(num.toFixed(0) + "小时");
|
|
}
|
|
} else if (refresh_counter > 60 && refresh_counter <= 3600) {
|
|
var num = new Number(refresh_counter / 60);
|
|
if (lang == "en-us") {
|
|
$("#chart_updated_time_text").html(num.toFixed(0) + "m");
|
|
} else {
|
|
$("#chart_updated_time_text").html(num.toFixed(0) + "分钟");
|
|
}
|
|
} else if (refresh_counter <= 60) {
|
|
if (lang == "en-us") {
|
|
$("#chart_updated_time_text").html(refresh_counter + "s");
|
|
} else {
|
|
$("#chart_updated_time_text").html(refresh_counter + "秒");
|
|
}
|
|
}
|
|
}
|
|
|
|
function clear_refresh_counter() {
|
|
window.clearInterval(refresh_handler);
|
|
refresh_counter = 0;
|
|
var lang = ChartManager.getInstance().getLanguage();
|
|
if (lang == "en-us") {
|
|
$("#chart_updated_time_text").html(refresh_counter + "s");
|
|
} else {
|
|
$("#chart_updated_time_text").html(refresh_counter + "秒");
|
|
}
|
|
refresh_handler = setInterval(refresh_function, KlineIns.intervalTime);
|
|
}
|
|
|
|
function RequestData(showLoading) {
|
|
AbortRequest();
|
|
window.clearTimeout(KlineIns.timer);
|
|
if (showLoading == true) {
|
|
$("#chart_loading").addClass("activated");
|
|
}
|
|
if (KlineIns.type == "socket" && KlineIns.socketClient) {
|
|
requestOverSocket();
|
|
} else {
|
|
requestOverHttp();
|
|
}
|
|
}
|
|
|
|
function parseRequestParam(str) {
|
|
return JSON.parse('{"' + decodeURI(str.replace(/&/g, "\",\"").replace(/=/g, "\":\"")) + '"}')
|
|
}
|
|
|
|
function requestOverSocket() {
|
|
if (!KlineIns.socketConnected) {
|
|
if (KlineIns.debug) {
|
|
console.log("DEBUG: socket is not coonnected")
|
|
}
|
|
return;
|
|
}
|
|
if (KlineIns.socketClient && KlineIns.socketClient.ws.readyState == 1) {
|
|
KlineIns.socketClient.send(KlineIns.sendPath, {}, JSON.stringify(parseRequestParam(KlineIns.requestParam)));
|
|
return;
|
|
}
|
|
if (KlineIns.debug) {
|
|
console.log("DEBUG: socket client is not ready yet ...");
|
|
}
|
|
KlineIns.timer = setTimeout(function () {
|
|
RequestData(true);
|
|
}, 1000);
|
|
}
|
|
function ndata(num){
|
|
var date = new Date(num);
|
|
return Date.parse(date);
|
|
}
|
|
function requestOverHttp() {
|
|
if (KlineIns.debug) {
|
|
console.log("DEBUG: " + KlineIns.requestParam);
|
|
}
|
|
$(document).ready(
|
|
KlineIns.G_HTTP_REQUEST = $.ajax({
|
|
type: "POST",
|
|
url: KlineIns.url,
|
|
dataType: 'json',
|
|
data: KlineIns.datas,
|
|
timeout: 30000,
|
|
created: Date.now(),
|
|
beforeSend: function () {
|
|
this.range = KlineIns.range;
|
|
this.symbol = KlineIns.symbol;
|
|
},
|
|
success: function (res) {
|
|
console.log(res)
|
|
// console.log(res.message.quotation)
|
|
var datas=res.message.quotation.reverse();
|
|
var dateses=[];
|
|
for(let i=0;i<datas.length;i++){
|
|
var dataList=[];
|
|
dataList.push(ndata(datas[i].end_time),Number(datas[i].start_price),Number(datas[i].highest),Number(datas[i].minimum),Number(datas[i].end_price),Number(datas[i].sum))
|
|
dateses.push(dataList)
|
|
}
|
|
console.log(dateses)
|
|
if (KlineIns.G_HTTP_REQUEST) {
|
|
requestSuccessHandler(dateses);
|
|
}
|
|
},
|
|
error: function (xhr, textStatus, errorThrown) {
|
|
if (KlineIns.debug) {
|
|
console.log(xhr);
|
|
}
|
|
if (xhr.status == 200 && xhr.readyState == 4) {
|
|
return;
|
|
}
|
|
KlineIns.timer = setTimeout(function () {
|
|
RequestData(true);
|
|
}, KlineIns.intervalTime);
|
|
},
|
|
complete: function () {
|
|
KlineIns.G_HTTP_REQUEST = null;
|
|
}
|
|
})
|
|
);
|
|
}
|
|
|
|
function requestSuccessHandler(res) {
|
|
if (KlineIns.debug) {
|
|
console.log(res);
|
|
}
|
|
// if (!res || !res.success) {
|
|
// KlineIns.timer = setTimeout(function () {
|
|
// RequestData(true);
|
|
// }, KlineIns.intervalTime);
|
|
// return;
|
|
// }
|
|
var chart = ChartManager.getInstance().getChart();
|
|
chart.setTitle();
|
|
KlineIns.data = eval(res);
|
|
|
|
var updateDataRes = KlineIns.chartMgr.updateData("frame0.k0", KlineIns.data);
|
|
KlineIns.requestParam = setHttpRequestParam(KlineIns.symbol, KlineIns.range, null, KlineIns.chartMgr.getDataSource("frame0.k0").getLastDate());
|
|
|
|
var intervalTime = KlineIns.intervalTime < KlineIns.range ? KlineIns.intervalTime : KlineIns.range;
|
|
|
|
if (!updateDataRes) {
|
|
KlineIns.timer = setTimeout(RequestData, intervalTime);
|
|
return;
|
|
}
|
|
if (KlineIns.data.trades && KlineIns.data.trades.length > 0) {
|
|
KlineTradeIns.pushTrades(KlineIns.data.trades);
|
|
KlineTradeIns.klineTradeInit = true;
|
|
}
|
|
if (KlineIns.data.depths) {
|
|
KlineTradeIns.updateDepth(KlineIns.data.depths);
|
|
}
|
|
clear_refresh_counter();
|
|
KlineIns.timer = setTimeout(TwoSecondThread, intervalTime);
|
|
$("#chart_loading").removeClass("activated");
|
|
ChartManager.getInstance().redraw('All', false);
|
|
}
|
|
|
|
function AbortRequest() {
|
|
if (KlineIns.type != "socket" || !KlineIns.socketClient) {
|
|
if (KlineIns.G_HTTP_REQUEST && KlineIns.G_HTTP_REQUEST.readyState != 4) {
|
|
KlineIns.G_HTTP_REQUEST.abort();
|
|
}
|
|
}
|
|
}
|
|
|
|
function TwoSecondThread() {
|
|
var f = KlineIns.chartMgr.getDataSource("frame0.k0").getLastDate();
|
|
|
|
if (f == -1) {
|
|
KlineIns.requestParam = setHttpRequestParam(KlineIns.symbol, KlineIns.range, KlineIns.limit, null);
|
|
} else {
|
|
KlineIns.requestParam = setHttpRequestParam(KlineIns.symbol, KlineIns.range, null, f.toString());
|
|
}
|
|
|
|
RequestData();
|
|
}
|
|
|
|
function readCookie() {
|
|
ChartSettings.get();
|
|
ChartSettings.save();
|
|
var tmp = ChartSettings.get();
|
|
ChartManager.getInstance().setChartStyle('frame0.k0', tmp.charts.chartStyle);
|
|
var symbol = tmp.charts.symbol;
|
|
if (!KlineIns.init) {
|
|
symbol = KlineIns.symbol;
|
|
KlineIns.init = true;
|
|
}
|
|
KlineIns.symbol = symbol;
|
|
switch_symbol_selected(symbol);
|
|
var period = tmp.charts.period;
|
|
switch_period(period);
|
|
$('#chart_period_' + period + '_v a').addClass('selected');
|
|
$('#chart_period_' + period + '_h a').addClass('selected');
|
|
if (tmp.charts.indicsStatus == 'close') {
|
|
switch_indic('off');
|
|
} else if (tmp.charts.indicsStatus == 'open') {
|
|
switch_indic('on');
|
|
}
|
|
var main_indic = $('#chart_select_main_indicator');
|
|
main_indic.find('a').each(function () {
|
|
if ($(this).attr('name') == tmp.charts.mIndic) {
|
|
$(this).addClass('selected');
|
|
}
|
|
});
|
|
var chart_style = $('#chart_select_chart_style');
|
|
chart_style.find('a').each(function () {
|
|
if ($(this)[0].innerHTML == tmp.charts.chartStyle) {
|
|
$(this).addClass('selected');
|
|
}
|
|
});
|
|
ChartManager.getInstance().getChart().setMainIndicator(tmp.charts.mIndic);
|
|
ChartManager.getInstance().setThemeName('frame0', tmp.theme);
|
|
switch_tools('off');
|
|
if (tmp.theme == 'Dark') {
|
|
switch_theme('dark');
|
|
} else if (tmp.theme == 'Light') {
|
|
switch_theme('light');
|
|
}
|
|
chart_switch_language(tmp.language || "zh-cn");
|
|
}
|
|
|
|
|
|
function setHttpRequestParam(mark_from, range, limit, since) {
|
|
var str = "symbol=" + mark_from + "&range=" + range;
|
|
if (limit != null)
|
|
str += "&limit=" + limit;
|
|
else
|
|
str += "&since=" + since;
|
|
if (KlineTradeIns.tradeDate.getTime() != 0) {
|
|
str += "&prevTradeTime=" + KlineTradeIns.tradeDate.getTime();
|
|
}
|
|
return str;
|
|
}
|
|
|
|
function refreshTemplate() {
|
|
KlineIns.chartMgr = DefaultTemplate.loadTemplate("frame0.k0", "");
|
|
ChartManager.getInstance().redraw('All', true);
|
|
}
|
|
|
|
function getRectCrossPt(rect, startPt, endPt) {
|
|
var crossPt;
|
|
var firstPt = {x: -1, y: -1};
|
|
var secondPt = {x: -1, y: -1};
|
|
var xdiff = endPt.x - startPt.x;
|
|
var ydiff = endPt.y - startPt.y;
|
|
if (Math.abs(xdiff) < 2) {
|
|
firstPt = {x: startPt.x, y: rect.top};
|
|
secondPt = {x: endPt.x, y: rect.bottom};
|
|
crossPt = [firstPt, secondPt];
|
|
return crossPt;
|
|
}
|
|
var k = ydiff / xdiff;
|
|
secondPt.x = rect.right;
|
|
secondPt.y = startPt.y + (rect.right - startPt.x) * k;
|
|
firstPt.x = rect.left;
|
|
firstPt.y = startPt.y + (rect.left - startPt.x) * k;
|
|
crossPt = [firstPt, secondPt];
|
|
return crossPt;
|
|
}
|
|
|
|
function chart_switch_language(lang) {
|
|
var tmp = lang.replace(/-/, '_');
|
|
$('#chart_language_switch_tmp').find('span').each(function () {
|
|
var name = $(this).attr('name');
|
|
var attr = $(this).attr(tmp);
|
|
name = '.' + name;
|
|
var obj = $(name)[0];
|
|
|
|
if (!obj)
|
|
return;
|
|
$(name).each(function () {
|
|
|
|
$(this)[0].innerHTML = attr;
|
|
});
|
|
});
|
|
$("#chart_language_setting_div li a[name='" + lang + "']").addClass("selected");
|
|
ChartManager.getInstance().setLanguage(lang);
|
|
ChartManager.getInstance().getChart().setTitle();
|
|
var tmp = ChartSettings.get();
|
|
tmp.language = lang;
|
|
ChartSettings.save();
|
|
KlineIns.onLangChange(lang);
|
|
}
|
|
|
|
function on_size(w, h) {
|
|
var width = w || window.innerWidth;
|
|
var chartWidth = KlineIns.showTrade ? (width - KlineIns.tradeWidth) : width;
|
|
var height = h || window.innerHeight;
|
|
var container = $(KlineIns.element);
|
|
container.css({
|
|
width: width + 'px',
|
|
height: height + 'px'
|
|
});
|
|
var toolBar = $('#chart_toolbar');
|
|
var toolPanel = $('#chart_toolpanel');
|
|
var canvasGroup = $('#chart_canvasGroup');
|
|
var tabBar = $('#chart_tabbar');
|
|
var toolPanelShown = toolPanel[0].style.display != 'inline' ? false : true;
|
|
var tabBarShown = tabBar[0].style.display != 'block' ? false : true;
|
|
var toolBarRect = {};
|
|
toolBarRect.x = 0;
|
|
toolBarRect.y = 0;
|
|
toolBarRect.w = chartWidth;
|
|
toolBarRect.h = 29;
|
|
var toolPanelRect = {};
|
|
toolPanelRect.x = 0;
|
|
toolPanelRect.y = toolBarRect.h + 1;
|
|
toolPanelRect.w = toolPanelShown ? 32 : 0;
|
|
toolPanelRect.h = height - toolPanelRect.y;
|
|
var tabBarRect = {};
|
|
tabBarRect.w = toolPanelShown ? chartWidth - (toolPanelRect.w + 1 ) : chartWidth;
|
|
tabBarRect.h = tabBarShown ? 22 : -1;
|
|
tabBarRect.x = chartWidth - tabBarRect.w;
|
|
tabBarRect.y = height - (tabBarRect.h + 1 );
|
|
var canvasGroupRect = {};
|
|
canvasGroupRect.x = tabBarRect.x;
|
|
canvasGroupRect.y = toolPanelRect.y;
|
|
canvasGroupRect.w = tabBarRect.w;
|
|
canvasGroupRect.h = tabBarRect.y - toolPanelRect.y;
|
|
toolBar.css({
|
|
left: toolBarRect.x + 'px',
|
|
top: toolBarRect.y + 'px',
|
|
width: toolBarRect.w + 'px',
|
|
height: toolBarRect.h + 'px'
|
|
});
|
|
if (toolPanelShown) {
|
|
toolPanel.css({
|
|
left: toolPanelRect.x + 'px',
|
|
top: toolPanelRect.y + 'px',
|
|
width: toolPanelRect.w + 'px',
|
|
height: toolPanelRect.h + 'px'
|
|
});
|
|
}
|
|
|
|
canvasGroup.css({
|
|
left: canvasGroupRect.x + 'px',
|
|
top: canvasGroupRect.y + 'px',
|
|
width: canvasGroupRect.w + 'px',
|
|
height: canvasGroupRect.h + 'px'
|
|
});
|
|
var mainCanvas = $('#chart_mainCanvas')[0];
|
|
var overlayCanvas = $('#chart_overlayCanvas')[0];
|
|
mainCanvas.width = canvasGroupRect.w;
|
|
mainCanvas.height = canvasGroupRect.h;
|
|
overlayCanvas.width = canvasGroupRect.w;
|
|
overlayCanvas.height = canvasGroupRect.h;
|
|
if (tabBarShown) {
|
|
tabBar.css({
|
|
left: tabBarRect.x + 'px',
|
|
top: tabBarRect.y + 'px',
|
|
width: tabBarRect.w + 'px',
|
|
height: tabBarRect.h + 'px'
|
|
});
|
|
}
|
|
var dlgSettings = $("#chart_parameter_settings");
|
|
dlgSettings.css({
|
|
left: (chartWidth - dlgSettings.width()) >> 1,
|
|
top: (height - dlgSettings.height()) >> 1
|
|
});
|
|
var dlgLoading = $("#chart_loading");
|
|
dlgLoading.css({
|
|
left: (chartWidth - dlgLoading.width()) >> 1,
|
|
top: (height - dlgLoading.height()) >> 2
|
|
});
|
|
var domElemCache = $('#chart_dom_elem_cache');
|
|
var rowTheme = $('#chart_select_theme')[0];
|
|
var rowTools = $('#chart_enable_tools')[0];
|
|
var rowIndic = $('#chart_enable_indicator')[0];
|
|
var periodsVert = $('#chart_toolbar_periods_vert');
|
|
var periodsHorz = $('#chart_toolbar_periods_horz')[0];
|
|
var showIndic = $('#chart_show_indicator')[0];
|
|
var showTools = $('#chart_show_tools')[0];
|
|
var selectTheme = $('#chart_toolbar_theme')[0];
|
|
var dropDownSettings = $('#chart_dropdown_settings');
|
|
var periodsVertNW = periodsVert[0].offsetWidth;
|
|
var periodsHorzNW = periodsVertNW + periodsHorz.offsetWidth;
|
|
var showIndicNW = periodsHorzNW + showIndic.offsetWidth + 4;
|
|
var showToolsNW = showIndicNW + showTools.offsetWidth + 4;
|
|
var selectThemeNW = showToolsNW + selectTheme.offsetWidth;
|
|
var dropDownSettingsW = dropDownSettings.find(".chart_dropdown_t")[0].offsetWidth + 150;
|
|
periodsVertNW += dropDownSettingsW;
|
|
periodsHorzNW += dropDownSettingsW;
|
|
showIndicNW += dropDownSettingsW;
|
|
showToolsNW += dropDownSettingsW;
|
|
selectThemeNW += dropDownSettingsW;
|
|
if (chartWidth < periodsHorzNW) {
|
|
domElemCache.append(periodsHorz);
|
|
} else {
|
|
periodsVert.after(periodsHorz);
|
|
}
|
|
if (chartWidth < showIndicNW) {
|
|
domElemCache.append(showIndic);
|
|
rowIndic.style.display = "";
|
|
} else {
|
|
dropDownSettings.before(showIndic);
|
|
rowIndic.style.display = "none";
|
|
}
|
|
if (chartWidth < showToolsNW) {
|
|
domElemCache.append(showTools);
|
|
rowTools.style.display = "";
|
|
} else {
|
|
dropDownSettings.before(showTools);
|
|
rowTools.style.display = "none";
|
|
}
|
|
if (chartWidth < selectThemeNW) {
|
|
domElemCache.append(selectTheme);
|
|
rowTheme.style.display = "";
|
|
} else {
|
|
dropDownSettings.before(selectTheme);
|
|
rowTheme.style.display = "none";
|
|
}
|
|
|
|
ChartManager.getInstance().redraw('All', true);
|
|
|
|
KlineIns.onResize(width, height);
|
|
}
|
|
|
|
function mouseWheel(e, delta) {
|
|
ChartManager.getInstance().scale(delta > 0 ? 1 : -1);
|
|
ChartManager.getInstance().redraw("All", true);
|
|
return false;
|
|
}
|
|
|
|
function switch_theme(name) {
|
|
|
|
$('#chart_toolbar_theme a').removeClass('selected');
|
|
$('#chart_select_theme a').removeClass('selected');
|
|
$('#chart_toolbar_theme').find('a').each(function () {
|
|
if ($(this).attr('name') == name) {
|
|
$(this).addClass('selected');
|
|
}
|
|
});
|
|
$('#chart_select_theme a').each(function () {
|
|
if ($(this).attr('name') == name) {
|
|
$(this).addClass('selected');
|
|
}
|
|
});
|
|
$(".chart_container").attr('class', "chart_container " + name);
|
|
$(".marketName_ a").attr('class', name);
|
|
|
|
if (name == 'dark') {
|
|
$(".trade_container").addClass("dark").removeClass("light");
|
|
ChartManager.getInstance().setThemeName('frame0', 'Dark');
|
|
var tmp = ChartSettings.get();
|
|
tmp.theme = 'Dark';
|
|
ChartSettings.save();
|
|
} else if (name == 'light') {
|
|
$(".trade_container").addClass("light").removeClass("dark");
|
|
ChartManager.getInstance().setThemeName('frame0', 'Light');
|
|
var tmp = ChartSettings.get();
|
|
tmp.theme = 'Light';
|
|
ChartSettings.save();
|
|
}
|
|
var a = {};
|
|
a.command = "set current theme";
|
|
a.content = name;
|
|
$('#chart_output_interface_text').val(JSON.stringify(a));
|
|
$('#chart_output_interface_submit').submit();
|
|
window._current_theme_change.raise(name);
|
|
ChartManager.getInstance().redraw();
|
|
|
|
KlineIns.onThemeChange(name);
|
|
}
|
|
|
|
function switch_tools(name) {
|
|
$(".chart_dropdown_data").removeClass("chart_dropdown-hover");
|
|
$("#chart_toolpanel .chart_toolpanel_button").removeClass("selected");
|
|
$('#chart_enable_tools a').removeClass('selected');
|
|
if (name == 'on') {
|
|
$('#chart_show_tools').addClass('selected');
|
|
$('#chart_enable_tools a').each(function () {
|
|
if ($(this).attr('name') == 'on') {
|
|
$(this).addClass('selected');
|
|
}
|
|
});
|
|
$('#chart_toolpanel')[0].style.display = 'inline';
|
|
if (ChartManager.getInstance()._drawingTool == ChartManager.DrawingTool.Cursor) {
|
|
$('#chart_Cursor').parent().addClass('selected');
|
|
} else if (ChartManager.getInstance()._drawingTool == ChartManager.DrawingTool.CrossCursor) {
|
|
$('#chart_CrossCursor').parent().addClass('selected');
|
|
}
|
|
} else if (name == 'off') {
|
|
$('#chart_show_tools').removeClass('selected');
|
|
$('#chart_enable_tools a').each(function () {
|
|
if ($(this).attr('name') == 'off') {
|
|
$(this).addClass('selected');
|
|
}
|
|
});
|
|
$('#chart_toolpanel')[0].style.display = 'none';
|
|
ChartManager.getInstance().setRunningMode(ChartManager.getInstance()._beforeDrawingTool);
|
|
ChartManager.getInstance().redraw("All", true);
|
|
}
|
|
on_size(KlineIns.width, KlineIns.height);
|
|
}
|
|
|
|
function switch_indic(name) {
|
|
$('#chart_enable_indicator a').removeClass('selected');
|
|
$("#chart_enable_indicator a[name='" + name + "']").addClass('selected');
|
|
if (name == 'on') {
|
|
$('#chart_show_indicator').addClass('selected');
|
|
var tmp = ChartSettings.get();
|
|
tmp.charts.indicsStatus = 'open';
|
|
ChartSettings.save();
|
|
var value = tmp.charts.indics[1];
|
|
if (Template.displayVolume == false)
|
|
ChartManager.getInstance().getChart().setIndicator(2, value);
|
|
else
|
|
ChartManager.getInstance().getChart().setIndicator(2, value);
|
|
$("#chart_tabbar").find('a').each(function () {
|
|
if ($(this).attr('name') == value)
|
|
$(this).addClass('selected');
|
|
});
|
|
$('#chart_tabbar')[0].style.display = 'block';
|
|
} else if (name == 'off') {
|
|
$('#chart_show_indicator').removeClass('selected');
|
|
ChartManager.getInstance().getChart().setIndicator(2, 'NONE');
|
|
var tmp = ChartSettings.get();
|
|
tmp.charts.indicsStatus = 'close';
|
|
ChartSettings.save();
|
|
$('#chart_tabbar')[0].style.display = 'none';
|
|
$("#chart_tabbar a").removeClass("selected");
|
|
}
|
|
on_size(KlineIns.width, KlineIns.height);
|
|
}
|
|
|
|
function switch_period(name) {
|
|
|
|
$(".chart_container .chart_toolbar_tabgroup a").removeClass("selected");
|
|
$("#chart_toolbar_periods_vert ul a").removeClass("selected");
|
|
$(".chart_container .chart_toolbar_tabgroup a").each(function () {
|
|
if ($(this).parent().attr('name') == name) {
|
|
$(this).addClass('selected');
|
|
}
|
|
});
|
|
$("#chart_toolbar_periods_vert ul a").each(function () {
|
|
if ($(this).parent().attr('name') == name) {
|
|
$(this).addClass('selected');
|
|
}
|
|
});
|
|
ChartManager.getInstance().showCursor();
|
|
calcPeriodWeight(name);
|
|
if (name == 'line') {
|
|
ChartManager.getInstance().getChart().strIsLine = true;
|
|
ChartManager.getInstance().setChartStyle('frame0.k0', 'Line');
|
|
ChartManager.getInstance().getChart().setCurrentPeriod('line');
|
|
var settings = ChartSettings.get();
|
|
settings.charts.period = name;
|
|
ChartSettings.save();
|
|
return;
|
|
}
|
|
ChartManager.getInstance().getChart().strIsLine = false;
|
|
var p = KlineIns.tagMapPeriod[name];
|
|
ChartManager.getInstance().setChartStyle('frame0.k0', ChartSettings.get().charts.chartStyle);
|
|
ChartManager.getInstance().getChart().setCurrentPeriod(p);
|
|
var settings = ChartSettings.get();
|
|
settings.charts.period = name;
|
|
ChartSettings.save();
|
|
}
|
|
|
|
function reset(symbol) {
|
|
KlineIns.symbol = symbol;
|
|
|
|
if (KlineIns.showTrade) {
|
|
KlineTradeIns.reset(symbol);
|
|
}
|
|
}
|
|
|
|
function switch_symbol_selected(symbol) {
|
|
reset(symbol);
|
|
$(".market_chooser ul a").removeClass("selected");
|
|
$(".market_chooser ul a[name='" + symbol + "']").addClass("selected");
|
|
ChartManager.getInstance().getChart()._symbol = symbol;
|
|
var settings = ChartSettings.get();
|
|
settings.charts.symbol = symbol;
|
|
ChartSettings.save();
|
|
}
|
|
|
|
function switch_symbol(symbol) {
|
|
switch_symbol_selected(symbol);
|
|
var settings = ChartSettings.get();
|
|
if (settings.charts.period == "line") {
|
|
ChartManager.getInstance().getChart().strIsLine = true;
|
|
ChartManager.getInstance().setChartStyle('frame0.k0', 'Line');
|
|
} else {
|
|
ChartManager.getInstance().getChart().strIsLine = false;
|
|
ChartManager.getInstance().setChartStyle('frame0.k0', ChartSettings.get().charts.chartStyle);
|
|
}
|
|
ChartManager.getInstance().getChart().setSymbol(symbol);
|
|
}
|
|
|
|
function calcPeriodWeight(period) {
|
|
var index = period;
|
|
if (period != 'line')
|
|
index = KlineIns.periodMap[KlineIns.tagMapPeriod[period]];
|
|
var period_weight = ChartSettings.get().charts.period_weight;
|
|
for (var i in period_weight) {
|
|
if (period_weight[i] > period_weight[index]) {
|
|
period_weight[i] -= 1;
|
|
}
|
|
}
|
|
period_weight[index] = 8;
|
|
ChartSettings.save();
|
|
}
|
|
|
|
function socketConnect() {
|
|
KlineIns.socketConnected = true;
|
|
if (KlineIns.socketClient && KlineIns.socketClient.ws.readyState == 1) {
|
|
console.log('DEBUG: already connected');
|
|
return;
|
|
}
|
|
if ( KlineIns.enableSockjs ) {
|
|
var socket = new SockJS(KlineIns.url);
|
|
KlineIns.socketClient = Stomp.over(socket);
|
|
} else {
|
|
KlineIns.socketClient = Stomp.client(KlineIns.url);
|
|
}
|
|
if (!KlineIns.debug) {
|
|
KlineIns.socketClient.debug = null;
|
|
}
|
|
KlineIns.socketClient.connect({}, function () {
|
|
KlineIns.socketClient.subscribe(KlineIns.subscribePath, function (res) {
|
|
requestSuccessHandler(JSON.parse(res.body));
|
|
});
|
|
}, function () {
|
|
KlineIns.socketClient.disconnect();
|
|
console.log("DEBUG: reconnect in 5 seconds ...");
|
|
setTimeout(function () {
|
|
socketConnect();
|
|
}, 5000);
|
|
});
|
|
}
|
|
|
|
var template_str = "\n" +
|
|
"<div class=\"trade_container dark\">\n" +
|
|
" <div class=\"m_cent\">\n" +
|
|
" <div class=\"m_guadan\">\n" +
|
|
" <div class=\"symbol-title\">\n" +
|
|
" <a class=\"dark\">test</a>\n" +
|
|
" \n" +
|
|
" </div>\n" +
|
|
" <div id=\"orderbook\">\n" +
|
|
" <div id=\"asks\">\n" +
|
|
" <div class=\"table\"> </div>\n" +
|
|
" </div>\n" +
|
|
" <div id=\"gasks\">\n" +
|
|
" <div class=\"table\"> </div>\n" +
|
|
" </div>\n" +
|
|
" <div id=\"price\" class=\"green\"></div>\n" +
|
|
" <div id=\"bids\">\n" +
|
|
" <div class=\"table\"> </div>\n" +
|
|
" </div>\n" +
|
|
" <div id=\"gbids\">\n" +
|
|
" <div class=\"table\"> </div>\n" +
|
|
" </div>\n" +
|
|
" </div>\n" +
|
|
" <div id=\"trades\" class=\"trades\">\n" +
|
|
" <div class=\"trades_list\"> </div>\n" +
|
|
" </div>\n" +
|
|
" \n" +
|
|
" </div>\n" +
|
|
" \n" +
|
|
" </div>\n" +
|
|
"</div>\n" +
|
|
|
|
"<div class=\"chart_container dark\">\n" +
|
|
" <div id=\"chart_dom_elem_cache\"></div>\n" +
|
|
" <!-- ToolBar -->\n" +
|
|
" <div id=\"chart_toolbar\">\n" +
|
|
" <div class=\"chart_toolbar_minisep\"></div>\n" +
|
|
" <!-- Periods -->\n" +
|
|
" <div class=\"chart_dropdown\" id=\"chart_toolbar_periods_vert\">\n" +
|
|
" <div class=\"chart_dropdown_t\"><a class=\"chart_str_period\">周期</a></div>\n" +
|
|
" <div class=\"chart_dropdown_data\" style=\"margin-left: -58px;\">\n" +
|
|
" <table>\n" +
|
|
" <tbody>\n" +
|
|
" <tr>\n" +
|
|
" <td>\n" +
|
|
" <ul>\n" +
|
|
" <li id=\"chart_period_1w_v\" style=\"display:none;\" name=\"1w\"><a class=\"chart_str_period_1w\">周线</a></li>\n" +
|
|
" <li id=\"chart_period_3d_v\" style=\"display:none;\" name=\"3d\"><a class=\"chart_str_period_3d\">3日</a></li>\n" +
|
|
" <li id=\"chart_period_1d_v\" style=\"display:none;\" name=\"1d\"><a class=\"chart_str_period_1d\">日线</a></li>\n" +
|
|
" <li id=\"chart_period_12h_v\" style=\"display:none;\" name=\"12h\"><a class=\"chart_str_period_12h\">12小时</a></li>\n" +
|
|
" <li id=\"chart_period_6h_v\" style=\"display:none;\" name=\"6h\"><a class=\"chart_str_period_6h\">6小时</a></li>\n" +
|
|
" <li id=\"chart_period_4h_v\" style=\"display:none;\" name=\"4h\"><a class=\"chart_str_period_4h\">4小时</a></li>\n" +
|
|
" <li id=\"chart_period_2h_v\" style=\"display:none;\" name=\"2h\"><a class=\"chart_str_period_2h\">2小时</a></li>\n" +
|
|
" <li id=\"chart_period_1h_v\" style=\"display:none;\" name=\"1h\"><a class=\"chart_str_period_1h\">1小时</a></li>\n" +
|
|
" </ul>\n" +
|
|
" </td>\n" +
|
|
" </tr>\n" +
|
|
" <tr>\n" +
|
|
" <td>\n" +
|
|
" <ul>\n" +
|
|
" <li id=\"chart_period_30m_v\" style=\"display:none;\" name=\"30m\"><a class=\"chart_str_period_30m\">30分钟</a></li>\n" +
|
|
" <li id=\"chart_period_15m_v\" style=\"display:none;\" name=\"15m\"><a class=\"chart_str_period_15m\">15分钟</a></li>\n" +
|
|
" <li id=\"chart_period_5m_v\" style=\"display:none;\" name=\"5m\"><a class=\"chart_str_period_5m\">5分钟</a></li>\n" +
|
|
" <li id=\"chart_period_3m_v\" style=\"display:none;\" name=\"3m\"><a class=\"chart_str_period_3m\">3分钟</a></li>\n" +
|
|
" <li id=\"chart_period_1m_v\" style=\"display:none;\" name=\"1m\"><a class=\"chart_str_period_1m selected\">1分钟</a></li>\n" +
|
|
" <li id=\"chart_period_line_v\" style=\"display:none;\" name=\"line\"><a class=\"chart_str_period_line\">分时</a>\n" +
|
|
" </li>\n" +
|
|
" </ul>\n" +
|
|
" </td>\n" +
|
|
" </tr>\n" +
|
|
" </tbody>\n" +
|
|
" </table>\n" +
|
|
" </div>\n" +
|
|
" </div>\n" +
|
|
" <div id=\"chart_toolbar_periods_horz\">\n" +
|
|
" <ul class=\"chart_toolbar_tabgroup\" style=\"padding-left:5px; padding-right:11px;\">\n" +
|
|
" <li id=\"chart_period_1w_h\" name=\"1w\" style=\"display: none;\"><a\ class=\"chart_str_period_1w\">周线</a></li>\n" +
|
|
" <li id=\"chart_period_3d_h\" name=\"3d\" style=\"display: none;\"><a\ class=\"chart_str_period_3d\">3日</a></li>\n" +
|
|
" <li id=\"chart_period_1d_h\" name=\"1d\" style=\"display: none;\"><a class=\"chart_str_period_1d\">日线</a></li>\n" +
|
|
" <li id=\"chart_period_12h_h\" name=\"12h\" style=\"display: none;\"><a class=\"chart_str_period_12h\">12小时</a></li>\n" +
|
|
" <li id=\"chart_period_6h_h\" name=\"6h\" style=\"display: none;\"><a class=\"chart_str_period_6h\">6小时</a></li>\n" +
|
|
" <li id=\"chart_period_4h_h\" name=\"4h\" style=\"display: none;\"><a class=\"chart_str_period_4h\">4小时</a></li>\n" +
|
|
" <li id=\"chart_period_2h_h\" name=\"2h\" style=\"display: none;\"><a class=\"chart_str_period_2h\">2小时</a></li>\n" +
|
|
" <li id=\"chart_period_1h_h\" name=\"1h\" style=\"display: none;\"><a class=\"chart_str_period_1h\">1小时</a></li>\n" +
|
|
" <li id=\"chart_period_30m_h\" name=\"30m\" style=\"display: none;\"><a class=\"chart_str_period_30m\">30分钟</a></li>\n" +
|
|
" <li id=\"chart_period_15m_h\" name=\"15m\" style=\"display: none;\"><a class=\"chart_str_period_15m\">15分钟</a></li>\n" +
|
|
" <li id=\"chart_period_5m_h\" name=\"5m\" style=\"display: none;\"><a class=\"chart_str_period_5m\">5分钟</a></li>\n" +
|
|
" <li id=\"chart_period_3m_h\" name=\"3m\" style=\"display: none;\"><a class=\"chart_str_period_3m\">3分钟</a></li>\n" +
|
|
" <li id=\"chart_period_1m_h\" name=\"1m\" style=\"display: none;\"><a class=\"chart_str_period_1m selected\">1分钟</a></li>\n" +
|
|
" <li id=\"chart_period_line_h\" name=\"line\" style=\"display: none;\"><a class=\"chart_str_period_line\">分时</a></li>\n" +
|
|
" </ul>\n" +
|
|
" </div>\n" +
|
|
" <div id=\"chart_show_indicator\" class=\"chart_toolbar_button chart_str_indicator_cap selected\">技术指标</div>\n" +
|
|
" <div id=\"chart_show_tools\" class=\"chart_toolbar_button chart_str_tools_cap\">画线工具</div>\n" +
|
|
" <div id=\"chart_toolbar_theme\">\n" +
|
|
" <div class=\"chart_toolbar_label chart_str_theme_cap\">主题选择</div>\n" +
|
|
" <a name=\"dark\" class=\"chart_icon chart_icon_theme_dark selected\"></a>\n" +
|
|
" <a name=\"light\" class=\"chart_icon chart_icon_theme_light\"></a>\n" +
|
|
" </div>\n" +
|
|
" <div class=\"chart_dropdown\" id=\"chart_dropdown_settings\">\n" +
|
|
" <div class=\"chart_dropdown_t\"><a class=\"chart_str_settings\">更多</a></div>\n" +
|
|
" <div class=\"chart_dropdown_data\" style=\"margin-left: -142px;\">\n" +
|
|
" <table>\n" +
|
|
" <tbody>\n" +
|
|
" <tr id=\"chart_select_main_indicator\">\n" +
|
|
" <td class=\"chart_str_main_indicator\">主指标</td>\n" +
|
|
" <td>\n" +
|
|
" <ul>\n" +
|
|
" <li><a name=\"MA\" class=\"selected\">MA</a></li>\n" +
|
|
" <li><a name=\"EMA\" class=\"\">EMA</a></li>\n" +
|
|
" <li><a name=\"BOLL\" class=\"\">BOLL</a></li>\n" +
|
|
" <li><a name=\"SAR\" class=\"\">SAR</a></li>\n" +
|
|
" <li><a name=\"NONE\" class=\"\">None</a></li>\n" +
|
|
" </ul>\n" +
|
|
" </td>\n" +
|
|
" </tr>\n" +
|
|
" <tr id=\"chart_select_chart_style\">\n" +
|
|
" <td class=\"chart_str_chart_style\">主图样式</td>\n" +
|
|
" <td>\n" +
|
|
" <ul>\n" +
|
|
" <li><a class=\"selected\">CandleStick</a></li>\n" +
|
|
" <li><a>CandleStickHLC</a></li>\n" +
|
|
" <li><a class=\"\">OHLC</a></li>\n" +
|
|
" </ul>\n" +
|
|
" </td>\n" +
|
|
" </tr>\n" +
|
|
" <tr id=\"chart_select_theme\" style=\"display: none;\">\n" +
|
|
" <td class=\"chart_str_theme\">主题选择</td>\n" +
|
|
" <td>\n" +
|
|
" <ul>\n" +
|
|
" <li>\n" +
|
|
" <a name=\"dark\" class=\"chart_icon chart_icon_theme_dark selected\"></a>\n" +
|
|
" </li>\n" +
|
|
" <li>\n" +
|
|
" <a name=\"light\" class=\"chart_icon chart_icon_theme_light\"></a>\n" +
|
|
" </li>\n" +
|
|
" </ul>\n" +
|
|
" </td>\n" +
|
|
" </tr>\n" +
|
|
" <tr id=\"chart_enable_tools\" style=\"display: none;\">\n" +
|
|
" <td class=\"chart_str_tools\">画线工具</td>\n" +
|
|
" <td>\n" +
|
|
" <ul>\n" +
|
|
" <li><a name=\"on\" class=\"chart_str_on\">开启</a></li>\n" +
|
|
" <li><a name=\"off\" class=\"chart_str_off selected\">关闭</a></li>\n" +
|
|
" </ul>\n" +
|
|
" </td>\n" +
|
|
" </tr>\n" +
|
|
" <tr id=\"chart_enable_indicator\" style=\"display: none;\">\n" +
|
|
" <td class=\"chart_str_indicator\">技术指标</td>\n" +
|
|
" <td>\n" +
|
|
" <ul>\n" +
|
|
" <li><a name=\"on\" class=\"chart_str_on selected\">开启</a></li>\n" +
|
|
" <li><a name=\"off\" class=\"chart_str_off\">关闭</a></li>\n" +
|
|
" </ul>\n" +
|
|
" </td>\n" +
|
|
" </tr>\n" +
|
|
" <tr>\n" +
|
|
" <td></td>\n" +
|
|
" <td>\n" +
|
|
" <ul>\n" +
|
|
" <li><a id=\"chart_btn_parameter_settings\"\n" +
|
|
" class=\"chart_str_indicator_parameters\">指标参数设置</a>\n" +
|
|
" </li>\n" +
|
|
" </ul>\n" +
|
|
" </td>\n" +
|
|
" </tr>\n" +
|
|
" </tbody>\n" +
|
|
" </table>\n" +
|
|
" </div>\n" +
|
|
" </div>\n" +
|
|
" <div class=\"chart_dropdown\" id=\"chart_language_setting_div\" style=\"padding-left: 5px;\">\n" +
|
|
" <div class=\"chart_dropdown_t\">\n" +
|
|
" <a class=\"chart_language_setting\">语言(LANG)</a>\n" +
|
|
" </div>\n" +
|
|
" <div class=\"chart_dropdown_data\" style=\"padding-top: 15px; margin-left: -12px;\">\n" +
|
|
" <ul>\n" +
|
|
" <li style=\"height: 25px;\"><a name=\"zh-cn\" class=\"selected\">简体中文(zh-CN)</a></li>\n" +
|
|
" <li style=\"height: 25px;\"><a name=\"en-us\">English(en-US)</a></li>\n" +
|
|
" <li style=\"height: 25px;\"><a name=\"zh-tw\">繁體中文(zh-HK)</a></li>\n" +
|
|
" </ul>\n" +
|
|
" </div>\n" +
|
|
" </div>\n" +
|
|
" <div id=\"chart_updated_time\">\n" +
|
|
" <div id=\"sizeIcon\" class=\"chart_BoxSize\"></div>\n" +
|
|
" </div>\n" +
|
|
" </div>\n" +
|
|
" <!-- ToolPanel -->\n" +
|
|
" <div id=\"chart_toolpanel\">\n" +
|
|
" <div class=\"chart_toolpanel_separator\"></div>\n" +
|
|
" <div class=\"chart_toolpanel_button\">\n" +
|
|
" <div class=\"chart_toolpanel_icon\" id=\"chart_Cursor\" name=\"Cursor\"></div>\n" +
|
|
" <div class=\"chart_toolpanel_tip chart_str_cursor\">光标</div>\n" +
|
|
" </div>\n" +
|
|
" <div class=\"chart_toolpanel_button\">\n" +
|
|
" <div class=\"chart_toolpanel_icon\" id=\"chart_CrossCursor\" name=\"CrossCursor\"></div>\n" +
|
|
" <div class=\"chart_toolpanel_tip chart_str_cross_cursor\">十字光标</div>\n" +
|
|
" </div>\n" +
|
|
" <div class=\"chart_toolpanel_button\">\n" +
|
|
" <div class=\"chart_toolpanel_icon\" id=\"chart_SegLine\" name=\"SegLine\"></div>\n" +
|
|
" <div class=\"chart_toolpanel_tip chart_str_seg_line\">线段</div>\n" +
|
|
" </div>\n" +
|
|
" <div class=\"chart_toolpanel_button\">\n" +
|
|
" <div class=\"chart_toolpanel_icon\" id=\"chart_StraightLine\" name=\"StraightLine\"></div>\n" +
|
|
" <div class=\"chart_toolpanel_tip chart_str_straight_line\">直线</div>\n" +
|
|
" </div>\n" +
|
|
" <div class=\"chart_toolpanel_button\">\n" +
|
|
" <div class=\"chart_toolpanel_icon\" id=\"chart_RayLine\" name=\"RayLine\"></div>\n" +
|
|
" <div class=\"chart_toolpanel_tip chart_str_ray_line\">射线</div>\n" +
|
|
" </div>\n" +
|
|
" <div class=\"chart_toolpanel_button\">\n" +
|
|
" <div class=\"chart_toolpanel_icon\" id=\"chart_ArrowLine\" name=\"ArrowLine\"></div>\n" +
|
|
" <div class=\"chart_toolpanel_tip chart_str_arrow_line\">箭头</div>\n" +
|
|
" </div>\n" +
|
|
" <div class=\"chart_toolpanel_button\">\n" +
|
|
" <div class=\"chart_toolpanel_icon\" id=\"chart_HoriSegLine\" name=\"HoriSegLine\"></div>\n" +
|
|
" <div class=\"chart_toolpanel_tip chart_str_horz_seg_line\">水平线段</div>\n" +
|
|
" </div>\n" +
|
|
" <div class=\"chart_toolpanel_button\">\n" +
|
|
" <div class=\"chart_toolpanel_icon\" id=\"chart_HoriStraightLine\" name=\"HoriStraightLine\"></div>\n" +
|
|
" <div class=\"chart_toolpanel_tip chart_str_horz_straight_line\">水平直线</div>\n" +
|
|
" </div>\n" +
|
|
" <div class=\"chart_toolpanel_button\">\n" +
|
|
" <div class=\"chart_toolpanel_icon\" id=\"chart_HoriRayLine\" name=\"HoriRayLine\"></div>\n" +
|
|
" <div class=\"chart_toolpanel_tip chart_str_horz_ray_line\">水平射线</div>\n" +
|
|
" </div>\n" +
|
|
" <div class=\"chart_toolpanel_button\">\n" +
|
|
" <div class=\"chart_toolpanel_icon\" id=\"chart_VertiStraightLine\" name=\"VertiStraightLine\"></div>\n" +
|
|
" <div class=\"chart_toolpanel_tip chart_str_vert_straight_line\">垂直直线</div>\n" +
|
|
" </div>\n" +
|
|
" <div class=\"chart_toolpanel_button\">\n" +
|
|
" <div class=\"chart_toolpanel_icon\" id=\"chart_PriceLine\" name=\"PriceLine\"></div>\n" +
|
|
" <div class=\"chart_toolpanel_tip chart_str_price_line\">价格线</div>\n" +
|
|
" </div>\n" +
|
|
" <div class=\"chart_toolpanel_button\">\n" +
|
|
" <div class=\"chart_toolpanel_icon\" id=\"chart_TriParallelLine\" name=\"TriParallelLine\"></div>\n" +
|
|
" <div class=\"chart_toolpanel_tip chart_str_tri_parallel_line\">价格通道线</div>\n" +
|
|
" </div>\n" +
|
|
" <div class=\"chart_toolpanel_button\">\n" +
|
|
" <div class=\"chart_toolpanel_icon\" id=\"chart_BiParallelLine\" name=\"BiParallelLine\"></div>\n" +
|
|
" <div class=\"chart_toolpanel_tip chart_str_bi_parallel_line\">平行直线</div>\n" +
|
|
" </div>\n" +
|
|
" <div class=\"chart_toolpanel_button\">\n" +
|
|
" <div class=\"chart_toolpanel_icon\" id=\"chart_BiParallelRayLine\" name=\"BiParallelRayLine\"></div>\n" +
|
|
" <div class=\"chart_toolpanel_tip chart_str_bi_parallel_ray\">平行射线</div>\n" +
|
|
" </div>\n" +
|
|
" <div class=\"chart_toolpanel_button\">\n" +
|
|
" <div class=\"chart_toolpanel_icon\" id=\"chart_DrawFibRetrace\" name=\"DrawFibRetrace\"></div>\n" +
|
|
" <div class=\"chart_toolpanel_tip chart_str_fib_retrace\">斐波纳契回调</div>\n" +
|
|
" </div>\n" +
|
|
" <div class=\"chart_toolpanel_button\">\n" +
|
|
" <div class=\"chart_toolpanel_icon\" id=\"chart_DrawFibFans\" name=\"DrawFibFans\"></div>\n" +
|
|
" <div class=\"chart_toolpanel_tip chart_str_fib_fans\">斐波纳契扇形</div>\n" +
|
|
" </div>\n" +
|
|
" <div style=\"padding-left: 3px;padding-top: 10px;\">\n" +
|
|
" <button style=\"color: red;\" id=\"clearCanvas\" title=\"Clear All\">X</button>\n" +
|
|
" </div>\n" +
|
|
" </div>\n" +
|
|
" <!-- Canvas Group -->\n" +
|
|
" <div id=\"chart_canvasGroup\" class=\"temp\">\n" +
|
|
" <canvas class=\"chart_canvas\" id=\"chart_mainCanvas\"\n" +
|
|
" style=\"cursor: default;\"></canvas>\n" +
|
|
" <canvas class=\"chart_canvas\" id=\"chart_overlayCanvas\"\n" +
|
|
" style=\"cursor: default;\"></canvas>\n" +
|
|
" </div>\n" +
|
|
" <!-- TabBar -->\n" +
|
|
" <div id=\"chart_tabbar\"\">\n" +
|
|
" <ul>\n" +
|
|
" <li><a name=\"MACD\" class=\"\">MACD</a></li>\n" +
|
|
" <li><a name=\"KDJ\" class=\"\">KDJ</a></li>\n" +
|
|
" <li><a name=\"StochRSI\" class=\"\">StochRSI</a></li>\n" +
|
|
" <li><a name=\"RSI\" class=\"\">RSI</a></li>\n" +
|
|
" <li><a name=\"DMI\" class=\"\">DMI</a></li>\n" +
|
|
" <li><a name=\"OBV\" class=\"\">OBV</a></li>\n" +
|
|
" <li><a name=\"BOLL\" class=\"\">BOLL</a></li>\n" +
|
|
" <li><a name=\"SAR\" class=\"\">SAR</a></li>\n" +
|
|
" <li><a name=\"DMA\" class=\"\">DMA</a></li>\n" +
|
|
" <li><a name=\"TRIX\" class=\"\">TRIX</a></li>\n" +
|
|
" <li><a name=\"BRAR\" class=\"\">BRAR</a></li>\n" +
|
|
" <li><a name=\"VR\" class=\"\">VR</a></li>\n" +
|
|
" <li><a name=\"EMV\" class=\"\">EMV</a></li>\n" +
|
|
" <li><a name=\"WR\" class=\"\">WR</a></li>\n" +
|
|
" <li><a name=\"ROC\" class=\"\">ROC</a></li>\n" +
|
|
" <li><a name=\"MTM\" class=\"\">MTM</a></li>\n" +
|
|
" <li><a name=\"PSY\">PSY</a></li>\n" +
|
|
" </ul>\n" +
|
|
" </div>\n" +
|
|
" <!-- Parameter Settings -->\n" +
|
|
" <div id=\"chart_parameter_settings\">\n" +
|
|
" <h2 class=\"chart_str_indicator_parameters\">指标参数设置</h2>\n" +
|
|
" <table>\n" +
|
|
" <tbody>\n" +
|
|
" <tr>\n" +
|
|
" <th>MA</th>\n" +
|
|
" <td><input name=\"MA\"><input name=\"MA\"><input name=\"MA\"><input name=\"MA\"><br><input\n" +
|
|
" name=\"MA\"><input\n" +
|
|
" name=\"MA\"></td>\n" +
|
|
" <td>\n" +
|
|
" <button class=\"chart_str_default\">默认值</button>\n" +
|
|
" </td>\n" +
|
|
" <th>DMA</th>\n" +
|
|
" <td><input name=\"DMA\"><input name=\"DMA\"><input name=\"DMA\"></td>\n" +
|
|
" <td>\n" +
|
|
" <button class=\"chart_str_default\">默认值</button>\n" +
|
|
" </td>\n" +
|
|
" </tr>\n" +
|
|
" <tr>\n" +
|
|
" <th>EMA</th>\n" +
|
|
" <td><input name=\"EMA\"><input name=\"EMA\"><input name=\"EMA\"><input name=\"EMA\"><br><input\n" +
|
|
" name=\"EMA\"><input name=\"EMA\"></td>\n" +
|
|
" <td>\n" +
|
|
" <button class=\"chart_str_default\">默认值</button>\n" +
|
|
" </td>\n" +
|
|
" <th>TRIX</th>\n" +
|
|
" <td><input name=\"TRIX\"><input name=\"TRIX\"></td>\n" +
|
|
" <td>\n" +
|
|
" <button class=\"chart_str_default\">默认值</button>\n" +
|
|
" </td>\n" +
|
|
" </tr>\n" +
|
|
" <tr>\n" +
|
|
" <th>VOLUME</th>\n" +
|
|
" <td><input name=\"VOLUME\"><input name=\"VOLUME\"></td>\n" +
|
|
" <td>\n" +
|
|
" <button class=\"chart_str_default\">默认值</button>\n" +
|
|
" </td>\n" +
|
|
" <th>BRAR</th>\n" +
|
|
" <td><input name=\"BRAR\"></td>\n" +
|
|
" <td>\n" +
|
|
" <button class=\"chart_str_default\">默认值</button>\n" +
|
|
" </td>\n" +
|
|
" </tr>\n" +
|
|
" <tr>\n" +
|
|
" <th>MACD</th>\n" +
|
|
" <td><input name=\"MACD\"><input name=\"MACD\"><input name=\"MACD\"></td>\n" +
|
|
" <td>\n" +
|
|
" <button class=\"chart_str_default\">默认值</button>\n" +
|
|
" </td>\n" +
|
|
" <th>VR</th>\n" +
|
|
" <td><input name=\"VR\"><input name=\"VR\"></td>\n" +
|
|
" <td>\n" +
|
|
" <button class=\"chart_str_default\">默认值</button>\n" +
|
|
" </td>\n" +
|
|
" </tr>\n" +
|
|
" <tr>\n" +
|
|
" <th>KDJ</th>\n" +
|
|
" <td><input name=\"KDJ\"><input name=\"KDJ\"><input name=\"KDJ\"></td>\n" +
|
|
" <td>\n" +
|
|
" <button class=\"chart_str_default\">默认值</button>\n" +
|
|
" </td>\n" +
|
|
" <th>EMV</th>\n" +
|
|
" <td><input name=\"EMV\"><input name=\"EMV\"></td>\n" +
|
|
" <td>\n" +
|
|
" <button class=\"chart_str_default\">默认值</button>\n" +
|
|
" </td>\n" +
|
|
" </tr>\n" +
|
|
" <tr>\n" +
|
|
" <th>StochRSI</th>\n" +
|
|
" <td><input name=\"StochRSI\"><input name=\"StochRSI\"><input name=\"StochRSI\"><input name=\"StochRSI\">\n" +
|
|
" </td>\n" +
|
|
" <td>\n" +
|
|
" <button class=\"chart_str_default\">默认值</button>\n" +
|
|
" </td>\n" +
|
|
" <th>WR</th>\n" +
|
|
" <td><input name=\"WR\"><input name=\"WR\"></td>\n" +
|
|
" <td>\n" +
|
|
" <button class=\"chart_str_default\">默认值</button>\n" +
|
|
" </td>\n" +
|
|
" </tr>\n" +
|
|
" <tr>\n" +
|
|
" <th>RSI</th>\n" +
|
|
" <td><input name=\"RSI\"><input name=\"RSI\"><input name=\"RSI\"></td>\n" +
|
|
" <td>\n" +
|
|
" <button class=\"chart_str_default\">默认值</button>\n" +
|
|
" </td>\n" +
|
|
" <th>ROC</th>\n" +
|
|
" <td><input name=\"ROC\"><input name=\"ROC\"></td>\n" +
|
|
" <td>\n" +
|
|
" <button class=\"chart_str_default\">默认值</button>\n" +
|
|
" </td>\n" +
|
|
" </tr>\n" +
|
|
" <tr>\n" +
|
|
" <th>DMI</th>\n" +
|
|
" <td><input name=\"DMI\"><input name=\"DMI\"></td>\n" +
|
|
" <td>\n" +
|
|
" <button class=\"chart_str_default\">默认值</button>\n" +
|
|
" </td>\n" +
|
|
" <th>MTM</th>\n" +
|
|
" <td><input name=\"MTM\"><input name=\"MTM\"></td>\n" +
|
|
" <td>\n" +
|
|
" <button class=\"chart_str_default\">默认值</button>\n" +
|
|
" </td>\n" +
|
|
" </tr>\n" +
|
|
" <tr>\n" +
|
|
" <th>OBV</th>\n" +
|
|
" <td><input name=\"OBV\"></td>\n" +
|
|
" <td>\n" +
|
|
" <button class=\"chart_str_default\">默认值</button>\n" +
|
|
" </td>\n" +
|
|
" <th>PSY</th>\n" +
|
|
" <td><input name=\"PSY\"><input name=\"PSY\"></td>\n" +
|
|
" <td>\n" +
|
|
" <button class=\"chart_str_default\">默认值</button>\n" +
|
|
" </td>\n" +
|
|
" </tr>\n" +
|
|
" <tr>\n" +
|
|
" <th>BOLL</th>\n" +
|
|
" <td><input name=\"BOLL\"></td>\n" +
|
|
" <td>\n" +
|
|
" <button class=\"chart_str_default\">默认值</button>\n" +
|
|
" </td>\n" +
|
|
" </tr>\n" +
|
|
" </tbody>\n" +
|
|
" </table>\n" +
|
|
" <div id=\"close_settings\"><a class=\"chart_str_close\">关闭</a></div>\n" +
|
|
" </div>\n" +
|
|
" <!-- Loading -->\n" +
|
|
" <div id=\"chart_loading\" class=\"chart_str_loading\">正在读取数据...</div>\n" +
|
|
" </div>\n" +
|
|
" <div style=\"display: none\" id=\"chart_language_switch_tmp\">\n" +
|
|
" <span name=\"chart_str_period\" zh_tw=\"週期\" zh_cn=\"周期\" en_us=\"TIME\"></span>\n" +
|
|
" <span name=\"chart_str_period_line\" zh_tw=\"分時\" zh_cn=\"分时\" en_us=\"Line\"></span>\n" +
|
|
" <span name=\"chart_str_period_1m\" zh_tw=\"1分钟\" zh_cn=\"1分钟\" en_us=\"1m\"></span>\n" +
|
|
" <span name=\"chart_str_period_3m\" zh_tw=\"3分钟\" zh_cn=\"3分钟\" en_us=\"3m\"></span>\n" +
|
|
" <span name=\"chart_str_period_5m\" zh_tw=\"5分钟\" zh_cn=\"5分钟\" en_us=\"5m\"></span>\n" +
|
|
" <span name=\"chart_str_period_15m\" zh_tw=\"15分钟\" zh_cn=\"15分钟\" en_us=\"15m\"></span>\n" +
|
|
" <span name=\"chart_str_period_30m\" zh_tw=\"30分钟\" zh_cn=\"30分钟\" en_us=\"30m\"></span>\n" +
|
|
" <span name=\"chart_str_period_1h\" zh_tw=\"1小時\" zh_cn=\"1小时\" en_us=\"1h\"></span>\n" +
|
|
" <span name=\"chart_str_period_2h\" zh_tw=\"2小時\" zh_cn=\"2小时\" en_us=\"2h\"></span>\n" +
|
|
" <span name=\"chart_str_period_4h\" zh_tw=\"4小時\" zh_cn=\"4小时\" en_us=\"4h\"></span>\n" +
|
|
" <span name=\"chart_str_period_6h\" zh_tw=\"6小時\" zh_cn=\"6小时\" en_us=\"6h\"></span>\n" +
|
|
" <span name=\"chart_str_period_12h\" zh_tw=\"12小時\" zh_cn=\"12小时\" en_us=\"12h\"></span>\n" +
|
|
" <span name=\"chart_str_period_1d\" zh_tw=\"日線\" zh_cn=\"日线\" en_us=\"1d\"></span>\n" +
|
|
" <span name=\"chart_str_period_3d\" zh_tw=\"3日\" zh_cn=\"3日\" en_us=\"3d\"></span>\n" +
|
|
" <span name=\"chart_str_period_1w\" zh_tw=\"周線\" zh_cn=\"周线\" en_us=\"1w\"></span>\n" +
|
|
"\n" +
|
|
" <span name=\"chart_str_settings\" zh_tw=\"更多\" zh_cn=\"更多\" en_us=\"MORE\"></span>\n" +
|
|
" <span name=\"chart_setting_main_indicator\" zh_tw=\"均線設置\" zh_cn=\"均线设置\" en_us=\"Main Indicator\"></span>\n" +
|
|
" <span name=\"chart_setting_main_indicator_none\" zh_tw=\"關閉均線\" zh_cn=\"关闭均线\" en_us=\"None\"></span>\n" +
|
|
" <span name=\"chart_setting_indicator_parameters\" zh_tw=\"指標參數設置\" zh_cn=\"指标参数设置\"\n" +
|
|
" en_us=\"Indicator Parameters\"></span>\n" +
|
|
"\n" +
|
|
" <span name=\"chart_str_chart_style\" zh_tw=\"主圖樣式\" zh_cn=\"主图样式\" en_us=\"Chart Style\"></span>\n" +
|
|
" <span name=\"chart_str_main_indicator\" zh_tw=\"主指標\" zh_cn=\"主指标\" en_us=\"Main Indicator\"></span>\n" +
|
|
" <span name=\"chart_str_indicator\" zh_tw=\"技術指標\" zh_cn=\"技术指标\" en_us=\"Indicator\"></span>\n" +
|
|
" <span name=\"chart_str_indicator_cap\" zh_tw=\"技術指標\" zh_cn=\"技术指标\" en_us=\"INDICATOR\"></span>\n" +
|
|
" <span name=\"chart_str_tools\" zh_tw=\"畫線工具\" zh_cn=\"画线工具\" en_us=\"Tools\"></span>\n" +
|
|
" <span name=\"chart_str_tools_cap\" zh_tw=\"畫線工具\" zh_cn=\"画线工具\" en_us=\"TOOLS\"></span>\n" +
|
|
" <span name=\"chart_str_theme\" zh_tw=\"主題選擇\" zh_cn=\"主题选择\" en_us=\"Theme\"></span>\n" +
|
|
" <span name=\"chart_str_theme_cap\" zh_tw=\"主題選擇\" zh_cn=\"主题选择\" en_us=\"THEME\"></span>\n" +
|
|
"\n" +
|
|
" <span name=\"chart_language_setting\" zh_tw=\"語言(LANG)\" zh_cn=\"语言(LANG)\" en_us=\"LANGUAGE\"></span>\n" +
|
|
" <span name=\"chart_exchanges_setting\" zh_tw=\"更多市場\" zh_cn=\"更多市场\" en_us=\"MORE MARKETS\"></span>\n" +
|
|
" <span name=\"chart_othercoin_setting\" zh_tw=\"其它市場\" zh_cn=\"其它市场\" en_us=\"OTHER MARKETS\"></span>\n" +
|
|
"\n" +
|
|
"\n" +
|
|
" <span name=\"chart_str_none\" zh_tw=\"關閉\" zh_cn=\"关闭\" en_us=\"None\"></span>\n" +
|
|
"\n" +
|
|
" <span name=\"chart_str_theme_dark\" zh_tw=\"深色主題\" zh_cn=\"深色主题\" en_us=\"Dark\"></span>\n" +
|
|
" <span name=\"chart_str_theme_light\" zh_tw=\"淺色主題\" zh_cn=\"浅色主题\" en_us=\"Light\"></span>\n" +
|
|
"\n" +
|
|
" <span name=\"chart_str_on\" zh_tw=\"開啟\" zh_cn=\"开启\" en_us=\"On\"></span>\n" +
|
|
" <span name=\"chart_str_off\" zh_tw=\"關閉\" zh_cn=\"关闭\" en_us=\"Off\"></span>\n" +
|
|
"\n" +
|
|
" <span name=\"chart_str_close\" zh_tw=\"關閉\" zh_cn=\"关闭\" en_us=\"CLOSE\"></span>\n" +
|
|
" <span name=\"chart_str_default\" zh_tw=\"默認值\" zh_cn=\"默认值\" en_us=\"default\"></span>\n" +
|
|
"\n" +
|
|
" <span name=\"chart_str_loading\" zh_tw=\"正在讀取數據...\" zh_cn=\"正在读取数据...\" en_us=\"Loading...\"></span>\n" +
|
|
"\n" +
|
|
" <span name=\"chart_str_indicator_parameters\" zh_tw=\"指標參數設置\" zh_cn=\"指标参数设置\"\n" +
|
|
" en_us=\"Indicator Parameters\"></span>\n" +
|
|
"\n" +
|
|
" <span name=\"chart_str_cursor\" zh_tw=\"光標\" zh_cn=\"光标\" en_us=\"Cursor\"></span>\n" +
|
|
" <span name=\"chart_str_cross_cursor\" zh_tw=\"十字光標\" zh_cn=\"十字光标\" en_us=\"Cross Cursor\"></span>\n" +
|
|
" <span name=\"chart_str_seg_line\" zh_tw=\"線段\" zh_cn=\"线段\" en_us=\"Trend Line\"></span>\n" +
|
|
" <span name=\"chart_str_straight_line\" zh_tw=\"直線\" zh_cn=\"直线\" en_us=\"Extended\"></span>\n" +
|
|
" <span name=\"chart_str_ray_line\" zh_tw=\"射線\" zh_cn=\"射线\" en_us=\"Ray\"></span>\n" +
|
|
" <span name=\"chart_str_arrow_line\" zh_tw=\"箭頭\" zh_cn=\"箭头\" en_us=\"Arrow\"></span>\n" +
|
|
" <span name=\"chart_str_horz_seg_line\" zh_tw=\"水平線段\" zh_cn=\"水平线段\" en_us=\"Horizontal Line\"></span>\n" +
|
|
" <span name=\"chart_str_horz_straight_line\" zh_tw=\"水平直線\" zh_cn=\"水平直线\" en_us=\"Horizontal Extended\"></span>\n" +
|
|
" <span name=\"chart_str_horz_ray_line\" zh_tw=\"水平射線\" zh_cn=\"水平射线\" en_us=\"Horizontal Ray\"></span>\n" +
|
|
" <span name=\"chart_str_vert_straight_line\" zh_tw=\"垂直直線\" zh_cn=\"垂直直线\" en_us=\"Vertical Extended\"></span>\n" +
|
|
" <span name=\"chart_str_price_line\" zh_tw=\"價格線\" zh_cn=\"价格线\" en_us=\"Price Line\"></span>\n" +
|
|
" <span name=\"chart_str_tri_parallel_line\" zh_tw=\"價格通道線\" zh_cn=\"价格通道线\" en_us=\"Parallel Channel\"></span>\n" +
|
|
" <span name=\"chart_str_bi_parallel_line\" zh_tw=\"平行直線\" zh_cn=\"平行直线\" en_us=\"Parallel Lines\"></span>\n" +
|
|
" <span name=\"chart_str_bi_parallel_ray\" zh_tw=\"平行射線\" zh_cn=\"平行射线\" en_us=\"Parallel Rays\"></span>\n" +
|
|
" <span name=\"chart_str_fib_retrace\" zh_tw=\"斐波納契回調\" zh_cn=\"斐波纳契回调\" en_us=\"Fibonacci Retracements\"></span>\n" +
|
|
" <span name=\"chart_str_fib_fans\" zh_tw=\"斐波納契扇形\" zh_cn=\"斐波纳契扇形\" en_us=\"Fibonacci Fans\"></span>\n" +
|
|
"\n" +
|
|
" <span name=\"chart_str_updated\" zh_tw=\"更新於\" zh_cn=\"更新于\" en_us=\"Updated\"></span>\n" +
|
|
" <span name=\"chart_str_ago\" zh_tw=\"前\" zh_cn=\"前\" en_us=\"ago\"></span>\n" +
|
|
"</div>\n";
|
|
|
|
function draw(instance) {
|
|
KlineIns = instance;
|
|
KlineTradeIns = new KlineTrade();
|
|
var template = $.parseHTML(template_str);
|
|
for (var k in KlineIns.ranges) {
|
|
var res = $(template).find('[name="' + KlineIns.ranges[k] + '"]');
|
|
res.each(function (i, e) {
|
|
$(e).attr("style", "display:inline-block");
|
|
});
|
|
}
|
|
$(KlineIns.element).html(template);
|
|
var refresh_handler = setInterval(refresh_function, KlineIns.intervalTime);
|
|
if (KlineIns.type == "socket") {
|
|
socketConnect();
|
|
}
|
|
window._setMarketFrom = function (content) {
|
|
Template.displayVolume = false;
|
|
refreshTemplate();
|
|
readCookie();
|
|
ChartManager.getInstance().getChart().setSymbol(content);
|
|
};
|
|
window._set_current_language = function (content) {
|
|
chart_switch_language(content);
|
|
};
|
|
window._set_current_depth = function (content) {
|
|
ChartManager.getInstance().getChart().updateDepth(content);
|
|
};
|
|
window._set_current_url = function (content) {
|
|
KlineIns.url = content;
|
|
};
|
|
window._set_current_contract_unit = function (str) {
|
|
ChartManager.getInstance().getChart().setCurrentContractUnit(str);
|
|
};
|
|
window._set_money_type = function (str) {
|
|
ChartManager.getInstance().getChart().setCurrentMoneyType(str);
|
|
};
|
|
window._set_usd_cny_rate = function (rate) {
|
|
ChartManager.getInstance().getChart()._usd_cny_rate = rate;
|
|
};
|
|
window._setCaptureMouseWheelDirectly = function (b) {
|
|
ChartManager.getInstance().setCaptureMouseWheelDirectly(b);
|
|
};
|
|
window._current_future_change = new MEvent();
|
|
window._current_theme_change = new MEvent();
|
|
KLineMouseEvent();
|
|
ChartManager.getInstance().bindCanvas("main", document.getElementById("chart_mainCanvas"));
|
|
ChartManager.getInstance().bindCanvas("overlay", document.getElementById("chart_overlayCanvas"));
|
|
refreshTemplate();
|
|
on_size(KlineIns.width, KlineIns.height);
|
|
readCookie();
|
|
|
|
KlineIns.setTheme(KlineIns.theme);
|
|
KlineIns.setLanguage(KlineIns.language);
|
|
|
|
$(KlineIns.element).css({visibility: "visible"});
|
|
}
|
|
|
|
try {
|
|
module.exports = exports = Kline;
|
|
} catch (e) {
|
|
}
|