@millistream/millistream-widgets 1.0.23 → 1.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/millistream-widgets.js +1165 -478
- package/package.json +1 -1
package/millistream-widgets.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
/**
|
|
2
|
+
* HiDPI Canvas Polyfill (1.0.10)
|
|
3
|
+
*
|
|
4
|
+
* Author: Jonathan D. Johnson (http://jondavidjohn.com)
|
|
5
|
+
* Homepage: https://github.com/jondavidjohn/hidpi-canvas-polyfill
|
|
6
|
+
* Issue Tracker: https://github.com/jondavidjohn/hidpi-canvas-polyfill/issues
|
|
7
|
+
* License: Apache-2.0
|
|
8
|
+
*/
|
|
9
|
+
(function(prototype) {
|
|
10
10
|
|
|
11
11
|
var pixelRatio = (function() {
|
|
12
12
|
var canvas = document.createElement('canvas'),
|
|
13
13
|
context = canvas.getContext('2d');
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
/*backingStore = context.backingStorePixelRatio ||
|
|
15
|
+
context.webkitBackingStorePixelRatio ||
|
|
16
|
+
context.mozBackingStorePixelRatio ||
|
|
17
|
+
context.msBackingStorePixelRatio ||
|
|
18
|
+
context.oBackingStorePixelRatio ||
|
|
19
|
+
context.backingStorePixelRatio || 1;
|
|
20
|
+
return (window.devicePixelRatio || 1) / backingStore;
|
|
21
|
+
*/
|
|
22
22
|
})(),
|
|
23
23
|
forEach = function(obj, func) {
|
|
24
24
|
for (var p in obj) {
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
},
|
|
30
30
|
|
|
31
31
|
ratioArgs = {
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
//'fillRect': 'all',
|
|
33
|
+
//'clearRect': 'all',
|
|
34
34
|
'strokeRect': 'all',
|
|
35
35
|
'moveTo': 'all',
|
|
36
36
|
'lineTo': 'all',
|
|
@@ -43,18 +43,18 @@
|
|
|
43
43
|
'rect': 'all',
|
|
44
44
|
'translate': 'all',
|
|
45
45
|
'createRadialGradient': 'all',
|
|
46
|
-
|
|
46
|
+
//'createLinearGradient': 'all'
|
|
47
47
|
};
|
|
48
48
|
|
|
49
49
|
if (pixelRatio === 1) return;
|
|
50
50
|
|
|
51
51
|
function getPixelRatio(_this) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
52
|
+
/* var backingStore = this.backingStorePixelRatio ||
|
|
53
|
+
this.webkitBackingStorePixelRatio ||
|
|
54
|
+
this.mozBackingStorePixelRatio ||
|
|
55
|
+
this.msBackingStorePixelRatio ||
|
|
56
|
+
this.oBackingStorePixelRatio ||
|
|
57
|
+
this.backingStorePixelRatio || 1;*/
|
|
58
58
|
var backingStore = _this.backingStorePixelRatio ||
|
|
59
59
|
_this.webkitBackingStorePixelRatio ||
|
|
60
60
|
_this.mozBackingStorePixelRatio ||
|
|
@@ -63,14 +63,14 @@
|
|
|
63
63
|
_this.backingStorePixelRatio || 1;
|
|
64
64
|
return (window.devicePixelRatio || 1) / backingStore;
|
|
65
65
|
|
|
66
|
-
}
|
|
66
|
+
}
|
|
67
67
|
|
|
68
68
|
forEach(ratioArgs, function(value, key) {
|
|
69
69
|
prototype[key] = (function(_super) {
|
|
70
70
|
return function() {
|
|
71
71
|
var i, len,
|
|
72
72
|
args = Array.prototype.slice.call(arguments);
|
|
73
|
-
if (key == 'lineTo' || key == 'moveTo') {
|
|
73
|
+
if (key == 'lineTo' || key == 'moveTo') { // PF
|
|
74
74
|
args = args.map(function(a) {
|
|
75
75
|
return a;
|
|
76
76
|
});
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
})(prototype[key]);
|
|
91
91
|
});
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
// Stroke lineWidth adjustment
|
|
94
94
|
prototype.stroke = (function(_super) {
|
|
95
95
|
return function() {
|
|
96
96
|
this.lineWidth *= getPixelRatio(this);
|
|
@@ -114,12 +114,12 @@
|
|
|
114
114
|
var i = _super.apply(this, args);
|
|
115
115
|
|
|
116
116
|
this.font = tmp;
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
117
|
+
/*this.font = this.font.replace(
|
|
118
|
+
/(\d+)(px|em|rem|pt)/g,
|
|
119
|
+
function(w, m, u) {
|
|
120
|
+
return Math.floor(m / getPixelRatio()) + u;
|
|
121
|
+
}
|
|
122
|
+
);*/
|
|
123
123
|
return i;
|
|
124
124
|
};
|
|
125
125
|
})(prototype.measureText);
|
|
@@ -145,8 +145,8 @@
|
|
|
145
145
|
return function() {
|
|
146
146
|
var args = Array.prototype.slice.call(arguments);
|
|
147
147
|
|
|
148
|
-
args[1] *= getPixelRatio(this);
|
|
149
|
-
args[2] *= getPixelRatio(this);
|
|
148
|
+
args[1] *= getPixelRatio(this); // x
|
|
149
|
+
args[2] *= getPixelRatio(this); // y
|
|
150
150
|
var tmp = this.font;
|
|
151
151
|
var _this = this;
|
|
152
152
|
this.font = this.font.replace(
|
|
@@ -158,12 +158,12 @@
|
|
|
158
158
|
|
|
159
159
|
_super.apply(this, args);
|
|
160
160
|
this.font = tmp;
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
161
|
+
/*this.font = this.font.replace(
|
|
162
|
+
/(\d+)(px|em|rem|pt)/g,
|
|
163
|
+
function(w, m, u) {
|
|
164
|
+
return (m / getPixelRatio()) + u;
|
|
165
|
+
}
|
|
166
|
+
);*/
|
|
167
167
|
};
|
|
168
168
|
})(prototype.strokeText);
|
|
169
169
|
|
|
@@ -185,17 +185,17 @@
|
|
|
185
185
|
}
|
|
186
186
|
prototype.getContext = (function(_super) {
|
|
187
187
|
return function(type) {
|
|
188
|
-
|
|
188
|
+
//var backingStore, ratio;
|
|
189
189
|
context = _super.call(this, type);
|
|
190
190
|
|
|
191
191
|
if (type === '2d') {
|
|
192
192
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
193
|
+
/*backingStore = context.backingStorePixelRatio ||
|
|
194
|
+
context.webkitBackingStorePixelRatio ||
|
|
195
|
+
context.mozBackingStorePixelRatio ||
|
|
196
|
+
context.msBackingStorePixelRatio ||
|
|
197
|
+
context.oBackingStorePixelRatio ||
|
|
198
|
+
context.backingStorePixelRatio || 1;*/
|
|
199
199
|
|
|
200
200
|
var ratio = getPixelRatio();
|
|
201
201
|
if (ratio > 1) {
|
|
@@ -220,7 +220,7 @@
|
|
|
220
220
|
|
|
221
221
|
})(HTMLCanvasElement.prototype);
|
|
222
222
|
|
|
223
|
-
|
|
223
|
+
// Millistream Chart
|
|
224
224
|
function Milli_Chart(settings) {
|
|
225
225
|
"use strict";
|
|
226
226
|
var _this = this;
|
|
@@ -242,13 +242,13 @@ function Milli_Chart(settings) {
|
|
|
242
242
|
compress: 1,
|
|
243
243
|
curveOnTop: true,
|
|
244
244
|
dateformat: 'd/m',
|
|
245
|
-
drawxaxis: true,
|
|
245
|
+
drawxaxis: true, // TODO: 0 no, 1 yes, 2 yeas with markers (3px lines)
|
|
246
246
|
drawyaxis: true,
|
|
247
247
|
drawy2axis: false,
|
|
248
248
|
enablezoom: true,
|
|
249
249
|
fields: ['name', 'tradecurrency', 'time', 'date', 'tradeprice', 'tradequantity', 'marketopen', 'marketclose'],
|
|
250
250
|
fillchart: false,
|
|
251
|
-
gridVerticalLines: true,
|
|
251
|
+
gridVerticalLines: true, // 0 off, 1 draw grid lines ,2 fillrect modulo
|
|
252
252
|
gridVerticalLinesStyle: 'line',
|
|
253
253
|
gridHorizontalLines: true,
|
|
254
254
|
gridHorizontalLinesStyle: 'dash',
|
|
@@ -257,7 +257,7 @@ function Milli_Chart(settings) {
|
|
|
257
257
|
instrument: null,
|
|
258
258
|
intradayDatePos: { x: 'center', y: 'bottom', orientation: 'horizontal', dateformat: 'd mmm' },
|
|
259
259
|
intradaylen: null,
|
|
260
|
-
messagetypes: 1030,
|
|
260
|
+
messagetypes: 1030, // quote,trades and performance
|
|
261
261
|
nochartlabel: 'No data to draw on',
|
|
262
262
|
onreadyCallback: null,
|
|
263
263
|
previousDayClose: true,
|
|
@@ -272,8 +272,8 @@ function Milli_Chart(settings) {
|
|
|
272
272
|
display: 'block'
|
|
273
273
|
},
|
|
274
274
|
xAxisSpacing: 0,
|
|
275
|
-
yAxisSpacing: 4,
|
|
276
|
-
xAxisModulo: 1
|
|
275
|
+
yAxisSpacing: 4, // undocumented
|
|
276
|
+
xAxisModulo: 1 // undocumented
|
|
277
277
|
};
|
|
278
278
|
var m_startdate = null;
|
|
279
279
|
var m_chartspaces = {
|
|
@@ -286,10 +286,10 @@ function Milli_Chart(settings) {
|
|
|
286
286
|
height: 0
|
|
287
287
|
}
|
|
288
288
|
};
|
|
289
|
-
var m_dummyDiv = null;
|
|
289
|
+
var m_dummyDiv = null; // dummy div For chartclasses
|
|
290
290
|
var m_canvas = null;
|
|
291
291
|
var m_ctx = null;
|
|
292
|
-
var m_datapoints = [];
|
|
292
|
+
var m_datapoints = []; // for mouseover
|
|
293
293
|
var m_dataPoints = {
|
|
294
294
|
arr: [],
|
|
295
295
|
map: new Map()
|
|
@@ -378,7 +378,7 @@ function Milli_Chart(settings) {
|
|
|
378
378
|
}
|
|
379
379
|
var m_instrumentCss = [{
|
|
380
380
|
color: '#E2507A',
|
|
381
|
-
|
|
381
|
+
//backgroundImage: 'linear-gradient(rgba(226, 80, 122, 0.6),rgba(226, 80, 122, 0))',
|
|
382
382
|
width: 1
|
|
383
383
|
}, {
|
|
384
384
|
color: '#ff0000',
|
|
@@ -427,10 +427,10 @@ function Milli_Chart(settings) {
|
|
|
427
427
|
}
|
|
428
428
|
|
|
429
429
|
function dateDiffInDays(a, b) {
|
|
430
|
-
|
|
430
|
+
// Discard the time and time-zone information.
|
|
431
431
|
const utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
|
|
432
432
|
const utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
|
|
433
|
-
return Math.floor((utc2 - utc1) / 86400000);
|
|
433
|
+
return Math.floor((utc2 - utc1) / 86400000); // ms per day
|
|
434
434
|
}
|
|
435
435
|
|
|
436
436
|
function findFirstWeekDay(date) {
|
|
@@ -444,7 +444,7 @@ function Milli_Chart(settings) {
|
|
|
444
444
|
}
|
|
445
445
|
|
|
446
446
|
function getFontSize(obj) {
|
|
447
|
-
|
|
447
|
+
//return parseInt(obj.fontSize) * window.devicePixelRatio;
|
|
448
448
|
return parseInt(obj.fontSize);
|
|
449
449
|
}
|
|
450
450
|
|
|
@@ -601,11 +601,23 @@ function Milli_Chart(settings) {
|
|
|
601
601
|
_this.scaleinfoY.lowLowerChart = null;
|
|
602
602
|
_this.scaleinfoY.highLowerChart = null;
|
|
603
603
|
var data, i;
|
|
604
|
+
var useCloseprice = false;
|
|
605
|
+
var today = new Date().getTime();
|
|
606
|
+
today -= today % 86400000;
|
|
607
|
+
var lastTradeDate = new Date().getTime();
|
|
608
|
+
var todaysOpenTime = new Date(new Date().toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z').getTime();
|
|
609
|
+
if (typeof _this.instruments[0].trades !== 'undefined' && _this.instruments[0].trades.length > 0) {
|
|
610
|
+
lastTradeDate = new Date(_this.instruments[0].trades[_this.instruments[0].trades.length - 1].timestamp).getTime();
|
|
611
|
+
lastTradeDate -= lastTradeDate % 86400000;
|
|
612
|
+
}
|
|
613
|
+
var quote_timestamp = _this.instruments[0].quotedate + _this.instruments[0].quotetime;
|
|
614
|
+
|
|
615
|
+
if ((_this.instruments[0].quotedate == today && quote_timestamp > todaysOpenTime) || _this.instruments[0].quotedate == lastTradeDate) useCloseprice = true;
|
|
604
616
|
for (var s = 0; s < _this.instruments.length; s++) {
|
|
605
617
|
if (_this.instruments[s].insref == 0) continue;
|
|
606
618
|
_this.instruments[s].startValue = null;
|
|
607
619
|
data = _this.instruments[s][_this.scaleinfoY.type];
|
|
608
|
-
if (_this.scaleinfoY.type != 'history') {
|
|
620
|
+
if (_this.scaleinfoY.type != 'history' && useCloseprice) {
|
|
609
621
|
if ((_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d') && !m_zoom.mousedown.timestamp) {
|
|
610
622
|
_this.instruments[s].startValue = parseFloat(_this.instruments[s].closeprice1d) * _this.instruments[s].factor;
|
|
611
623
|
}
|
|
@@ -613,7 +625,7 @@ function Milli_Chart(settings) {
|
|
|
613
625
|
var quantity = 0;
|
|
614
626
|
|
|
615
627
|
for (i = 0; i < data.length; i++) {
|
|
616
|
-
|
|
628
|
+
// only calc on visible data
|
|
617
629
|
var price = data[i].price * _this.instruments[s].factor;
|
|
618
630
|
quantity = 0;
|
|
619
631
|
if (data[i].quantity !== 'undefined') {
|
|
@@ -621,7 +633,8 @@ function Milli_Chart(settings) {
|
|
|
621
633
|
}
|
|
622
634
|
if (data[i].timestamp < _this.scaleinfoX.startTimeStamp) {
|
|
623
635
|
if (_this.scaleinfoY.type == 'history') _this.instruments[s].startValue = price;
|
|
624
|
-
else if (_this.settings.chartlen != '1d' && _this.settings.chartlen != '0d' && !m_zoom.mousedown.timestamp) {
|
|
636
|
+
//else if (_this.settings.chartlen != '1d' && _this.settings.chartlen != '0d' && !m_zoom.mousedown.timestamp) {
|
|
637
|
+
else if (useCloseprice == false || m_zoom.mousedown.timestamp) {
|
|
625
638
|
_this.instruments[s].startValue = price;
|
|
626
639
|
}
|
|
627
640
|
continue;
|
|
@@ -631,7 +644,7 @@ function Milli_Chart(settings) {
|
|
|
631
644
|
}
|
|
632
645
|
|
|
633
646
|
if (_this.scaleinfoY.type != 'history' && (data[i].timestamp % 86400000 < _this.instruments[0].opentimestamp || data[i].timestamp % 86400000 > _this.instruments[0].closetimestamp)) {
|
|
634
|
-
|
|
647
|
+
// stämmer detta kan det bli överlapp vid sommartid/vintertid?
|
|
635
648
|
continue;
|
|
636
649
|
}
|
|
637
650
|
|
|
@@ -658,7 +671,7 @@ function Milli_Chart(settings) {
|
|
|
658
671
|
if (_this.scaleinfoY.lowLowerChart == null || _this.scaleinfoY.lowLowerChart > quantity) _this.scaleinfoY.lowLowerChart = quantity;
|
|
659
672
|
if (_this.scaleinfoY.highLowerChart == null || _this.scaleinfoY.highLowerChart < quantity) _this.scaleinfoY.highLowerChart = quantity;
|
|
660
673
|
}
|
|
661
|
-
if ((_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d') && !m_zoom.mousedown.timestamp) {
|
|
674
|
+
if ((_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d') && !m_zoom.mousedown.timestamp) { // if closeprice is used calch high/low on it
|
|
662
675
|
var cp = parseFloat(_this.instruments[s].closeprice1d) * _this.instruments[s].factor;
|
|
663
676
|
if (_this.scaleinfoY.lowValue > cp) _this.scaleinfoY.lowValue = cp;
|
|
664
677
|
else
|
|
@@ -687,11 +700,11 @@ function Milli_Chart(settings) {
|
|
|
687
700
|
_this.scaleinfoY.lowValue -= 1;
|
|
688
701
|
_this.scaleinfoY.highValue += 1;
|
|
689
702
|
}
|
|
690
|
-
|
|
703
|
+
// do we have any analyzis we need to take into account
|
|
691
704
|
for (i = 0; i < _this.settings.indicators.length; i++) {
|
|
692
705
|
if (_this.scaleinfoY.type == 'history') data = _this.settings.indicators[i].history;
|
|
693
706
|
else data = _this.settings.indicators[i].trades;
|
|
694
|
-
for (
|
|
707
|
+
for (s = 0; s < data.length; s++) {
|
|
695
708
|
if (data[s].timestamp < _this.scaleinfoX.startTimeStamp) {
|
|
696
709
|
continue;
|
|
697
710
|
}
|
|
@@ -707,38 +720,11 @@ function Milli_Chart(settings) {
|
|
|
707
720
|
}
|
|
708
721
|
}
|
|
709
722
|
}
|
|
723
|
+
_this.scaleinfoY2.lowValue = (_this.scaleinfoY.lowValue - _this.instruments[0].startValue) / _this.instruments[0].startValue * 100;
|
|
724
|
+
_this.scaleinfoY2.highValue = (_this.scaleinfoY.highValue - _this.instruments[0].startValue) / _this.instruments[0].startValue * 100;
|
|
710
725
|
return 1;
|
|
711
726
|
}
|
|
712
727
|
|
|
713
|
-
function plotLower(valuePerPixel, lineLength) {
|
|
714
|
-
m_ctx.save();
|
|
715
|
-
m_ctx.strokeStyle = m_instrumentCss[0].color;
|
|
716
|
-
m_ctx.lineWidth = m_instrumentCss[0].width;
|
|
717
|
-
var width = Math.round(m_chartspaces.lowerChart.width / (m_datapoints.length + 1) / 2);
|
|
718
|
-
if (width < 2) width = 2;
|
|
719
|
-
else if (width > 20) width = 20;
|
|
720
|
-
m_ctx.lineWidth = width;
|
|
721
|
-
for (var i = 0; i < m_datapoints.length; i++) {
|
|
722
|
-
var x = m_datapoints[i].x + 0.5;
|
|
723
|
-
m_ctx.lineWidth = width;
|
|
724
|
-
if (x - width <= m_chartspaces.lowerChart.left) {
|
|
725
|
-
m_ctx.lineWidth = width / 2;
|
|
726
|
-
x += m_ctx.lineWidth / 2;
|
|
727
|
-
} else
|
|
728
|
-
if (x + width >= m_chartspaces.lowerChart.right) {
|
|
729
|
-
m_ctx.lineWidth = width / 2;
|
|
730
|
-
x -= m_ctx.lineWidth / 2 + 1;
|
|
731
|
-
}
|
|
732
|
-
m_ctx.beginPath();
|
|
733
|
-
m_ctx.moveTo(x, m_chartspaces.lowerChart.bottom - 0.5);
|
|
734
|
-
var y = Math.round(m_chartspaces.lowerChart.bottom - (m_datapoints[i].quantity * valuePerPixel)) - 1;
|
|
735
|
-
m_ctx.closePath();
|
|
736
|
-
m_ctx.lineTo(x, y - 0.5);
|
|
737
|
-
m_ctx.stroke();
|
|
738
|
-
}
|
|
739
|
-
m_ctx.restore();
|
|
740
|
-
}
|
|
741
|
-
|
|
742
728
|
function drawYLegendLower(x, numticks, lineLength, markers) {
|
|
743
729
|
var i;
|
|
744
730
|
_this.scaleinfoY.lowLowerChart = null;
|
|
@@ -760,7 +746,7 @@ function Milli_Chart(settings) {
|
|
|
760
746
|
var maxValue = _this.scaleinfoY.highLowerChart == 0 ? 100 : _this.scaleinfoY.highLowerChart + (tickSize * 0.2);
|
|
761
747
|
var valuePerPixel = lineLength / maxValue;
|
|
762
748
|
if (isNaN(valuePerPixel) || !isFinite(valuePerPixel)) {
|
|
763
|
-
(
|
|
749
|
+
console.log('cant draw valuePerPixel' + valuePerPixel, lineLength, maxValue);
|
|
764
750
|
return false;
|
|
765
751
|
}
|
|
766
752
|
var value = 0;
|
|
@@ -781,7 +767,7 @@ function Milli_Chart(settings) {
|
|
|
781
767
|
m_ctx.closePath();
|
|
782
768
|
m_ctx.restore();
|
|
783
769
|
} else
|
|
784
|
-
if (_this.settings.drawyaxis == true && markers == true) {
|
|
770
|
+
if (_this.settings.drawyaxis == true && markers == true) { // draw legenditem markers for price
|
|
785
771
|
m_ctx.beginPath();
|
|
786
772
|
m_ctx.moveTo(m_chartspaces.lowerChart.left, y + 0.5);
|
|
787
773
|
m_ctx.lineTo(m_chartspaces.lowerChart.left + 3, y + 0.5);
|
|
@@ -793,7 +779,7 @@ function Milli_Chart(settings) {
|
|
|
793
779
|
var label = formatLargeNumber(value, 0, _this);
|
|
794
780
|
var textpos = x - 5;
|
|
795
781
|
if (m_yLegendCss.verticalAlign == 'top') {
|
|
796
|
-
if (y - (getFontSize(m_yLegendCss)) > 0)
|
|
782
|
+
if (y - (getFontSize(m_yLegendCss)) > 0) // dont draw if cropped
|
|
797
783
|
m_ctx.fillText(label, textpos, y - ((getFontSize(m_yLegendCss) + 2)));
|
|
798
784
|
} else
|
|
799
785
|
m_ctx.fillText(label, textpos, y - (getFontSize(m_yLegendCss) / 2));
|
|
@@ -811,7 +797,7 @@ function Milli_Chart(settings) {
|
|
|
811
797
|
m_ctx.fillStyle = m_yLegendCss.color;
|
|
812
798
|
var lineLen = m_chartspaces.lowerChart.bottom - m_chartspaces.lowerChart.top;
|
|
813
799
|
var numticks = lineLen / (getFontSize(m_yLegendCss) * 2);
|
|
814
|
-
if (numticks > 8) numticks = 8;
|
|
800
|
+
if (numticks > 8) numticks = 8; // limit to 8 items on Y legend ( this is not an absolut count, since we calculate nice legend numbers
|
|
815
801
|
|
|
816
802
|
m_ctx.beginPath();
|
|
817
803
|
m_ctx.strokeStyle = m_gridVerticalCss.color;
|
|
@@ -825,21 +811,22 @@ function Milli_Chart(settings) {
|
|
|
825
811
|
}
|
|
826
812
|
|
|
827
813
|
function checkYLegendSpace(y, text) {
|
|
828
|
-
|
|
814
|
+
//if (y - (getFontSize(m_yLegendCss) / 2) - m_chartspaces.chart.top < 0) return false;
|
|
829
815
|
if (y - (getFontSize(m_yLegendCss)) - m_chartspaces.chart.top < 0) return false;
|
|
830
816
|
if (y > m_chartspaces.chart.bottom) return false;
|
|
831
817
|
return true;
|
|
832
818
|
}
|
|
833
819
|
|
|
834
|
-
function drawY2Legend(x) {
|
|
820
|
+
function drawY2Legend(x) { // percent
|
|
821
|
+
if (_this.instruments[0].pricetype == 'yield') return;
|
|
835
822
|
if (_this.settings.absoluteScaling == true) {
|
|
836
823
|
for (var s = 1; s < _this.instruments.length; s++) {
|
|
837
824
|
if (_this.instruments[s].insref != 0) return;
|
|
838
825
|
}
|
|
839
826
|
}
|
|
840
|
-
|
|
827
|
+
|
|
841
828
|
_this.scaleinfoY2.maxValue = _this.scaleinfoY2.highValue + (_this.scaleinfoY2.tickSize * 0.2);
|
|
842
|
-
_this.scaleinfoY2.minValue = _this.scaleinfoY2.lowValue
|
|
829
|
+
_this.scaleinfoY2.minValue = _this.scaleinfoY2.lowValue - (_this.scaleinfoY2.tickSize * 0.2);
|
|
843
830
|
m_ctx.font = m_y2LegendCss.fontWeight + ' ' + m_y2LegendCss.fontSize + ' ' + m_y2LegendCss.fontFamily;
|
|
844
831
|
var value;
|
|
845
832
|
if (_this.scaleinfoY2.highValue == _this.scaleinfoY2.lowValue) {
|
|
@@ -859,7 +846,7 @@ function Milli_Chart(settings) {
|
|
|
859
846
|
var count = 0;
|
|
860
847
|
for (;;) {
|
|
861
848
|
if (count++ > 10) {
|
|
862
|
-
()
|
|
849
|
+
console.log('break out');
|
|
863
850
|
break;
|
|
864
851
|
}
|
|
865
852
|
var v;
|
|
@@ -870,9 +857,9 @@ function Milli_Chart(settings) {
|
|
|
870
857
|
var y = Math.round(m_chartspaces.chart.height - getScaledSetting(m_chartCss.marginBottom) - ((v - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel));
|
|
871
858
|
|
|
872
859
|
if (y <= m_chartspaces.chart.top) break;
|
|
873
|
-
|
|
860
|
+
//if (y > m_chartspaces.chart.bottom) break;
|
|
874
861
|
if (y <= m_chartspaces.chart.bottom) {
|
|
875
|
-
if (_this.settings.drawy2axis == true) {
|
|
862
|
+
if (_this.settings.drawy2axis == true) { // draw legenditem markers for diff
|
|
876
863
|
m_ctx.beginPath();
|
|
877
864
|
m_ctx.moveTo(x, y + 0.5);
|
|
878
865
|
if ((m_y2LegendCss.float == 'left' && m_y2LegendCss.textAlign == 'left') || (m_y2LegendCss.float == 'right' && m_y2LegendCss.textAlign == 'left')) {
|
|
@@ -902,10 +889,16 @@ function Milli_Chart(settings) {
|
|
|
902
889
|
|
|
903
890
|
function drawYLegend(si, x, gridHorizontalLines, number, draw) {
|
|
904
891
|
var value;
|
|
905
|
-
si.maxValue = si.highValue + (si.tickSize * 0.2);
|
|
906
|
-
si.minValue = si.lowValue - (si.tickSize * 0.2);
|
|
892
|
+
//si.maxValue = si.highValue + (si.tickSize * 0.2);
|
|
893
|
+
//si.minValue = si.lowValue - (si.tickSize * 0.2);
|
|
894
|
+
|
|
895
|
+
let v = (si.highValue - si.lowValue) / si.lineLength;
|
|
896
|
+
si.maxValue = si.highValue + (v * parseInt(m_yLegendCss.fontSize));
|
|
897
|
+
si.minValue = si.lowValue - (v * parseInt(m_yLegendCss.fontSize));
|
|
898
|
+
|
|
899
|
+
|
|
907
900
|
m_ctx.font = m_yLegendCss.fontWeight + ' ' + m_yLegendCss.fontSize + ' ' + m_yLegendCss.fontFamily;
|
|
908
|
-
if (si.highValue == si.lowValue) {
|
|
901
|
+
if (si.highValue == si.lowValue) { // only have one value so set values for 1 line only
|
|
909
902
|
si.maxValue = si.maxValue + si.tickSize;
|
|
910
903
|
si.minValue = si.minValue - si.tickSize;
|
|
911
904
|
value = Math.abs(si.lowValue);
|
|
@@ -917,14 +910,14 @@ function Milli_Chart(settings) {
|
|
|
917
910
|
}
|
|
918
911
|
si.valuePerPixel = si.lineLength / (si.maxValue - si.minValue);
|
|
919
912
|
if (isNaN(si.valuePerPixel) || !isFinite(si.valuePerPixel)) {
|
|
920
|
-
(
|
|
913
|
+
console.log('cant draw valuePerPixel', si.valuePerPixel, si.lineLength, si.maxValue, si.minValue);
|
|
921
914
|
return false;
|
|
922
915
|
}
|
|
923
916
|
var textpos;
|
|
924
917
|
var count = 0;
|
|
925
918
|
for (;;) {
|
|
926
919
|
if (count++ > 10) {
|
|
927
|
-
()
|
|
920
|
+
console.log('failsafe break');
|
|
928
921
|
break;
|
|
929
922
|
}
|
|
930
923
|
var y = Math.round(m_chartspaces.chart.height - getScaledSetting(m_chartCss.marginBottom) - ((value - si.minValue) * si.valuePerPixel));
|
|
@@ -948,7 +941,7 @@ function Milli_Chart(settings) {
|
|
|
948
941
|
}
|
|
949
942
|
|
|
950
943
|
} else
|
|
951
|
-
if (_this.settings.drawyaxis == true && number == 1 && draw) {
|
|
944
|
+
if (_this.settings.drawyaxis == true && number == 1 && draw) { // draw legenditem markers for price
|
|
952
945
|
if (!draw) return;
|
|
953
946
|
m_ctx.beginPath();
|
|
954
947
|
m_ctx.moveTo(m_chartspaces.chart.left, y + 0.5);
|
|
@@ -986,48 +979,49 @@ function Milli_Chart(settings) {
|
|
|
986
979
|
m_ctx.fillStyle = m_yLegendCss.color;
|
|
987
980
|
if (0 == calcHighLow()) {
|
|
988
981
|
m_ctx.restore();
|
|
989
|
-
()
|
|
982
|
+
console.log('fail highlow');
|
|
990
983
|
return;
|
|
991
984
|
}
|
|
992
985
|
_this.scaleinfoY.lineLength = m_chartspaces.chart.bottom - m_chartspaces.chart.top;
|
|
993
986
|
_this.scaleinfoY2.lineLength = _this.scaleinfoY.lineLength;
|
|
994
|
-
|
|
987
|
+
//var numticks = (_this.scaleinfoY.lineLength / window.devicePixelRatio) / (getFontSize(m_yLegendCss) * _this.settings.yAxisSpacing);
|
|
995
988
|
var numticks = _this.scaleinfoY.lineLength / (getFontSize(m_yLegendCss) * _this.settings.yAxisSpacing);
|
|
996
|
-
if (numticks > 8) numticks = 8;
|
|
989
|
+
if (numticks > 8) numticks = 8; // limit to 8 items on Y legend ( this is not an absolut count, since we calculate nice legend numbers
|
|
997
990
|
_this.scaleinfoY.tickSize = getTickValue(_this.scaleinfoY.lowValue, _this.scaleinfoY.highValue, numticks);
|
|
998
|
-
_this.scaleinfoY.decimals = _this.scaleinfoY.tickSize.countDecimals();
|
|
991
|
+
_this.scaleinfoY.decimals = _this.scaleinfoY.tickSize.countDecimals(); // räkna på diffen mellan high low kanske?
|
|
999
992
|
_this.scaleinfoY.decimals = _this.scaleinfoY.decimals > 4 ? 4 : _this.scaleinfoY.decimals;
|
|
1000
993
|
_this.scaleinfoY.decimals = _this.scaleinfoY.decimals < 2 ? 2 : _this.scaleinfoY.decimals;
|
|
1001
994
|
var label = formatNiceNumber(_this.scaleinfoY.highValue, _this.settings.thousandseparator, _this.settings.decimalseparator, _this.scaleinfoY.decimals);
|
|
1002
995
|
if (_this.settings.drawyaxis) {
|
|
1003
996
|
if (m_yLegendCss.float != 'right') {
|
|
1004
|
-
m_chartspaces.chart.left = 10 + Math.round(m_ctx.measureText(label).width);
|
|
997
|
+
m_chartspaces.chart.left = 10 + Math.round(m_ctx.measureText(label).width); // + 'px'; // räkna fram hur hur mycket plats Y värdena tar och sätt margin till det, skall vi göra så?
|
|
1005
998
|
m_chartspaces.lowerChart.left = m_chartspaces.chart.left;
|
|
1006
999
|
} else {
|
|
1007
1000
|
if (m_yLegendCss.textAlign == 'right') {
|
|
1008
|
-
m_chartspaces.chart.right = m_canvas.width - (10 + Math.round(m_ctx.measureText(label).width));
|
|
1001
|
+
m_chartspaces.chart.right = m_canvas.width - (10 + Math.round(m_ctx.measureText(label).width)); // + 'px'; // räkna fram hur hur mycket plats Y värdena tar och sätt margin till det, skall vi göra så?
|
|
1009
1002
|
m_chartspaces.lowerChart.right = m_chartspaces.chart.right;
|
|
1010
1003
|
}
|
|
1011
1004
|
}
|
|
1012
1005
|
}
|
|
1013
|
-
if (_this.settings.drawy2axis) {
|
|
1014
|
-
|
|
1006
|
+
if (_this.settings.drawy2axis) { // calc space for y2
|
|
1007
|
+
//var numticks = _this.scaleinfoY2.lineLength / (getFontSize(m_yLegendCss) * _this.settings.yAxisSpacing);
|
|
1015
1008
|
_this.scaleinfoY2.tickSize = getTickValue(_this.scaleinfoY2.lowValue, _this.scaleinfoY2.highValue, numticks);
|
|
1016
1009
|
|
|
1017
|
-
_this.scaleinfoY2.decimals = _this.scaleinfoY2.tickSize.countDecimals();
|
|
1010
|
+
_this.scaleinfoY2.decimals = _this.scaleinfoY2.tickSize.countDecimals(); // räkna på diffen mellan high low kanske?
|
|
1018
1011
|
_this.scaleinfoY2.decimals = _this.scaleinfoY2.decimals > 4 ? 4 : _this.scaleinfoY2.decimals;
|
|
1019
1012
|
_this.scaleinfoY2.decimals = _this.scaleinfoY2.decimals < 0 ? 0 : _this.scaleinfoY2.decimals;
|
|
1020
1013
|
|
|
1021
1014
|
var widestDiff = '-' + Math.max(Math.abs(_this.scaleinfoY2.highValue), Math.abs(_this.scaleinfoY2.lowValue));
|
|
1022
|
-
label = formatNiceNumber(widestDiff, _this.settings.thousandseparator, _this.settings.decimalseparator, _this.scaleinfoY2.decimals) + ' %';
|
|
1015
|
+
if (_this.settings.priceIndicator == false) label = formatNiceNumber(widestDiff, _this.settings.thousandseparator, _this.settings.decimalseparator, _this.scaleinfoY2.decimals) + ' %';
|
|
1016
|
+
else label = formatNiceNumber(widestDiff, _this.settings.thousandseparator, _this.settings.decimalseparator, _this.scaleinfoY2.decimals < 2 ? 2 : _this.scaleinfoY2.decimals) + ' %'; // priceIndicator has 2 decimals
|
|
1023
1017
|
if (m_y2LegendCss.float != 'right') {
|
|
1024
1018
|
if (m_y2LegendCss.textAlign == 'left')
|
|
1025
|
-
m_chartspaces.chart.left = 10 + Math.round(m_ctx.measureText(label).width);
|
|
1019
|
+
m_chartspaces.chart.left = 10 + Math.round(m_ctx.measureText(label).width); // + 'px'; // räkna fram hur hur mycket plats Y värdena tar och sätt margin till det, skall vi göra så?
|
|
1026
1020
|
m_chartspaces.lowerChart.left = m_chartspaces.chart.left;
|
|
1027
1021
|
} else {
|
|
1028
|
-
|
|
1022
|
+
// kolla setting om den skall vara "i diagrammet"
|
|
1029
1023
|
if (m_y2LegendCss.textAlign == 'right')
|
|
1030
|
-
m_chartspaces.chart.right = m_canvas.width - (10 + Math.round(m_ctx.measureText(label).width));
|
|
1024
|
+
m_chartspaces.chart.right = m_canvas.width - (10 + Math.round(m_ctx.measureText(label).width)); // + 'px'; // räkna fram hur hur mycket plats Y värdena tar och sätt margin till det, skall vi göra så?
|
|
1031
1025
|
m_chartspaces.lowerChart.right = m_chartspaces.chart.right;
|
|
1032
1026
|
}
|
|
1033
1027
|
}
|
|
@@ -1075,7 +1069,7 @@ function Milli_Chart(settings) {
|
|
|
1075
1069
|
}
|
|
1076
1070
|
|
|
1077
1071
|
function drawXAxisGridlines(p, newday) {
|
|
1078
|
-
|
|
1072
|
+
// draws the vertical grid or dots
|
|
1079
1073
|
m_ctx.save();
|
|
1080
1074
|
m_ctx.strokeStyle = m_gridVerticalCss.color;
|
|
1081
1075
|
if (_this.settings.gridVerticalLines) {
|
|
@@ -1098,7 +1092,7 @@ function Milli_Chart(settings) {
|
|
|
1098
1092
|
m_ctx.closePath();
|
|
1099
1093
|
}
|
|
1100
1094
|
} else
|
|
1101
|
-
if (_this.settings.drawxaxis != 0) {
|
|
1095
|
+
if (_this.settings.drawxaxis != 0) { // if no grid but drawxaxis , add markers for date/time
|
|
1102
1096
|
m_ctx.beginPath();
|
|
1103
1097
|
m_ctx.moveTo(p.x + 0.5, p.y);
|
|
1104
1098
|
m_ctx.lineTo(p.x + 0.5, p.y + 3);
|
|
@@ -1109,13 +1103,13 @@ function Milli_Chart(settings) {
|
|
|
1109
1103
|
}
|
|
1110
1104
|
|
|
1111
1105
|
function calcXScale(starttime, endtime) {
|
|
1112
|
-
|
|
1106
|
+
// vad är detta?
|
|
1113
1107
|
_this.scaleinfoX.startDate = new Date(starttime);
|
|
1114
1108
|
_this.scaleinfoX.endDate = new Date(endtime);
|
|
1115
1109
|
_this.scaleinfoX.days = getNumberOfDays(starttime, endtime);
|
|
1116
1110
|
_this.scaleinfoX.lineLength = m_chartspaces.chart.right - m_chartspaces.chart.left;
|
|
1117
|
-
var datesize = new Date('2888-12-28');
|
|
1118
|
-
_this.scaleinfoX.itemwidth = getStringWidth(m_ctx, formatDate(datesize, _this.settings.dateformat, _this)) * 2;
|
|
1111
|
+
var datesize = new Date('2888-12-28'); // bredaste datum jag kan komma på
|
|
1112
|
+
_this.scaleinfoX.itemwidth = getStringWidth(m_ctx, formatDate(datesize, _this.settings.dateformat, _this)) * 2; // kolla rätt format en 8a för varje tecken
|
|
1119
1113
|
|
|
1120
1114
|
var maxLegendItems = _this.scaleinfoX.lineLength / (_this.scaleinfoX.itemwidth * 2);
|
|
1121
1115
|
|
|
@@ -1137,7 +1131,7 @@ function Milli_Chart(settings) {
|
|
|
1137
1131
|
var tmp = 60;
|
|
1138
1132
|
while (tmp < x) {
|
|
1139
1133
|
tmp += 60;
|
|
1140
|
-
if (x - tmp < 20) break;
|
|
1134
|
+
if (x - tmp < 20) break; // if less than 20 mins to next hour breakout
|
|
1141
1135
|
}
|
|
1142
1136
|
_this.scaleinfoX.ticksize = tmp * 60000;
|
|
1143
1137
|
}
|
|
@@ -1145,22 +1139,22 @@ function Milli_Chart(settings) {
|
|
|
1145
1139
|
}
|
|
1146
1140
|
|
|
1147
1141
|
function getXPosition(timestamp) {
|
|
1148
|
-
var offset = (timestamp.getTime() - _this.scaleinfoX.startDate.getTime()) / (86400000 * 7);
|
|
1142
|
+
var offset = (timestamp.getTime() - _this.scaleinfoX.startDate.getTime()) / (86400000 * 7); // veckor
|
|
1149
1143
|
offset = offset * 86400000 * 2 / _this.scaleinfoX.timePerPixel;
|
|
1150
1144
|
return Math.round(m_chartspaces.chart.left + ((timestamp.getTime() - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel) - offset);
|
|
1151
1145
|
}
|
|
1152
1146
|
|
|
1153
1147
|
function checkXLegendSides(x, text) {
|
|
1154
|
-
|
|
1148
|
+
// right
|
|
1155
1149
|
if (_this.scaleinfoX.lineLength + m_chartspaces.chart.left < x + (m_ctx.measureText(text).width / 2)) return false;
|
|
1156
|
-
|
|
1150
|
+
// left
|
|
1157
1151
|
if (m_chartspaces.chart.left > x - (m_ctx.measureText(text).width / 2)) return false;
|
|
1158
1152
|
return true;
|
|
1159
1153
|
|
|
1160
1154
|
}
|
|
1161
1155
|
|
|
1162
1156
|
function drawXAxisYears(starttime, endtime) {
|
|
1163
|
-
if (getNumberOfDays(starttime, endtime) < 250) return drawXAxisMonth(starttime, endtime);
|
|
1157
|
+
if (getNumberOfDays(starttime, endtime) < 250) return drawXAxisMonth(starttime, endtime); // exchange days
|
|
1164
1158
|
m_ctx.save();
|
|
1165
1159
|
m_ctx.font = m_xLegendCss.fontWeight + ' ' + m_xLegendCss.fontSize + ' ' + m_xLegendCss.fontFamily;
|
|
1166
1160
|
m_ctx.strokeStyle = m_gridHorizontalCss.color;
|
|
@@ -1176,7 +1170,7 @@ function Milli_Chart(settings) {
|
|
|
1176
1170
|
}
|
|
1177
1171
|
m_ctx.strokeStyle = m_gridVerticalCss.color;
|
|
1178
1172
|
var legendItems = [];
|
|
1179
|
-
|
|
1173
|
+
// draw Years
|
|
1180
1174
|
var year = _this.scaleinfoX.startDate.getFullYear() + 1;
|
|
1181
1175
|
var numItems = 0,
|
|
1182
1176
|
x, draw, i, text;
|
|
@@ -1193,7 +1187,7 @@ function Milli_Chart(settings) {
|
|
|
1193
1187
|
text = year;
|
|
1194
1188
|
if (checkXLegendSides(x, text)) {
|
|
1195
1189
|
if (_this.settings.yearLabelsPos == 'top') {
|
|
1196
|
-
m_ctx.save();
|
|
1190
|
+
m_ctx.save(); // flip and write new years on top
|
|
1197
1191
|
var fontMetrix = m_ctx.measureText(text);
|
|
1198
1192
|
x = x + fontMetrix.actualBoundingBoxAscent + fontMetrix.actualBoundingBoxDescent + 2;
|
|
1199
1193
|
var y = m_chartspaces.chart.top;
|
|
@@ -1210,14 +1204,14 @@ function Milli_Chart(settings) {
|
|
|
1210
1204
|
}
|
|
1211
1205
|
year++;
|
|
1212
1206
|
}
|
|
1213
|
-
if (numItems * m_ctx.measureText('8888').width / _this.scaleinfoX.lineLength > 0.3) numItems = 11;
|
|
1214
|
-
|
|
1215
|
-
if (numItems < 10) {
|
|
1207
|
+
if (numItems * m_ctx.measureText('8888').width / _this.scaleinfoX.lineLength > 0.3) numItems = 11; // keep it clean
|
|
1208
|
+
// draw half year
|
|
1209
|
+
if (numItems < 10) { // max 10 items här för att skriva halvår
|
|
1216
1210
|
year = new Date(_this.scaleinfoX.startDate.getFullYear() + '-07-01T00:00:00Z');
|
|
1217
1211
|
if (year.getTime() < _this.scaleinfoX.startDate.getTime())
|
|
1218
1212
|
year = new Date(_this.scaleinfoX.startDate.getFullYear() + 1 + '-07-01T00:00:00Z');
|
|
1219
1213
|
while (year < _this.scaleinfoX.endDate) {
|
|
1220
|
-
x = getXPosition(new Date(year.getFullYear() + '-07-01T00:00:00Z'));
|
|
1214
|
+
x = getXPosition(new Date(year.getFullYear() + '-07-01T00:00:00Z')); // 7
|
|
1221
1215
|
draw = true;
|
|
1222
1216
|
for (i = 0; i < legendItems.length; i++) {
|
|
1223
1217
|
if (Math.abs(legendItems[i].x - x) < getMaxDateWidth()) {
|
|
@@ -1236,13 +1230,13 @@ function Milli_Chart(settings) {
|
|
|
1236
1230
|
year = new Date((year.getFullYear() + 1) + '-07-01T00:00:00Z');
|
|
1237
1231
|
}
|
|
1238
1232
|
}
|
|
1239
|
-
|
|
1240
|
-
if (numItems * m_ctx.measureText('8888').width / _this.scaleinfoX.lineLength > 0.3) numItems = 11;
|
|
1241
|
-
if (numItems < 10) {
|
|
1233
|
+
// draw Quarter
|
|
1234
|
+
if (numItems * m_ctx.measureText('8888').width / _this.scaleinfoX.lineLength > 0.3) numItems = 11; // keep it clean
|
|
1235
|
+
if (numItems < 10) { // max 10 items här för att skriva kvartal
|
|
1242
1236
|
year = new Date(_this.scaleinfoX.startDate.getFullYear() + '-04-01T00:00:00Z');
|
|
1243
1237
|
if (year.getTime() < _this.scaleinfoX.startDate.getTime())
|
|
1244
1238
|
year = new Date(_this.scaleinfoX.startDate.getFullYear() + 1 + '-04-01T00:00:00Z');
|
|
1245
|
-
var dontPrint = false;
|
|
1239
|
+
var dontPrint = false; // if no space for first quarter dont print second either
|
|
1246
1240
|
while (year < _this.scaleinfoX.endDate) {
|
|
1247
1241
|
x = getXPosition(new Date(year.getFullYear() + '-04-01T00:00:00Z'));
|
|
1248
1242
|
draw = true;
|
|
@@ -1263,7 +1257,7 @@ function Milli_Chart(settings) {
|
|
|
1263
1257
|
legendItems.push({ 'text': text, timestamp: new Date(year + '-04-01T00:00:00Z'), 'x': x });
|
|
1264
1258
|
year = new Date((year.getFullYear() + 1) + '-04-01T00:00:00Z');
|
|
1265
1259
|
}
|
|
1266
|
-
|
|
1260
|
+
// Draw Quarter 2
|
|
1267
1261
|
if (dontPrint == false) {
|
|
1268
1262
|
year = new Date(_this.scaleinfoX.startDate.getFullYear() + '-10-01T00:00:00Z');
|
|
1269
1263
|
if (year.getTime() < _this.scaleinfoX.startDate.getTime())
|
|
@@ -1300,7 +1294,7 @@ function Milli_Chart(settings) {
|
|
|
1300
1294
|
m_ctx.strokeStyle = m_gridHorizontalCss.color;
|
|
1301
1295
|
m_ctx.fillStyle = m_xLegendCss.color;
|
|
1302
1296
|
calcXScale(starttime, endtime);
|
|
1303
|
-
if (_this.settings.drawxaxis != 0) {
|
|
1297
|
+
if (_this.settings.drawxaxis != 0) { // draw line
|
|
1304
1298
|
m_ctx.beginPath();
|
|
1305
1299
|
m_ctx.moveTo(m_chartspaces.chart.left, m_chartspaces.chart.height - getScaledSetting(m_chartCss.marginBottom) + 0.5);
|
|
1306
1300
|
m_ctx.lineTo(m_chartspaces.chart.right, m_chartspaces.chart.height - getScaledSetting(m_chartCss.marginBottom) + 0.5);
|
|
@@ -1315,14 +1309,14 @@ function Milli_Chart(settings) {
|
|
|
1315
1309
|
var draw = true;
|
|
1316
1310
|
var offset = 0;
|
|
1317
1311
|
var count = 0;
|
|
1318
|
-
while (currentDate.getTime() < _this.scaleinfoX.endTimeStamp) {
|
|
1312
|
+
while (currentDate.getTime() < _this.scaleinfoX.endTimeStamp) { // oklart om det skall vara så här 2021-06-01
|
|
1319
1313
|
draw = true;
|
|
1320
|
-
while (currentDate.getDay() == 0 || currentDate.getDay() == 6) {
|
|
1314
|
+
while (currentDate.getDay() == 0 || currentDate.getDay() == 6) { // move past weekends , maybe skip this if date is available in data
|
|
1321
1315
|
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
1322
1316
|
offset += 86400000 / _this.scaleinfoX.timePerPixel;
|
|
1323
1317
|
}
|
|
1324
1318
|
x = Math.round(m_chartspaces.chart.left + ((currentDate.getTime() - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel) - offset);
|
|
1325
|
-
if (lastx == 0 && m_chartspaces.chart.left > (x - (getMaxDateWidth() / 2))) {
|
|
1319
|
+
if (lastx == 0 && m_chartspaces.chart.left > (x - (getMaxDateWidth() / 2))) { // do not print left of y legend
|
|
1326
1320
|
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
1327
1321
|
continue;
|
|
1328
1322
|
}
|
|
@@ -1340,7 +1334,7 @@ function Milli_Chart(settings) {
|
|
|
1340
1334
|
}
|
|
1341
1335
|
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
1342
1336
|
}
|
|
1343
|
-
|
|
1337
|
+
// vad är detta?
|
|
1344
1338
|
if (typeof m_chartCss.boxShadow !== 'undefined' && typeof m_chartCss.boxShadow.rightWidth !== 'undefined') {
|
|
1345
1339
|
if (m_chartCss.boxShadow.rightWidth == 0) drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, false);
|
|
1346
1340
|
} else {
|
|
@@ -1352,9 +1346,9 @@ function Milli_Chart(settings) {
|
|
|
1352
1346
|
function calcXScaleTick(starttime, endtime) {
|
|
1353
1347
|
_this.scaleinfoX.startDate = new Date(starttime);
|
|
1354
1348
|
_this.scaleinfoX.endDate = new Date(endtime);
|
|
1355
|
-
_this.scaleinfoX.days = getNumberOfDays(starttime, endtime);
|
|
1356
|
-
_this.scaleinfoX.lineLength = m_chartspaces.chart.right - m_chartspaces.chart.left;
|
|
1357
|
-
_this.scaleinfoX.itemwidth = getStringWidth(m_ctx, '88:88') * 2;
|
|
1349
|
+
_this.scaleinfoX.days = getNumberOfDays(starttime, endtime); // kan vi nog skita i
|
|
1350
|
+
_this.scaleinfoX.lineLength = m_chartspaces.chart.right - m_chartspaces.chart.left;
|
|
1351
|
+
_this.scaleinfoX.itemwidth = getStringWidth(m_ctx, '88:88') * 2; // kolla rätt format en 8a för varje tecken
|
|
1358
1352
|
var maxLegendItems = Math.floor(_this.scaleinfoX.lineLength / (_this.scaleinfoX.itemwidth * 2));
|
|
1359
1353
|
|
|
1360
1354
|
if (_this.scaleinfoY.type != 'history') {
|
|
@@ -1381,38 +1375,41 @@ function Milli_Chart(settings) {
|
|
|
1381
1375
|
for (i = 0; i < arr.length; i++) {
|
|
1382
1376
|
pixelsperday[i] = arr[i] * timePerPixel;
|
|
1383
1377
|
}
|
|
1384
|
-
var x = totalmilli / maxLegendItems / 60000;
|
|
1378
|
+
//var x = totalmilli / maxLegendItems / 60000;
|
|
1385
1379
|
var numticks = maxLegendItems;
|
|
1386
1380
|
|
|
1387
1381
|
_this.scaleinfoX.milliPerDay = new Date('2019-01-01T' + _this.instruments[0].marketclose + 'Z') - new Date('2019-01-01T' + _this.instruments[0].marketopen + 'Z');
|
|
1388
1382
|
_this.scaleinfoX.timePerPixel = timePerPixel;
|
|
1389
1383
|
|
|
1384
|
+
//_this.scaleinfoX.timePerPixel = (_this.scaleinfoX.milliPerDay * _this.scaleinfoX.days) / _this.scaleinfoX.lineLength;
|
|
1385
|
+
|
|
1386
|
+
|
|
1390
1387
|
_this.scaleinfoX.tickPixelsPerDay = pixelsperday;
|
|
1391
1388
|
|
|
1392
1389
|
var factor = 60;
|
|
1393
1390
|
if (numticks < 1)
|
|
1394
|
-
_this.scaleinfoX.ticksize = 86400000;
|
|
1391
|
+
_this.scaleinfoX.ticksize = 86400000; // öhh?
|
|
1395
1392
|
else {
|
|
1396
1393
|
if (numticks < 2) numticks = 2;
|
|
1397
|
-
x = _this.scaleinfoX.milliPerDay / numticks / 60000;
|
|
1398
|
-
if (totalmilli > 4 * 3600000) factor = 60;
|
|
1394
|
+
// x = _this.scaleinfoX.milliPerDay / numticks / 60000;
|
|
1395
|
+
if (totalmilli > 4 * 3600000) factor = 60; // 4 timmar
|
|
1399
1396
|
else
|
|
1400
|
-
if (totalmilli > 2 * 3600000) factor = 30;
|
|
1397
|
+
if (totalmilli > 2 * 3600000) factor = 30; // 2 timmar
|
|
1401
1398
|
else
|
|
1402
|
-
if (totalmilli > 3600000) factor = 20;
|
|
1399
|
+
if (totalmilli > 3600000) factor = 20; // 1 timma
|
|
1403
1400
|
else
|
|
1404
|
-
if (totalmilli > 3600000 / 2) factor = 10;
|
|
1401
|
+
if (totalmilli > 3600000 / 2) factor = 10; // 30 min
|
|
1405
1402
|
else
|
|
1406
|
-
if (totalmilli > 3600000 / 4) factor = 5;
|
|
1403
|
+
if (totalmilli > 3600000 / 4) factor = 5; // 15 min
|
|
1407
1404
|
else factor = 1;
|
|
1408
|
-
_this.scaleinfoX.ticksize = factor * 60000;
|
|
1405
|
+
_this.scaleinfoX.ticksize = factor * 60000; // time to add to next legenditem
|
|
1409
1406
|
}
|
|
1410
1407
|
return;
|
|
1411
1408
|
}
|
|
1412
1409
|
}
|
|
1413
1410
|
|
|
1414
1411
|
function formatChartTime(value, format) {
|
|
1415
|
-
|
|
1412
|
+
// internal
|
|
1416
1413
|
if (typeof value !== 'string') return "";
|
|
1417
1414
|
var datetime = new Date();
|
|
1418
1415
|
datetime.setHours(parseInt(value));
|
|
@@ -1471,7 +1468,7 @@ function Milli_Chart(settings) {
|
|
|
1471
1468
|
m_ctx.fillStyle = m_xLegendCss.color;
|
|
1472
1469
|
m_ctx.textAlign = "left";
|
|
1473
1470
|
calcXScaleTick(starttime, endtime);
|
|
1474
|
-
if (_this.settings.drawxaxis != 0) {
|
|
1471
|
+
if (_this.settings.drawxaxis != 0) { // draw line for legend
|
|
1475
1472
|
m_ctx.beginPath();
|
|
1476
1473
|
m_ctx.moveTo(m_chartspaces.chart.left, m_chartspaces.chart.bottom + 0.5);
|
|
1477
1474
|
m_ctx.lineTo(m_chartspaces.chart.right, m_chartspaces.chart.bottom + 0.5);
|
|
@@ -1488,20 +1485,19 @@ function Milli_Chart(settings) {
|
|
|
1488
1485
|
var legendItems = [];
|
|
1489
1486
|
var openhour = new Date(new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z')).getTime() % 86400000;
|
|
1490
1487
|
var closehour = new Date(new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z')).getTime() % 86400000;
|
|
1491
|
-
|
|
1488
|
+
// add daysstarts
|
|
1492
1489
|
var middleOfDay = new Date(currentDate.getTime() - (currentDate.getTime() % 86400000) + ((openhour + closehour) / 2));
|
|
1493
1490
|
if (_this.settings.intradayDatePos.x == 'left' && (_this.settings.intradayDatePos.y == 'scale' || _this.settings.intradayDatePos.y == 'top')) {
|
|
1494
1491
|
middleOfDay = new Date(currentDate.getTime());
|
|
1495
1492
|
}
|
|
1496
|
-
if (currentDate.getTime() % 3600000 != 0)
|
|
1497
|
-
currentDate = new Date(currentDate.getTime() - currentDate.getTime() % 3600000 + 3600000);
|
|
1498
|
-
|
|
1493
|
+
if (currentDate.getTime() % 3600000 != 0) // if not full hour, move up to next full hour
|
|
1494
|
+
currentDate = new Date(currentDate.getTime() - currentDate.getTime() % 3600000 + 3600000); // START om full hour (if modulo == 0 then + 3600000 kanske)
|
|
1499
1495
|
var firstDate = new Date(currentDate);
|
|
1500
1496
|
var days = calcTimeSpanInDays(starttime, endtime);
|
|
1501
1497
|
if (m_zoom.mouseup.timestamp == null || (m_zoom.mouseup.timestamp != null && days > 1)) {
|
|
1502
1498
|
while (currentDate.getTime() < _this.scaleinfoX.endTimeStamp) {
|
|
1503
1499
|
draw = true;
|
|
1504
|
-
while (currentDate.getDay() == 0 || currentDate.getDay() == 6) {
|
|
1500
|
+
while (currentDate.getDay() == 0 || currentDate.getDay() == 6) { // move past weekends , maybe skip this if date is available in data
|
|
1505
1501
|
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
1506
1502
|
if (_this.settings.intradayDatePos.x == 'left' && (_this.settings.intradayDatePos.y == 'scale' || _this.settings.intradayDatePos.y == 'top')) {
|
|
1507
1503
|
middleOfDay = new Date(currentDate.getTime());
|
|
@@ -1514,20 +1510,20 @@ function Milli_Chart(settings) {
|
|
|
1514
1510
|
if (lastx != 0 && lastx + (getMaxTimeWidth() / 2) > (x - getMaxTimeWidth())) {
|
|
1515
1511
|
draw = false;
|
|
1516
1512
|
} else
|
|
1517
|
-
if (m_zoom.mouseup.timestamp != null && firstDate.getTime() === currentDate.getTime())
|
|
1513
|
+
if (m_zoom.mouseup.timestamp != null && firstDate.getTime() === currentDate.getTime()) {
|
|
1518
1514
|
draw = false;
|
|
1515
|
+
}
|
|
1519
1516
|
if (draw) {
|
|
1520
1517
|
lastx = x + 0.5;
|
|
1521
1518
|
var text = formatChartTime(currentDate.toTimeString().substring(0, 8), _this.settings.timeformat);
|
|
1522
1519
|
var date = formatDate(currentDate, _this.settings.intradayDatePos.dateformat, _this);
|
|
1523
|
-
if (_this.scaleinfoX.lineLength + m_chartspaces.chart.left > x - getMaxTimeWidth()) {
|
|
1520
|
+
if (_this.scaleinfoX.lineLength + m_chartspaces.chart.left > x - getMaxTimeWidth()) { // not to far right?
|
|
1524
1521
|
if (_this.settings.intradayDatePos.y == 'scale' && _this.settings.chartlen != '0d' && _this.settings.chartlen != '1d') {
|
|
1525
|
-
|
|
1522
|
+
// draw date on under time, todo fix setting name
|
|
1526
1523
|
m_ctx.fillText(date, middleX - (m_ctx.measureText(date).width / 2), m_chartspaces.chart.bottom + getScaledSetting(m_xLegendCss.paddingTop));
|
|
1527
1524
|
legendItems.push({ x: middleX, type: 0, text: date, width: m_ctx.measureText(date) });
|
|
1528
1525
|
} else if (_this.settings.intradayDatePos.y == 'bottom' && _this.settings.chartlen != '0d' && _this.settings.chartlen != '1d') {
|
|
1529
1526
|
m_ctx.fillText(date, middleX - (m_ctx.measureText(date).width / 2), m_chartspaces.chart.bottom + getScaledSetting(m_xLegendCss.paddingTop) + parseInt(m_xLegendCss.fontSize) * window.devicePixelRatio);
|
|
1530
|
-
|
|
1531
1527
|
m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_chartspaces.chart.bottom + getScaledSetting(m_xLegendCss.paddingTop));
|
|
1532
1528
|
legendItems.push({ x: x, type: 0, text: text });
|
|
1533
1529
|
} else {
|
|
@@ -1547,7 +1543,7 @@ function Milli_Chart(settings) {
|
|
|
1547
1543
|
if (_this.settings.intradayDatePos.x == 'center') {
|
|
1548
1544
|
m_ctx.fillText(date, middleX - (m_ctx.measureText(date).width / 2), getScaledSetting(m_chartCss.marginTop));
|
|
1549
1545
|
} else {
|
|
1550
|
-
|
|
1546
|
+
//m_ctx.fillText(date, x - (m_ctx.measureText(date).width / 2), getScaledSetting(m_chartCss.marginTop));
|
|
1551
1547
|
m_ctx.fillText(date, middleX + 1, getScaledSetting(m_chartCss.marginTop));
|
|
1552
1548
|
}
|
|
1553
1549
|
}
|
|
@@ -1555,17 +1551,17 @@ function Milli_Chart(settings) {
|
|
|
1555
1551
|
}
|
|
1556
1552
|
}
|
|
1557
1553
|
}
|
|
1558
|
-
if (x != m_chartspaces.chart.left + 0.5) {
|
|
1554
|
+
if (x != m_chartspaces.chart.left + 0.5) { // do not draw the first line, it is already drawn
|
|
1559
1555
|
if (_this.settings.intradayDatePos.y != 'bottom') {
|
|
1560
1556
|
if (openhour == currentDate.getTime() % 86400000) {
|
|
1561
|
-
drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, true);
|
|
1557
|
+
drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, true); // dash?
|
|
1562
1558
|
} else {
|
|
1563
|
-
drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, false);
|
|
1559
|
+
drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, false); // dash?
|
|
1564
1560
|
}
|
|
1565
1561
|
}
|
|
1566
1562
|
}
|
|
1567
1563
|
}
|
|
1568
|
-
|
|
1564
|
+
// Move to next day and set starting hour correct if we have open at half hour
|
|
1569
1565
|
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
1570
1566
|
currentDate = new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z');
|
|
1571
1567
|
middleOfDay = new Date(currentDate.getTime() - (currentDate.getTime() % 86400000) + ((openhour + closehour) / 2));
|
|
@@ -1573,23 +1569,23 @@ function Milli_Chart(settings) {
|
|
|
1573
1569
|
middleOfDay = new Date(currentDate);
|
|
1574
1570
|
}
|
|
1575
1571
|
|
|
1576
|
-
if (currentDate.getTime() % 3600000 != 0)
|
|
1577
|
-
currentDate = new Date(currentDate.getTime() - currentDate.getTime() % 3600000 + 3600000);
|
|
1578
|
-
|
|
1572
|
+
if (currentDate.getTime() % 3600000 != 0) // if not full hour, move up to next full hour
|
|
1573
|
+
currentDate = new Date(currentDate.getTime() - currentDate.getTime() % 3600000 + 3600000); // START om full hour (if modulo == 0 then + 3600000 kanske)
|
|
1574
|
+
//}
|
|
1579
1575
|
offset += (86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel;
|
|
1580
1576
|
}
|
|
1581
1577
|
}
|
|
1582
|
-
|
|
1578
|
+
// add timestamps
|
|
1583
1579
|
currentDate = new Date(starttime);
|
|
1584
|
-
if (currentDate.getTime() % 3600000 != 0)
|
|
1585
|
-
currentDate = new Date(currentDate.getTime() - currentDate.getTime() % 3600000 + 3600000);
|
|
1580
|
+
if (currentDate.getTime() % 3600000 != 0) // if not full hour, move up to next full hour
|
|
1581
|
+
currentDate = new Date(currentDate.getTime() - currentDate.getTime() % 3600000 + 3600000); // START om full hour (if modulo == 0 then + 3600000 kanske)
|
|
1586
1582
|
|
|
1587
1583
|
var maxHourLegends;
|
|
1588
1584
|
if (legendItems.length == 0)
|
|
1589
|
-
maxHourLegends = Math.floor((_this.scaleinfoX.lineLength - m_chartspaces.chart.left - getMaxTimeWidth()) / (getMaxTimeWidth() * 3));
|
|
1585
|
+
maxHourLegends = Math.floor((_this.scaleinfoX.lineLength - m_chartspaces.chart.left - getMaxTimeWidth()) / (getMaxTimeWidth() * 3)); // varför tar vi bort margin???
|
|
1590
1586
|
else if (legendItems.length == 1) {
|
|
1591
1587
|
if (m_zoom.mouseup.timestamp && days == 2) {
|
|
1592
|
-
|
|
1588
|
+
// ta den största delen av linjen och mät på
|
|
1593
1589
|
if (_this.scaleinfoX.lineLength / 2 < legendItems[0].x + m_chartspaces.chart.left)
|
|
1594
1590
|
maxHourLegends = Math.floor((_this.scaleinfoX.lineLength - (_this.scaleinfoX.lineLength - legendItems[0].x) - getMaxTimeWidth()) / (getMaxTimeWidth() * 3));
|
|
1595
1591
|
else
|
|
@@ -1597,15 +1593,15 @@ function Milli_Chart(settings) {
|
|
|
1597
1593
|
} else
|
|
1598
1594
|
maxHourLegends = Math.floor((_this.scaleinfoX.lineLength - legendItems[0].x - getMaxTimeWidth()) / (getMaxTimeWidth() * 3));
|
|
1599
1595
|
} else {
|
|
1600
|
-
maxHourLegends = Math.floor((legendItems[legendItems.length - 1].x - legendItems[legendItems.length - 2].x - getMaxTimeWidth()) / (getMaxTimeWidth() * 3));
|
|
1596
|
+
maxHourLegends = Math.floor((legendItems[legendItems.length - 1].x - legendItems[legendItems.length - 2].x - getMaxTimeWidth()) / (getMaxTimeWidth() * 3)); // calculate with the last days length
|
|
1601
1597
|
}
|
|
1602
1598
|
|
|
1603
|
-
var tickSize;
|
|
1599
|
+
var tickSize; // per day
|
|
1604
1600
|
if (days == 1) {
|
|
1605
|
-
|
|
1601
|
+
// use start and endtime as ticksize
|
|
1606
1602
|
tickSize = new Date(endtime - starttime);
|
|
1607
|
-
} else if (m_zoom.mouseup.timestamp && days == 2) {
|
|
1608
|
-
|
|
1603
|
+
} else if (m_zoom.mouseup.timestamp && days == 2) { // zoom with 2 days
|
|
1604
|
+
// use the day with most time as tickSize
|
|
1609
1605
|
var tmpDate = new Date(starttime);
|
|
1610
1606
|
tickSize = new Date(new Date(tmpDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z') - new Date(starttime)).getTime();
|
|
1611
1607
|
var firstDay = tickSize;
|
|
@@ -1614,13 +1610,13 @@ function Milli_Chart(settings) {
|
|
|
1614
1610
|
tickSize += new Date(endtime - new Date(tmpDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z').getTime()).getTime();
|
|
1615
1611
|
tickSize = new Date(Math.max(firstDay, secondDay));
|
|
1616
1612
|
} else {
|
|
1617
|
-
|
|
1613
|
+
// use full day as tickSize
|
|
1618
1614
|
tickSize = new Date(new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z') - new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z'));
|
|
1619
1615
|
}
|
|
1620
1616
|
var interval;
|
|
1621
1617
|
var modularvalue = 3600000;
|
|
1622
1618
|
|
|
1623
|
-
|
|
1619
|
+
// calc the ticksize to add to time(interval) when drawing and the modulu value
|
|
1624
1620
|
if (tickSize.getTime() < 1800000) {
|
|
1625
1621
|
tickSize = tickSize.getTime() / 60000;
|
|
1626
1622
|
interval = Math.floor(tickSize / (maxHourLegends + 1)) * 60000;
|
|
@@ -1639,14 +1635,14 @@ function Milli_Chart(settings) {
|
|
|
1639
1635
|
interval = Math.floor(tickSize / (maxHourLegends + 1)) * 3600000;
|
|
1640
1636
|
}
|
|
1641
1637
|
if (interval == 0) {
|
|
1642
|
-
|
|
1638
|
+
// default 1h
|
|
1643
1639
|
interval = 3600000;
|
|
1644
1640
|
modularvalue = 3600000;
|
|
1645
1641
|
}
|
|
1646
1642
|
if (interval % 60000 != 0) {
|
|
1647
|
-
interval = (interval - interval % 60000) + 60000;
|
|
1643
|
+
interval = (interval - interval % 60000) + 60000; // remove sekunder
|
|
1648
1644
|
}
|
|
1649
|
-
|
|
1645
|
+
// print other times
|
|
1650
1646
|
offset = 0;
|
|
1651
1647
|
lastx = 0;
|
|
1652
1648
|
var closeTime = new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
|
|
@@ -1655,41 +1651,41 @@ function Milli_Chart(settings) {
|
|
|
1655
1651
|
|
|
1656
1652
|
var workDate = new Date(currentDate);
|
|
1657
1653
|
currentDate = new Date(starttime);
|
|
1658
|
-
if (currentDate.getTime() % modularvalue != 0)
|
|
1659
|
-
currentDate = new Date(currentDate.getTime() - currentDate.getTime() % modularvalue + modularvalue);
|
|
1654
|
+
if (currentDate.getTime() % modularvalue != 0) // if not full hour, move up to next full hour
|
|
1655
|
+
currentDate = new Date(currentDate.getTime() - currentDate.getTime() % modularvalue + modularvalue); // START om full hour (if modulo == 0 then + 3600000 kanske)
|
|
1660
1656
|
|
|
1661
1657
|
var count = 0;
|
|
1662
1658
|
while (currentDate.getTime() <= _this.scaleinfoX.endTimeStamp) {
|
|
1663
1659
|
dayLightChange = (closeTime.getTimezoneOffset() - new Date().getTimezoneOffset()) * 60000;
|
|
1664
1660
|
if (count++ > 100) {
|
|
1665
|
-
break;
|
|
1661
|
+
break; // just make sure we dont do an infinity loop
|
|
1666
1662
|
|
|
1667
1663
|
}
|
|
1668
1664
|
draw = true;
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
1672
|
-
closeTime = new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
|
|
1673
|
-
if (currentDate.getTime() % modularvalue != 0)
|
|
1674
|
-
currentDate = new Date(currentDate.getTime() - currentDate.getTime() % modularvalue + modularvalue);
|
|
1675
|
-
workDate = new Date(workDate.getTime() + 86400000);
|
|
1676
|
-
offset += 86400000 / _this.scaleinfoX.timePerPixel;
|
|
1677
|
-
}
|
|
1665
|
+
// bytt plats på if och while nedan 2022-11-07
|
|
1678
1666
|
if (currentDate.getTime() > closeTime.getTime()) {
|
|
1679
|
-
|
|
1667
|
+
// draw DayEnd(start) dash line
|
|
1680
1668
|
var dayStart = new Date(workDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
|
|
1681
1669
|
x = Math.round(m_chartspaces.chart.left + ((dayStart.getTime() - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel) - offset);
|
|
1682
|
-
drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, true);
|
|
1670
|
+
drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, true); // dash?
|
|
1683
1671
|
|
|
1684
1672
|
closeTime = new Date(closeTime.getTime() + 86400000);
|
|
1685
1673
|
workDate = new Date(workDate.getTime() + 86400000);
|
|
1686
1674
|
currentDate = new Date(workDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z');
|
|
1687
1675
|
|
|
1688
|
-
if (currentDate.getTime() % modularvalue != 0)
|
|
1689
|
-
currentDate = new Date(currentDate.getTime() - currentDate.getTime() % modularvalue + modularvalue);
|
|
1676
|
+
if (currentDate.getTime() % modularvalue != 0) // if not full hour, move up to next full hour
|
|
1677
|
+
currentDate = new Date(currentDate.getTime() - currentDate.getTime() % modularvalue + modularvalue); // START om full hour (if modulo == 0 then + 3600000 kanske)
|
|
1690
1678
|
offset += (86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel;
|
|
1691
1679
|
continue;
|
|
1692
1680
|
}
|
|
1681
|
+
while (currentDate.getDay() == 0 || currentDate.getDay() == 6) { // move past weekends , maybe skip this if date is available in data
|
|
1682
|
+
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
1683
|
+
closeTime = new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
|
|
1684
|
+
if (currentDate.getTime() % modularvalue != 0) // if not full hour, move up to next full hour
|
|
1685
|
+
currentDate = new Date(currentDate.getTime() - currentDate.getTime() % modularvalue + modularvalue); // START om full hour (if modulo == 0 then + 3600000 kanske)
|
|
1686
|
+
workDate = new Date(workDate.getTime() + 86400000);
|
|
1687
|
+
offset += 86400000 / _this.scaleinfoX.timePerPixel;
|
|
1688
|
+
}
|
|
1693
1689
|
x = Math.round(m_chartspaces.chart.left + ((currentDate.getTime() - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel) - offset);
|
|
1694
1690
|
for (var i = 0; i < legendItems.length; i++) {
|
|
1695
1691
|
if (x < legendItems[i].x && x + (getMaxTimeWidth() / 2) > (legendItems[i].x - getMaxTimeWidth())) {
|
|
@@ -1706,23 +1702,23 @@ function Milli_Chart(settings) {
|
|
|
1706
1702
|
}
|
|
1707
1703
|
}
|
|
1708
1704
|
if (lastx + (getMaxTimeWidth() / 2) > (x - getMaxTimeWidth())) {
|
|
1709
|
-
|
|
1705
|
+
//draw = false;
|
|
1710
1706
|
}
|
|
1711
1707
|
if (draw) {
|
|
1712
1708
|
lastx = x;
|
|
1713
|
-
|
|
1714
|
-
if (_this.scaleinfoX.lineLength + m_chartspaces.chart.left > x - getMaxTimeWidth()) {
|
|
1709
|
+
// if day change and setting print on top as well
|
|
1710
|
+
if (_this.scaleinfoX.lineLength + m_chartspaces.chart.left > x - getMaxTimeWidth()) { // not to far right?
|
|
1715
1711
|
var label = formatChartTime(currentDate.toTimeString().substring(0, 8), _this.settings.timeformat);
|
|
1716
1712
|
x = Math.round(x);
|
|
1717
1713
|
m_ctx.fillText(label, x - (m_ctx.measureText(label).width / 2), m_chartspaces.chart.bottom + getScaledSetting(m_xLegendCss.paddingTop));
|
|
1718
|
-
legendItems.push({ x: x, type: 0 });
|
|
1714
|
+
legendItems.push({ x: x, type: 0, text: label });
|
|
1719
1715
|
}
|
|
1720
1716
|
drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, false);
|
|
1721
1717
|
}
|
|
1722
1718
|
currentDate = new Date(currentDate.getTime() + interval);
|
|
1723
1719
|
}
|
|
1724
1720
|
|
|
1725
|
-
|
|
1721
|
+
// vad är detta?
|
|
1726
1722
|
if (typeof m_chartCss.boxShadow !== 'undefined' && typeof m_chartCss.boxShadow.rightWidth !== 'undefined') {
|
|
1727
1723
|
if (m_chartCss.boxShadow.rightWidth == 0) drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, false);
|
|
1728
1724
|
|
|
@@ -1756,11 +1752,15 @@ function Milli_Chart(settings) {
|
|
|
1756
1752
|
var oldValue = undefined;
|
|
1757
1753
|
var newValue = undefined;
|
|
1758
1754
|
var offsetWidth = 0;
|
|
1759
|
-
if (_this.
|
|
1755
|
+
if (_this.instruments[0].pricetype == 'yield') {
|
|
1756
|
+
newValue = formatNiceNumber(obj.instruments[0].price, _this.settings.thousandseparator, _this.settings.decimalseparator, _this.settings.num_decimals, false);
|
|
1757
|
+
if (m_y2LegendCss.textAlign == 'left') offsetWidth = 1;
|
|
1758
|
+
} else if (_this.settings.drawyaxis && m_yLegendCss.float == 'right') {
|
|
1760
1759
|
newValue = formatNiceNumber(obj.instruments[0].price, _this.settings.thousandseparator, _this.settings.decimalseparator, _this.settings.num_decimals, false);
|
|
1761
1760
|
if (m_yLegendCss.textAlign == 'left') offsetWidth = 1;
|
|
1762
1761
|
} else if (_this.settings.drawy2axis && m_y2LegendCss.float == 'right') {
|
|
1763
|
-
newValue = formatNiceNumber(obj.instruments[0].diff, _this.settings.thousandseparator, _this.settings.decimalseparator, 2, false) + '%';
|
|
1762
|
+
if (obj.instruments[0].diff > 0) newValue = '+' + formatNiceNumber(obj.instruments[0].diff, _this.settings.thousandseparator, _this.settings.decimalseparator, 2, false) + '%';
|
|
1763
|
+
else newValue = formatNiceNumber(obj.instruments[0].diff, _this.settings.thousandseparator, _this.settings.decimalseparator, 2, false) + '%';
|
|
1764
1764
|
if (m_y2LegendCss.textAlign == 'left') offsetWidth = 1;
|
|
1765
1765
|
} else return;
|
|
1766
1766
|
if (typeof m_priceIndicator !== 'undefined') {
|
|
@@ -1771,7 +1771,7 @@ function Milli_Chart(settings) {
|
|
|
1771
1771
|
m_priceIndicator.setAttribute('class', 'millistream-chart-price-indicator');
|
|
1772
1772
|
}
|
|
1773
1773
|
m_priceIndicator.innerHTML = newValue;
|
|
1774
|
-
m_priceIndicator.style.left = (m_chartspaces.chart.right / window.devicePixelRatio) - (offsetWidth == 0 ? -1 : m_priceIndicator.offsetWidth) + 'px';
|
|
1774
|
+
m_priceIndicator.style.left = (m_chartspaces.chart.right / window.devicePixelRatio) - (offsetWidth == 0 ? -1 : m_priceIndicator.offsetWidth) + 'px'; // offsetWidth with devicePixelRatio???
|
|
1775
1775
|
m_priceIndicator.style.top = obj.instruments[0].y - (m_priceIndicator.offsetHeight / 2) + 'px';
|
|
1776
1776
|
newValue = MillistreamWidgetApi_getElementNumber(_this, m_priceIndicator);
|
|
1777
1777
|
MillistreamWidgetApi_flashElement(_this, m_priceIndicator, newValue, oldValue);
|
|
@@ -1850,6 +1850,8 @@ function Milli_Chart(settings) {
|
|
|
1850
1850
|
var instr = {};
|
|
1851
1851
|
instr.chartType = _this.scaleinfoY.type;
|
|
1852
1852
|
instr.name = _this.instruments[x].name;
|
|
1853
|
+
instr.instrumenttype = _this.instruments[x].instrumenttype;
|
|
1854
|
+
instr.pricetype = _this.instruments[x].pricetype;
|
|
1853
1855
|
if (typeof _this.instruments[x].symbol !== 'undefined')
|
|
1854
1856
|
instr.symbol = _this.instruments[x].symbol;
|
|
1855
1857
|
|
|
@@ -1858,13 +1860,13 @@ function Milli_Chart(settings) {
|
|
|
1858
1860
|
instr.data.price = formatNiceNumber(instr.data.price, _this.settings.thousandseparator, _this.settings.decimalseparator, _this.settings.num_decimals, false);
|
|
1859
1861
|
|
|
1860
1862
|
if (typeof _this.instruments[x].toolTip === 'undefined') {
|
|
1861
|
-
|
|
1863
|
+
// add textdiv
|
|
1862
1864
|
_this.instruments[x].toolTip = document.createElement('div');
|
|
1863
1865
|
_this.instruments[x].toolTip.style.display = _this.settings.tooltip.display;
|
|
1864
|
-
_this.instruments[x].toolTip.setAttribute('class', 'millistream-chart-tooltip');
|
|
1866
|
+
_this.instruments[x].toolTip.setAttribute('class', 'millistream-chart-tooltip'); // set class so we can measure it might change below depending on position
|
|
1865
1867
|
_this.instruments[x].toolTip.position = 'absolute';
|
|
1866
1868
|
m_canvas.parentNode.appendChild(_this.instruments[x].toolTip);
|
|
1867
|
-
|
|
1869
|
+
// add pointer div
|
|
1868
1870
|
_this.instruments[x].toolTipPointer = document.createElement('div');
|
|
1869
1871
|
m_canvas.parentNode.appendChild(_this.instruments[x].toolTipPointer);
|
|
1870
1872
|
_this.instruments[x].toolTipPointer.setAttribute('class', 'millistream-chart-pointer');
|
|
@@ -1879,16 +1881,16 @@ function Milli_Chart(settings) {
|
|
|
1879
1881
|
var pointerWidth = _this.instruments[x].toolTipPointer.offsetWidth + parseInt(pointerStyle.marginLeft) + parseInt(pointerStyle.marginRight);
|
|
1880
1882
|
var pointerHeight = _this.instruments[x].toolTipPointer.offsetHeight + parseInt(pointerStyle.marginTop) + parseInt(pointerStyle.marginBottom);
|
|
1881
1883
|
var posy = obj.instruments[x].y - (_this.instruments[x].toolTip.offsetHeight / 2);
|
|
1882
|
-
if (m_dataPoints.arr[i] + (_this.instruments[x].toolTip.offsetWidth * 1.5) > m_canvas.width) {
|
|
1883
|
-
|
|
1884
|
+
if (m_dataPoints.arr[i] + (_this.instruments[x].toolTip.offsetWidth * 1.5) > m_canvas.width) { // || m_dataPoints.arr[i] + (_this.instruments[x].toolTip.offsetWidth * 1.5) > m_canvas.width) { // TODO +10 should be calculated better
|
|
1885
|
+
// draw the hover to the left
|
|
1884
1886
|
_this.instruments[x].toolTip.style.left = (obj.instruments[x].x - _this.instruments[x].toolTip.offsetWidth - (pointerWidth / 2)) + 1 + 'px';
|
|
1885
1887
|
} else {
|
|
1886
|
-
|
|
1888
|
+
// draw hover to the right
|
|
1887
1889
|
_this.instruments[x].toolTip.style.left = (obj.instruments[x].x + (pointerWidth / 2)) + 'px';
|
|
1888
1890
|
}
|
|
1889
1891
|
_this.instruments[x].toolTip.style.top = posy + 'px';
|
|
1890
1892
|
toolArray.push({ top: (obj.instruments[x].y - (pointerHeight / 2)), instrument: x });
|
|
1891
|
-
_this.instruments[x].toolTipPointer.style.left = (obj.instruments[x].x - (pointerWidth / 2)) + 1 + 'px';
|
|
1893
|
+
_this.instruments[x].toolTipPointer.style.left = (obj.instruments[x].x - (pointerWidth / 2)) + 1 + 'px'; // hmm plus 1??
|
|
1892
1894
|
_this.instruments[x].toolTipPointer.style.top = (obj.instruments[x].y - (pointerHeight / 2)) + 'px';
|
|
1893
1895
|
if (posy > highy) highy = posy;
|
|
1894
1896
|
if (posy < lowy) lowy = posy;
|
|
@@ -1932,13 +1934,12 @@ function Milli_Chart(settings) {
|
|
|
1932
1934
|
enddate: new Date(_this.scaleinfoX.endTimeStamp).toISOString().substring(0, 10)
|
|
1933
1935
|
};
|
|
1934
1936
|
|
|
1935
|
-
}
|
|
1937
|
+
};
|
|
1936
1938
|
|
|
1937
1939
|
_this.setDateInterval = function(startdate, enddate) {
|
|
1938
1940
|
startdate = startdate.replaceAll('\/', '-');
|
|
1939
1941
|
enddate = enddate.replaceAll('\/', '-');
|
|
1940
1942
|
m_zoom.mousedown.timestamp = findFirstWeekDay(new Date(startdate + 'T00:00:00Z'));
|
|
1941
|
-
() => {};
|
|
1942
1943
|
|
|
1943
1944
|
m_zoom.mouseup.timestamp = new Date(enddate + 'T00:00:00Z');
|
|
1944
1945
|
|
|
@@ -1947,7 +1948,7 @@ function Milli_Chart(settings) {
|
|
|
1947
1948
|
m_zoom.mouseup.timestamp = new Date(m_zoom.mouseup.timestamp + 'T00:00:00Z');
|
|
1948
1949
|
}
|
|
1949
1950
|
_this.settings.chartlen = 'max';
|
|
1950
|
-
_this.scaleinfoY.type
|
|
1951
|
+
_this.scaleinfoY.type = 'history';
|
|
1951
1952
|
_this.drawChart();
|
|
1952
1953
|
};
|
|
1953
1954
|
|
|
@@ -1982,7 +1983,7 @@ function Milli_Chart(settings) {
|
|
|
1982
1983
|
}
|
|
1983
1984
|
}
|
|
1984
1985
|
}
|
|
1985
|
-
if (_this.scaleinfoY.type == 'trades' && count > 0 && _this.instruments[0].closeprice1d) return true;
|
|
1986
|
+
if (_this.scaleinfoY.type == 'trades' && count > 0 && _this.instruments[0].closeprice1d) return true; // we can draw on closeprice 1d -> first trade
|
|
1986
1987
|
var y = (m_chartspaces.chart.bottom - m_chartspaces.chart.top) / 2 + m_chartspaces.chart.top;
|
|
1987
1988
|
var x = (m_chartspaces.chart.right - m_chartspaces.chart.left) / 2 + m_chartspaces.chart.left;
|
|
1988
1989
|
m_ctx.save();
|
|
@@ -2014,7 +2015,7 @@ function Milli_Chart(settings) {
|
|
|
2014
2015
|
|
|
2015
2016
|
_this.drawChart = function() {
|
|
2016
2017
|
if (m_zoom.isZooming) {
|
|
2017
|
-
return;
|
|
2018
|
+
return; // prevent redraw due to push updates when zooming
|
|
2018
2019
|
}
|
|
2019
2020
|
|
|
2020
2021
|
for (var i = 0; i < _this.settings.indicators.length; i++) {
|
|
@@ -2057,7 +2058,7 @@ function Milli_Chart(settings) {
|
|
|
2057
2058
|
m_dataPoints.map = new Map();
|
|
2058
2059
|
m_dataPoints.arr = [];
|
|
2059
2060
|
if (_this.instruments.length < 0) {
|
|
2060
|
-
()
|
|
2061
|
+
console.log('no chartdata');
|
|
2061
2062
|
return;
|
|
2062
2063
|
}
|
|
2063
2064
|
calcChartSpaces();
|
|
@@ -2066,51 +2067,51 @@ function Milli_Chart(settings) {
|
|
|
2066
2067
|
var len = parseInt(_this.settings.chartlen.substring(0, _this.settings.chartlen.length - 1));
|
|
2067
2068
|
m_ctx.clearRect(0, 0, m_canvas.width, m_canvas.height);
|
|
2068
2069
|
m_ctx.lineWidth = 1 / window.devicePixelRatio;
|
|
2069
|
-
m_ctx.textBaseline = 'top';
|
|
2070
|
-
var
|
|
2070
|
+
m_ctx.textBaseline = 'top'; // important!
|
|
2071
|
+
var s;
|
|
2071
2072
|
if (period == 'd' && _this.settings.chartlen != 'ytd') {
|
|
2072
2073
|
if (m_zoom.mousedown.timestamp) {
|
|
2073
2074
|
_this.scaleinfoX.endTimeStamp = m_zoom.mouseup.timestamp > m_zoom.mousedown.timestamp ? m_zoom.mouseup.timestamp : m_zoom.mousedown.timestamp;
|
|
2074
2075
|
_this.scaleinfoX.startTimeStamp = m_zoom.mouseup.timestamp < m_zoom.mousedown.timestamp ? m_zoom.mouseup.timestamp : m_zoom.mousedown.timestamp;
|
|
2075
2076
|
} else {
|
|
2076
|
-
_this.scaleinfoX.startTimeStamp = getTickStartDate(len);
|
|
2077
|
-
|
|
2078
|
-
|
|
2077
|
+
_this.scaleinfoX.startTimeStamp = getTickStartDate(len); // calc not to start with weekends
|
|
2078
|
+
// back up x days from quotedate if needed
|
|
2079
|
+
// TODO if startTimeStamp < quotedate -len borde det vara
|
|
2079
2080
|
var quoteDate = businessDaysSubtraction(_this.instruments[0].quotedate, len);
|
|
2080
|
-
if (_this.scaleinfoX.startTimeStamp - _this.scaleinfoX.startTimeStamp % 86400000 > quoteDate) {
|
|
2081
|
+
if (_this.scaleinfoX.startTimeStamp - _this.scaleinfoX.startTimeStamp % 86400000 > quoteDate) { // if startdate > quotedate back startdate
|
|
2081
2082
|
_this.scaleinfoX.startTimeStamp -= _this.scaleinfoX.startTimeStamp - _this.scaleinfoX.startTimeStamp % 86400000;
|
|
2082
2083
|
_this.scaleinfoX.startTimeStamp += quoteDate;
|
|
2083
2084
|
}
|
|
2084
|
-
_this.scaleinfoX.endTimeStamp = new Date();
|
|
2085
|
+
_this.scaleinfoX.endTimeStamp = new Date(); // om helg TODO
|
|
2085
2086
|
if (len > 1)
|
|
2086
2087
|
_this.scaleinfoX.endTimeStamp = new Date(_this.scaleinfoX.endTimeStamp.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z').getTime();
|
|
2087
2088
|
else if (len == 1) {
|
|
2088
|
-
|
|
2089
|
+
// check if startdate is not today (due to exchange is closed f ex DJ)
|
|
2089
2090
|
if (_this.scaleinfoX.startTimeStamp % 86400000 != new Date().getTime() % 86400) {
|
|
2090
2091
|
_this.scaleinfoX.endTimeStamp = new Date(new Date(_this.scaleinfoX.startTimeStamp).toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z').getTime();
|
|
2091
2092
|
} else
|
|
2092
2093
|
_this.scaleinfoX.endTimeStamp = new Date(_this.scaleinfoX.endTimeStamp.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z').getTime();
|
|
2093
2094
|
} else {
|
|
2094
|
-
|
|
2095
|
+
// check that the last trade is not later than closetime
|
|
2095
2096
|
var tradetimestamp = new Date(_this.instruments[0].trades[_this.instruments[0].trades.length - 1].timestamp).getTime();
|
|
2096
2097
|
var closetimestamp = new Date(new Date(_this.instruments[0].trades[_this.instruments[0].trades.length - 1].timestamp).toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z').getTime();
|
|
2097
2098
|
if (closetimestamp < tradetimestamp)
|
|
2098
|
-
_this.scaleinfoX.endTimeStamp = new Date(closetimestamp);
|
|
2099
|
+
_this.scaleinfoX.endTimeStamp = new Date(closetimestamp); // borde inte rita med closeprice1d då heller eller spelar det ingen roll?
|
|
2099
2100
|
else
|
|
2100
2101
|
_this.scaleinfoX.endTimeStamp = new Date(tradetimestamp);
|
|
2101
2102
|
}
|
|
2102
2103
|
if (_this.scaleinfoX.endTimeStamp - (_this.scaleinfoX.endTimeStamp % 86400000) > _this.instruments[0].quotedate) {
|
|
2103
2104
|
_this.scaleinfoX.endTimeStamp -= _this.scaleinfoX.endTimeStamp - _this.scaleinfoX.endTimeStamp % 86400000;
|
|
2104
|
-
_this.scaleinfoX.endTimeStamp += _this.instruments[0].quotedate;
|
|
2105
|
+
_this.scaleinfoX.endTimeStamp += _this.instruments[0].quotedate; // set enddate = last Quotedate
|
|
2105
2106
|
}
|
|
2106
2107
|
}
|
|
2107
2108
|
setTimeSpanData();
|
|
2108
2109
|
_this.scaleinfoY.type = 'trades';
|
|
2109
2110
|
if (_this.settings.absoluteScaling == true) {
|
|
2110
|
-
for (
|
|
2111
|
+
for (s = 1; s < _this.instruments.length; s++) _this.instruments[s].factor = 1;
|
|
2111
2112
|
} else
|
|
2112
2113
|
if (_this.instruments.length > 1) {
|
|
2113
|
-
|
|
2114
|
+
// calc factors
|
|
2114
2115
|
var instrumentprice;
|
|
2115
2116
|
for (i = 0; i < _this.instruments[0].trades.length; i++) {
|
|
2116
2117
|
if (_this.instruments[0].trades[i].timestamp >= _this.scaleinfoX.startTimeStamp) {
|
|
@@ -2118,7 +2119,7 @@ function Milli_Chart(settings) {
|
|
|
2118
2119
|
break;
|
|
2119
2120
|
}
|
|
2120
2121
|
}
|
|
2121
|
-
for (
|
|
2122
|
+
for (s = 1; s < _this.instruments.length; s++) {
|
|
2122
2123
|
if (_this.instruments[s].insref != 0) {
|
|
2123
2124
|
for (i = 0; i < _this.instruments[s].trades.length; i++) {
|
|
2124
2125
|
if (_this.instruments[s].trades[i].timestamp >= _this.scaleinfoX.startTimeStamp) {
|
|
@@ -2147,7 +2148,6 @@ function Milli_Chart(settings) {
|
|
|
2147
2148
|
|
|
2148
2149
|
} else
|
|
2149
2150
|
if (period == 'm') {
|
|
2150
|
-
() => {};
|
|
2151
2151
|
|
|
2152
2152
|
if (m_zoom.mousedown.timestamp) {
|
|
2153
2153
|
_this.scaleinfoX.startTimeStamp = m_zoom.mousedown.timestamp > m_zoom.mouseup.timestamp ? m_zoom.mouseup.timestamp : m_zoom.mousedown.timestamp;
|
|
@@ -2162,12 +2162,12 @@ function Milli_Chart(settings) {
|
|
|
2162
2162
|
if (_this.instruments[0].history.length > 1 && _this.scaleinfoX.startTimeStamp < _this.instruments[0].history[0].timestamp) _this.scaleinfoX.startTimeStamp = _this.instruments[0].history[0].timestamp;
|
|
2163
2163
|
|
|
2164
2164
|
_this.scaleinfoX.endTimeStamp = new Date().getTime();
|
|
2165
|
-
_this.scaleinfoX.endTimeStamp = _this.scaleinfoX.endTimeStamp - (_this.scaleinfoX.endTimeStamp % 86400000);
|
|
2165
|
+
_this.scaleinfoX.endTimeStamp = _this.scaleinfoX.endTimeStamp - (_this.scaleinfoX.endTimeStamp % 86400000); // TODO: detta kan vi nog ta bort eller skall det vara med closetime?
|
|
2166
2166
|
}
|
|
2167
2167
|
setTimeSpanData();
|
|
2168
2168
|
_this.scaleinfoY.type = 'history';
|
|
2169
2169
|
if (_this.settings.absoluteScaling == true) {
|
|
2170
|
-
for (
|
|
2170
|
+
for (s = 1; s < _this.instruments.length; s++) _this.instruments[s].factor = 1;
|
|
2171
2171
|
} else calcCompareFactors('history');
|
|
2172
2172
|
_this.instruments[0].factor = 1;
|
|
2173
2173
|
|
|
@@ -2197,7 +2197,7 @@ function Milli_Chart(settings) {
|
|
|
2197
2197
|
_this.scaleinfoX.startTimeStamp = _this.instruments[0].history[0].timestamp;
|
|
2198
2198
|
} else
|
|
2199
2199
|
if (_this.settings.chartlen == 'ytd') {
|
|
2200
|
-
_this.scaleinfoX.startTimeStamp = new Date(new Date().getFullYear() + '-01-01').getTime();
|
|
2200
|
+
_this.scaleinfoX.startTimeStamp = new Date(new Date().getFullYear() + '-01-01').getTime(); // TODO, hur skall vi göra här om det inte finns data runt här?
|
|
2201
2201
|
} else {
|
|
2202
2202
|
_this.scaleinfoX.startTimeStamp = new Date().getTime() - (86400000 * 365 * (isNaN(len) ? 1 : len));
|
|
2203
2203
|
}
|
|
@@ -2205,12 +2205,12 @@ function Milli_Chart(settings) {
|
|
|
2205
2205
|
_this.scaleinfoX.startTimeStamp = findFirstWeekDay(_this.scaleinfoX.startTimeStamp).getTime();
|
|
2206
2206
|
|
|
2207
2207
|
_this.scaleinfoX.endTimeStamp = new Date().getTime();
|
|
2208
|
-
_this.scaleinfoX.endTimeStamp = _this.scaleinfoX.endTimeStamp - (_this.scaleinfoX.endTimeStamp % 86400000);
|
|
2208
|
+
_this.scaleinfoX.endTimeStamp = _this.scaleinfoX.endTimeStamp - (_this.scaleinfoX.endTimeStamp % 86400000); // TODO: detta kan vi nog ta bort eller skall det vara med closetime?
|
|
2209
2209
|
}
|
|
2210
2210
|
setTimeSpanData();
|
|
2211
2211
|
_this.scaleinfoY.type = 'history';
|
|
2212
2212
|
if (_this.settings.absoluteScaling == true) {
|
|
2213
|
-
for (
|
|
2213
|
+
for (s = 1; s < _this.instruments.length; s++) _this.instruments[s].factor = 1;
|
|
2214
2214
|
} else calcCompareFactors('history');
|
|
2215
2215
|
|
|
2216
2216
|
_this.instruments[0].factor = 1;
|
|
@@ -2227,10 +2227,10 @@ function Milli_Chart(settings) {
|
|
|
2227
2227
|
|
|
2228
2228
|
}
|
|
2229
2229
|
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2230
|
+
/*for (const [key, a] of m_analyzisMethod.entries()) {
|
|
2231
|
+
if (a.method == 'bb') plotBollingerBand(a, 'history');
|
|
2232
|
+
else plotMovingAverage(a, 'history');
|
|
2233
|
+
}*/
|
|
2234
2234
|
}
|
|
2235
2235
|
drawBoxShadow(m_chartspaces.chart);
|
|
2236
2236
|
|
|
@@ -2241,14 +2241,14 @@ function Milli_Chart(settings) {
|
|
|
2241
2241
|
}
|
|
2242
2242
|
if (typeof m_chartCss.backgroundColor !== 'undefined') {
|
|
2243
2243
|
m_ctx.save();
|
|
2244
|
-
|
|
2244
|
+
//if (_this.settings.curveOnTop == false)
|
|
2245
2245
|
m_ctx.globalCompositeOperation = 'destination-over';
|
|
2246
2246
|
m_ctx.fillStyle = m_chartCss.backgroundColor;
|
|
2247
|
-
|
|
2247
|
+
//m_ctx.fillRect(0, 0, m_canvas.width, m_canvas.height);
|
|
2248
2248
|
m_ctx.fillRect(0, 0, m_canvas.width, m_canvas.height);
|
|
2249
2249
|
m_ctx.restore();
|
|
2250
2250
|
}
|
|
2251
|
-
|
|
2251
|
+
//onMouseOut();
|
|
2252
2252
|
};
|
|
2253
2253
|
|
|
2254
2254
|
function drawBoxShadow(space) {
|
|
@@ -2279,6 +2279,8 @@ function Milli_Chart(settings) {
|
|
|
2279
2279
|
if (instr == null) return;
|
|
2280
2280
|
|
|
2281
2281
|
if (typeof data.name !== 'undefined') instr.name = data.name;
|
|
2282
|
+
if (typeof data.instrumenttype !== 'undefined') instr.instrumenttype = data.instrumenttype;
|
|
2283
|
+
else instr.instrumenttype = -1;
|
|
2282
2284
|
if (typeof data.pricetype !== 'undefined') instr.pricetype = data.pricetype;
|
|
2283
2285
|
else instr.pricetype = 'price';
|
|
2284
2286
|
if (typeof data.symbol !== 'undefined') instr.symbol = data.symbol;
|
|
@@ -2286,7 +2288,7 @@ function Milli_Chart(settings) {
|
|
|
2286
2288
|
|
|
2287
2289
|
if (typeof data.tradecurrency !== 'undefined') instr.tradecurrency = data.tradecurrency;
|
|
2288
2290
|
if (data.marketopen && data.marketclose) {
|
|
2289
|
-
if (new Date('2020-01-01T' + data.marketopen + 'Z') > new Date('2020-01-01T' + data.marketclose + 'Z')) {
|
|
2291
|
+
if (new Date('2020-01-01T' + data.marketopen + 'Z') > new Date('2020-01-01T' + data.marketclose + 'Z')) { // om close är tidiagre än open så sätter vi nedan tider
|
|
2290
2292
|
data.marketopen = '00:00:00';
|
|
2291
2293
|
data.marketclose = '22:00:00';
|
|
2292
2294
|
}
|
|
@@ -2298,7 +2300,9 @@ function Milli_Chart(settings) {
|
|
|
2298
2300
|
instr.quotedate = new Date().getTime();
|
|
2299
2301
|
instr.quotedate -= instr.quotedate % 86400000;
|
|
2300
2302
|
}
|
|
2301
|
-
|
|
2303
|
+
if (typeof data.time !== 'undefined') {
|
|
2304
|
+
instr.quotetime = ((parseInt(data.time) * 3600) + (parseInt(data.time.substring(3, 5)) * 60) + parseInt(data.time.substring(6, 8))) * 1000;
|
|
2305
|
+
} else instr.quotetime = 0;
|
|
2302
2306
|
if (typeof data.marketopen !== 'undefined') {
|
|
2303
2307
|
if (!data.marketopen) {
|
|
2304
2308
|
data.marketopen = '00:00:00';
|
|
@@ -2318,7 +2322,7 @@ function Milli_Chart(settings) {
|
|
|
2318
2322
|
instr.trades = [];
|
|
2319
2323
|
instr.hashmap.clear();
|
|
2320
2324
|
for (i = 0; i < data.trades.length; i++) {
|
|
2321
|
-
if (data.trades[i].tradecode & 16) {
|
|
2325
|
+
if (data.trades[i].tradecode & 16) { // canceltrade
|
|
2322
2326
|
continue;
|
|
2323
2327
|
}
|
|
2324
2328
|
item = [];
|
|
@@ -2335,7 +2339,7 @@ function Milli_Chart(settings) {
|
|
|
2335
2339
|
}
|
|
2336
2340
|
instr.trades.push(item);
|
|
2337
2341
|
instr.hashmap.set(item.timestamp, item);
|
|
2338
|
-
|
|
2342
|
+
// we might have recieved trades from push before dataapi
|
|
2339
2343
|
instr.trades.sort(function(a, b) {
|
|
2340
2344
|
return a.timestamp - b.timestamp;
|
|
2341
2345
|
});
|
|
@@ -2348,7 +2352,7 @@ function Milli_Chart(settings) {
|
|
|
2348
2352
|
instr.history = [];
|
|
2349
2353
|
for (i = 0; i < data.history.length; i++) {
|
|
2350
2354
|
item = [];
|
|
2351
|
-
if (typeof data.history[i].date !== 'undefined' && data.history[i].closeprice != null) {
|
|
2355
|
+
if (typeof data.history[i].date !== 'undefined' && data.history[i].closeprice != null) { // inget pris eller datum = onintressant, borde kanske skippas vid selecten i pitten också
|
|
2352
2356
|
var timestamp = new Date(data.history[i].date + 'T00:00:00Z').getTime();
|
|
2353
2357
|
item.timestamp = timestamp;
|
|
2354
2358
|
} else continue;
|
|
@@ -2358,7 +2362,7 @@ function Milli_Chart(settings) {
|
|
|
2358
2362
|
if (typeof data.history[i].dividend !== 'undefined') item.dividend = data.history[i].dividend;
|
|
2359
2363
|
instr.history.push(item);
|
|
2360
2364
|
}
|
|
2361
|
-
if (_this.settings.hcurve && instr.history.length > 0) {
|
|
2365
|
+
if (_this.settings.hcurve && instr.history.length > 0) { // varför på all historik, och inte bara på hcurve
|
|
2362
2366
|
if (!isToday(new Date(instr.history[instr.history.length - 1].timestamp))) {
|
|
2363
2367
|
var addItem = {};
|
|
2364
2368
|
MillistreamWidgetApi_AssignObject(instr.history[instr.history.length - 1], addItem);
|
|
@@ -2383,7 +2387,7 @@ function Milli_Chart(settings) {
|
|
|
2383
2387
|
};
|
|
2384
2388
|
|
|
2385
2389
|
function plotExternalHistoricalData(data) {
|
|
2386
|
-
|
|
2390
|
+
// används för dividend osv
|
|
2387
2391
|
m_ctx.save();
|
|
2388
2392
|
var startpoint = { x: 0, y: 0 };
|
|
2389
2393
|
var endpoint = { x: 0, y: 0 };
|
|
@@ -2407,25 +2411,25 @@ function Milli_Chart(settings) {
|
|
|
2407
2411
|
currentDate.setMinutes(lastdate.getMinutes());
|
|
2408
2412
|
currentDate.setSeconds(lastdate.getSeconds());
|
|
2409
2413
|
|
|
2410
|
-
if (lastdate.toISOString().substring(0, 10) != currentDate.toISOString().substring(0, 10)) {
|
|
2414
|
+
if (lastdate.toISOString().substring(0, 10) != currentDate.toISOString().substring(0, 10)) { // new date
|
|
2411
2415
|
var tmp = new Date(lastdate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
|
|
2412
2416
|
var nextDate = new Date(data[i].timestamp);
|
|
2413
|
-
tmp = tmp.getTime() + 86400000 - _this.scaleinfoX.milliPerDay;
|
|
2417
|
+
tmp = tmp.getTime() + 86400000 - _this.scaleinfoX.milliPerDay; // increase to next days starttime
|
|
2414
2418
|
currentDate = new Date(tmp);
|
|
2415
2419
|
while (dateDiffInDays(currentDate, nextDate) > 0) {
|
|
2416
2420
|
if (currentDate.getDay() == 0 || currentDate.getDay() == 6)
|
|
2417
2421
|
offset += 86400000 / _this.scaleinfoX.timePerPixel;
|
|
2418
2422
|
else
|
|
2419
|
-
offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel);
|
|
2423
|
+
offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel); // * dateDiffInDays(lastdate, currentDate);
|
|
2420
2424
|
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
2421
2425
|
}
|
|
2422
|
-
offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel);
|
|
2426
|
+
offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel); // * dateDiffInDays(lastdate, currentDate);
|
|
2423
2427
|
lastdate = currentDate;
|
|
2424
2428
|
startpoint.x = Math.round(m_chartspaces.chart.left + ((data[i].timestamp - startDate) / _this.scaleinfoX.timePerPixel)) + 0.5 - offset;
|
|
2425
|
-
|
|
2429
|
+
// TODO: här blir det fel när det är från 00:00: 23:59 men göms av tmpx < startpoint.x
|
|
2426
2430
|
|
|
2427
2431
|
}
|
|
2428
|
-
|
|
2432
|
+
//startpoint.y = Math.round(m_canvas.height - getScaledSetting(m_chartCss.marginBottom) - (((data[i].price * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
|
|
2429
2433
|
startpoint.y = Math.round(m_chartspaces.chart.height - getScaledSetting(m_chartCss.marginBottom) - (((data[i].price * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
|
|
2430
2434
|
maxy = maxy > startpoint.y ? maxy : startpoint.y;
|
|
2431
2435
|
|
|
@@ -2467,19 +2471,19 @@ function Milli_Chart(settings) {
|
|
|
2467
2471
|
var endtimeToday = new Date(data[i].timestamp);
|
|
2468
2472
|
if (endtimeToday.getDay() == 0 || endtimeToday.getDay() == 6) continue;
|
|
2469
2473
|
if (_this.scaleinfoY.type != 'history') {
|
|
2470
|
-
endtimeToday = new Date(endtimeToday.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
|
|
2474
|
+
endtimeToday = new Date(endtimeToday.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z'); // borde räcka att göra 1 gång när det blir nytt datum
|
|
2471
2475
|
}
|
|
2472
2476
|
if (data[i].timestamp > endtimeToday.getTime()) {
|
|
2473
|
-
continue;
|
|
2477
|
+
continue; // dataticks efter stängning ritas inte
|
|
2474
2478
|
}
|
|
2475
2479
|
currentDate = new Date(data[i].timestamp);
|
|
2476
2480
|
currentDate.setHours(lastdate.getHours());
|
|
2477
2481
|
currentDate.setMinutes(lastdate.getMinutes());
|
|
2478
2482
|
currentDate.setSeconds(lastdate.getSeconds());
|
|
2479
|
-
if (lastdate.toISOString().substring(0, 10) != currentDate.toISOString().substring(0, 10)) {
|
|
2483
|
+
if (lastdate.toISOString().substring(0, 10) != currentDate.toISOString().substring(0, 10)) { // new date
|
|
2480
2484
|
tmp = new Date(lastdate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
|
|
2481
2485
|
var nextDate = new Date(data[i].timestamp);
|
|
2482
|
-
tmp = tmp.getTime() + 86400000 - _this.scaleinfoX.milliPerDay;
|
|
2486
|
+
tmp = tmp.getTime() + 86400000 - _this.scaleinfoX.milliPerDay; // increase to next days starttime
|
|
2483
2487
|
|
|
2484
2488
|
currentDate = new Date(tmp);
|
|
2485
2489
|
while (dateDiffInDays(currentDate, nextDate) > 0) {
|
|
@@ -2489,11 +2493,11 @@ function Milli_Chart(settings) {
|
|
|
2489
2493
|
offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel);
|
|
2490
2494
|
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
2491
2495
|
}
|
|
2492
|
-
offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel);
|
|
2496
|
+
offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel); // * dateDiffInDays(lastdate, currentDate);
|
|
2493
2497
|
lastdate = currentDate;
|
|
2494
2498
|
startpoint.x = Math.round(m_chartspaces.chart.left + ((data[i].timestamp - startDate) / _this.scaleinfoX.timePerPixel)) + 0.5 - offset;
|
|
2495
2499
|
|
|
2496
|
-
|
|
2500
|
+
// TODO: här blir det fel när det är från 00:00: 23:59 men göms av tmpx < startpoint.x
|
|
2497
2501
|
if (_this.scaleinfoY.type == 'trades' && tmpx < startpoint.x) {
|
|
2498
2502
|
ret.push(startpoint.x, startpoint.y);
|
|
2499
2503
|
}
|
|
@@ -2529,7 +2533,7 @@ function Milli_Chart(settings) {
|
|
|
2529
2533
|
if (line.length == 0) return;
|
|
2530
2534
|
m_ctx.save();
|
|
2531
2535
|
m_ctx.beginPath();
|
|
2532
|
-
m_ctx.closePath();
|
|
2536
|
+
m_ctx.closePath(); // clear path
|
|
2533
2537
|
m_ctx.moveTo(line[0].x, line[0].y);
|
|
2534
2538
|
for (var i = 1; i < line.length; i++) {
|
|
2535
2539
|
m_ctx.lineTo(line[i].x, line[i].y);
|
|
@@ -2560,7 +2564,7 @@ function Milli_Chart(settings) {
|
|
|
2560
2564
|
}
|
|
2561
2565
|
var sma = calcAnalyzisLine(data, 2);
|
|
2562
2566
|
m_ctx.beginPath();
|
|
2563
|
-
m_ctx.closePath();
|
|
2567
|
+
m_ctx.closePath(); // clear path
|
|
2564
2568
|
m_ctx.moveTo(sma[0].x, sma[0].y);
|
|
2565
2569
|
for (i = 0; i < sma.length; i++) m_ctx.lineTo(sma[i].x, sma[i].y);
|
|
2566
2570
|
m_ctx.stroke();
|
|
@@ -2568,10 +2572,39 @@ function Milli_Chart(settings) {
|
|
|
2568
2572
|
return;
|
|
2569
2573
|
}
|
|
2570
2574
|
|
|
2575
|
+
function plotLower(valuePerPixel, lineLength) {
|
|
2576
|
+
m_ctx.save();
|
|
2577
|
+
m_ctx.strokeStyle = m_instrumentCss[0].color;
|
|
2578
|
+
m_ctx.lineWidth = m_instrumentCss[0].width;
|
|
2579
|
+
var width = Math.round(m_chartspaces.lowerChart.width / (m_datapoints.length + 1) / 2);
|
|
2580
|
+
if (width < 2) width = 2;
|
|
2581
|
+
else if (width > 20) width = 20;
|
|
2582
|
+
m_ctx.lineWidth = width;
|
|
2583
|
+
for (var i = 0; i < m_datapoints.length; i++) {
|
|
2584
|
+
var x = (m_datapoints[i].x + 0.5) * window.devicePixelRatio;
|
|
2585
|
+
m_ctx.lineWidth = width;
|
|
2586
|
+
if (x - width <= m_chartspaces.lowerChart.left) {
|
|
2587
|
+
m_ctx.lineWidth = width / 2;
|
|
2588
|
+
x += m_ctx.lineWidth / 2;
|
|
2589
|
+
} else
|
|
2590
|
+
if (x + width >= m_chartspaces.lowerChart.right) {
|
|
2591
|
+
m_ctx.lineWidth = width / 2;
|
|
2592
|
+
x -= m_ctx.lineWidth / 2 + 1;
|
|
2593
|
+
}
|
|
2594
|
+
m_ctx.beginPath();
|
|
2595
|
+
m_ctx.moveTo(x, m_chartspaces.lowerChart.bottom - 0.5);
|
|
2596
|
+
var y = Math.round(m_chartspaces.lowerChart.bottom - (m_datapoints[i].quantity * valuePerPixel)) - 1;
|
|
2597
|
+
m_ctx.closePath();
|
|
2598
|
+
m_ctx.lineTo(x, y - 0.5);
|
|
2599
|
+
m_ctx.stroke();
|
|
2600
|
+
}
|
|
2601
|
+
m_ctx.restore();
|
|
2602
|
+
}
|
|
2603
|
+
|
|
2571
2604
|
function plotData(data, instrument) {
|
|
2572
2605
|
m_ctx.save();
|
|
2573
2606
|
if (_this.settings.curveOnTop == false)
|
|
2574
|
-
m_ctx.globalCompositeOperation = 'destination-over';
|
|
2607
|
+
m_ctx.globalCompositeOperation = 'destination-over'; // dont draw over labels inside the chart
|
|
2575
2608
|
m_ctx.strokeStyle = m_instrumentCss[instrument].color;
|
|
2576
2609
|
var factor = _this.instruments[instrument].factor;
|
|
2577
2610
|
var startpoint = { x: 0, y: 0 };
|
|
@@ -2580,7 +2613,6 @@ function Milli_Chart(settings) {
|
|
|
2580
2613
|
var len = data.length;
|
|
2581
2614
|
m_ctx.lineWidth = m_instrumentCss[instrument].width / window.devicePixelRatio;
|
|
2582
2615
|
m_ctx.beginPath();
|
|
2583
|
-
|
|
2584
2616
|
var startx = 0;
|
|
2585
2617
|
var starty = 0;
|
|
2586
2618
|
var lastdate = new Date(_this.scaleinfoX.startTimeStamp);
|
|
@@ -2589,10 +2621,10 @@ function Milli_Chart(settings) {
|
|
|
2589
2621
|
var maxy = 0;
|
|
2590
2622
|
var hCurveLastPoint = null;
|
|
2591
2623
|
var quantity = 0;
|
|
2592
|
-
|
|
2624
|
+
var nextDate;
|
|
2593
2625
|
for (var i = 0; i < len; i++) {
|
|
2594
|
-
var currentDate;
|
|
2595
|
-
|
|
2626
|
+
var currentDate = new Date(data[i].timestamp);
|
|
2627
|
+
// var lastItem = data[i];
|
|
2596
2628
|
var tmpx = startpoint.x;
|
|
2597
2629
|
var tmp;
|
|
2598
2630
|
if (data[i].timestamp < _this.scaleinfoX.startTimeStamp) {
|
|
@@ -2600,42 +2632,48 @@ function Milli_Chart(settings) {
|
|
|
2600
2632
|
continue;
|
|
2601
2633
|
}
|
|
2602
2634
|
if (data[i].timestamp > _this.scaleinfoX.endTimeStamp) {
|
|
2603
|
-
break;
|
|
2635
|
+
break; // continue?
|
|
2604
2636
|
}
|
|
2605
2637
|
if (data[i].timestamp > new Date().getTime())
|
|
2606
2638
|
break;
|
|
2607
2639
|
|
|
2608
2640
|
if (_this.scaleinfoY.type != 'history' && (data[i].timestamp % 86400000 < _this.instruments[0].opentimestamp || data[i].timestamp % 86400000 > _this.instruments[0].closetimestamp)) {
|
|
2609
|
-
|
|
2641
|
+
// stämmer detta kan det bli överlapp vid sommartid/vintertid?
|
|
2610
2642
|
continue;
|
|
2611
2643
|
}
|
|
2612
2644
|
var endtimeToday = new Date(data[i].timestamp);
|
|
2613
|
-
if (endtimeToday.getDay() == 0 || endtimeToday.getDay() == 6) continue;
|
|
2645
|
+
if (endtimeToday.getDay() == 0 || endtimeToday.getDay() == 6) continue; // do not draw weekends TODO: if main instrument has weekenddata draw it, but need to fix that in all drawfunctions
|
|
2614
2646
|
if (_this.scaleinfoY.type != 'history') {
|
|
2615
|
-
endtimeToday = new Date(endtimeToday.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
|
|
2647
|
+
endtimeToday = new Date(endtimeToday.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z'); // borde räcka att göra 1 gång när det blir nytt datum
|
|
2616
2648
|
}
|
|
2617
2649
|
if (data[i].timestamp > endtimeToday.getTime()) {
|
|
2618
|
-
continue;
|
|
2650
|
+
continue; // dataticks efter stängning ritas inte
|
|
2619
2651
|
}
|
|
2620
2652
|
|
|
2621
2653
|
if (_this.scaleinfoY.type == 'history') {
|
|
2622
|
-
|
|
2623
|
-
|
|
2654
|
+
//var point = { price: data[i].price, open: null, x: endpoint.x - 0.5, y: endpoint.y - 0.5, timestamp: data[i].timestamp };
|
|
2655
|
+
//m_datapoints.push(point);
|
|
2624
2656
|
} else
|
|
2625
|
-
if (_this.settings.previousDayClose && addedcloseprice1d == false && m_zoom.mouseup.timestamp == null) {
|
|
2626
|
-
currentDate = new Date(
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2657
|
+
if (_this.settings.previousDayClose && addedcloseprice1d == false && m_zoom.mouseup.timestamp == null) { // only draw closeprice1d on today charts
|
|
2658
|
+
currentDate = new Date(startDate);
|
|
2659
|
+
if (_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d') { // plot the closeprice1d
|
|
2660
|
+
endpoint.y = Math.round(m_chartspaces.chart.height - getScaledSetting(m_chartCss.marginBottom) - (((parseFloat(_this.instruments[instrument].closeprice1d)) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
|
|
2661
|
+
endpoint.x = m_chartspaces.chart.left + 0.5 - offset;
|
|
2662
|
+
} else {
|
|
2663
|
+
if (!isToday(new Date(data[i].timestamp))) {
|
|
2664
|
+
nextDate = new Date(data[i].timestamp);
|
|
2665
|
+
while (dateDiffInDays(currentDate, nextDate) > 0) {
|
|
2666
|
+
if (currentDate.getDay() == 0 || currentDate.getDay() == 6)
|
|
2667
|
+
offset += 86400000 / _this.scaleinfoX.timePerPixel;
|
|
2668
|
+
else
|
|
2669
|
+
offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel); // * dateDiffInDays(lastdate, currentDate);
|
|
2670
|
+
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
2671
|
+
}
|
|
2672
|
+
tmp = new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z');
|
|
2673
|
+
endpoint.y = Math.round(m_chartspaces.chart.height - getScaledSetting(m_chartCss.marginBottom) - (((parseFloat(_this.instruments[instrument].startValue)) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
|
|
2674
|
+
endpoint.x = Math.round(m_chartspaces.chart.left + ((tmp.getTime() - startDate) / _this.scaleinfoX.timePerPixel)) + 0.5 - offset;
|
|
2675
|
+
}
|
|
2676
|
+
}
|
|
2639
2677
|
m_ctx.moveTo(endpoint.x, endpoint.y);
|
|
2640
2678
|
lastdate = new Date(data[i].timestamp);
|
|
2641
2679
|
addedcloseprice1d = true;
|
|
@@ -2646,25 +2684,24 @@ function Milli_Chart(settings) {
|
|
|
2646
2684
|
currentDate.setHours(lastdate.getHours());
|
|
2647
2685
|
currentDate.setMinutes(lastdate.getMinutes());
|
|
2648
2686
|
currentDate.setSeconds(lastdate.getSeconds());
|
|
2649
|
-
if (lastdate.toISOString().substring(0, 10) != currentDate.toISOString().substring(0, 10)) {
|
|
2687
|
+
if (lastdate.toISOString().substring(0, 10) != currentDate.toISOString().substring(0, 10)) { // new date
|
|
2650
2688
|
tmp = new Date(lastdate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
tmp = tmp.getTime() + 86400000 - _this.scaleinfoX.milliPerDay;
|
|
2689
|
+
nextDate = new Date(data[i].timestamp);
|
|
2690
|
+
tmp = tmp.getTime() + 86400000 - _this.scaleinfoX.milliPerDay; // increase to next days starttime
|
|
2654
2691
|
|
|
2655
2692
|
currentDate = new Date(tmp);
|
|
2656
2693
|
while (dateDiffInDays(currentDate, nextDate) > 0) {
|
|
2657
2694
|
if (currentDate.getDay() == 0 || currentDate.getDay() == 6)
|
|
2658
2695
|
offset += 86400000 / _this.scaleinfoX.timePerPixel;
|
|
2659
2696
|
else
|
|
2660
|
-
offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel);
|
|
2697
|
+
offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel); // * dateDiffInDays(lastdate, currentDate);
|
|
2661
2698
|
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
2662
2699
|
}
|
|
2663
|
-
offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel);
|
|
2700
|
+
offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel); // * dateDiffInDays(lastdate, currentDate);
|
|
2664
2701
|
lastdate = currentDate;
|
|
2665
2702
|
startpoint.x = Math.round(m_chartspaces.chart.left + ((data[i].timestamp - startDate) / _this.scaleinfoX.timePerPixel)) + 0.5 - offset;
|
|
2666
2703
|
|
|
2667
|
-
|
|
2704
|
+
// TODO: här blir det fel när det är från 00:00: 23:59 men göms av tmpx < startpoint.x
|
|
2668
2705
|
if (_this.scaleinfoY.type == 'trades' && tmpx < startpoint.x) {
|
|
2669
2706
|
m_ctx.lineTo(startpoint.x, startpoint.y);
|
|
2670
2707
|
}
|
|
@@ -2673,6 +2710,7 @@ function Milli_Chart(settings) {
|
|
|
2673
2710
|
maxy = maxy > startpoint.y ? maxy : startpoint.y;
|
|
2674
2711
|
|
|
2675
2712
|
startpoint.x = Math.round(m_chartspaces.chart.left + ((data[i].timestamp - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel)) + 0.5;
|
|
2713
|
+
|
|
2676
2714
|
startpoint.x -= offset;
|
|
2677
2715
|
quantity += data[i].quantity;
|
|
2678
2716
|
if (startpoint.x != endpoint.x || startpoint.y != endpoint.y) {
|
|
@@ -2693,7 +2731,7 @@ function Milli_Chart(settings) {
|
|
|
2693
2731
|
if (tmpx < startpoint.x) {
|
|
2694
2732
|
if (_this.settings.hcurve) m_ctx.lineTo(startpoint.x, endpoint.y);
|
|
2695
2733
|
m_ctx.lineTo(startpoint.x, startpoint.y);
|
|
2696
|
-
|
|
2734
|
+
//m_ctx.bezierCurveTo(startpoint.x, startpoint.y, endpoint.x - 1, endpoint.y - 1, endpoint.x, endpoint.y); // läs på om detta för "runda linjer"
|
|
2697
2735
|
|
|
2698
2736
|
if (instrument == 0) {
|
|
2699
2737
|
point = { price: data[i].price, open: data[i].openprice, x: startpoint.x / window.devicePixelRatio - 0.5, y: startpoint.y / window.devicePixelRatio - 0.5, timestamp: data[i].timestamp, date: new Date(data[i].timestamp), quantity: quantity };
|
|
@@ -2710,7 +2748,7 @@ function Milli_Chart(settings) {
|
|
|
2710
2748
|
m_datapoints.push(point);
|
|
2711
2749
|
if (_this.settings.hcurve && _this.scaleinfoY.type == 'history') {
|
|
2712
2750
|
if (isToday(currentDate)) {
|
|
2713
|
-
|
|
2751
|
+
// only 1 point in hcurve chart, draw line from start of chart to end date
|
|
2714
2752
|
m_ctx.moveTo(m_chartspaces.chart.left, startpoint.y);
|
|
2715
2753
|
point = { price: data[i].price, open: data[i].openprice, x: m_chartspaces.chart.left / window.devicePixelRatio - 0.5, y: startpoint.y / window.devicePixelRatio - 0.5, timestamp: data[i].timestamp, date: new Date(data[i].timestamp), insref: _this.instruments[instrument].insref, diff: data[i].diff, quantity: quantity };
|
|
2716
2754
|
m_datapoints.push(point);
|
|
@@ -2718,12 +2756,12 @@ function Milli_Chart(settings) {
|
|
|
2718
2756
|
m_datapoints.push(point);
|
|
2719
2757
|
startx = m_chartspaces.chart.left;
|
|
2720
2758
|
starty = startpoint.y;
|
|
2721
|
-
|
|
2759
|
+
// last point so break out and store startx and starty from fake point
|
|
2722
2760
|
break;
|
|
2723
2761
|
} else if (hCurveLastPoint) {
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2762
|
+
/* var y = Math.round(m_canvas.height - getScaledSetting(m_chartCss.marginBottom) - (((hCurveLastPoint.price * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
|
|
2763
|
+
m_ctx.moveTo(m_chartspaces.chart.left, y);
|
|
2764
|
+
m_ctx.lineTo(startpoint.x, y);*/
|
|
2727
2765
|
}
|
|
2728
2766
|
}
|
|
2729
2767
|
quantity = 0;
|
|
@@ -2736,7 +2774,7 @@ function Milli_Chart(settings) {
|
|
|
2736
2774
|
endpoint.y = startpoint.y;
|
|
2737
2775
|
}
|
|
2738
2776
|
if (data[i].dividend) {
|
|
2739
|
-
|
|
2777
|
+
//console.log('div', data[i]);
|
|
2740
2778
|
}
|
|
2741
2779
|
}
|
|
2742
2780
|
m_dataPoints.arr.sort(function(a, b) {
|
|
@@ -2760,7 +2798,7 @@ function Milli_Chart(settings) {
|
|
|
2760
2798
|
m_ctx.fill();
|
|
2761
2799
|
} else
|
|
2762
2800
|
m_ctx.closePath();
|
|
2763
|
-
|
|
2801
|
+
// eftersom vi kör med m_datapoints här så missar vi dom som plottas på samma ställe som punkten innan, gör vi det???
|
|
2764
2802
|
if (instrument == 0) {
|
|
2765
2803
|
drawPriceIndicator();
|
|
2766
2804
|
drawClosePriceIndicator();
|
|
@@ -2769,13 +2807,13 @@ function Milli_Chart(settings) {
|
|
|
2769
2807
|
m_ctx.restore();
|
|
2770
2808
|
}
|
|
2771
2809
|
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2810
|
+
/* function drawCompare(resp) {
|
|
2811
|
+
parseData(resp[0], 1);
|
|
2812
|
+
_this.drawChart();
|
|
2813
|
+
requestStreaming();
|
|
2814
|
+
return;
|
|
2815
|
+
}
|
|
2816
|
+
*/
|
|
2779
2817
|
|
|
2780
2818
|
_this.setChartLength = function(len) {
|
|
2781
2819
|
_this.settings.chartlen = len;
|
|
@@ -2907,7 +2945,7 @@ function Milli_Chart(settings) {
|
|
|
2907
2945
|
};
|
|
2908
2946
|
req.open("GET", url, true);
|
|
2909
2947
|
req.onerror = function(error) {
|
|
2910
|
-
(
|
|
2948
|
+
console.log('Fetch data error', error);
|
|
2911
2949
|
};
|
|
2912
2950
|
req.send();
|
|
2913
2951
|
}
|
|
@@ -2915,13 +2953,13 @@ function Milli_Chart(settings) {
|
|
|
2915
2953
|
_this.refreshData = function() {
|
|
2916
2954
|
_this.instruments.forEach(function(c, pos) {
|
|
2917
2955
|
if (c.insref != 0) {
|
|
2918
|
-
fetchTrades(c.insref);
|
|
2956
|
+
if (_this.settings.intradaylen) fetchTrades(c.insref);
|
|
2919
2957
|
fetchHistory(c.insref);
|
|
2920
2958
|
}
|
|
2921
2959
|
});
|
|
2922
|
-
|
|
2960
|
+
//fetch data and redraw ( for no push charts)
|
|
2923
2961
|
};
|
|
2924
|
-
|
|
2962
|
+
// Compare functions
|
|
2925
2963
|
_this.removeAllCompares = function() {
|
|
2926
2964
|
if (_this.instruments.length == 1) return;
|
|
2927
2965
|
for (var i = 0; i < 3; i++)
|
|
@@ -2968,21 +3006,23 @@ function Milli_Chart(settings) {
|
|
|
2968
3006
|
|
|
2969
3007
|
_this.instruments[pos] = instr;
|
|
2970
3008
|
|
|
2971
|
-
fetchTrades(insref);
|
|
3009
|
+
if (_this.settings.intradaylen) fetchTrades(insref);
|
|
2972
3010
|
fetchHistory(insref);
|
|
2973
3011
|
return 1;
|
|
2974
3012
|
};
|
|
2975
|
-
|
|
2976
|
-
|
|
3013
|
+
// Size functions
|
|
2977
3014
|
function setChartSize() {
|
|
2978
3015
|
var offset = 0;
|
|
3016
|
+
// set canvas size to 0 so it does not prevent the div to resize
|
|
3017
|
+
_this.settings.target.style.height = '0px';
|
|
3018
|
+
_this.settings.target.style.width = '0px';
|
|
2979
3019
|
if (_this.settings.target.parentNode.classList.contains('chartcontainer')) {
|
|
2980
3020
|
offset = _this.settings.target.getBoundingClientRect().top - _this.settings.target.parentNode.getBoundingClientRect().top;
|
|
2981
3021
|
}
|
|
2982
3022
|
_this.settings.target.style.height = (_this.settings.target.parentNode.offsetHeight - offset) + 'px';
|
|
2983
3023
|
_this.settings.target.style.width = _this.settings.target.parentNode.offsetWidth + 'px';
|
|
2984
|
-
|
|
2985
|
-
|
|
3024
|
+
//_this.settings.target.style.height = (_this.settings.target.parentNode.offsetHeight - offset) * window.devicePixelRatio + 'px';
|
|
3025
|
+
//_this.settings.target.style.width = _this.settings.target.parentNode.offsetWidth * window.devicePixelRatio + 'px';
|
|
2986
3026
|
m_canvas.setRect(_this.settings.target.offsetHeight, _this.settings.target.offsetWidth);
|
|
2987
3027
|
}
|
|
2988
3028
|
|
|
@@ -2991,7 +3031,7 @@ function Milli_Chart(settings) {
|
|
|
2991
3031
|
m_resizing.height = m_canvas.height;
|
|
2992
3032
|
};
|
|
2993
3033
|
|
|
2994
|
-
_this.
|
|
3034
|
+
_this.resizing = function(e, ui) {
|
|
2995
3035
|
var diff = (m_resizing.height - m_canvas.height) / m_canvas.height * 100;
|
|
2996
3036
|
if (Math.abs(diff) > 1) {
|
|
2997
3037
|
setChartSize();
|
|
@@ -3002,8 +3042,8 @@ function Milli_Chart(settings) {
|
|
|
3002
3042
|
diff = (m_resizing.width - m_canvas.width) / m_canvas.width * 100;
|
|
3003
3043
|
if (Math.abs(diff) > 1) {
|
|
3004
3044
|
setChartSize();
|
|
3005
|
-
|
|
3006
|
-
|
|
3045
|
+
//m_canvas.height = Math.floor(_this.settings.target.offsetHeight * window.devicePixelRatio);
|
|
3046
|
+
//m_canvas.width = Math.floor(_this.settings.target.offsetWidth * window.devicePixelRatio);
|
|
3007
3047
|
m_resizing.width = m_canvas.width;
|
|
3008
3048
|
m_resizing.height = m_canvas.height;
|
|
3009
3049
|
_this.drawChart();
|
|
@@ -3035,11 +3075,11 @@ function Milli_Chart(settings) {
|
|
|
3035
3075
|
m_canvas = MillistreamWidgetApi_addElement(_this, 'canvas', 'millistream-chart-canvas', _this.settings.target);
|
|
3036
3076
|
m_ctx = m_canvas.getContext("2d");
|
|
3037
3077
|
setChartSize();
|
|
3038
|
-
m_canvas.addEventListener('mousemove', onMouseMove, false);
|
|
3078
|
+
m_canvas.addEventListener('mousemove', onMouseMove, false); // disable while loading and enable on drawReady
|
|
3039
3079
|
m_canvas.addEventListener('mouseout', onMouseOut, false);
|
|
3040
3080
|
m_canvas.style.cursor = "crosshair";
|
|
3041
3081
|
m_canvas.onmousedown = (function(evt) {
|
|
3042
|
-
if (
|
|
3082
|
+
if (evt.which != 1) return; // ignore right and middle
|
|
3043
3083
|
if (_this.settings.enablezoom == false) return;
|
|
3044
3084
|
if (m_datapoints.length == 0) return;
|
|
3045
3085
|
var rect = m_canvas.getBoundingClientRect();
|
|
@@ -3065,7 +3105,7 @@ function Milli_Chart(settings) {
|
|
|
3065
3105
|
clearZoom();
|
|
3066
3106
|
return;
|
|
3067
3107
|
}
|
|
3068
|
-
if (Math.abs(x - m_zoom.mousedown.pos) > 5) {
|
|
3108
|
+
if (Math.abs(x - m_zoom.mousedown.pos) > 5) { // only handle zoom with 5 pixels width
|
|
3069
3109
|
var i;
|
|
3070
3110
|
for (i = m_datapoints.length - 1; i > 0; i--) {
|
|
3071
3111
|
if (x >= m_datapoints[i].x) {
|
|
@@ -3082,7 +3122,7 @@ function Milli_Chart(settings) {
|
|
|
3082
3122
|
m_zoom.mousedown.pos = 0;
|
|
3083
3123
|
m_zoom.mousedown.i = 0;
|
|
3084
3124
|
if (m_zoom.mousedown.oldtimestamp != null) {
|
|
3085
|
-
m_zoom.mousedown.timestamp = m_zoom.mousedown.oldtimestamp;
|
|
3125
|
+
m_zoom.mousedown.timestamp = m_zoom.mousedown.oldtimestamp; // so we do not unzoom if zoomed
|
|
3086
3126
|
m_zoom.mousedown.oldtimestamp = null;
|
|
3087
3127
|
} else
|
|
3088
3128
|
m_zoom.mousedown.timestamp = null;
|
|
@@ -3129,12 +3169,15 @@ function Milli_Chart(settings) {
|
|
|
3129
3169
|
if (instr.pricetype == 'price' || instr.pricetype == 'nav') {
|
|
3130
3170
|
if (typeof json['148'] !== 'undefined') {
|
|
3131
3171
|
instr.closeprice1d = parseFloat(json['148']);
|
|
3172
|
+
update = true;
|
|
3132
3173
|
}
|
|
3133
3174
|
} else
|
|
3134
3175
|
if (typeof json['262'] !== 'undefined') {
|
|
3135
|
-
instr.closeprice1d = parseFloat(json['
|
|
3176
|
+
instr.closeprice1d = parseFloat(json['262']);
|
|
3177
|
+
update = true;
|
|
3136
3178
|
}
|
|
3137
3179
|
}
|
|
3180
|
+
var timestamp;
|
|
3138
3181
|
if (mref == 'quote') {
|
|
3139
3182
|
if (instr.history.length == 0) return;
|
|
3140
3183
|
if (json['3'] && !isToday(new Date(json['3']))) return;
|
|
@@ -3143,9 +3186,12 @@ function Milli_Chart(settings) {
|
|
|
3143
3186
|
instr.quotedate = new Date(json['3']).getTime();
|
|
3144
3187
|
instr.quotedate -= instr.quotedate % 86400000;
|
|
3145
3188
|
}
|
|
3189
|
+
if (json['4']) {
|
|
3190
|
+
instr.quotetime = ((parseInt(json[4]) * 3600) + (parseInt(json[4].substring(3, 5)) * 60) + parseInt(json[4].substring(6, 8))) * 1000;
|
|
3191
|
+
}
|
|
3146
3192
|
var price = undefined;
|
|
3147
3193
|
var quantity = undefined;
|
|
3148
|
-
|
|
3194
|
+
timestamp = new Date().getTime();
|
|
3149
3195
|
timestamp -= timestamp % 86400000;
|
|
3150
3196
|
var obj = instr.history[instr.history.length - 1];
|
|
3151
3197
|
if (instr.pricetype == 'yield') {
|
|
@@ -3172,31 +3218,31 @@ function Milli_Chart(settings) {
|
|
|
3172
3218
|
if (_this.scaleinfoY.type == 'history') update = true;
|
|
3173
3219
|
} else {
|
|
3174
3220
|
if (json['3'] && json['36'] && (json['12'] || json['201'])) {
|
|
3175
|
-
|
|
3221
|
+
timestamp = new Date(json['3'] + 'T' + json['36'].substring(0, 6) + '00' + 'Z').getTime();
|
|
3176
3222
|
var data = instr.hashmap.get(timestamp);
|
|
3177
3223
|
if (typeof data === 'undefined') {
|
|
3178
3224
|
data = {};
|
|
3179
|
-
|
|
3225
|
+
//data.tradereference = json['14'];
|
|
3180
3226
|
data.timestamp = timestamp;
|
|
3181
3227
|
calcAnalyizis = true;
|
|
3182
3228
|
if (instr.pricetype == 'price') {
|
|
3183
3229
|
update = true;
|
|
3184
|
-
data.price = parseFloat(json['12']);
|
|
3185
|
-
data.open = parseFloat(json['12']);
|
|
3186
|
-
data.high = parseFloat(json['12']);
|
|
3187
|
-
data.low = parseFloat(json['12']);
|
|
3230
|
+
data.price = parseFloat(json['12']); // eller 201 för tradeyield
|
|
3231
|
+
data.open = parseFloat(json['12']); // eller 201 för tradeyield
|
|
3232
|
+
data.high = parseFloat(json['12']); // eller 201 för tradeyield
|
|
3233
|
+
data.low = parseFloat(json['12']); // eller 201 för tradeyield
|
|
3188
3234
|
data.quantity = typeof json['13'] === 'undefined' ? 0 : parseInt(json['13']);
|
|
3189
|
-
} else if (instr.pricetype == '
|
|
3190
|
-
data.price = parseFloat(json['201']);
|
|
3191
|
-
data.open = parseFloat(json['201']);
|
|
3192
|
-
data.high = parseFloat(json['201']);
|
|
3193
|
-
data.low = parseFloat(json['201']);
|
|
3235
|
+
} else if (instr.pricetype == 'yield') {
|
|
3236
|
+
data.price = parseFloat(json['201']); // eller 201 för tradeyield
|
|
3237
|
+
data.open = parseFloat(json['201']); // eller 201 för tradeyield
|
|
3238
|
+
data.high = parseFloat(json['201']); // eller 201 för tradeyield
|
|
3239
|
+
data.low = parseFloat(json['201']); // eller 201 för tradeyield
|
|
3194
3240
|
data.quantity = typeof json['13'] === 'undefined' ? 0 : parseInt(json['13']);
|
|
3195
3241
|
update = true;
|
|
3196
3242
|
}
|
|
3197
3243
|
if (update) {
|
|
3198
3244
|
if (instr.trades.length != 0 && data.timestamp < instr.trades[instr.trades.length - 1].timestamp) {
|
|
3199
|
-
|
|
3245
|
+
// TODO console.log("pushtrade is older than last trade ignoring, should file it on correct postition");
|
|
3200
3246
|
} else
|
|
3201
3247
|
instr.hashmap.set(data.timestamp, data);
|
|
3202
3248
|
instr.trades.push(data);
|
|
@@ -3205,24 +3251,24 @@ function Milli_Chart(settings) {
|
|
|
3205
3251
|
if (instr.pricetype == 'price') {
|
|
3206
3252
|
if (data.price != parseFloat(json['12']))
|
|
3207
3253
|
calcAnalyizis = true;
|
|
3208
|
-
data.price = parseFloat(json['12']);
|
|
3254
|
+
data.price = parseFloat(json['12']); // eller 201 för tradeyield
|
|
3209
3255
|
data.quantity += typeof json['13'] === 'undefined' ? 0 : parseInt(json['13']);
|
|
3210
3256
|
if (_this.scaleinfoY.type == 'trades') update = true;
|
|
3211
3257
|
} else {
|
|
3212
|
-
if (instr.pricetype == '
|
|
3258
|
+
if (instr.pricetype == 'yield') {
|
|
3213
3259
|
if (data.price != parseFloat(json['201']))
|
|
3214
3260
|
calcAnalyizis = true;
|
|
3215
|
-
data.price = parseFloat(json['201']);
|
|
3261
|
+
data.price = parseFloat(json['201']); // eller 201 för tradeyield
|
|
3216
3262
|
data.quantity += typeof json['13'] === 'undefined' ? 0 : parseInt(json['13']);
|
|
3217
3263
|
if (_this.scaleinfoY.type == 'trades') update = true;
|
|
3218
3264
|
}
|
|
3219
|
-
|
|
3265
|
+
// TODo: updatera med quantity, open , high,low osv?
|
|
3220
3266
|
}
|
|
3221
3267
|
}
|
|
3222
3268
|
}
|
|
3223
3269
|
if (calcAnalyizis && insref == _this.instruments[0].insref) {
|
|
3224
3270
|
for (var i = 0; i < _this.settings.indicators.length; i++) {
|
|
3225
|
-
|
|
3271
|
+
//for (const [key, a] of m_analyzisMethod.entries()) {
|
|
3226
3272
|
switch (_this.settings.indicators[i].method) {
|
|
3227
3273
|
case 'sma':
|
|
3228
3274
|
_this.settings.indicators[i].trades = [];
|
|
@@ -3237,7 +3283,7 @@ function Milli_Chart(settings) {
|
|
|
3237
3283
|
_this.settings.indicators[i].trades = bollingerBands(_this.instruments[0].trades, _this.settings.indicators[i].method_length, _this.settings.indicators[i].stddev | 2);
|
|
3238
3284
|
break;
|
|
3239
3285
|
default:
|
|
3240
|
-
|
|
3286
|
+
// draw custom added?
|
|
3241
3287
|
break;
|
|
3242
3288
|
}
|
|
3243
3289
|
}
|
|
@@ -3246,18 +3292,19 @@ function Milli_Chart(settings) {
|
|
|
3246
3292
|
_this.drawChart();
|
|
3247
3293
|
}
|
|
3248
3294
|
return;
|
|
3249
|
-
}
|
|
3250
|
-
}
|
|
3295
|
+
}
|
|
3296
|
+
};
|
|
3251
3297
|
|
|
3252
|
-
|
|
3298
|
+
// used by trader
|
|
3253
3299
|
_this.exportData = function() {
|
|
3254
3300
|
let ret = [];
|
|
3255
|
-
|
|
3301
|
+
var i;
|
|
3302
|
+
var date, datestr;
|
|
3256
3303
|
if (_this.scaleinfoY.type == 'trades') {
|
|
3257
3304
|
if (_this.instruments.length > 0) {
|
|
3258
|
-
for (
|
|
3259
|
-
|
|
3260
|
-
|
|
3305
|
+
for (i = 0; i < _this.instruments[0].trades.length; i++) {
|
|
3306
|
+
date = new Date(_this.instruments[0].trades[i].timestamp - new Date().getTimezoneOffset() * 60000); // tz_offset in minutes
|
|
3307
|
+
datestr = date.toISOString();
|
|
3261
3308
|
|
|
3262
3309
|
ret.push([datestr.substring(0, 10), datestr.substring(11, 23), _this.instruments[0].trades[i].price, _this.instruments[0].trades[i].quantity]);
|
|
3263
3310
|
}
|
|
@@ -3269,9 +3316,9 @@ function Milli_Chart(settings) {
|
|
|
3269
3316
|
];
|
|
3270
3317
|
} else {
|
|
3271
3318
|
if (_this.instruments.length > 0) {
|
|
3272
|
-
for (
|
|
3273
|
-
|
|
3274
|
-
|
|
3319
|
+
for (i = 0; i < _this.instruments[0].history.length; i++) {
|
|
3320
|
+
date = new Date(_this.instruments[0].history[i].timestamp);
|
|
3321
|
+
datestr = date.toISOString();
|
|
3275
3322
|
|
|
3276
3323
|
ret.push([datestr.substring(0, 10), "", _this.instruments[0].history[i].price, _this.instruments[0].history[i].quantity]);
|
|
3277
3324
|
}
|
|
@@ -3282,10 +3329,10 @@ function Milli_Chart(settings) {
|
|
|
3282
3329
|
...ret
|
|
3283
3330
|
];
|
|
3284
3331
|
}
|
|
3285
|
-
}
|
|
3332
|
+
};
|
|
3286
3333
|
|
|
3287
3334
|
_this.destroyWidget = function() {
|
|
3288
|
-
|
|
3335
|
+
// if we have subscriptions send in an empty array to unsubscribe all and release it
|
|
3289
3336
|
if (MillistreamWidgetApi_isObjectEmpty(_this.unsubscriptions) == false)
|
|
3290
3337
|
_this.requestid = _this.settings.streaming.MillistreamWidgetStreamingApi_subscribeInstruments(_this, _this.requestid, []);
|
|
3291
3338
|
return 0;
|
|
@@ -3309,23 +3356,25 @@ function Milli_Chart(settings) {
|
|
|
3309
3356
|
}
|
|
3310
3357
|
|
|
3311
3358
|
function fetchHistory(instrument) {
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3359
|
+
if (_this.settings.historylen) {
|
|
3360
|
+
var oldfields = _this.settings.fields;
|
|
3361
|
+
_this.settings.fields = [...['name', 'tradecurrency', 'date', 'closeprice', 'closequantity', 'marketopen', 'marketclose'], ...oldfields];
|
|
3362
|
+
var url = milli_data_api_url + "widget=historychart&token=" + _this.settings.token + "&target=buildwidget&fields=" + _this.settings.fields + "&language=sv&insref=" + instrument + '&startdate=' + m_startdate + '&intradaylen=' + _this.settings.intradaylen + '&xhr=' + (_this.settings.xhr == true ? '1' : '0');
|
|
3363
|
+
if (typeof _this.settings.pricetype !== 'undefined') url += '&pricingtype=' + _this.settings.pricetype;
|
|
3364
|
+
if (_this.settings.adjusted == true) url += '&adjusted=1';
|
|
3365
|
+
_this.settings.fields = oldfields;
|
|
3366
|
+
if (_this.settings.xhr) {
|
|
3367
|
+
getXhrJson(url);
|
|
3368
|
+
} else {
|
|
3369
|
+
millistream_data_api.fetch(url, function(data) {
|
|
3370
|
+
_this.buildwidget(data);
|
|
3371
|
+
});
|
|
3372
|
+
}
|
|
3324
3373
|
}
|
|
3325
3374
|
}
|
|
3326
3375
|
|
|
3327
3376
|
_this.drawWidget = function() {
|
|
3328
|
-
|
|
3377
|
+
// remove standard fields from array, they will be requested anyway
|
|
3329
3378
|
_this.settings.fields = _this.settings.fields.filter(function(obj) {
|
|
3330
3379
|
return ['name', 'tradecurrency', 'time', 'date', 'tradeprice', 'tradequantity', 'marketopen', 'marketclose', 'closeprice1d', 'closeprice', 'closequantity'].indexOf(obj) == -1;
|
|
3331
3380
|
});
|
|
@@ -3351,7 +3400,7 @@ function Milli_Chart(settings) {
|
|
|
3351
3400
|
var e = new Date();
|
|
3352
3401
|
var days = 0;
|
|
3353
3402
|
var newlen = 0;
|
|
3354
|
-
while (days < _this.settings.intradaylen - 1) {
|
|
3403
|
+
while (days < _this.settings.intradaylen - 1) { // include today
|
|
3355
3404
|
d -= 86400000;
|
|
3356
3405
|
e.setTime(d);
|
|
3357
3406
|
if (e.getDay() != 0 && e.getDay() != 6)
|
|
@@ -3394,7 +3443,6 @@ function Milli_Chart(settings) {
|
|
|
3394
3443
|
|
|
3395
3444
|
(function updatePixelRatio() {
|
|
3396
3445
|
matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`).addEventListener('change', updatePixelRatio, { once: true });
|
|
3397
|
-
() => {};
|
|
3398
3446
|
_this.drawChart();
|
|
3399
3447
|
})();
|
|
3400
3448
|
|
|
@@ -3405,7 +3453,638 @@ function Milli_Chart(settings) {
|
|
|
3405
3453
|
}
|
|
3406
3454
|
});
|
|
3407
3455
|
}
|
|
3408
|
-
|
|
3456
|
+
function Milli_OptionsList(settings) {
|
|
3457
|
+
let _this = this;
|
|
3458
|
+
let requestid = null;
|
|
3459
|
+
|
|
3460
|
+
_this.settings = {
|
|
3461
|
+
autodraw: true,
|
|
3462
|
+
//fields: ['insref','symbol','derivativeindicator','diff1d','diff1dprc','openinterest', 'quantity', 'bidprice', 'askprice', 'lastprice','strikeprice','strikedate','isin','instrumenttype','expirationtype','dte'],
|
|
3463
|
+
fields: ['openinterest', 'quantity', 'bidprice', 'askprice', 'lastprice'],
|
|
3464
|
+
instrument: 772,
|
|
3465
|
+
instrumenttype: [5],
|
|
3466
|
+
instrumentsubtype: [0],
|
|
3467
|
+
messagetypes: 2,
|
|
3468
|
+
num_decimals: 2,
|
|
3469
|
+
onreadyCallback: null,
|
|
3470
|
+
streaming: false,
|
|
3471
|
+
target: null,
|
|
3472
|
+
flash: true,
|
|
3473
|
+
controlcolumn: 0,
|
|
3474
|
+
stylecolumn: null,
|
|
3475
|
+
strikedatefilter: [],
|
|
3476
|
+
expirationtypefilter: [],
|
|
3477
|
+
custom_columns: {},
|
|
3478
|
+
sortorder: 'asc',
|
|
3479
|
+
strikedateHeader: true,
|
|
3480
|
+
hidePuts: false
|
|
3481
|
+
};
|
|
3482
|
+
MillistreamWidgetApi_AssignObject(MillistreamWidgetSettings, _this.settings);
|
|
3483
|
+
|
|
3484
|
+
if (settings) {
|
|
3485
|
+
MillistreamWidgetApi_AssignObject(settings, _this.settings);
|
|
3486
|
+
}
|
|
3487
|
+
|
|
3488
|
+
_this.unsubscriptions = {};
|
|
3489
|
+
let m_instruments = new Map();
|
|
3490
|
+
let m_cellMap = new Map();
|
|
3491
|
+
let m_currentinsrefs = [];
|
|
3492
|
+
let m_pushfields = [];
|
|
3493
|
+
let m_strikes = [];
|
|
3494
|
+
|
|
3495
|
+
let m_strikepricedecimals = 2;
|
|
3496
|
+
|
|
3497
|
+
let m_lang_en = {
|
|
3498
|
+
askprice: 'Ask',
|
|
3499
|
+
bidprice: 'Bid',
|
|
3500
|
+
askquantity: 'Askquantity',
|
|
3501
|
+
bidquantity: 'Bidquantity',
|
|
3502
|
+
calls: 'CALLS',
|
|
3503
|
+
date: 'Date',
|
|
3504
|
+
dayhighprice: 'High',
|
|
3505
|
+
daylowprice: 'Low',
|
|
3506
|
+
diff1d: '+/-',
|
|
3507
|
+
diff1dprc: '%',
|
|
3508
|
+
lastprice: 'Last',
|
|
3509
|
+
openinterest: 'OI',
|
|
3510
|
+
quantity: 'Quantity',
|
|
3511
|
+
puts: 'PUTS',
|
|
3512
|
+
strikedate: 'Strike date',
|
|
3513
|
+
strikeprice: 'Strike price',
|
|
3514
|
+
symbol: 'Symbol',
|
|
3515
|
+
time: 'Time',
|
|
3516
|
+
rho: 'Rho',
|
|
3517
|
+
theta: 'Theta',
|
|
3518
|
+
delta: 'Delta',
|
|
3519
|
+
vega: 'Vega',
|
|
3520
|
+
gamma: 'Gamma',
|
|
3521
|
+
iv: 'IV',
|
|
3522
|
+
ivask: 'Ask IV',
|
|
3523
|
+
ivbid: 'Bid IV',
|
|
3524
|
+
weeklytype: '(w)',
|
|
3525
|
+
dte: 'DTE',
|
|
3526
|
+
strikes: 'Strikes'
|
|
3527
|
+
};
|
|
3528
|
+
|
|
3529
|
+
let m_lang_sv = {
|
|
3530
|
+
askprice: 'Sälj',
|
|
3531
|
+
bidprice: 'Köp',
|
|
3532
|
+
askquantity: 'Säljvolym',
|
|
3533
|
+
bidquantity: 'Köpvolym',
|
|
3534
|
+
calls: 'Köpoptioner',
|
|
3535
|
+
date: 'Datum',
|
|
3536
|
+
dayhighprice: 'Högst',
|
|
3537
|
+
daylowprice: 'Lägst',
|
|
3538
|
+
diff1d: '+/-',
|
|
3539
|
+
diff1dprc: '%',
|
|
3540
|
+
lastprice: 'Senast',
|
|
3541
|
+
openinterest: 'ÖB',
|
|
3542
|
+
puts: 'Säljoptioner',
|
|
3543
|
+
quantity: 'Volym',
|
|
3544
|
+
strikedate: 'Lösendag',
|
|
3545
|
+
strikeprice: 'Lösenpris',
|
|
3546
|
+
symbol: 'Kortnamn',
|
|
3547
|
+
time: 'Tid',
|
|
3548
|
+
rho: 'Rho',
|
|
3549
|
+
theta: 'Theta',
|
|
3550
|
+
delta: 'Delta',
|
|
3551
|
+
vega: 'Vega',
|
|
3552
|
+
gamma: 'Gamma',
|
|
3553
|
+
iv: 'IV',
|
|
3554
|
+
ivask: 'Sälj IV',
|
|
3555
|
+
ivbid: 'Köp IV',
|
|
3556
|
+
weeklytype: '(v)',
|
|
3557
|
+
dte: 'DTE',
|
|
3558
|
+
strikes: 'Lösenpris'
|
|
3559
|
+
};
|
|
3560
|
+
|
|
3561
|
+
_this.destroyWidget = function() {
|
|
3562
|
+
// if we have subscriptions send in an empty array to unsubscribe all and release it
|
|
3563
|
+
if (MillistreamWidgetApi_isObjectEmpty(_this.unsubscriptions) == false)
|
|
3564
|
+
_this.requestid = _this.settings.streaming.MillistreamWidgetStreamingApi_subscribeInstruments(_this, _this.requestid, []);
|
|
3565
|
+
return 0;
|
|
3566
|
+
};
|
|
3567
|
+
|
|
3568
|
+
_this.get_lang_text = function(string) {
|
|
3569
|
+
if (_this.settings.custom_lang && _this.settings.custom_lang[string]) return _this.settings.custom_lang[string];
|
|
3570
|
+
switch (_this.settings.language) {
|
|
3571
|
+
case 'sv':
|
|
3572
|
+
return m_lang_sv[string];
|
|
3573
|
+
case 'en':
|
|
3574
|
+
return m_lang_en[string];
|
|
3575
|
+
default:
|
|
3576
|
+
return string;
|
|
3577
|
+
}
|
|
3578
|
+
};
|
|
3579
|
+
|
|
3580
|
+
function add_custom_element(el, cl, parent, type, name, onclick, insref) {
|
|
3581
|
+
let element = document.createElement(el);
|
|
3582
|
+
if (cl) element.setAttribute("class", cl);
|
|
3583
|
+
if (parent) parent.appendChild(element);
|
|
3584
|
+
if (onclick) {
|
|
3585
|
+
element.onclick = (function(e) {
|
|
3586
|
+
_this.fire_custom_onclick(onclick, e, insref);
|
|
3587
|
+
});
|
|
3588
|
+
}
|
|
3589
|
+
if (type) element.type = type;
|
|
3590
|
+
if (name) element.value = name;
|
|
3591
|
+
return element;
|
|
3592
|
+
}
|
|
3593
|
+
|
|
3594
|
+
_this.fire_custom_onclick = function(onclick, e, insref) {
|
|
3595
|
+
let instr = m_instruments.get(insref);
|
|
3596
|
+
let obj = {};
|
|
3597
|
+
obj.event = e;
|
|
3598
|
+
obj.source = _this;
|
|
3599
|
+
|
|
3600
|
+
_this.settings.link_field.forEach(function(element) {
|
|
3601
|
+
let info = MillistreamWidgetApi_getColumnInfo(_this, element);
|
|
3602
|
+
if (typeof instr[info[0]] !== 'undefined') obj[element] = instr[info[0]]; // kolla om vi har push
|
|
3603
|
+
else if (typeof instr[element] !== 'undefined') obj[element] = instr[element];
|
|
3604
|
+
});
|
|
3605
|
+
onclick(obj);
|
|
3606
|
+
};
|
|
3607
|
+
|
|
3608
|
+
|
|
3609
|
+
_this.getStrikeDates = function() {
|
|
3610
|
+
return m_strikedates;
|
|
3611
|
+
};
|
|
3612
|
+
|
|
3613
|
+
function getNumDecimals(widget, value) {
|
|
3614
|
+
if (value == null) return 0;
|
|
3615
|
+
let parts = value.toString().split('.');
|
|
3616
|
+
if (parts.length == 2) {
|
|
3617
|
+
while (parts[1].charAt(parts[1].length - 1) == "0") { // remove trailing zeros
|
|
3618
|
+
parts[1] = parts[1].slice(0, -1);
|
|
3619
|
+
}
|
|
3620
|
+
return parts[1].length;
|
|
3621
|
+
}
|
|
3622
|
+
return 0;
|
|
3623
|
+
}
|
|
3624
|
+
|
|
3625
|
+
function sortOptions(resp) {
|
|
3626
|
+
let decimals = 0;
|
|
3627
|
+
let expirys = [];
|
|
3628
|
+
|
|
3629
|
+
for (i = 0; i < resp.instruments.length; i++) {
|
|
3630
|
+
let dec = getNumDecimals(_this, resp.instruments[i].strikeprice);
|
|
3631
|
+
decimals = decimals > dec ? decimals : dec;
|
|
3632
|
+
|
|
3633
|
+
m_instruments.set(resp.instruments[i].insref, resp.instruments[i]);
|
|
3634
|
+
let strike = null;
|
|
3635
|
+
if (typeof expirys[resp.instruments[i].strikedate] === 'undefined') {
|
|
3636
|
+
expirys[resp.instruments[i].strikedate] = 1;
|
|
3637
|
+
let strikedata = {};
|
|
3638
|
+
strikedata.strikedate = resp.instruments[i].strikedate;
|
|
3639
|
+
strikedata.expirationtype = resp.instruments[i].expirationtype;
|
|
3640
|
+
/*let date = new Date(resp.instruments[i].strikedate);
|
|
3641
|
+
let opts;
|
|
3642
|
+
switch (_this.settings.language) {
|
|
3643
|
+
case 'sv':
|
|
3644
|
+
opts = { day: 'numeric', month: 'short' };
|
|
3645
|
+
date = date.toLocaleDateString('sv-SE', opts);
|
|
3646
|
+
let parts = date.split(' ');
|
|
3647
|
+
date = parts[0] + ' ' + parts[1].substring(0, 3);
|
|
3648
|
+
break;
|
|
3649
|
+
default:
|
|
3650
|
+
opts = { month: 'short', day: 'numeric' };
|
|
3651
|
+
date = date.toLocaleDateString('en-US', opts);
|
|
3652
|
+
break;
|
|
3653
|
+
}
|
|
3654
|
+
//strikedata.date = date;*/
|
|
3655
|
+
strikedata.dte = resp.instruments[i].dte;
|
|
3656
|
+
m_strikedates.push(strikedata);
|
|
3657
|
+
}
|
|
3658
|
+
let f = 0;
|
|
3659
|
+
if (resp.instruments[i].strikeprice != null) {
|
|
3660
|
+
for (let s = 0; s < m_strikes.length; s++) {
|
|
3661
|
+
if (m_strikes[s].strikedate == resp.instruments[i].strikedate && m_strikes[s].strikeprice == resp.instruments[i].strikeprice) {
|
|
3662
|
+
strike = m_strikes[s];
|
|
3663
|
+
break;
|
|
3664
|
+
}
|
|
3665
|
+
}
|
|
3666
|
+
} else f = 1;
|
|
3667
|
+
|
|
3668
|
+
if (strike == null) {
|
|
3669
|
+
m_strikes.push({
|
|
3670
|
+
strikedate: resp.instruments[i].strikedate,
|
|
3671
|
+
strikeprice: resp.instruments[i].strikeprice,
|
|
3672
|
+
calls: null,
|
|
3673
|
+
puts: null,
|
|
3674
|
+
future: f
|
|
3675
|
+
});
|
|
3676
|
+
if (resp.instruments[i].expirationtype) m_strikes[m_strikes.length - 1].expirationtype = parseInt(resp.instruments[i].expirationtype);
|
|
3677
|
+
strike = m_strikes[m_strikes.length - 1];
|
|
3678
|
+
}
|
|
3679
|
+
if (resp.instruments[i].derivativeindicator == 0 || resp.instruments[i].derivativeindicator == 3) { // calls and futures
|
|
3680
|
+
strike.calls = resp.instruments[i];
|
|
3681
|
+
} else if (resp.instruments[i].derivativeindicator == 1) { // puts
|
|
3682
|
+
strike.puts = resp.instruments[i];
|
|
3683
|
+
}
|
|
3684
|
+
}
|
|
3685
|
+
m_strikepricedecimals = decimals == 1 ? 2 : decimals;
|
|
3686
|
+
m_strikedates.sort(function(a, b) {
|
|
3687
|
+
return a.strikedate.replace(/-/g, '') - b.strikedate.replace(/-/g, '');
|
|
3688
|
+
});
|
|
3689
|
+
m_strikes.sort(function(a, b) {
|
|
3690
|
+
if (a.strikedate == b.strikedate) {
|
|
3691
|
+
if (a.future == 1 || b.future == 1) {
|
|
3692
|
+
return (b.future - a.future);
|
|
3693
|
+
}
|
|
3694
|
+
return (a.strikeprice - b.strikeprice) * (_this.settings.sortorder == 'asc' ? 1 : -1);
|
|
3695
|
+
}
|
|
3696
|
+
return a.strikedate.replace(/-/g, '') - b.strikedate.replace(/-/g, '');
|
|
3697
|
+
});
|
|
3698
|
+
}
|
|
3699
|
+
_this.applyFilter = function() {
|
|
3700
|
+
check_which_strikes_to_show();
|
|
3701
|
+
};
|
|
3702
|
+
|
|
3703
|
+
function check_which_strikes_to_show() {
|
|
3704
|
+
if (m_strikes.length == 0)
|
|
3705
|
+
return;
|
|
3706
|
+
let strikedate = m_strikes[0].strikedate;
|
|
3707
|
+
let pos = 0;
|
|
3708
|
+
let newinsrefs = [];
|
|
3709
|
+
let s, h1, h2, i;
|
|
3710
|
+
for (i = 0; i < m_strikes.length; i++) {
|
|
3711
|
+
if (m_strikes[i].strikedate != strikedate) {
|
|
3712
|
+
if (_this.settings.strikedateHeader) {
|
|
3713
|
+
h1 = m_strikes[pos].row.parentNode.rows[m_strikes[pos].row.rowIndex - 1];
|
|
3714
|
+
h2 = m_strikes[pos].row.parentNode.rows[m_strikes[pos].row.rowIndex - 2];
|
|
3715
|
+
}
|
|
3716
|
+
if ((_this.settings.strikedatefilter.length != 0 && _this.settings.strikedatefilter.indexOf(strikedate) == -1) || (_this.settings.expirationtypefilter.length != 0 && _this.settings.expirationtypefilter.indexOf(m_strikes[i - 1].expirationtype) == -1) || typeof m_strikes[i].expirationtype === 'undefined') {
|
|
3717
|
+
if (_this.settings.strikedateHeader) {
|
|
3718
|
+
h1.style.display = 'none';
|
|
3719
|
+
h2.style.display = 'none';
|
|
3720
|
+
}
|
|
3721
|
+
for (s = pos; s < i; s++) {
|
|
3722
|
+
m_strikes[s].row.style.display = 'none';
|
|
3723
|
+
}
|
|
3724
|
+
} else {
|
|
3725
|
+
if (_this.settings.strikedateHeader) {
|
|
3726
|
+
h1.style.display = 'table-row';
|
|
3727
|
+
h2.style.display = 'table-row';
|
|
3728
|
+
}
|
|
3729
|
+
for (s = pos; s < i; s++) {
|
|
3730
|
+
m_strikes[s].row.style.display = 'table-row';
|
|
3731
|
+
if (m_strikes[s].calls != null) newinsrefs.push(parseInt(m_strikes[s].calls.insref));
|
|
3732
|
+
if (m_strikes[s].puts != null) newinsrefs.push(parseInt(m_strikes[s].puts.insref));
|
|
3733
|
+
}
|
|
3734
|
+
}
|
|
3735
|
+
pos = i;
|
|
3736
|
+
strikedate = m_strikes[i].strikedate;
|
|
3737
|
+
}
|
|
3738
|
+
}
|
|
3739
|
+
if (i != 0) {
|
|
3740
|
+
if (_this.settings.strikedateHeader) {
|
|
3741
|
+
h1 = m_strikes[pos].row.parentNode.rows[m_strikes[pos].row.rowIndex - 1];
|
|
3742
|
+
h2 = m_strikes[pos].row.parentNode.rows[m_strikes[pos].row.rowIndex - 2];
|
|
3743
|
+
}
|
|
3744
|
+
for (s = pos; s < i; s++) {
|
|
3745
|
+
if ((_this.settings.strikedatefilter.length != 0 && _this.settings.strikedatefilter.indexOf(m_strikes[s].strikedate) == -1) || (_this.settings.expirationtypefilter.length == 0 && _this.settings.expirationtypefilter.indexOf(m_strikes[s].expirationtype) != -1)) {
|
|
3746
|
+
if (_this.settings.strikedateHeader) {
|
|
3747
|
+
h1.style.display = 'none';
|
|
3748
|
+
h2.style.display = 'none';
|
|
3749
|
+
}
|
|
3750
|
+
for (s = pos; s < i; s++) {
|
|
3751
|
+
m_strikes[s].row.style.display = 'none';
|
|
3752
|
+
}
|
|
3753
|
+
continue;
|
|
3754
|
+
} else {
|
|
3755
|
+
if (_this.settings.strikedateHeader) {
|
|
3756
|
+
h1.style.display = 'table-row';
|
|
3757
|
+
h2.style.display = 'table-row';
|
|
3758
|
+
}
|
|
3759
|
+
}
|
|
3760
|
+
m_strikes[s].row.style.display = 'table-row';
|
|
3761
|
+
if (m_strikes[s].calls != null) newinsrefs.push(parseInt(m_strikes[s].calls.insref));
|
|
3762
|
+
if (m_strikes[s].puts != null) newinsrefs.push(parseInt(m_strikes[s].puts.insref));
|
|
3763
|
+
}
|
|
3764
|
+
}
|
|
3765
|
+
|
|
3766
|
+
if (_this.settings.streaming != false) {
|
|
3767
|
+
const sortedinsrefs = newinsrefs.slice().sort();
|
|
3768
|
+
let comp = (m_currentinsrefs.length === sortedinsrefs.length && m_currentinsrefs.slice().sort().every(function(value, index) {
|
|
3769
|
+
return value === sortedinsrefs[index];
|
|
3770
|
+
}));
|
|
3771
|
+
if (comp == false) {
|
|
3772
|
+
m_currentinsrefs = sortedinsrefs;
|
|
3773
|
+
_this.requestid = _this.settings.streaming.MillistreamWidgetStreamingApi_subscribeInstruments(_this, _this.requestid, m_currentinsrefs);
|
|
3774
|
+
}
|
|
3775
|
+
}
|
|
3776
|
+
}
|
|
3777
|
+
|
|
3778
|
+
_this.streamingCallback = function(insref, mref, json) {
|
|
3779
|
+
let keys = Object.keys(json);
|
|
3780
|
+
for (let s = 0; s < keys.length; s++) {
|
|
3781
|
+
if (m_pushfields.indexOf(parseInt(keys[s])) == -1) {
|
|
3782
|
+
continue; // not needed for display or link
|
|
3783
|
+
}
|
|
3784
|
+
let cellMap = m_cellMap.get(insref + ':' + keys[s]);
|
|
3785
|
+
if (cellMap) {
|
|
3786
|
+
let info = MillistreamWidgetApi_getColumnInfo(_this, keys[s]);
|
|
3787
|
+
_this.settings.stylecolumn = cellMap.stylecolumn;
|
|
3788
|
+
_this.settings.controlcolumn = cellMap.controlcolumn;
|
|
3789
|
+
print_field(_this, cellMap.element, info[0], json[info[0]], _this.settings.num_decimals);
|
|
3790
|
+
}
|
|
3791
|
+
}
|
|
3792
|
+
};
|
|
3793
|
+
|
|
3794
|
+
function buildlist(resp) {
|
|
3795
|
+
m_cellMap.clear();
|
|
3796
|
+
m_instruments.clear();
|
|
3797
|
+
m_strikedates = [];
|
|
3798
|
+
m_strikeprices = [];
|
|
3799
|
+
sortOptions(resp);
|
|
3800
|
+
if (typeof _this.settings.onData !== 'undefined') _this.settings.onData();
|
|
3801
|
+
|
|
3802
|
+
if (m_strikedates.length != 0) {
|
|
3803
|
+
let table = MillistreamWidgetApi_addElement(_this, 'table', 'millistream-optionslist-table', _this.settings.target);
|
|
3804
|
+
let pos = 0;
|
|
3805
|
+
let info;
|
|
3806
|
+
let callheader = null;
|
|
3807
|
+
let putheader = null;
|
|
3808
|
+
let tbody = MillistreamWidgetApi_addElement(_this, 'tbody', null, table);
|
|
3809
|
+
let i;
|
|
3810
|
+
for (i = 0; i < _this.settings.fields.length; i++) {
|
|
3811
|
+
let f = MillistreamWidgetApi_getColumnInfo(_this, _this.settings.fields[i]);
|
|
3812
|
+
if (-1 == m_pushfields.indexOf(f[0])) m_pushfields.push(f[0]);
|
|
3813
|
+
}
|
|
3814
|
+
if (m_strikedates.length == 0) return;
|
|
3815
|
+
for (let s = 0; s < m_strikedates.length; s++) {
|
|
3816
|
+
let display = '';
|
|
3817
|
+
let tr;
|
|
3818
|
+
if (_this.settings.strikedateHeader) {
|
|
3819
|
+
tr = MillistreamWidgetApi_addElement(_this, 'tr', null, tbody);
|
|
3820
|
+
tr.setAttribute('data-strikedate', m_strikedates[s].strikedate);
|
|
3821
|
+
if (_this.settings.strikedatefilter.length != 0 && _this.settings.strikedatefilter.indexOf(m_strikedates[s].strikedate) == -1) {
|
|
3822
|
+
tr.style.display = 'none';
|
|
3823
|
+
display = 'none';
|
|
3824
|
+
}
|
|
3825
|
+
callheader = MillistreamWidgetApi_addElement(_this, 'th', 'millistream-optionslist-header-calls' + ' millistream-string', tr, null, null);
|
|
3826
|
+
putheader = MillistreamWidgetApi_addElement(_this, 'th', 'millistream-optionslist-header-puts' + ' millistream-string', tr, null, null);
|
|
3827
|
+
} else if (_this.settings.strikedatefilter.length != 0 && _this.settings.strikedatefilter.indexOf(m_strikedates[s].strikedate) == -1) {
|
|
3828
|
+
display = 'none';
|
|
3829
|
+
}
|
|
3830
|
+
tr = MillistreamWidgetApi_addElement(_this, 'tr', 'millistream-optionslist-options-table-header', tbody);
|
|
3831
|
+
|
|
3832
|
+
let cpos, added_columns = 0;
|
|
3833
|
+
|
|
3834
|
+
if (display == 'none') tr.style.display = 'none';
|
|
3835
|
+
for (i = 0; i < _this.settings.fields.length; i++) {
|
|
3836
|
+
for (cpos in _this.settings.custom_columns) {
|
|
3837
|
+
if (cpos == added_columns) {
|
|
3838
|
+
MillistreamWidgetApi_addElement(_this, 'th', 'millistream-optionslist-table-th', tr, null, _this.settings.custom_columns[cpos].name);
|
|
3839
|
+
added_columns++;
|
|
3840
|
+
}
|
|
3841
|
+
}
|
|
3842
|
+
info = MillistreamWidgetApi_getColumnInfo(_this, _this.settings.fields[i]);
|
|
3843
|
+
th = MillistreamWidgetApi_addElement(_this, 'th', 'millistream-optionslist-table-th millistream-' + info[1] + ' millistream-' + _this.settings.fields[i], tr, null, info[3]);
|
|
3844
|
+
added_columns++;
|
|
3845
|
+
}
|
|
3846
|
+
for (cpos in _this.settings.custom_columns) {
|
|
3847
|
+
if (cpos == added_columns) {
|
|
3848
|
+
MillistreamWidgetApi_addElement(_this, 'th', 'millistream-optionslist-table-th', tr, null, this.settings.custom_columns[cpos].name);
|
|
3849
|
+
added_columns++;
|
|
3850
|
+
}
|
|
3851
|
+
}
|
|
3852
|
+
th = MillistreamWidgetApi_addElement(_this, 'th', 'millistream-optionslist-table-th millistream-optionslist-yheader millistream-sortable-cursor millistream-sorting-' + _this.settings.sortorder, tr);
|
|
3853
|
+
th.innerHTML = _this.get_lang_text('strikes');
|
|
3854
|
+
th.onclick = (function(e) {
|
|
3855
|
+
_this.settings.sortorder = _this.settings.sortorder == 'asc' ? 'desc' : 'asc';
|
|
3856
|
+
let tmp = [];
|
|
3857
|
+
let first = 0; // ignore first header and future
|
|
3858
|
+
while (first < table.childNodes[0].childNodes.length) {
|
|
3859
|
+
if (table.childNodes[0].childNodes[first].childNodes[0].nodeName == 'TH') {
|
|
3860
|
+
let offset = 0;
|
|
3861
|
+
if (!table.childNodes[0].childNodes[first].classList.contains('millistream-optionslist-options-table-header'))
|
|
3862
|
+
offset = 1;
|
|
3863
|
+
table.childNodes[0].childNodes[first + offset].cells[e.srcElement.cellIndex].classList.remove('millistream-sorting-' + (_this.settings.sortorder == 'asc' ? 'desc' : 'asc'));
|
|
3864
|
+
table.childNodes[0].childNodes[first + offset].cells[e.srcElement.cellIndex].classList.add('millistream-sorting-' + _this.settings.sortorder);
|
|
3865
|
+
for (s = 0; s < tmp.length; s++) {
|
|
3866
|
+
table.childNodes[0].insertBefore(tmp[s], table.childNodes[0].childNodes[first + offset]);
|
|
3867
|
+
}
|
|
3868
|
+
first = first + tmp.length + 1 + offset;
|
|
3869
|
+
tmp = [];
|
|
3870
|
+
}
|
|
3871
|
+
tmp.push(table.childNodes[0].childNodes[first]);
|
|
3872
|
+
table.childNodes[0].removeChild(table.childNodes[0].childNodes[first]);
|
|
3873
|
+
}
|
|
3874
|
+
if (tmp.length > 0) {
|
|
3875
|
+
for (s = 0; s < tmp.length; s++) {
|
|
3876
|
+
table.childNodes[0].insertBefore(tmp[s], table.childNodes[0].childNodes[first]);
|
|
3877
|
+
}
|
|
3878
|
+
}
|
|
3879
|
+
m_strikes.sort(function(a, b) {
|
|
3880
|
+
if (a.strikedate == b.strikedate) {
|
|
3881
|
+
return (a.strikeprice - b.strikeprice) * (_this.settings.sortorder == 'asc' ? 1 : -1);
|
|
3882
|
+
}
|
|
3883
|
+
return a.strikedate.replace(/-/g, '') - b.strikedate.replace(/-/g, '');
|
|
3884
|
+
});
|
|
3885
|
+
});
|
|
3886
|
+
|
|
3887
|
+
cpos = 0;
|
|
3888
|
+
//added_columns = 0;
|
|
3889
|
+
if (_this.settings.hidePuts == false) {
|
|
3890
|
+
for (i = _this.settings.fields.length - 1; i >= 0; i--) {
|
|
3891
|
+
// flip bid and ask for puts
|
|
3892
|
+
if (_this.settings.fields[i] == 'bidprice' && _this.settings.fields[i].indexOf('askprice') != 0) {
|
|
3893
|
+
info = MillistreamWidgetApi_getColumnInfo(_this, 'askprice');
|
|
3894
|
+
MillistreamWidgetApi_addElement(_this, 'th', 'millistream-optionslist-table-th millistream-' + info[1] + ' millistream-askprice', tr, null, info[3]);
|
|
3895
|
+
} else
|
|
3896
|
+
if (_this.settings.fields[i] == 'askprice' && _this.settings.fields[i].indexOf('bidprice') != 0) {
|
|
3897
|
+
info = MillistreamWidgetApi_getColumnInfo(_this, 'bidprice');
|
|
3898
|
+
MillistreamWidgetApi_addElement(_this, 'th', 'millistream-optionslist-table-th millistream-' + info[1] + ' millistream-bidprice', tr, null, info[3]);
|
|
3899
|
+
} else {
|
|
3900
|
+
info = MillistreamWidgetApi_getColumnInfo(_this, _this.settings.fields[i]);
|
|
3901
|
+
MillistreamWidgetApi_addElement(_this, 'th', 'millistream-optionslist-table-th millistream-' + info[1] + ' millistream-' + _this.settings.fields[i], tr, null, info[3]);
|
|
3902
|
+
}
|
|
3903
|
+
for (cpos in _this.settings.custom_columns) {
|
|
3904
|
+
if (cpos == i + 1) {
|
|
3905
|
+
MillistreamWidgetApi_addElement(_this, 'th', 'millistream-optionslist-table-th', tr, null, _this.settings.custom_columns[cpos].name);
|
|
3906
|
+
added_columns++;
|
|
3907
|
+
}
|
|
3908
|
+
}
|
|
3909
|
+
added_columns++;
|
|
3910
|
+
}
|
|
3911
|
+
for (cpos in _this.settings.custom_columns) {
|
|
3912
|
+
if (cpos == i + 1) {
|
|
3913
|
+
MillistreamWidgetApi_addElement(_this, 'th', 'millistream-optionslist-table-th', tr, null, _this.settings.custom_columns[cpos].name);
|
|
3914
|
+
added_columns++;
|
|
3915
|
+
}
|
|
3916
|
+
}
|
|
3917
|
+
}
|
|
3918
|
+
let numcalls = 0;
|
|
3919
|
+
let numputs = 0;
|
|
3920
|
+
let td;
|
|
3921
|
+
let x;
|
|
3922
|
+
for (i = pos; i < m_strikes.length; i++) {
|
|
3923
|
+
let cellMap;
|
|
3924
|
+
if (m_strikeprices.indexOf(m_strikes[i].strikeprice) == -1) m_strikeprices.push(m_strikes[i].strikeprice);
|
|
3925
|
+
if (m_strikes[i].strikedate == m_strikedates[s].strikedate) {
|
|
3926
|
+
added_columns = 0;
|
|
3927
|
+
let otr = MillistreamWidgetApi_addElement(_this, 'tr', 'millistream-optionlist-row', tbody);
|
|
3928
|
+
otr.onclick = function(e) {
|
|
3929
|
+
if (typeof _this.settings.onRowClick === 'function') {
|
|
3930
|
+
if (e.srcElement.nodeName == 'TD') {
|
|
3931
|
+
if (e.srcElement.cellIndex < _this.settings.fields.length + Object.keys(_this.settings.custom_columns).length) {
|
|
3932
|
+
if (e.srcElement.parentNode.getAttribute('call') !== null)
|
|
3933
|
+
_this.settings.onRowClick(e.srcElement.parentNode.getAttribute('call'));
|
|
3934
|
+
} else
|
|
3935
|
+
if (e.srcElement.cellIndex > _this.settings.fields.length + Object.keys(_this.settings.custom_columns).length) {
|
|
3936
|
+
if (e.srcElement.parentNode.getAttribute('put') !== null)
|
|
3937
|
+
_this.settings.onRowClick(e.srcElement.parentNode.getAttribute('put'));
|
|
3938
|
+
}
|
|
3939
|
+
return;
|
|
3940
|
+
}
|
|
3941
|
+
}
|
|
3942
|
+
};
|
|
3943
|
+
if (display == 'none') otr.style.display = 'none';
|
|
3944
|
+
m_strikes[i].row = otr;
|
|
3945
|
+
if (m_strikes[i].calls) numcalls++;
|
|
3946
|
+
for (x = 0; x < _this.settings.fields.length; x++) {
|
|
3947
|
+
for (cpos in _this.settings.custom_columns) {
|
|
3948
|
+
if (cpos == added_columns) {
|
|
3949
|
+
td = MillistreamWidgetApi_addTableCell2(_this, null, 'millistream-optionslist-call-cell', otr);
|
|
3950
|
+
if (m_strikes[i].calls && (typeof _this.settings.custom_columns[cpos].condition !== 'function' || _this.settings.custom_columns[cpos].condition(m_strikes[i].calls))) {
|
|
3951
|
+
if (_this.settings.custom_columns[cpos].instruments && -1 != _this.settings.custom_columns[cpos].instruments.indexOf(m_strikes[i].insref)) {
|
|
3952
|
+
add_custom_element(_this.settings.custom_columns[cpos].element, _this.settings.custom_columns[cpos].alternate_class, td, _this.settings.custom_columns[cpos].type, _this.settings.custom_columns[cpos].name, _this.settings.custom_columns[cpos].onclick, m_strikes[i].calls.insref);
|
|
3953
|
+
} else {
|
|
3954
|
+
add_custom_element(_this.settings.custom_columns[cpos].element, _this.settings.custom_columns[cpos].class, td, _this.settings.custom_columns[cpos].type, _this.settings.custom_columns[cpos].name, _this.settings.custom_columns[cpos].onclick, m_strikes[i].calls.insref);
|
|
3955
|
+
}
|
|
3956
|
+
}
|
|
3957
|
+
added_columns++;
|
|
3958
|
+
}
|
|
3959
|
+
}
|
|
3960
|
+
|
|
3961
|
+
info = MillistreamWidgetApi_getColumnInfo(_this, _this.settings.fields[x]);
|
|
3962
|
+
td = MillistreamWidgetApi_addTableCell2(_this, _this.settings.fields[x], 'millistream-' + info[1] + ' millistream-optionslist-call-cell ' + ' millistream-' + _this.settings.fields[x], otr, m_strikes[i].calls);
|
|
3963
|
+
if (m_strikes[i].calls) {
|
|
3964
|
+
otr.setAttribute('call', m_strikes[i].calls.insref);
|
|
3965
|
+
cellMap = {
|
|
3966
|
+
insref: m_strikes[i].calls.insref,
|
|
3967
|
+
element: td,
|
|
3968
|
+
stylecolumn: _this.settings.stylecolumn,
|
|
3969
|
+
controlcolumn: _this.settings.controlcolumn
|
|
3970
|
+
};
|
|
3971
|
+
m_cellMap.set(cellMap.insref + ':' + info[0], cellMap);
|
|
3972
|
+
}
|
|
3973
|
+
added_columns++;
|
|
3974
|
+
}
|
|
3975
|
+
for (cpos in _this.settings.custom_columns) {
|
|
3976
|
+
if (cpos == added_columns) {
|
|
3977
|
+
td = MillistreamWidgetApi_addTableCell2(_this, null, 'millistream-optionslist-call-cell', otr);
|
|
3978
|
+
if (m_strikes[i].calls) {
|
|
3979
|
+
if (_this.settings.custom_columns[cpos].instruments && -1 != _this.settings.custom_columns[cpos].instruments.indexOf(m_strikes[i].insref)) {
|
|
3980
|
+
add_custom_element(_this.settings.custom_columns[cpos].element, _this.settings.custom_columns[cpos].alternate_class, td, _this.settings.custom_columns[cpos].type, _this.settings.custom_columns[cpos].name, _this.settings.custom_columns[cpos].onclick, m_strikes[i].calls.insref);
|
|
3981
|
+
} else {
|
|
3982
|
+
add_custom_element(_this.settings.custom_columns[cpos].element, _this.settings.custom_columns[cpos].class, td, _this.settings.custom_columns[cpos].type, _this.settings.custom_columns[cpos].name, _this.settings.custom_columns[cpos].onclick, m_strikes[i].calls.insref);
|
|
3983
|
+
}
|
|
3984
|
+
}
|
|
3985
|
+
added_columns++;
|
|
3986
|
+
}
|
|
3987
|
+
}
|
|
3988
|
+
// add strike column
|
|
3989
|
+
td = MillistreamWidgetApi_addElement(_this, 'td', 'millistream-optionslist-yheader millistream-numeric', otr);
|
|
3990
|
+
td.innerHTML = m_strikes[i].strikeprice == null ? 'Fut | Fwd' : formatNiceNumber(m_strikes[i].strikeprice, _this.settings.thousandseparator, _this.settings.decimalseparator, m_strikepricedecimals);
|
|
3991
|
+
|
|
3992
|
+
if (m_strikes[i].puts) numputs++;
|
|
3993
|
+
let field = null;
|
|
3994
|
+
if (_this.settings.hidePuts == false) {
|
|
3995
|
+
for (x = _this.settings.fields.length - 1; x >= 0; x--) {
|
|
3996
|
+
// flip bid and ask for puts
|
|
3997
|
+
|
|
3998
|
+
field = _this.settings.fields[x];
|
|
3999
|
+
if (_this.settings.fields[x] == 'bidprice' && _this.settings.fields[x].indexOf('askprice') != 0) {
|
|
4000
|
+
info = MillistreamWidgetApi_getColumnInfo(_this, 'askprice');
|
|
4001
|
+
field = 'askprice';
|
|
4002
|
+
} else
|
|
4003
|
+
if (_this.settings.fields[x] == 'askprice' && _this.settings.fields[x].indexOf('bidprice') != 0) {
|
|
4004
|
+
info = MillistreamWidgetApi_getColumnInfo(_this, 'bidprice');
|
|
4005
|
+
field = 'bidprice';
|
|
4006
|
+
} else
|
|
4007
|
+
info = MillistreamWidgetApi_getColumnInfo(_this, _this.settings.fields[x]);
|
|
4008
|
+
|
|
4009
|
+
td = MillistreamWidgetApi_addTableCell2(_this, field, 'millistream-' + info[1] + ' millistream-optionslist-put-cell ' + ' millistream-' + field, otr, m_strikes[i].puts);
|
|
4010
|
+
if (m_strikes[i].puts) {
|
|
4011
|
+
otr.setAttribute('put', m_strikes[i].puts.insref);
|
|
4012
|
+
cellMap = {
|
|
4013
|
+
insref: m_strikes[i].puts.insref,
|
|
4014
|
+
element: td,
|
|
4015
|
+
stylecolumn: _this.settings.stylecolumn == null ? null : _this.settings.stylecolumn.map(x => added_columns + _this.settings.fields.length - x + 2),
|
|
4016
|
+
controlcolumn: _this.settings.controlcolumn == null ? null : added_columns + _this.settings.fields.length - _this.settings.controlcolumn + 2,
|
|
4017
|
+
};
|
|
4018
|
+
m_cellMap.set(cellMap.insref + ':' + info[0], cellMap);
|
|
4019
|
+
}
|
|
4020
|
+
for (cpos in _this.settings.custom_columns) {
|
|
4021
|
+
if (cpos == x + 1) {
|
|
4022
|
+
td = MillistreamWidgetApi_addTableCell2(_this, null, 'millistream-optionslist-put-cell', otr);
|
|
4023
|
+
if (m_strikes[i].puts && (typeof _this.settings.custom_columns[cpos].condition !== 'function' || _this.settings.custom_columns[cpos].condition(m_strikes[i].puts))) {
|
|
4024
|
+
if (_this.settings.custom_columns[cpos].instruments && -1 != _this.settings.custom_columns[cpos].instruments.indexOf(m_strikes[i].insref)) {
|
|
4025
|
+
add_custom_element(_this.settings.custom_columns[cpos].element, _this.settings.custom_columns[cpos].alternate_class, td, _this.settings.custom_columns[cpos].type, _this.settings.custom_columns[cpos].name, _this.settings.custom_columns[cpos].onclick, m_strikes[i].puts.insref);
|
|
4026
|
+
} else {
|
|
4027
|
+
add_custom_element(_this.settings.custom_columns[cpos].element, _this.settings.custom_columns[cpos].class, td, _this.settings.custom_columns[cpos].type, _this.settings.custom_columns[cpos].name, _this.settings.custom_columns[cpos].onclick, m_strikes[i].puts.insref);
|
|
4028
|
+
}
|
|
4029
|
+
}
|
|
4030
|
+
added_columns++;
|
|
4031
|
+
}
|
|
4032
|
+
}
|
|
4033
|
+
}
|
|
4034
|
+
for (cpos in _this.settings.custom_columns) {
|
|
4035
|
+
if (cpos == x + 1) {
|
|
4036
|
+
td = MillistreamWidgetApi_addTableCell2(_this, null, 'millistream-optionslist-put-cell', otr);
|
|
4037
|
+
if (m_strikes[i].puts && (typeof _this.settings.custom_columns[cpos].condition !== 'function' || _this.settings.custom_columns[cpos].condition(m_strikes[i].puts))) {
|
|
4038
|
+
if (_this.settings.custom_columns[cpos].instruments && -1 != _this.settings.custom_columns[cpos].instruments.indexOf(m_strikes[i].insref)) {
|
|
4039
|
+
add_custom_element(_this.settings.custom_columns[cpos].element, _this.settings.custom_columns[cpos].alternate_class, td, _this.settings.custom_columns[cpos].type, _this.settings.custom_columns[cpos].name, _this.settings.custom_columns[cpos].onclick, m_strikes[i].puts.insref);
|
|
4040
|
+
} else {
|
|
4041
|
+
add_custom_element(_this.settings.custom_columns[cpos].element, _this.settings.custom_columns[cpos].class, td, _this.settings.custom_columns[cpos].type, _this.settings.custom_columns[cpos].name, _this.settings.custom_columns[cpos].onclick, m_strikes[i].puts.insref);
|
|
4042
|
+
}
|
|
4043
|
+
}
|
|
4044
|
+
added_columns++;
|
|
4045
|
+
}
|
|
4046
|
+
}
|
|
4047
|
+
}
|
|
4048
|
+
} else break;
|
|
4049
|
+
}
|
|
4050
|
+
if (_this.settings.strikedateHeader) {
|
|
4051
|
+
callheader.innerHTML = _this.get_lang_text('calls') + ' · ' + m_strikedates[s].strikedate + ' ' + (m_strikedates[s].expirationtype == '2' ? _this.get_lang_text('weeklytype') : ' ') + ' · ' + m_strikedates[s].dte + ' ' + _this.get_lang_text('dte') + ' · ' + numcalls + ' strikes';
|
|
4052
|
+
console.log(callheader.innerHTML);
|
|
4053
|
+
callheader.colSpan = _this.settings.fields.length + 1 + Object.keys(_this.settings.custom_columns).length;
|
|
4054
|
+
putheader.innerHTML = _this.get_lang_text('puts') + ' · ' + m_strikedates[s].strikedate + ' ' + (m_strikedates[s].expirationtype == '2' ? _this.get_lang_text('weeklytype') : ' ') + ' · ' + m_strikedates[s].dte + ' ' + _this.get_lang_text('dte') + ' · ' + numputs + ' strikes';
|
|
4055
|
+
putheader.colSpan = _this.settings.fields.length + Object.keys(_this.settings.custom_columns).length;
|
|
4056
|
+
}
|
|
4057
|
+
pos = i;
|
|
4058
|
+
}
|
|
4059
|
+
check_which_strikes_to_show();
|
|
4060
|
+
}
|
|
4061
|
+
if (_this.settings.onreadyCallback) _this.settings.onreadyCallback();
|
|
4062
|
+
}
|
|
4063
|
+
|
|
4064
|
+
|
|
4065
|
+
_this.drawWidget = function() {
|
|
4066
|
+
|
|
4067
|
+
if (MillistreamWidgetApi_isObjectEmpty(_this.unsubscriptions) == false)
|
|
4068
|
+
_this.requestid = _this.settings.streaming.MillistreamWidgetStreamingApi_subscribeInstruments(_this, _this.requestid, []);
|
|
4069
|
+
|
|
4070
|
+
if (_this.settings.target) {
|
|
4071
|
+
_this.settings.target.innerHTML = '';
|
|
4072
|
+
}
|
|
4073
|
+
|
|
4074
|
+
m_strikes = [];
|
|
4075
|
+
m_pushfields = [];
|
|
4076
|
+
m_currentinsrefs = [];
|
|
4077
|
+
m_cellMap = new Map();
|
|
4078
|
+
|
|
4079
|
+
let url = MillistreamWidgetApi_buildQuery(_this, 'optionslist');
|
|
4080
|
+
millistream_data_api.fetch(url, function(data) {
|
|
4081
|
+
buildlist(data);
|
|
4082
|
+
});
|
|
4083
|
+
};
|
|
4084
|
+
if (this.settings.autodraw == true) this.drawWidget();
|
|
4085
|
+
|
|
4086
|
+
}
|
|
4087
|
+
var milli_data_api_url = 'https://stage.millistream.com/widgets/3.0.4/data/milli_widget_dataapi.php?';
|
|
3409
4088
|
|
|
3410
4089
|
var millistream_data_api = {
|
|
3411
4090
|
callbackcounter: 0,
|
|
@@ -3453,14 +4132,14 @@ function MillistreamWidgetApi_buildQuery(widget, type) {
|
|
|
3453
4132
|
if (typeof widget.settings.instrumenttype !== 'object') {
|
|
3454
4133
|
throw new Error(widget.constructor.name + ': instrumenttype is not valid');
|
|
3455
4134
|
}
|
|
3456
|
-
|
|
4135
|
+
//if (widget.settings.instrument == null) // removed 2021-10-12 for "mylist" functionality
|
|
3457
4136
|
url += '&instrumenttypes=' + widget.settings.instrumenttype.join();
|
|
3458
4137
|
}
|
|
3459
4138
|
if (widget.settings.instrumentsubtype != null) {
|
|
3460
4139
|
if (typeof widget.settings.instrumentsubtype !== 'object') {
|
|
3461
4140
|
throw new Error(widget.constructor.name + ': instrumentsubtype is not valid');
|
|
3462
4141
|
}
|
|
3463
|
-
|
|
4142
|
+
//if (widget.settings.instrument == null) // removed 2021-10-12 for "mylist" functionality
|
|
3464
4143
|
url += '&instrumentsubtypes=' + widget.settings.instrumentsubtype.join();
|
|
3465
4144
|
}
|
|
3466
4145
|
if (widget.settings.derivativeindicator != null) {
|
|
@@ -3570,10 +4249,10 @@ function MillistreamWidgetApi_buildQuery(widget, type) {
|
|
|
3570
4249
|
}
|
|
3571
4250
|
}
|
|
3572
4251
|
if (typeof widget.settings.headerinterval === 'string' && widget.settings.headerinterval == 'instrumenttype') {
|
|
3573
|
-
if (widget.settings.fields.indexOf('instrumenttype') == -1) {
|
|
4252
|
+
if (widget.settings.fields.indexOf('instrumenttype') == -1 && widget.settings.link_field.indexOf('instrumenttype') == -1) {
|
|
3574
4253
|
url += ',instrumenttype';
|
|
3575
4254
|
}
|
|
3576
|
-
if (widget.settings.fields.indexOf('instrumentsubtype') == -1) {
|
|
4255
|
+
if (widget.settings.fields.indexOf('instrumentsubtype') == -1 && widget.settings.link_field.indexOf('instrumentsubtype') == -1) {
|
|
3577
4256
|
url += ',instrumentsubtype';
|
|
3578
4257
|
}
|
|
3579
4258
|
}
|
|
@@ -3696,7 +4375,7 @@ function MillistreamWidgetApi_buildQuery(widget, type) {
|
|
|
3696
4375
|
if (typeof widget.settings.fundcompany !== 'object' && widget.settings.fundcompany !== null) throw new Error(widget.constructor.name + ': fundcompany is not valid');
|
|
3697
4376
|
url += '&fundcompany=' + widget.settings.fundcompany.join(',');
|
|
3698
4377
|
}
|
|
3699
|
-
if (typeof widget.settings.expirationtype !== 'undefined') {
|
|
4378
|
+
if (typeof widget.settings.expirationtype !== 'undefined' && widget.settings.expirationtype != null) {
|
|
3700
4379
|
if (typeof widget.settings.expirationtype !== 'number' && widget.settings.expirationtype !== null) throw new Error(widget.constructor.name + ': expirationtype is not valid');
|
|
3701
4380
|
url += '&expirationtype=' + widget.settings.expirationtype;
|
|
3702
4381
|
}
|
|
@@ -3747,7 +4426,7 @@ function MillistreamWidgetApi_buildQuery(widget, type) {
|
|
|
3747
4426
|
if (typeof widget.settings.xhr !== 'undefined' && widget.settings.xhr == true) {
|
|
3748
4427
|
url += '&xhr=1';
|
|
3749
4428
|
}
|
|
3750
|
-
|
|
4429
|
+
console.log(url);
|
|
3751
4430
|
return url;
|
|
3752
4431
|
}
|
|
3753
4432
|
|
|
@@ -3809,12 +4488,12 @@ function MillistreamWidgetApi_addPagination(widget) {
|
|
|
3809
4488
|
li.onclick = function() {
|
|
3810
4489
|
MillistreamWidgetApi_getPaginationPage(widget, 'next');
|
|
3811
4490
|
};
|
|
3812
|
-
if (widget.pagination.numPages < max + 1) li.style.display = 'none';
|
|
4491
|
+
if (widget.pagination.numPages < max + 1) li.style.display = 'none'; // dont show if less than 6 pages
|
|
3813
4492
|
li = MillistreamWidgetApi_addElement(widget, 'li', 'millistream-list-pagination-li', widget.pagination.ul, null, '>>');
|
|
3814
4493
|
li.onclick = function() {
|
|
3815
4494
|
MillistreamWidgetApi_getPaginationPage(widget, 'last');
|
|
3816
4495
|
};
|
|
3817
|
-
if (widget.pagination.numPages < max + 1) li.style.display = 'none';
|
|
4496
|
+
if (widget.pagination.numPages < max + 1) li.style.display = 'none'; // dont show if less than 6 pages
|
|
3818
4497
|
}
|
|
3819
4498
|
} else
|
|
3820
4499
|
if (widget.settings.pagination > 0 && widget.pagination.numPages < 2) {
|
|
@@ -3882,11 +4561,11 @@ function MillistreamWidgetApi_getPaginationPage(widget, page) {
|
|
|
3882
4561
|
startno = 1;
|
|
3883
4562
|
} else
|
|
3884
4563
|
if (widget.pagination.selectedPage > widget.pagination.numPages - 2) {
|
|
3885
|
-
startno = widget.pagination.numPages - (max - 1);
|
|
4564
|
+
startno = widget.pagination.numPages - (max - 1); //4;
|
|
3886
4565
|
|
|
3887
4566
|
} else {
|
|
3888
4567
|
startno = widget.pagination.selectedPage - 2 < 1 ? 1 : widget.pagination.selectedPage - (max - Math.ceil(max / 2));
|
|
3889
|
-
|
|
4568
|
+
//startno = widget.pagination.selectedPage - 1;
|
|
3890
4569
|
}
|
|
3891
4570
|
for (i = 2; i < items.length - 2; i++) {
|
|
3892
4571
|
items[i].innerHTML = (startno);
|
|
@@ -3925,15 +4604,15 @@ function MillistreamWidgetApi_getElementHeight(el) {
|
|
|
3925
4604
|
return rect.height + s;
|
|
3926
4605
|
}
|
|
3927
4606
|
|
|
3928
|
-
|
|
4607
|
+
// Push blipp funktioner
|
|
3929
4608
|
function MillistreamWidgetApi_clearFlash(el) {
|
|
3930
|
-
|
|
4609
|
+
//internal and external
|
|
3931
4610
|
el.classList.remove('millistream-flash-up');
|
|
3932
4611
|
el.classList.remove('millistream-flash-down');
|
|
3933
4612
|
}
|
|
3934
4613
|
|
|
3935
4614
|
function milli_clearValuedFlash(widget, el, oldValue) {
|
|
3936
|
-
|
|
4615
|
+
// internal borde gå att bygga bort
|
|
3937
4616
|
var currentValue = MillistreamWidgetApi_getElementNumber(widget, el);
|
|
3938
4617
|
if (currentValue == oldValue || currentValue == 0) {
|
|
3939
4618
|
MillistreamWidgetApi_clearFlash(el);
|
|
@@ -3941,7 +4620,7 @@ function milli_clearValuedFlash(widget, el, oldValue) {
|
|
|
3941
4620
|
}
|
|
3942
4621
|
|
|
3943
4622
|
function MillistreamWidgetApi_flashElement(widget, el, newValue, oldValue) {
|
|
3944
|
-
|
|
4623
|
+
// internal
|
|
3945
4624
|
if (newValue == oldValue) return;
|
|
3946
4625
|
MillistreamWidgetApi_clearFlash(el);
|
|
3947
4626
|
if (newValue == '' || !newValue) return;
|
|
@@ -3960,11 +4639,14 @@ function MillistreamWidgetApi_flashElement(widget, el, newValue, oldValue) {
|
|
|
3960
4639
|
}
|
|
3961
4640
|
|
|
3962
4641
|
|
|
3963
|
-
|
|
4642
|
+
// numeriska funktioner
|
|
3964
4643
|
function MillistreamWidgetApi_isNumber(widget, testsubject) {
|
|
3965
4644
|
if (!testsubject) return;
|
|
3966
|
-
|
|
3967
|
-
|
|
4645
|
+
if(isNaN(testsubject)) {
|
|
4646
|
+
var n = testsubject.replace(widget.settings.decimalseparator, '.').split(widget.settings.thousandseparator).join('');
|
|
4647
|
+
return !isNaN(parseFloat(n)) && isFinite(n);
|
|
4648
|
+
}
|
|
4649
|
+
return !isNaN(parseFloat(testsubject)) && isFinite(testsubject);
|
|
3968
4650
|
}
|
|
3969
4651
|
|
|
3970
4652
|
function MillistreamWidgetApi_getNumDecimals(widget, value, current, validfields) {
|
|
@@ -3973,7 +4655,7 @@ function MillistreamWidgetApi_getNumDecimals(widget, value, current, validfields
|
|
|
3973
4655
|
if (value == null || MillistreamWidgetApi_isNumber(widget, value) == false) return current;
|
|
3974
4656
|
var parts = value.toString().split('.');
|
|
3975
4657
|
if (parts.length == 2) {
|
|
3976
|
-
while (parts[1].charAt(parts[1].length - 1) == "0") {
|
|
4658
|
+
while (parts[1].charAt(parts[1].length - 1) == "0") { // remove trailing zeros
|
|
3977
4659
|
parts[1] = parts[1].slice(0, -1);
|
|
3978
4660
|
}
|
|
3979
4661
|
return current > parts[1].length ? current : parts[1].length;
|
|
@@ -3982,7 +4664,7 @@ function MillistreamWidgetApi_getNumDecimals(widget, value, current, validfields
|
|
|
3982
4664
|
}
|
|
3983
4665
|
|
|
3984
4666
|
function MillistreamWidgetApi_getElementNumber(widget, el) {
|
|
3985
|
-
|
|
4667
|
+
// internal and Orderbook
|
|
3986
4668
|
var res = parseFloat(el.innerHTML.replace(widget.settings.decimalseparator, '.').split(widget.settings.thousandseparator).join(''));
|
|
3987
4669
|
if (!isNaN(parseFloat(res)) && isFinite(res)) return res;
|
|
3988
4670
|
return 0;
|
|
@@ -4013,7 +4695,7 @@ function MillistreamWidgetApi_colorCell(widget, element, info) {
|
|
|
4013
4695
|
MillistreamWidgetApi_setCellColor(widget, element, v);
|
|
4014
4696
|
}
|
|
4015
4697
|
} else
|
|
4016
|
-
if (widget.settings.controlcolumn || widget.settings.controlcolumn == 0) {
|
|
4698
|
+
if (widget.settings.controlcolumn || widget.settings.controlcolumn == 0) { // works for tables
|
|
4017
4699
|
if (widget.settings.stylecolumn === null) return;
|
|
4018
4700
|
var tr = element.parentNode;
|
|
4019
4701
|
while (tr.tagName.toLowerCase() != 'tr') {
|
|
@@ -4022,13 +4704,13 @@ function MillistreamWidgetApi_colorCell(widget, element, info) {
|
|
|
4022
4704
|
if (tr.cells.length > widget.settings.controlcolumn) {
|
|
4023
4705
|
v = MillistreamWidgetApi_getElementNumber(widget, tr.cells[widget.settings.controlcolumn]);
|
|
4024
4706
|
var el;
|
|
4025
|
-
if (widget.settings.stylecolumn && widget.settings.stylecolumn[0] == -1) {
|
|
4026
|
-
el = tr;
|
|
4707
|
+
if (widget.settings.stylecolumn && widget.settings.stylecolumn[0] == -1) { // color row
|
|
4708
|
+
el = tr; //element.parentNode;
|
|
4027
4709
|
MillistreamWidgetApi_setCellColor(widget, tr, v);
|
|
4028
4710
|
|
|
4029
4711
|
} else {
|
|
4030
4712
|
for (var s = 0; s < widget.settings.stylecolumn.length; s++) {
|
|
4031
|
-
el = tr.cells[widget.settings.stylecolumn[s]];
|
|
4713
|
+
el = tr.cells[widget.settings.stylecolumn[s]]; //element.parentNode.cells[widget.stylecolumn[s]];
|
|
4032
4714
|
if (el) {
|
|
4033
4715
|
MillistreamWidgetApi_setCellColor(widget, el, v);
|
|
4034
4716
|
}
|
|
@@ -4036,17 +4718,17 @@ function MillistreamWidgetApi_colorCell(widget, element, info) {
|
|
|
4036
4718
|
}
|
|
4037
4719
|
}
|
|
4038
4720
|
} else
|
|
4039
|
-
if (widget.settings.positiveclass && widget.settings.negativeclass) {
|
|
4721
|
+
if (widget.settings.positiveclass && widget.settings.negativeclass) { // non table elements
|
|
4040
4722
|
v = MillistreamWidgetApi_getElementNumber(widget, element);
|
|
4041
4723
|
MillistreamWidgetApi_setCellColor(widget, element, v);
|
|
4042
4724
|
}
|
|
4043
4725
|
}
|
|
4044
4726
|
|
|
4045
4727
|
function print_field(widget, element, field, value, overridedecimals) {
|
|
4046
|
-
|
|
4728
|
+
// internal and external
|
|
4047
4729
|
var f = parseInt(field);
|
|
4048
4730
|
var info = MillistreamWidgetApi_getColumnInfo(widget, f.toString());
|
|
4049
|
-
if (typeof value === 'undefined' || value == null || (!value && isNaN(value) == true)) {
|
|
4731
|
+
if (typeof value === 'undefined' || value == null || (!value && isNaN(value) == true)) { // kolla field?
|
|
4050
4732
|
if (info[4] & 16) {
|
|
4051
4733
|
value = '0.0';
|
|
4052
4734
|
} else {
|
|
@@ -4092,7 +4774,7 @@ function print_field(widget, element, field, value, overridedecimals) {
|
|
|
4092
4774
|
else
|
|
4093
4775
|
element.innerHTML = formatFactorNumber(value, widget.settings.factor, widget.settings.num_decimals, widget.settings.thousandseparator, widget.settings.decimalseparator);
|
|
4094
4776
|
} else if (info[4] & 4)
|
|
4095
|
-
element.innerHTML = formatNiceNumber(value, widget.settings.thousandseparator, widget.settings.decimalseparator, 0);
|
|
4777
|
+
element.innerHTML = formatNiceNumber(value, widget.settings.thousandseparator, widget.settings.decimalseparator, 0); // no decimals
|
|
4096
4778
|
else if (info[4] & 1 && overridedecimals)
|
|
4097
4779
|
element.innerHTML = formatNiceNumber(value, widget.settings.thousandseparator, widget.settings.decimalseparator, overridedecimals || widget.settings.num_decimals);
|
|
4098
4780
|
else {
|
|
@@ -4110,8 +4792,8 @@ function print_field(widget, element, field, value, overridedecimals) {
|
|
|
4110
4792
|
}
|
|
4111
4793
|
|
|
4112
4794
|
function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
4113
|
-
|
|
4114
|
-
|
|
4795
|
+
// internal and external
|
|
4796
|
+
// return array with MDF_F_FIELD,type,align, name var, overridable decimal bitwise [1 = override output,2 = can override,4 = no decimals,8 can be shortened to M, K etc], 16 = override NULL with 0 , 32 = can color diff
|
|
4115
4797
|
switch (name) {
|
|
4116
4798
|
case '222':
|
|
4117
4799
|
case 'accountsreceivable':
|
|
@@ -4202,7 +4884,7 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
|
4202
4884
|
return [232, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
|
|
4203
4885
|
case '404':
|
|
4204
4886
|
case 'd1':
|
|
4205
|
-
return [404, 'date', 'right', widget.get_lang_text(name) || name, 0];
|
|
4887
|
+
return [404, 'date', 'right', widget.get_lang_text(name) || name, 0]; // Security type
|
|
4206
4888
|
case '3':
|
|
4207
4889
|
case 'date':
|
|
4208
4890
|
return [3, 'date', 'right', widget.get_lang_text(name) || name, 0];
|
|
@@ -4456,10 +5138,10 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
|
4456
5138
|
return [229, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
|
|
4457
5139
|
case '395':
|
|
4458
5140
|
case 'n2':
|
|
4459
|
-
return [395, 'numeric', 'left', widget.get_lang_text(name) || name, 0];
|
|
5141
|
+
return [395, 'numeric', 'left', widget.get_lang_text(name) || name, 0]; // Security type
|
|
4460
5142
|
case '396':
|
|
4461
5143
|
case 'n3':
|
|
4462
|
-
return [396, 'numeric', 'left', widget.get_lang_text(name) || name, 0];
|
|
5144
|
+
return [396, 'numeric', 'left', widget.get_lang_text(name) || name, 0]; // Security type
|
|
4463
5145
|
case '22':
|
|
4464
5146
|
case 'name':
|
|
4465
5147
|
return [22, 'string', 'left', widget.get_lang_text(name) || name, 0];
|
|
@@ -4471,10 +5153,10 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
|
4471
5153
|
return [138, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
|
|
4472
5154
|
case '48':
|
|
4473
5155
|
case 'newsid':
|
|
4474
|
-
return [48, 'string', 'left', 'newsid', 0];
|
|
5156
|
+
return [48, 'string', 'left', 'newsid', 0]; // hardoded should not be used by any display
|
|
4475
5157
|
case 'newstype':
|
|
4476
5158
|
case '86':
|
|
4477
|
-
return [86, 'string', 'left', 'newstype', 0];
|
|
5159
|
+
return [86, 'string', 'left', 'newstype', 0]; // hardoded should not be used by any display
|
|
4478
5160
|
case '219':
|
|
4479
5161
|
case 'noncurrentasset':
|
|
4480
5162
|
return [219, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
|
|
@@ -4534,13 +5216,13 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
|
4534
5216
|
return [98, 'string', 'left', widget.get_lang_text(name) || name, 0];
|
|
4535
5217
|
case '180':
|
|
4536
5218
|
case 's3':
|
|
4537
|
-
return [180, 'string', 'left', widget.get_lang_text(name) || name, 0];
|
|
5219
|
+
return [180, 'string', 'left', widget.get_lang_text(name) || name, 0]; // Position
|
|
4538
5220
|
case '181':
|
|
4539
5221
|
case 's4':
|
|
4540
|
-
return [181, 'string', 'left', widget.get_lang_text(name) || name, 0];
|
|
5222
|
+
return [181, 'string', 'left', widget.get_lang_text(name) || name, 0]; // Position
|
|
4541
5223
|
case '393':
|
|
4542
5224
|
case 's10':
|
|
4543
|
-
return [393, 'string', 'left', widget.get_lang_text(name) || name, 0];
|
|
5225
|
+
return [393, 'string', 'left', widget.get_lang_text(name) || name, 0]; // comment
|
|
4544
5226
|
case '127':
|
|
4545
5227
|
case 'sales':
|
|
4546
5228
|
return [127, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
|
|
@@ -4577,7 +5259,7 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
|
4577
5259
|
case '227':
|
|
4578
5260
|
case 'totalassets':
|
|
4579
5261
|
return [227, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
|
|
4580
|
-
case '1023':
|
|
5262
|
+
case '1023': // TODO, define this with correct value
|
|
4581
5263
|
case 'totalnumberofshares':
|
|
4582
5264
|
return [1023, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
|
|
4583
5265
|
case '233':
|
|
@@ -4626,7 +5308,7 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
|
4626
5308
|
case 'vega':
|
|
4627
5309
|
return [703, 'numeric', 'right', widget.get_lang_text(name) || name, 0];
|
|
4628
5310
|
|
|
4629
|
-
|
|
5311
|
+
// brokerstats
|
|
4630
5312
|
case '3000':
|
|
4631
5313
|
case 'boughtquantity':
|
|
4632
5314
|
return [3000, 'numeric', 'right', widget.get_lang_text(name) || name, 4];
|
|
@@ -4814,7 +5496,7 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
|
4814
5496
|
case '3060':
|
|
4815
5497
|
case 'soldturnoverytd':
|
|
4816
5498
|
return [3060, 'numeric', 'left', widget.get_lang_text(name) || name, 4];
|
|
4817
|
-
|
|
5499
|
+
// key ratios egen definerade
|
|
4818
5500
|
case 'per_last':
|
|
4819
5501
|
case '3100':
|
|
4820
5502
|
return [3100, 'numeric', 'right', widget.get_lang_text(name) || name, 0];
|
|
@@ -4935,7 +5617,7 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
|
4935
5617
|
case 'latestreport':
|
|
4936
5618
|
case '3140':
|
|
4937
5619
|
return [3140, 'date', 'right', widget.get_lang_text(name) || name, 0];
|
|
4938
|
-
|
|
5620
|
+
// basicdata join fields
|
|
4939
5621
|
case 'fundcompanyname':
|
|
4940
5622
|
case '3200':
|
|
4941
5623
|
return [3200, 'string', 'left', widget.get_lang_text(name) || name, 0];
|
|
@@ -4954,17 +5636,17 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
|
4954
5636
|
case '3205':
|
|
4955
5637
|
case 'underlyingsymbol':
|
|
4956
5638
|
return [3204, 'string', 'left', widget.get_lang_text(name) || name, 0];
|
|
4957
|
-
case '3206':
|
|
5639
|
+
case '3206': // tmcwatch
|
|
4958
5640
|
case 'multiplier':
|
|
4959
5641
|
return [3206, 'string', 'left', widget.get_lang_text(name) || name, 0];
|
|
4960
|
-
case '3207':
|
|
5642
|
+
case '3207': // tmcwach
|
|
4961
5643
|
case 'type':
|
|
4962
5644
|
return [3207, 'string', 'left', widget.get_lang_text(name) || name, 0];
|
|
4963
|
-
case '3208':
|
|
5645
|
+
case '3208': // tmcwach
|
|
4964
5646
|
case 'direction':
|
|
4965
5647
|
return [3208, 'string', 'left', widget.get_lang_text(name) || name, 0];
|
|
4966
5648
|
|
|
4967
|
-
|
|
5649
|
+
// optionwatch
|
|
4968
5650
|
case '3300':
|
|
4969
5651
|
case 'iv30d':
|
|
4970
5652
|
case 'ivXXd':
|
|
@@ -5007,8 +5689,8 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
|
5007
5689
|
}
|
|
5008
5690
|
}
|
|
5009
5691
|
|
|
5010
|
-
function set_hashed_element(widget, insref, info, json, num_dec) {
|
|
5011
|
-
|
|
5692
|
+
function set_hashed_element(widget, insref, info, json, num_dec) { // called from push
|
|
5693
|
+
// external : list
|
|
5012
5694
|
var key = insref + '_' + info[0];
|
|
5013
5695
|
var arr = widget.cell_map.get(key);
|
|
5014
5696
|
if (arr !== undefined) {
|
|
@@ -5018,9 +5700,9 @@ function set_hashed_element(widget, insref, info, json, num_dec) {
|
|
|
5018
5700
|
}
|
|
5019
5701
|
}
|
|
5020
5702
|
|
|
5021
|
-
|
|
5703
|
+
// Create Element functions
|
|
5022
5704
|
function MillistreamWidgetApi_addElementToMap(insref, field, element, widget) {
|
|
5023
|
-
|
|
5705
|
+
// internal
|
|
5024
5706
|
if (insref && field && widget && widget.cell_map) {
|
|
5025
5707
|
var key = insref + '_' + field;
|
|
5026
5708
|
var arr = widget.cell_map.get(key);
|
|
@@ -5036,7 +5718,7 @@ function MillistreamWidgetApi_addElementToMap(insref, field, element, widget) {
|
|
|
5036
5718
|
}
|
|
5037
5719
|
|
|
5038
5720
|
function MillistreamWidgetApi_addElement(widget, el, cl, parent, field, value, overridedecimals) {
|
|
5039
|
-
|
|
5721
|
+
// external
|
|
5040
5722
|
var element = document.createElement(el);
|
|
5041
5723
|
if (cl)
|
|
5042
5724
|
element.setAttribute('class', cl);
|
|
@@ -5059,6 +5741,7 @@ function MillistreamWidgetApi_addTableCell2(widget, key, cl, parent, json, decim
|
|
|
5059
5741
|
if (cl) td.setAttribute('class', cl);
|
|
5060
5742
|
if (info[1] == 'numeric' && json && json[key]) {
|
|
5061
5743
|
var v = 0;
|
|
5744
|
+
if(!isNaN(json[key])) json[key] = json[key].toString();
|
|
5062
5745
|
var res = parseFloat(json[key].replace(widget.settings.decimalseparator, '.').split(widget.settings.thousandseparator).join(''));
|
|
5063
5746
|
if (!isNaN(parseFloat(res)) && isFinite(res)) v = res;
|
|
5064
5747
|
/*if (typeof widget.settings.positiveclass === 'string' && typeof widget.settings.negativeclass) {
|
|
@@ -5119,7 +5802,7 @@ function MillistreamWidgetApi_addTableCell(widget, key, cl, parent, json, decima
|
|
|
5119
5802
|
widget.settings.link_field.forEach(function(element) {
|
|
5120
5803
|
hrefparam[element] = json[element];
|
|
5121
5804
|
});
|
|
5122
|
-
if (info[0] == 1) {
|
|
5805
|
+
if (info[0] == 1) { // headline, borde inte behövas i list
|
|
5123
5806
|
td.onclick = function(e) {
|
|
5124
5807
|
hrefparam.event = e;
|
|
5125
5808
|
hrefparam.source = widget;
|
|
@@ -5235,7 +5918,7 @@ function fabs(value) {
|
|
|
5235
5918
|
}
|
|
5236
5919
|
|
|
5237
5920
|
function zeroPad(number, width) {
|
|
5238
|
-
|
|
5921
|
+
//internal
|
|
5239
5922
|
if (number <= 9.9999999 * Math.pow(10, width)) return ("0000000" + number).slice(-width);
|
|
5240
5923
|
return number;
|
|
5241
5924
|
}
|
|
@@ -5280,7 +5963,7 @@ function formatNiceNumber(y, thousandSeparator, decimalSeparator, precision, add
|
|
|
5280
5963
|
}
|
|
5281
5964
|
|
|
5282
5965
|
function formatDate(date, format, widget) {
|
|
5283
|
-
|
|
5966
|
+
// internal
|
|
5284
5967
|
var timeStamp, mon, day;
|
|
5285
5968
|
if (format == 'yyyy-mm-dd') {
|
|
5286
5969
|
timeStamp = new Date(date);
|
|
@@ -5294,66 +5977,66 @@ function formatDate(date, format, widget) {
|
|
|
5294
5977
|
day = timeStamp.getDate();
|
|
5295
5978
|
return timeStamp.getFullYear() % 100 + '-' + (mon <= 9 ? '0' + mon : mon) + '-' + (day <= 9 ? '0' + day : day);
|
|
5296
5979
|
}
|
|
5297
|
-
if (format == 'b dd') {
|
|
5980
|
+
if (format == 'b dd') { // Jan 01
|
|
5298
5981
|
timeStamp = new Date(date);
|
|
5299
5982
|
mon = timeStamp.toDateString().split(' ');
|
|
5300
5983
|
day = timeStamp.getDate();
|
|
5301
5984
|
return mon[1] + ' ' + (day <= 9 ? '0' + day : day);
|
|
5302
5985
|
}
|
|
5303
|
-
if (format == 'b dd yyyy') {
|
|
5986
|
+
if (format == 'b dd yyyy') { // Jan 01 2017
|
|
5304
5987
|
timeStamp = new Date(date);
|
|
5305
5988
|
mon = timeStamp.toDateString().split(' ');
|
|
5306
5989
|
day = timeStamp.getDate();
|
|
5307
5990
|
return mon[1] + ' ' + (day <= 9 ? '0' + day : day) + ' ' + timeStamp.getFullYear();
|
|
5308
5991
|
}
|
|
5309
|
-
if (format == 'dd/mm') {
|
|
5992
|
+
if (format == 'dd/mm') { // Jan 01 2017
|
|
5310
5993
|
timeStamp = new Date(date);
|
|
5311
5994
|
mon = timeStamp.getMonth() + 1;
|
|
5312
5995
|
day = timeStamp.getDate();
|
|
5313
5996
|
return (day <= 9 ? '0' + day : day) + '/' + (mon <= 9 ? '0' + mon : mon);
|
|
5314
5997
|
}
|
|
5315
|
-
if (format == 'd/m') {
|
|
5998
|
+
if (format == 'd/m') { // Jan 01 2017
|
|
5316
5999
|
timeStamp = new Date(date);
|
|
5317
6000
|
return (timeStamp.getDate() + '/' + (timeStamp.getMonth() + 1));
|
|
5318
6001
|
}
|
|
5319
6002
|
if (format == 'd mmm yyyy') {
|
|
5320
6003
|
timeStamp = new Date(date);
|
|
5321
|
-
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3);
|
|
6004
|
+
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3); // lang....
|
|
5322
6005
|
day = timeStamp.getDate();
|
|
5323
6006
|
return day + ' ' + mon + ' ' + timeStamp.getFullYear();
|
|
5324
6007
|
}
|
|
5325
6008
|
if (format == 'dd mmm yyyy') {
|
|
5326
6009
|
timeStamp = new Date(date);
|
|
5327
|
-
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3);
|
|
6010
|
+
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3); // lang....
|
|
5328
6011
|
day = timeStamp.getDate();
|
|
5329
6012
|
return (day <= 9 ? '0' + day : day) + ' ' + mon + ' ' + timeStamp.getFullYear();
|
|
5330
6013
|
}
|
|
5331
6014
|
if (format == 'dd mmm') {
|
|
5332
6015
|
timeStamp = new Date(date);
|
|
5333
|
-
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3);
|
|
6016
|
+
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3); // lang....
|
|
5334
6017
|
day = timeStamp.getDate();
|
|
5335
6018
|
return (day <= 9 ? '0' + day : day) + ' ' + mon;
|
|
5336
6019
|
}
|
|
5337
6020
|
if (format == 'd mmm') {
|
|
5338
6021
|
timeStamp = new Date(date);
|
|
5339
|
-
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3);
|
|
6022
|
+
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3); // lang....
|
|
5340
6023
|
day = timeStamp.getDate();
|
|
5341
6024
|
return day + ' ' + mon;
|
|
5342
6025
|
}
|
|
5343
6026
|
if (format == 'mmm yyyy') {
|
|
5344
6027
|
timeStamp = new Date(date);
|
|
5345
|
-
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3);
|
|
6028
|
+
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3); // lang....
|
|
5346
6029
|
timeStamp = mon + ' ' + timeStamp.getFullYear();
|
|
5347
6030
|
return timeStamp;
|
|
5348
6031
|
}
|
|
5349
6032
|
if (format == 'mmm yy') {
|
|
5350
6033
|
timeStamp = new Date(date);
|
|
5351
|
-
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3);
|
|
6034
|
+
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3); // lang
|
|
5352
6035
|
timeStamp = mon + ' ' + (timeStamp.getFullYear() % 100 < 9 ? '0' + timeStamp.getFullYear() % 100 : timeStamp.getFullYear() % 100);
|
|
5353
6036
|
return timeStamp;
|
|
5354
6037
|
}
|
|
5355
6038
|
|
|
5356
|
-
|
|
6039
|
+
// default yyyy-mm-dd
|
|
5357
6040
|
timeStamp = new Date(date);
|
|
5358
6041
|
mon = timeStamp.getMonth() + 1;
|
|
5359
6042
|
day = timeStamp.getDate();
|
|
@@ -5361,7 +6044,7 @@ function formatDate(date, format, widget) {
|
|
|
5361
6044
|
}
|
|
5362
6045
|
|
|
5363
6046
|
function formatTime(value, format) {
|
|
5364
|
-
|
|
6047
|
+
// internal
|
|
5365
6048
|
if (typeof value !== 'string') return "";
|
|
5366
6049
|
var datetime = new Date();
|
|
5367
6050
|
var tz_offset = datetime.getTimezoneOffset();
|
|
@@ -5438,7 +6121,10 @@ Number.prototype.countDecimals = function() {
|
|
|
5438
6121
|
//if (isNaN(this.valueOf()) || Math.floor(this.valueOf()) === this.valueOf()) return 0;
|
|
5439
6122
|
if (isNaN(this.valueOf())) return 0;
|
|
5440
6123
|
if (Math.floor(this.valueOf()) === this.valueOf()) return 0;
|
|
5441
|
-
|
|
6124
|
+
var parts = this.toString().split(".");
|
|
6125
|
+
if (parts.length > 1) return parts[1].length;
|
|
6126
|
+
return 0;
|
|
6127
|
+
//return this.toString().split(".")[1].length || 0;
|
|
5442
6128
|
};
|
|
5443
6129
|
|
|
5444
6130
|
|
|
@@ -5590,7 +6276,7 @@ function MillistreamWidgetApi_scrollIntoView(scrollarea, elem, xalign, yalign) {
|
|
|
5590
6276
|
scrollarea.scrollLeft = elem.offsetLeft - scrollarea.getBoundingClientRect().width / 2;
|
|
5591
6277
|
}
|
|
5592
6278
|
|
|
5593
|
-
|
|
6279
|
+
// scrollIntoView : replace this, breaks apps
|
|
5594
6280
|
}
|
|
5595
6281
|
|
|
5596
6282
|
var MillistreamWidgetSettings = {
|
|
@@ -5610,9 +6296,9 @@ function MillistreamWidgetStreamingApi(settings) {
|
|
|
5610
6296
|
server: 'wss://stage.millistream.com:8900',
|
|
5611
6297
|
alarmClient: null
|
|
5612
6298
|
};
|
|
5613
|
-
var m_requestid = 1;
|
|
6299
|
+
var m_requestid = 1; // 0 is invalid
|
|
5614
6300
|
var m_socket = null;
|
|
5615
|
-
var m_requests = [];
|
|
6301
|
+
var m_requests = []; // queued requests not sent
|
|
5616
6302
|
var m_requestcallbacks = new Map();
|
|
5617
6303
|
|
|
5618
6304
|
|
|
@@ -5645,7 +6331,7 @@ function MillistreamWidgetStreamingApi(settings) {
|
|
|
5645
6331
|
req = new Object({
|
|
5646
6332
|
"widget": widget,
|
|
5647
6333
|
});
|
|
5648
|
-
m_requestcallbacks.set(requestid.toString(), req);
|
|
6334
|
+
m_requestcallbacks.set(requestid.toString(), req); // this requestid will be forarded to this widget
|
|
5649
6335
|
}
|
|
5650
6336
|
var request = '';
|
|
5651
6337
|
if (MillistreamWidgetApi_isObjectEmpty(widget.unsubscriptions) == false) {
|
|
@@ -5707,7 +6393,7 @@ function MillistreamWidgetStreamingApi(settings) {
|
|
|
5707
6393
|
|
|
5708
6394
|
|
|
5709
6395
|
widget.unsubscriptions.type = 'insrefs';
|
|
5710
|
-
widget.unsubscriptions.insrefs = insrefs.slice(0);
|
|
6396
|
+
widget.unsubscriptions.insrefs = insrefs.slice(0); // copy array
|
|
5711
6397
|
widget.unsubscriptions.messagetypes = widget.settings.messagetypes;
|
|
5712
6398
|
widget.unsubscriptions.requestid = requestid;
|
|
5713
6399
|
|
|
@@ -5720,7 +6406,7 @@ function MillistreamWidgetStreamingApi(settings) {
|
|
|
5720
6406
|
|
|
5721
6407
|
function reconnect() {
|
|
5722
6408
|
if (!m_socket.CLOSED) {
|
|
5723
|
-
|
|
6409
|
+
//console.log('not closed');
|
|
5724
6410
|
return;
|
|
5725
6411
|
}
|
|
5726
6412
|
m_requests.forEach(function(request) {
|
|
@@ -5739,21 +6425,21 @@ function MillistreamWidgetStreamingApi(settings) {
|
|
|
5739
6425
|
try {
|
|
5740
6426
|
m_socket = new WebSocket(_this.settings.server);
|
|
5741
6427
|
m_socket.onopen = function() {
|
|
5742
|
-
(
|
|
6428
|
+
console.log('Connected to millistream push'); /*RemoveLogging:skip*/
|
|
5743
6429
|
if (m_requests.length > 0) {
|
|
5744
6430
|
m_requests.forEach(function(request) {
|
|
5745
6431
|
if (request.send == 0) {
|
|
5746
|
-
|
|
6432
|
+
//console.log('rerequest:', request.request);
|
|
5747
6433
|
m_socket.send('{ "token":"' + _this.settings.token + '",' + request.request);
|
|
5748
6434
|
}
|
|
5749
6435
|
});
|
|
5750
6436
|
}
|
|
5751
6437
|
};
|
|
5752
6438
|
m_socket.onerror = function() {
|
|
5753
|
-
()
|
|
6439
|
+
console.log('Error, disconnected'); /*RemoveLogging:skip*/
|
|
5754
6440
|
};
|
|
5755
6441
|
m_socket.onclose = function() {
|
|
5756
|
-
()
|
|
6442
|
+
console.log('Disconnected'); /*RemoveLogging:skip*/
|
|
5757
6443
|
reconnect();
|
|
5758
6444
|
};
|
|
5759
6445
|
|
|
@@ -5762,9 +6448,9 @@ function MillistreamWidgetStreamingApi(settings) {
|
|
|
5762
6448
|
try {
|
|
5763
6449
|
jsondata = JSON.parse(msg.data);
|
|
5764
6450
|
} catch (e) {
|
|
5765
|
-
(
|
|
6451
|
+
console.log('invalid data', msg.data); /*RemoveLogging:skip*/
|
|
5766
6452
|
}
|
|
5767
|
-
|
|
6453
|
+
//console.log(JSON.stringify(jsondata));
|
|
5768
6454
|
if (typeof jsondata.instruments !== 'undefined') {
|
|
5769
6455
|
for (var s = 0; s < jsondata.instruments.length; s++) {
|
|
5770
6456
|
var insref = jsondata.instruments[s].insref;
|
|
@@ -5790,22 +6476,23 @@ function MillistreamWidgetStreamingApi(settings) {
|
|
|
5790
6476
|
if (_this.settings.statusCallback !== null) _this.settings.statusCallback(jsondata);
|
|
5791
6477
|
} else
|
|
5792
6478
|
if (typeof jsondata.alarm !== 'undefined') {
|
|
5793
|
-
(
|
|
6479
|
+
console.log('Alarm: ' + JSON.stringify(jsondata));
|
|
5794
6480
|
if (null != _this.settings.alarmClient) {
|
|
5795
6481
|
_this.settings.alarmClient(jsondata);
|
|
5796
6482
|
}
|
|
5797
6483
|
|
|
5798
6484
|
} else
|
|
5799
|
-
()
|
|
6485
|
+
console.log(JSON.stringify(jsondata)); /*RemoveLogging:skip*/
|
|
5800
6486
|
};
|
|
5801
6487
|
} catch (exception) {
|
|
5802
|
-
(
|
|
6488
|
+
console.log('Exception error: ' + exception); /*RemoveLogging:skip*/
|
|
5803
6489
|
reconnect();
|
|
5804
6490
|
}
|
|
5805
6491
|
}
|
|
5806
6492
|
milli_stream_connect();
|
|
5807
6493
|
}
|
|
5808
6494
|
exports.Milli_Chart = Milli_Chart;
|
|
6495
|
+
exports.Milli_OptionsList = Milli_OptionsList;
|
|
5809
6496
|
exports.MillistreamWidgetSettings = MillistreamWidgetSettings;
|
|
5810
6497
|
exports.formatDate = formatDate;
|
|
5811
6498
|
exports.MillistreamWidgetStreamingApi = MillistreamWidgetStreamingApi;
|