package.src.traces.ohlc.calc.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of plotly.js Show documentation
Show all versions of plotly.js Show documentation
The open source javascript graphing library that powers plotly
The newest version!
'use strict';
var Lib = require('../../lib');
var _ = Lib._;
var Axes = require('../../plots/cartesian/axes');
var alignPeriod = require('../../plots/cartesian/align_period');
var BADNUM = require('../../constants/numerical').BADNUM;
function calc(gd, trace) {
var xa = Axes.getFromId(gd, trace.xaxis);
var ya = Axes.getFromId(gd, trace.yaxis);
var tickLen = convertTickWidth(gd, xa, trace);
var minDiff = trace._minDiff;
trace._minDiff = null;
var origX = trace._origX;
trace._origX = null;
var x = trace._xcalc;
trace._xcalc = null;
var cd = calcCommon(gd, trace, origX, x, ya, ptFunc);
trace._extremes[xa._id] = Axes.findExtremes(xa, x, {vpad: minDiff / 2});
if(cd.length) {
Lib.extendFlat(cd[0].t, {
wHover: minDiff / 2,
tickLen: tickLen
});
return cd;
} else {
return [{t: {empty: true}}];
}
}
function ptFunc(o, h, l, c) {
return {
o: o,
h: h,
l: l,
c: c
};
}
// shared between OHLC and candlestick
// ptFunc makes a calcdata point specific to each trace type, from oi, hi, li, ci
function calcCommon(gd, trace, origX, x, ya, ptFunc) {
var o = ya.makeCalcdata(trace, 'open');
var h = ya.makeCalcdata(trace, 'high');
var l = ya.makeCalcdata(trace, 'low');
var c = ya.makeCalcdata(trace, 'close');
var hasTextArray = Lib.isArrayOrTypedArray(trace.text);
var hasHovertextArray = Lib.isArrayOrTypedArray(trace.hovertext);
// we're optimists - before we have any changing data, assume increasing
var increasing = true;
var cPrev = null;
var hasPeriod = !!trace.xperiodalignment;
var cd = [];
for(var i = 0; i < x.length; i++) {
var xi = x[i];
var oi = o[i];
var hi = h[i];
var li = l[i];
var ci = c[i];
if(xi !== BADNUM && oi !== BADNUM && hi !== BADNUM && li !== BADNUM && ci !== BADNUM) {
if(ci === oi) {
// if open == close, look for a change from the previous close
if(cPrev !== null && ci !== cPrev) increasing = ci > cPrev;
// else (c === cPrev or cPrev is null) no change
} else increasing = ci > oi;
cPrev = ci;
var pt = ptFunc(oi, hi, li, ci);
pt.pos = xi;
pt.yc = (oi + ci) / 2;
pt.i = i;
pt.dir = increasing ? 'increasing' : 'decreasing';
// For categoryorder, store low and high
pt.x = pt.pos;
pt.y = [li, hi];
if(hasPeriod) pt.orig_p = origX[i]; // used by hover
if(hasTextArray) pt.tx = trace.text[i];
if(hasHovertextArray) pt.htx = trace.hovertext[i];
cd.push(pt);
} else {
cd.push({pos: xi, empty: true});
}
}
trace._extremes[ya._id] = Axes.findExtremes(ya, Lib.concat(l, h), {padded: true});
if(cd.length) {
cd[0].t = {
labels: {
open: _(gd, 'open:') + ' ',
high: _(gd, 'high:') + ' ',
low: _(gd, 'low:') + ' ',
close: _(gd, 'close:') + ' '
}
};
}
return cd;
}
/*
* find min x-coordinates difference of all traces
* attached to this x-axis and stash the result in _minDiff
* in all traces; when a trace uses this in its
* calc step it deletes _minDiff, so that next calc this is
* done again in case the data changed.
* also since we need it here, stash _xcalc (and _origX) on the trace
*/
function convertTickWidth(gd, xa, trace) {
var minDiff = trace._minDiff;
if(!minDiff) {
var fullData = gd._fullData;
var ohlcTracesOnThisXaxis = [];
minDiff = Infinity;
var i;
for(i = 0; i < fullData.length; i++) {
var tracei = fullData[i];
if(tracei.type === 'ohlc' &&
tracei.visible === true &&
tracei.xaxis === xa._id
) {
ohlcTracesOnThisXaxis.push(tracei);
var origX = xa.makeCalcdata(tracei, 'x');
tracei._origX = origX;
var xcalc = alignPeriod(trace, xa, 'x', origX).vals;
tracei._xcalc = xcalc;
var _minDiff = Lib.distinctVals(xcalc).minDiff;
if(_minDiff && isFinite(_minDiff)) {
minDiff = Math.min(minDiff, _minDiff);
}
}
}
// if minDiff is still Infinity here, set it to 1
if(minDiff === Infinity) minDiff = 1;
for(i = 0; i < ohlcTracesOnThisXaxis.length; i++) {
ohlcTracesOnThisXaxis[i]._minDiff = minDiff;
}
}
return minDiff * trace.tickwidth;
}
module.exports = {
calc: calc,
calcCommon: calcCommon
};