klinecharts
Version:
Lightweight k-line chart built with html5 canvas
1,315 lines (1,275 loc) • 613 kB
JavaScript
/**
* @license
* KLineChart v10.0.0-alpha5
* Copyright (c) 2019 lihu.
* Licensed under Apache License 2.0 https://www.apache.org/licenses/LICENSE-2.0
*/
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
var extendStatics = function(d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
}
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function __generator(thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
}
function __values(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
}
function __read(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
}
function __spreadArray(to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
/**
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- ignore
function merge(target, source) {
if ((!isObject(target) && !isObject(source))) {
return;
}
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access -- ignore
var targetProp = target[key];
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access -- ignore
var sourceProp = source[key];
if (isObject(sourceProp) &&
isObject(targetProp)) {
merge(targetProp, sourceProp);
}
else {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- ignore
if (isValid(source[key])) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access -- ignore
target[key] = clone(source[key]);
}
}
}
}
}
function clone(target) {
if (!isObject(target)) {
return target;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- ignore
var copy = null;
if (isArray(target)) {
copy = [];
}
else {
copy = {};
}
for (var key in target) {
if (Object.prototype.hasOwnProperty.call(target, key)) {
var v = target[key];
if (isObject(v)) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- ignore
copy[key] = clone(v);
}
else {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- ignore
copy[key] = v;
}
}
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-return -- ignore
return copy;
}
function isArray(value) {
return Object.prototype.toString.call(value) === '[object Array]';
}
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters -- ignore
function isFunction(value) {
return typeof value === 'function';
}
function isObject(value) {
return (typeof value === 'object') && isValid(value);
}
function isNumber(value) {
return typeof value === 'number' && Number.isFinite(value);
}
function isValid(value) {
return value !== null && value !== undefined;
}
function isBoolean(value) {
return typeof value === 'boolean';
}
function isString(value) {
return typeof value === 'string';
}
/**
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function isTransparent(color) {
return color === 'transparent' ||
color === 'none' ||
/^[rR][gG][Bb][Aa]\(([\s]*(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?)[\s]*,){3}[\s]*0[\s]*\)$/.test(color) ||
/^[hH][Ss][Ll][Aa]\(([\s]*(360|3[0-5][0-9]|[012]?[0-9][0-9]?)[\s]*,)([\s]*((100|[0-9][0-9]?)%|0)[\s]*,){2}([\s]*0[\s]*)\)$/.test(color);
}
function hexToRgb(hex, alpha) {
var h = hex.replace(/^#/, '');
var i = parseInt(h, 16);
var r = (i >> 16) & 255;
var g = (i >> 8) & 255;
var b = i & 255;
return "rgba(".concat(r, ", ").concat(g, ", ").concat(b, ", ").concat(alpha !== null && alpha !== void 0 ? alpha : 1, ")");
}
/**
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* line type
*/
var LineType;
(function (LineType) {
LineType["Dashed"] = "dashed";
LineType["Solid"] = "solid";
})(LineType || (LineType = {}));
var PathType;
(function (PathType) {
PathType["Stroke"] = "stroke";
PathType["Fill"] = "fill";
})(PathType || (PathType = {}));
var PolygonType;
(function (PolygonType) {
PolygonType["Stroke"] = "stroke";
PolygonType["Fill"] = "fill";
PolygonType["StrokeFill"] = "stroke_fill";
})(PolygonType || (PolygonType = {}));
var TooltipShowRule;
(function (TooltipShowRule) {
TooltipShowRule["Always"] = "always";
TooltipShowRule["FollowCross"] = "follow_cross";
TooltipShowRule["None"] = "none";
})(TooltipShowRule || (TooltipShowRule = {}));
var TooltipShowType;
(function (TooltipShowType) {
TooltipShowType["Standard"] = "standard";
TooltipShowType["Rect"] = "rect";
})(TooltipShowType || (TooltipShowType = {}));
var TooltipFeatureType;
(function (TooltipFeatureType) {
TooltipFeatureType["Path"] = "path";
TooltipFeatureType["IconFont"] = "icon_font";
})(TooltipFeatureType || (TooltipFeatureType = {}));
var TooltipFeaturePosition;
(function (TooltipFeaturePosition) {
TooltipFeaturePosition["Left"] = "left";
TooltipFeaturePosition["Middle"] = "middle";
TooltipFeaturePosition["Right"] = "right";
})(TooltipFeaturePosition || (TooltipFeaturePosition = {}));
var CandleTooltipRectPosition;
(function (CandleTooltipRectPosition) {
CandleTooltipRectPosition["Fixed"] = "fixed";
CandleTooltipRectPosition["Pointer"] = "pointer";
})(CandleTooltipRectPosition || (CandleTooltipRectPosition = {}));
var CandleType;
(function (CandleType) {
CandleType["CandleSolid"] = "candle_solid";
CandleType["CandleStroke"] = "candle_stroke";
CandleType["CandleUpStroke"] = "candle_up_stroke";
CandleType["CandleDownStroke"] = "candle_down_stroke";
CandleType["Ohlc"] = "ohlc";
CandleType["Area"] = "area";
})(CandleType || (CandleType = {}));
var CandleColorCompareRule;
(function (CandleColorCompareRule) {
CandleColorCompareRule["CurrentOpen"] = "current_open";
CandleColorCompareRule["PreviousClose"] = "previous_close";
})(CandleColorCompareRule || (CandleColorCompareRule = {}));
var Color = {
RED: '#F92855',
GREEN: '#2DC08E',
WHITE: '#FFFFFF',
GREY: '#76808F',
BLUE: '#1677FF'
};
function getDefaultGridStyle() {
return {
show: true,
horizontal: {
show: true,
size: 1,
color: '#EDEDED',
style: LineType.Dashed,
dashedValue: [2, 2]
},
vertical: {
show: true,
size: 1,
color: '#EDEDED',
style: LineType.Dashed,
dashedValue: [2, 2]
}
};
}
/**
* Get default candle style
* @type {{area: {backgroundColor: [{offset: number, color: string}, {offset: number, color: string}], lineColor: string, lineSize: number, value: string}, bar: {noChangeColor: string, upColor: string, downColor: string}, tooltip: {rect: {offsetTop: number, fillColor: string, borderColor: string, paddingBottom: number, borderRadius: number, paddingRight: number, borderSize: number, offsetLeft: number, paddingTop: number, paddingLeft: number, offsetRight: number}, showRule: string, values: null, showType: string, text: {marginRight: number, size: number, color: string, weight: string, marginBottom: number, family: string, marginTop: number, marginLeft: number}, labels: string[]}, type: string, priceMark: {high: {textMargin: number, textSize: number, color: string, textFamily: string, show: boolean, textWeight: string}, last: {noChangeColor: string, upColor: string, line: {dashValue: number[], size: number, show: boolean, style: string}, show: boolean, text: {paddingBottom: number, size: number, color: string, paddingRight: number, show: boolean, weight: string, paddingTop: number, family: string, paddingLeft: number}, downColor: string}, low: {textMargin: number, textSize: number, color: string, textFamily: string, show: boolean, textWeight: string}, show: boolean}}}
*/
function getDefaultCandleStyle() {
var highLow = {
show: true,
color: Color.GREY,
textOffset: 5,
textSize: 10,
textFamily: 'Helvetica Neue',
textWeight: 'normal'
};
return {
type: CandleType.CandleSolid,
bar: {
compareRule: CandleColorCompareRule.CurrentOpen,
upColor: Color.GREEN,
downColor: Color.RED,
noChangeColor: Color.GREY,
upBorderColor: Color.GREEN,
downBorderColor: Color.RED,
noChangeBorderColor: Color.GREY,
upWickColor: Color.GREEN,
downWickColor: Color.RED,
noChangeWickColor: Color.GREY
},
area: {
lineSize: 2,
lineColor: Color.BLUE,
smooth: false,
value: 'close',
backgroundColor: [{
offset: 0,
color: hexToRgb(Color.BLUE, 0.01)
}, {
offset: 1,
color: hexToRgb(Color.BLUE, 0.2)
}],
point: {
show: true,
color: Color.BLUE,
radius: 4,
rippleColor: hexToRgb(Color.BLUE, 0.3),
rippleRadius: 8,
animation: true,
animationDuration: 1000
}
},
priceMark: {
show: true,
high: __assign({}, highLow),
low: __assign({}, highLow),
last: {
show: true,
compareRule: CandleColorCompareRule.CurrentOpen,
upColor: Color.GREEN,
downColor: Color.RED,
noChangeColor: Color.GREY,
line: {
show: true,
style: LineType.Dashed,
dashedValue: [4, 4],
size: 1
},
text: {
show: true,
style: PolygonType.Fill,
size: 12,
paddingLeft: 4,
paddingTop: 4,
paddingRight: 4,
paddingBottom: 4,
borderColor: 'transparent',
borderStyle: LineType.Solid,
borderSize: 0,
borderDashedValue: [2, 2],
color: Color.WHITE,
family: 'Helvetica Neue',
weight: 'normal',
borderRadius: 2
}
}
},
tooltip: {
offsetLeft: 4,
offsetTop: 6,
offsetRight: 4,
offsetBottom: 6,
showRule: TooltipShowRule.Always,
showType: TooltipShowType.Standard,
custom: [
{ title: 'time', value: '{time}' },
{ title: 'open', value: '{open}' },
{ title: 'high', value: '{high}' },
{ title: 'low', value: '{low}' },
{ title: 'close', value: '{close}' },
{ title: 'volume', value: '{volume}' }
],
defaultValue: 'n/a',
rect: {
position: CandleTooltipRectPosition.Fixed,
paddingLeft: 4,
paddingRight: 4,
paddingTop: 4,
paddingBottom: 4,
offsetLeft: 4,
offsetTop: 4,
offsetRight: 4,
offsetBottom: 4,
borderRadius: 4,
borderSize: 1,
borderColor: '#F2F3F5',
color: '#FEFEFE'
},
text: {
size: 12,
family: 'Helvetica Neue',
weight: 'normal',
color: Color.GREY,
marginLeft: 8,
marginTop: 4,
marginRight: 8,
marginBottom: 4
},
features: []
}
};
}
/**
* Get default indicator style
*/
function getDefaultIndicatorStyle() {
var alphaGreen = hexToRgb(Color.GREEN, 0.7);
var alphaRed = hexToRgb(Color.RED, 0.7);
return {
ohlc: {
compareRule: CandleColorCompareRule.CurrentOpen,
upColor: alphaGreen,
downColor: alphaRed,
noChangeColor: Color.GREY
},
bars: [{
style: PolygonType.Fill,
borderStyle: LineType.Solid,
borderSize: 1,
borderDashedValue: [2, 2],
upColor: alphaGreen,
downColor: alphaRed,
noChangeColor: Color.GREY
}],
lines: ['#FF9600', '#935EBD', Color.BLUE, '#E11D74', '#01C5C4'].map(function (color) { return ({
style: LineType.Solid,
smooth: false,
size: 1,
dashedValue: [2, 2],
color: color
}); }),
circles: [{
style: PolygonType.Fill,
borderStyle: LineType.Solid,
borderSize: 1,
borderDashedValue: [2, 2],
upColor: alphaGreen,
downColor: alphaRed,
noChangeColor: Color.GREY
}],
lastValueMark: {
show: false,
text: {
show: false,
style: PolygonType.Fill,
color: Color.WHITE,
size: 12,
family: 'Helvetica Neue',
weight: 'normal',
borderStyle: LineType.Solid,
borderColor: 'transparent',
borderSize: 0,
borderDashedValue: [2, 2],
paddingLeft: 4,
paddingTop: 4,
paddingRight: 4,
paddingBottom: 4,
borderRadius: 2
}
},
tooltip: {
offsetLeft: 4,
offsetTop: 6,
offsetRight: 4,
offsetBottom: 6,
showRule: TooltipShowRule.Always,
showType: TooltipShowType.Standard,
showName: true,
showParams: true,
defaultValue: 'n/a',
text: {
size: 12,
family: 'Helvetica Neue',
weight: 'normal',
color: Color.GREY,
marginLeft: 8,
marginTop: 4,
marginRight: 8,
marginBottom: 4
},
features: []
}
};
}
function getDefaultAxisStyle() {
return {
show: true,
size: 'auto',
axisLine: {
show: true,
color: '#DDDDDD',
size: 1
},
tickText: {
show: true,
color: Color.GREY,
size: 12,
family: 'Helvetica Neue',
weight: 'normal',
marginStart: 4,
marginEnd: 6
},
tickLine: {
show: true,
size: 1,
length: 3,
color: '#DDDDDD'
}
};
}
function getDefaultCrosshairStyle() {
function item() {
return {
show: true,
line: {
show: true,
style: LineType.Dashed,
dashedValue: [4, 2],
size: 1,
color: Color.GREY
},
text: {
show: true,
style: PolygonType.Fill,
color: Color.WHITE,
size: 12,
family: 'Helvetica Neue',
weight: 'normal',
borderStyle: LineType.Solid,
borderDashedValue: [2, 2],
borderSize: 1,
borderColor: Color.GREY,
borderRadius: 2,
paddingLeft: 4,
paddingRight: 4,
paddingTop: 4,
paddingBottom: 4,
backgroundColor: Color.GREY
}
};
}
return {
show: true,
horizontal: item(),
vertical: item()
};
}
function getDefaultOverlayStyle() {
var pointBorderColor = hexToRgb(Color.BLUE, 0.35);
var alphaBg = hexToRgb(Color.BLUE, 0.25);
function text() {
return {
style: PolygonType.Fill,
color: Color.WHITE,
size: 12,
family: 'Helvetica Neue',
weight: 'normal',
borderStyle: LineType.Solid,
borderDashedValue: [2, 2],
borderSize: 1,
borderRadius: 2,
borderColor: Color.BLUE,
paddingLeft: 4,
paddingRight: 4,
paddingTop: 4,
paddingBottom: 4,
backgroundColor: Color.BLUE
};
}
return {
point: {
color: Color.BLUE,
borderColor: pointBorderColor,
borderSize: 1,
radius: 5,
activeColor: Color.BLUE,
activeBorderColor: pointBorderColor,
activeBorderSize: 3,
activeRadius: 5
},
line: {
style: LineType.Solid,
smooth: false,
color: Color.BLUE,
size: 1,
dashedValue: [2, 2]
},
rect: {
style: PolygonType.Fill,
color: alphaBg,
borderColor: Color.BLUE,
borderSize: 1,
borderRadius: 0,
borderStyle: LineType.Solid,
borderDashedValue: [2, 2]
},
polygon: {
style: PolygonType.Fill,
color: Color.BLUE,
borderColor: Color.BLUE,
borderSize: 1,
borderStyle: LineType.Solid,
borderDashedValue: [2, 2]
},
circle: {
style: PolygonType.Fill,
color: alphaBg,
borderColor: Color.BLUE,
borderSize: 1,
borderStyle: LineType.Solid,
borderDashedValue: [2, 2]
},
arc: {
style: LineType.Solid,
color: Color.BLUE,
size: 1,
dashedValue: [2, 2]
},
text: text()
};
}
function getDefaultSeparatorStyle() {
return {
size: 1,
color: '#DDDDDD',
fill: true,
activeBackgroundColor: hexToRgb(Color.BLUE, 0.08)
};
}
function getDefaultStyles() {
return {
grid: getDefaultGridStyle(),
candle: getDefaultCandleStyle(),
indicator: getDefaultIndicatorStyle(),
xAxis: getDefaultAxisStyle(),
yAxis: getDefaultAxisStyle(),
separator: getDefaultSeparatorStyle(),
crosshair: getDefaultCrosshairStyle(),
overlay: getDefaultOverlayStyle()
};
}
/**
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var DEV = process.env.NODE_ENV === 'development';
function log(templateText, tagStyle, messageStyle, api, invalidParam, append) {
if (DEV) {
var apiStr = api !== '' ? "Call api `".concat(api, "`").concat(invalidParam !== '' || append !== '' ? ', ' : '.') : '';
var invalidParamStr = invalidParam !== '' ? "invalid parameter `".concat(invalidParam, "`").concat(append !== '' ? ', ' : '.') : '';
var appendStr = append !== '' ? append : '';
console.log(templateText, tagStyle, messageStyle, apiStr, invalidParamStr, appendStr);
}
}
function logWarn(api, invalidParam, append) {
log('%c😑 klinecharts warning%c %s%s%s', 'padding:3px 4px;border-radius:2px;color:#ffffff;background-color:#FF9600', 'color:#FF9600', api, invalidParam, append !== null && append !== void 0 ? append : '');
}
function logError(api, invalidParam, append) {
log('%c😟 klinecharts error%c %s%s%s', 'padding:3px 4px;border-radius:2px;color:#ffffff;background-color:#F92855;', 'color:#F92855;', api, invalidParam, append );
}
function logTag() {
log('%c❤️ Welcome to klinecharts. Version is 10.0.0-alpha5', 'border-radius:4px;border:dashed 1px #1677FF;line-height:70px;padding:0 20px;margin:16px 0;font-size:14px;color:#1677FF;', '', '', '', '');
}
/**
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var reEscapeChar = /\\(\\)?/g;
var rePropName = RegExp('[^.[\\]]+' + '|' +
'\\[(?:' +
'([^"\'][^[]*)' + '|' +
'(["\'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2' +
')\\]' + '|' +
'(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))', 'g');
function formatValue(data, key, defaultValue) {
if (isValid(data)) {
var path_1 = [];
key.replace(rePropName, function (subString) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
var k = subString;
if (isValid(args[1])) {
k = args[2].replace(reEscapeChar, '$1');
}
else if (isValid(args[0])) {
k = args[0].trim();
}
path_1.push(k);
return '';
});
var value = data;
var index = 0;
var length_1 = path_1.length;
while (isValid(value) && index < length_1) {
value = value === null || value === void 0 ? void 0 : value[path_1[index++]];
}
return isValid(value) ? value : (defaultValue !== null && defaultValue !== void 0 ? defaultValue : '--');
}
return defaultValue !== null && defaultValue !== void 0 ? defaultValue : '--';
}
function formatTimestampToDateTime(dateTimeFormat, timestamp) {
var date = {};
dateTimeFormat.formatToParts(new Date(timestamp)).forEach(function (_a) {
var type = _a.type, value = _a.value;
switch (type) {
case 'year': {
date.YYYY = value;
break;
}
case 'month': {
date.MM = value;
break;
}
case 'day': {
date.DD = value;
break;
}
case 'hour': {
date.HH = value === '24' ? '00' : value;
break;
}
case 'minute': {
date.mm = value;
break;
}
case 'second': {
date.ss = value;
break;
}
}
});
return date;
}
function formatTimestampToString(dateTimeFormat, timestamp, format) {
var date = formatTimestampToDateTime(dateTimeFormat, timestamp);
// eslint-disable-next-line @typescript-eslint/no-unsafe-return -- ignore
return format.replace(/YYYY|MM|DD|HH|mm|ss/g, function (key) { return date[key]; });
}
function formatPrecision(value, precision) {
var v = +value;
if (isNumber(v)) {
return v.toFixed(precision !== null && precision !== void 0 ? precision : 2);
}
return "".concat(value);
}
function formatBigNumber(value) {
var v = +value;
if (isNumber(v)) {
if (v > 1000000000) {
return "".concat(+((v / 1000000000).toFixed(3)), "B");
}
if (v > 1000000) {
return "".concat(+((v / 1000000).toFixed(3)), "M");
}
if (v > 1000) {
return "".concat(+((v / 1000).toFixed(3)), "K");
}
}
return "".concat(value);
}
function formatThousands(value, sign) {
var vl = "".concat(value);
if (sign.length === 0) {
return vl;
}
if (vl.includes('.')) {
var arr = vl.split('.');
return "".concat(arr[0].replace(/(\d)(?=(\d{3})+$)/g, function ($1) { return "".concat($1).concat(sign); }), ".").concat(arr[1]);
}
return vl.replace(/(\d)(?=(\d{3})+$)/g, function ($1) { return "".concat($1).concat(sign); });
}
function formatFoldDecimal(value, threshold) {
var vl = "".concat(value);
var reg = new RegExp('\\.0{' + threshold + ',}[1-9][0-9]*$');
if (reg.test(vl)) {
var result = vl.split('.');
var lastIndex = result.length - 1;
var v = result[lastIndex];
var match = /0*/.exec(v);
if (isValid(match)) {
var count = match[0].length;
result[lastIndex] = v.replace(/0*/, "0{".concat(count, "}"));
return result.join('.');
}
}
return vl;
}
/**
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var measureCtx = null;
/**
* Get pixel ratio
* @param canvas
* @returns {number}
*/
function getPixelRatio(canvas) {
var _a, _b;
return (_b = (_a = canvas.ownerDocument.defaultView) === null || _a === void 0 ? void 0 : _a.devicePixelRatio) !== null && _b !== void 0 ? _b : 1;
}
function createFont(size, weight, family) {
return "".concat(weight !== null && weight !== void 0 ? weight : 'normal', " ").concat(size !== null && size !== void 0 ? size : 12, "px ").concat(family !== null && family !== void 0 ? family : 'Helvetica Neue');
}
/**
* Measure the width of text
* @param text
* @returns {number}
*/
function calcTextWidth(text, size, weight, family) {
if (!isValid(measureCtx)) {
var canvas = document.createElement('canvas');
var pixelRatio = getPixelRatio(canvas);
measureCtx = canvas.getContext('2d');
measureCtx.scale(pixelRatio, pixelRatio);
}
measureCtx.font = createFont(size, weight, family);
return Math.round(measureCtx.measureText(text).width);
}
/**
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var ActionType;
(function (ActionType) {
ActionType["OnZoom"] = "onZoom";
ActionType["OnScroll"] = "onScroll";
ActionType["OnVisibleRangeChange"] = "onVisibleRangeChange";
ActionType["OnCandleTooltipFeatureClick"] = "onCandleTooltipFeatureClick";
ActionType["OnCrosshairChange"] = "onCrosshairChange";
ActionType["OnCandleBarClick"] = "onCandleBarClick";
ActionType["OnPaneDrag"] = "onPaneDrag";
})(ActionType || (ActionType = {}));
var Action = /** @class */ (function () {
function Action() {
this._callbacks = [];
}
Action.prototype.subscribe = function (callback) {
var index = this._callbacks.indexOf(callback);
if (index < 0) {
this._callbacks.push(callback);
}
};
Action.prototype.unsubscribe = function (callback) {
if (isFunction(callback)) {
var index = this._callbacks.indexOf(callback);
if (index > -1) {
this._callbacks.splice(index, 1);
}
}
else {
this._callbacks = [];
}
};
Action.prototype.execute = function (data) {
this._callbacks.forEach(function (callback) {
callback(data);
});
};
Action.prototype.isEmpty = function () {
return this._callbacks.length === 0;
};
return Action;
}());
/**
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var IndicatorSeries;
(function (IndicatorSeries) {
IndicatorSeries["Normal"] = "normal";
IndicatorSeries["Price"] = "price";
IndicatorSeries["Volume"] = "volume";
})(IndicatorSeries || (IndicatorSeries = {}));
var IndicatorEventTarget;
(function (IndicatorEventTarget) {
IndicatorEventTarget["Feature"] = "feature";
})(IndicatorEventTarget || (IndicatorEventTarget = {}));
var IndicatorDataState;
(function (IndicatorDataState) {
IndicatorDataState["Loading"] = "loading";
IndicatorDataState["Error"] = "error";
IndicatorDataState["Ready"] = "ready";
})(IndicatorDataState || (IndicatorDataState = {}));
function eachFigures(indicator, dataIndex, defaultStyles, eachFigureCallback) {
var result = indicator.result;
var figures = indicator.figures;
var styles = indicator.styles;
var circleStyles = formatValue(styles, 'circles', defaultStyles.circles);
var circleStyleCount = circleStyles.length;
var barStyles = formatValue(styles, 'bars', defaultStyles.bars);
var barStyleCount = barStyles.length;
var lineStyles = formatValue(styles, 'lines', defaultStyles.lines);
var lineStyleCount = lineStyles.length;
var circleCount = 0;
var barCount = 0;
var lineCount = 0;
// eslint-disable-next-line @typescript-eslint/init-declarations -- ignore
var defaultFigureStyles;
var figureIndex = 0;
figures.forEach(function (figure) {
var _a;
switch (figure.type) {
case 'circle': {
figureIndex = circleCount;
var styles_1 = circleStyles[circleCount % circleStyleCount];
defaultFigureStyles = __assign(__assign({}, styles_1), { color: styles_1.noChangeColor });
circleCount++;
break;
}
case 'bar': {
figureIndex = barCount;
var styles_2 = barStyles[barCount % barStyleCount];
defaultFigureStyles = __assign(__assign({}, styles_2), { color: styles_2.noChangeColor });
barCount++;
break;
}
case 'line': {
figureIndex = lineCount;
defaultFigureStyles = lineStyles[lineCount % lineStyleCount];
lineCount++;
break;
}
}
if (isValid(figure.type)) {
var ss = (_a = figure.styles) === null || _a === void 0 ? void 0 : _a.call(figure, {
data: {
prev: result[dataIndex - 1],
current: result[dataIndex],
next: result[dataIndex + 1]
},
indicator: indicator,
defaultStyles: defaultStyles
});
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument -- ignore
eachFigureCallback(figure, __assign(__assign({}, defaultFigureStyles), ss), figureIndex);
}
});
}
var IndicatorImp = /** @class */ (function () {
function IndicatorImp(indicator) {
this.precision = 4;
this.calcParams = [];
this.shouldOhlc = false;
this.shouldFormatBigNumber = false;
this.visible = true;
this.zLevel = 0;
this.series = IndicatorSeries.Normal;
this.figures = [];
this.minValue = null;
this.maxValue = null;
this.styles = null;
this.shouldUpdate = function (prev, current) {
var calc = JSON.stringify(prev.calcParams) !== JSON.stringify(current.calcParams) ||
prev.figures !== current.figures ||
prev.calc !== current.calc;
var draw = calc ||
prev.shortName !== current.shortName ||
prev.series !== current.series ||
prev.minValue !== current.minValue ||
prev.maxValue !== current.maxValue ||
prev.precision !== current.precision ||
prev.shouldOhlc !== current.shouldOhlc ||
prev.shouldFormatBigNumber !== current.shouldFormatBigNumber ||
prev.visible !== current.visible ||
prev.zLevel !== current.zLevel ||
prev.extendData !== current.extendData ||
prev.regenerateFigures !== current.regenerateFigures ||
prev.createTooltipDataSource !== current.createTooltipDataSource ||
prev.draw !== current.draw;
return { calc: calc, draw: draw };
};
this.calc = function () { return []; };
this.regenerateFigures = null;
this.createTooltipDataSource = null;
this.draw = null;
this.onClick = null;
this.onDataStateChange = null;
this.result = [];
this._lockSeriesPrecision = false;
this.override(indicator);
this._lockSeriesPrecision = false;
}
IndicatorImp.prototype.override = function (indicator) {
var _a, _b;
var _c = this, result = _c.result, currentOthers = __rest(_c, ["result"]);
this._prevIndicator = __assign(__assign({}, clone(currentOthers)), { result: result });
var id = indicator.id, name = indicator.name, shortName = indicator.shortName, precision = indicator.precision, styles = indicator.styles, figures = indicator.figures, calcParams = indicator.calcParams, others = __rest(indicator, ["id", "name", "shortName", "precision", "styles", "figures", "calcParams"]);
if (!isString(this.id) && isString(id)) {
this.id = id;
}
if (!isString(this.name)) {
this.name = name !== null && name !== void 0 ? name : '';
}
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- ignore
this.shortName = (_a = shortName !== null && shortName !== void 0 ? shortName : this.shortName) !== null && _a !== void 0 ? _a : this.name;
if (isNumber(precision)) {
this.precision = precision;
this._lockSeriesPrecision = true;
}
if (isValid(styles)) {
(_b = this.styles) !== null && _b !== void 0 ? _b : (this.styles = {});
merge(this.styles, styles);
}
merge(this, others);
if (isValid(calcParams)) {
this.calcParams = calcParams;
if (isFunction(this.regenerateFigures)) {
this.figures = this.regenerateFigures(this.calcParams);
}
}
this.figures = figures !== null && figures !== void 0 ? figures : this.figures;
};
IndicatorImp.prototype.setSeriesPrecision = function (precision) {
if (!this._lockSeriesPrecision) {
this.precision = precision;
}
};
IndicatorImp.prototype.shouldUpdateImp = function () {
var sort = this._prevIndicator.zLevel !== this.zLevel;
var result = this.shouldUpdate(this._prevIndicator, this);
if (isBoolean(result)) {
return { calc: result, draw: result, sort: sort };
}
return __assign(__assign({}, result), { sort: sort });
};
IndicatorImp.prototype.calcImp = function (dataList) {
return __awaiter(this, void 0, void 0, function () {
var result;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4 /*yield*/, this.calc(dataList, this)];
case 1:
result = _a.sent();
this.result = result;
return [2 /*return*/, true];
case 2:
_a.sent();
return [2 /*return*/, false];
case 3: return [2 /*return*/];
}
});
});
};
IndicatorImp.extend = function (template) {
var Custom = /** @class */ (function (_super) {
__extends(Custom, _super);
function Custom() {
return _super.call(this, template) || this;
}
return Custom;
}(IndicatorImp));
return Custom;
};
return IndicatorImp;
}());
/**
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var OverlayMode;
(function (OverlayMode) {
OverlayMode["Normal"] = "normal";
OverlayMode["WeakMagnet"] = "weak_magnet";
OverlayMode["StrongMagnet"] = "strong_magnet";
})(OverlayMode || (OverlayMode = {}));
function checkOverlayFigureEvent(targetEventType, figure) {
var _a;
var ignoreEvent = (_a = figure === null || figure === void 0 ? void 0 : figure.ignoreEvent) !== null && _a !== void 0 ? _a : false;
if (isBoolean(ignoreEvent)) {
return !ignoreEvent;
}
return !ignoreEvent.includes(targetEventType);
}
var OVERLAY_DRAW_STEP_START = 1;
var OVERLAY_DRAW_STEP_FINISHED = -1;
var OVERLAY_ID_PREFIX = 'overlay_';
var OVERLAY_FIGURE_KEY_PREFIX = 'overlay_figure_';
var OverlayImp = /** @class */ (function () {
function OverlayImp(overlay) {
this.groupId = '';
this.totalStep = 1;
this.currentStep = OVERLAY_DRAW_STEP_START;
this.lock = false;
this.visible = true;
this.zLevel = 0;
this.needDefaultPointFigure = false;
this.needDefaultXAxisFigure = false;
this.needDefaultYAxisFigure = false;
this.mode = OverlayMode.Normal;
this.modeSensitivity = 8;
this.points = [];
this.styles = null;
this.createPointFigures = null;
this.createXAxisFigures = null;
this.createYAxisFigures = null;
this.performEventPressedMove = null;
this.performEventMoveForDrawing = null;
this.onDrawStart = null;
this.onDrawing = null;
this.onDrawEnd = null;
this.onClick = null;
this.onDoubleClick = null;
this.onRightClick = null;
this.onPressedMoveStart = null;
this.onPressedMoving = null;
this.onPressedMoveEnd = null;
this.onMouseEnter = null;
this.onMouseLeave = null;
this.onRemoved = null;
this.onSelected = null;
this.onDeselected = null;
this._prevZLevel = 0;
this._prevPressedPoint = null;
this._prevPressedPoints = [];
this.override(overlay);
}
OverlayImp.prototype.override = function (overlay) {
var _a, _b;
this._prevOverlay = clone(this);
var id = overlay.id, name = overlay.name; overlay.currentStep; var points = overlay.points, styles = overlay.styles, others = __rest(overlay, ["id", "name", "currentStep", "points", "styles"]);
merge(this, others);
if (!isString(this.name)) {
this.name = name !== null && name !== void 0 ? name : '';
}
if (!isString(this.id) && isString(id)) {
this.id = id;
}
if (isValid(styles)) {
(_a = this.styles) !== null && _a !== void 0 ? _a : (this.styles = {});
merge(this.styles, styles);
}
if (isArray(points) && points.length > 0) {
var repeatTotalStep = 0;
this.points = __spreadArray([], __read(points), false);
if (points.length >= this.totalStep - 1) {
this.currentStep = OVERLAY_DRAW_STEP_FINISHED;
repeatTotalStep = this.totalStep - 1;
}
else {
this.currentStep = points.length + 1;
repeatTotalStep = points.length;
}
// Prevent wrong drawing due to wrong points
if (isFunction(this.performEventMoveForDrawing)) {
for (var i = 0; i < repeatTotalStep; i++) {
this.performEventMoveForDrawing({
currentStep: i + 2,
mode: this.mode,
points: this.points,
performPointIndex: i,
performPoint: this.points[i]
});
}
}
if (this.currentStep === OVERLAY_DRAW_STEP_FINISHED) {
(_b = this.performEventPressedMove) === null || _b === void 0 ? void 0 : _b.call(this, {
currentStep: this.currentStep,
mode: this.mode,
points: this.points,
performPointIndex: this.points.length - 1,
performPoint: this.points[this.points.length - 1]
});
}
}