extjs-gpl
Version:
GPL licensed version of Sencha Ext JS
163 lines (149 loc) • 5.59 kB
JavaScript
/**
* @class Ext.chart.series.sprite.CandleStick
* @extends Ext.chart.series.sprite.Aggregative
*
* CandleStick series sprite.
*/
Ext.define('Ext.chart.series.sprite.CandleStick', {
alias: 'sprite.candlestickSeries',
extend: 'Ext.chart.series.sprite.Aggregative',
inheritableStatics: {
def: {
processors: {
raiseStyle: function (n, o) {
return Ext.merge({}, o || {}, n);
},
dropStyle: function (n, o) {
return Ext.merge({}, o || {}, n);
},
/**
* @cfg {Number} [barWidth=15] The bar width of the candles.
*/
barWidth: 'number',
/**
* @cfg {Number} [padding=3] The amount of padding between candles.
*/
padding: 'number',
/**
* @cfg {String} [ohlcType='candlestick'] Determines whether candlestick or ohlc is used.
*/
ohlcType: 'enums(candlestick,ohlc)'
},
defaults: {
raiseStyle: {
strokeStyle: 'green',
fillStyle: 'green'
},
dropStyle: {
strokeStyle: 'red',
fillStyle: 'red'
},
planar: false,
barWidth: 15,
padding: 3,
lineJoin: 'miter',
miterLimit: 5,
ohlcType: 'candlestick'
},
triggers: {
raiseStyle: 'raiseStyle',
dropStyle: 'dropStyle'
},
updaters: {
raiseStyle: function () {
this.raiseTemplate && this.raiseTemplate.setAttributes(this.attr.raiseStyle);
},
dropStyle: function () {
this.dropTemplate && this.dropTemplate.setAttributes(this.attr.dropStyle);
}
}
}
},
candlestick: function (ctx, open, high, low, close, mid, halfWidth) {
var minOC = Math.min(open, close),
maxOC = Math.max(open, close);
ctx.moveTo(mid, low);
ctx.lineTo(mid, maxOC);
ctx.moveTo(mid + halfWidth, maxOC);
ctx.lineTo(mid + halfWidth, minOC);
ctx.lineTo(mid - halfWidth, minOC);
ctx.lineTo(mid - halfWidth, maxOC);
ctx.closePath();
ctx.moveTo(mid, high);
ctx.lineTo(mid, minOC);
},
ohlc: function (ctx, open, high, low, close, mid, halfWidth) {
ctx.moveTo(mid, high);
ctx.lineTo(mid, low);
ctx.moveTo(mid, open);
ctx.lineTo(mid - halfWidth, open);
ctx.moveTo(mid, close);
ctx.lineTo(mid + halfWidth, close);
},
constructor: function () {
this.callParent(arguments);
this.raiseTemplate = new Ext.draw.sprite.Rect({parent: this});
this.dropTemplate = new Ext.draw.sprite.Rect({parent: this});
},
getGapWidth: function () {
var attr = this.attr,
barWidth = attr.barWidth,
padding = attr.padding;
return barWidth + padding;
},
renderAggregates: function (aggregates, start, end, surface, ctx, clip) {
var me = this,
attr = this.attr,
dataX = attr.dataX,
matrix = attr.matrix,
xx = matrix.getXX(),
yy = matrix.getYY(),
dx = matrix.getDX(),
dy = matrix.getDY(),
barWidth = attr.barWidth / xx,
template,
ohlcType = attr.ohlcType,
halfWidth = Math.round(barWidth * 0.5 * xx),
opens = aggregates.open,
closes = aggregates.close,
maxYs = aggregates.maxY,
minYs = aggregates.minY,
startIdxs = aggregates.startIdx,
open, high, low, close, mid,
i,
pixelAdjust = attr.lineWidth * surface.devicePixelRatio / 2;
pixelAdjust -= Math.floor(pixelAdjust);
ctx.save();
template = this.raiseTemplate;
template.useAttributes(ctx, clip);
ctx.beginPath();
for (i = start; i < end; i++) {
if (opens[i] <= closes[i]) {
open = Math.round(opens[i] * yy + dy) + pixelAdjust;
high = Math.round(maxYs[i] * yy + dy) + pixelAdjust;
low = Math.round(minYs[i] * yy + dy) + pixelAdjust;
close = Math.round(closes[i] * yy + dy) + pixelAdjust;
mid = Math.round(dataX[startIdxs[i]] * xx + dx) + pixelAdjust;
me[ohlcType](ctx, open, high, low, close, mid, halfWidth);
}
}
ctx.fillStroke(template.attr);
ctx.restore();
ctx.save();
template = this.dropTemplate;
template.useAttributes(ctx, clip);
ctx.beginPath();
for (i = start; i < end; i++) {
if (opens[i] > closes[i]) {
open = Math.round(opens[i] * yy + dy) + pixelAdjust;
high = Math.round(maxYs[i] * yy + dy) + pixelAdjust;
low = Math.round(minYs[i] * yy + dy) + pixelAdjust;
close = Math.round(closes[i] * yy + dy) + pixelAdjust;
mid = Math.round(dataX[startIdxs[i]] * xx + dx) + pixelAdjust;
me[ohlcType](ctx, open, high, low, close, mid, halfWidth);
}
}
ctx.fillStroke(template.attr);
ctx.restore();
}
});