@millistream/millistream-widgets 1.0.22 → 1.0.24
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 +523 -471
- 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,24 @@ 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
|
-
|
|
3013
|
+
// Size functions
|
|
2976
3014
|
|
|
2977
3015
|
function setChartSize() {
|
|
2978
3016
|
var offset = 0;
|
|
3017
|
+
// set canvas size to 0 so it does not prevent the div to resize
|
|
3018
|
+
_this.settings.target.style.height = '0px';
|
|
3019
|
+
_this.settings.target.style.width = '0px';
|
|
2979
3020
|
if (_this.settings.target.parentNode.classList.contains('chartcontainer')) {
|
|
2980
3021
|
offset = _this.settings.target.getBoundingClientRect().top - _this.settings.target.parentNode.getBoundingClientRect().top;
|
|
2981
3022
|
}
|
|
2982
3023
|
_this.settings.target.style.height = (_this.settings.target.parentNode.offsetHeight - offset) + 'px';
|
|
2983
3024
|
_this.settings.target.style.width = _this.settings.target.parentNode.offsetWidth + 'px';
|
|
2984
|
-
|
|
2985
|
-
|
|
3025
|
+
//_this.settings.target.style.height = (_this.settings.target.parentNode.offsetHeight - offset) * window.devicePixelRatio + 'px';
|
|
3026
|
+
//_this.settings.target.style.width = _this.settings.target.parentNode.offsetWidth * window.devicePixelRatio + 'px';
|
|
2986
3027
|
m_canvas.setRect(_this.settings.target.offsetHeight, _this.settings.target.offsetWidth);
|
|
2987
3028
|
}
|
|
2988
3029
|
|
|
@@ -2991,7 +3032,7 @@ function Milli_Chart(settings) {
|
|
|
2991
3032
|
m_resizing.height = m_canvas.height;
|
|
2992
3033
|
};
|
|
2993
3034
|
|
|
2994
|
-
_this.
|
|
3035
|
+
_this.resizing = function(e, ui) {
|
|
2995
3036
|
var diff = (m_resizing.height - m_canvas.height) / m_canvas.height * 100;
|
|
2996
3037
|
if (Math.abs(diff) > 1) {
|
|
2997
3038
|
setChartSize();
|
|
@@ -3002,8 +3043,8 @@ function Milli_Chart(settings) {
|
|
|
3002
3043
|
diff = (m_resizing.width - m_canvas.width) / m_canvas.width * 100;
|
|
3003
3044
|
if (Math.abs(diff) > 1) {
|
|
3004
3045
|
setChartSize();
|
|
3005
|
-
|
|
3006
|
-
|
|
3046
|
+
//m_canvas.height = Math.floor(_this.settings.target.offsetHeight * window.devicePixelRatio);
|
|
3047
|
+
//m_canvas.width = Math.floor(_this.settings.target.offsetWidth * window.devicePixelRatio);
|
|
3007
3048
|
m_resizing.width = m_canvas.width;
|
|
3008
3049
|
m_resizing.height = m_canvas.height;
|
|
3009
3050
|
_this.drawChart();
|
|
@@ -3035,11 +3076,11 @@ function Milli_Chart(settings) {
|
|
|
3035
3076
|
m_canvas = MillistreamWidgetApi_addElement(_this, 'canvas', 'millistream-chart-canvas', _this.settings.target);
|
|
3036
3077
|
m_ctx = m_canvas.getContext("2d");
|
|
3037
3078
|
setChartSize();
|
|
3038
|
-
m_canvas.addEventListener('mousemove', onMouseMove, false);
|
|
3079
|
+
m_canvas.addEventListener('mousemove', onMouseMove, false); // disable while loading and enable on drawReady
|
|
3039
3080
|
m_canvas.addEventListener('mouseout', onMouseOut, false);
|
|
3040
3081
|
m_canvas.style.cursor = "crosshair";
|
|
3041
3082
|
m_canvas.onmousedown = (function(evt) {
|
|
3042
|
-
if (
|
|
3083
|
+
if (evt.which != 1) return; // ignore right and middle
|
|
3043
3084
|
if (_this.settings.enablezoom == false) return;
|
|
3044
3085
|
if (m_datapoints.length == 0) return;
|
|
3045
3086
|
var rect = m_canvas.getBoundingClientRect();
|
|
@@ -3065,7 +3106,7 @@ function Milli_Chart(settings) {
|
|
|
3065
3106
|
clearZoom();
|
|
3066
3107
|
return;
|
|
3067
3108
|
}
|
|
3068
|
-
if (Math.abs(x - m_zoom.mousedown.pos) > 5) {
|
|
3109
|
+
if (Math.abs(x - m_zoom.mousedown.pos) > 5) { // only handle zoom with 5 pixels width
|
|
3069
3110
|
var i;
|
|
3070
3111
|
for (i = m_datapoints.length - 1; i > 0; i--) {
|
|
3071
3112
|
if (x >= m_datapoints[i].x) {
|
|
@@ -3082,7 +3123,7 @@ function Milli_Chart(settings) {
|
|
|
3082
3123
|
m_zoom.mousedown.pos = 0;
|
|
3083
3124
|
m_zoom.mousedown.i = 0;
|
|
3084
3125
|
if (m_zoom.mousedown.oldtimestamp != null) {
|
|
3085
|
-
m_zoom.mousedown.timestamp = m_zoom.mousedown.oldtimestamp;
|
|
3126
|
+
m_zoom.mousedown.timestamp = m_zoom.mousedown.oldtimestamp; // so we do not unzoom if zoomed
|
|
3086
3127
|
m_zoom.mousedown.oldtimestamp = null;
|
|
3087
3128
|
} else
|
|
3088
3129
|
m_zoom.mousedown.timestamp = null;
|
|
@@ -3129,12 +3170,15 @@ function Milli_Chart(settings) {
|
|
|
3129
3170
|
if (instr.pricetype == 'price' || instr.pricetype == 'nav') {
|
|
3130
3171
|
if (typeof json['148'] !== 'undefined') {
|
|
3131
3172
|
instr.closeprice1d = parseFloat(json['148']);
|
|
3173
|
+
update = true;
|
|
3132
3174
|
}
|
|
3133
3175
|
} else
|
|
3134
3176
|
if (typeof json['262'] !== 'undefined') {
|
|
3135
|
-
instr.closeprice1d = parseFloat(json['
|
|
3177
|
+
instr.closeprice1d = parseFloat(json['262']);
|
|
3178
|
+
update = true;
|
|
3136
3179
|
}
|
|
3137
3180
|
}
|
|
3181
|
+
var timestamp;
|
|
3138
3182
|
if (mref == 'quote') {
|
|
3139
3183
|
if (instr.history.length == 0) return;
|
|
3140
3184
|
if (json['3'] && !isToday(new Date(json['3']))) return;
|
|
@@ -3143,9 +3187,12 @@ function Milli_Chart(settings) {
|
|
|
3143
3187
|
instr.quotedate = new Date(json['3']).getTime();
|
|
3144
3188
|
instr.quotedate -= instr.quotedate % 86400000;
|
|
3145
3189
|
}
|
|
3190
|
+
if (json['4']) {
|
|
3191
|
+
instr.quotetime = ((parseInt(json[4]) * 3600) + (parseInt(json[4].substring(3, 5)) * 60) + parseInt(json[4].substring(6, 8))) * 1000;
|
|
3192
|
+
}
|
|
3146
3193
|
var price = undefined;
|
|
3147
3194
|
var quantity = undefined;
|
|
3148
|
-
|
|
3195
|
+
timestamp = new Date().getTime();
|
|
3149
3196
|
timestamp -= timestamp % 86400000;
|
|
3150
3197
|
var obj = instr.history[instr.history.length - 1];
|
|
3151
3198
|
if (instr.pricetype == 'yield') {
|
|
@@ -3172,31 +3219,31 @@ function Milli_Chart(settings) {
|
|
|
3172
3219
|
if (_this.scaleinfoY.type == 'history') update = true;
|
|
3173
3220
|
} else {
|
|
3174
3221
|
if (json['3'] && json['36'] && (json['12'] || json['201'])) {
|
|
3175
|
-
|
|
3222
|
+
timestamp = new Date(json['3'] + 'T' + json['36'].substring(0, 6) + '00' + 'Z').getTime();
|
|
3176
3223
|
var data = instr.hashmap.get(timestamp);
|
|
3177
3224
|
if (typeof data === 'undefined') {
|
|
3178
3225
|
data = {};
|
|
3179
|
-
|
|
3226
|
+
//data.tradereference = json['14'];
|
|
3180
3227
|
data.timestamp = timestamp;
|
|
3181
3228
|
calcAnalyizis = true;
|
|
3182
3229
|
if (instr.pricetype == 'price') {
|
|
3183
3230
|
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']);
|
|
3231
|
+
data.price = parseFloat(json['12']); // eller 201 för tradeyield
|
|
3232
|
+
data.open = parseFloat(json['12']); // eller 201 för tradeyield
|
|
3233
|
+
data.high = parseFloat(json['12']); // eller 201 för tradeyield
|
|
3234
|
+
data.low = parseFloat(json['12']); // eller 201 för tradeyield
|
|
3188
3235
|
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']);
|
|
3236
|
+
} else if (instr.pricetype == 'yield') {
|
|
3237
|
+
data.price = parseFloat(json['201']); // eller 201 för tradeyield
|
|
3238
|
+
data.open = parseFloat(json['201']); // eller 201 för tradeyield
|
|
3239
|
+
data.high = parseFloat(json['201']); // eller 201 för tradeyield
|
|
3240
|
+
data.low = parseFloat(json['201']); // eller 201 för tradeyield
|
|
3194
3241
|
data.quantity = typeof json['13'] === 'undefined' ? 0 : parseInt(json['13']);
|
|
3195
3242
|
update = true;
|
|
3196
3243
|
}
|
|
3197
3244
|
if (update) {
|
|
3198
3245
|
if (instr.trades.length != 0 && data.timestamp < instr.trades[instr.trades.length - 1].timestamp) {
|
|
3199
|
-
|
|
3246
|
+
// TODO console.log("pushtrade is older than last trade ignoring, should file it on correct postition");
|
|
3200
3247
|
} else
|
|
3201
3248
|
instr.hashmap.set(data.timestamp, data);
|
|
3202
3249
|
instr.trades.push(data);
|
|
@@ -3205,24 +3252,24 @@ function Milli_Chart(settings) {
|
|
|
3205
3252
|
if (instr.pricetype == 'price') {
|
|
3206
3253
|
if (data.price != parseFloat(json['12']))
|
|
3207
3254
|
calcAnalyizis = true;
|
|
3208
|
-
data.price = parseFloat(json['12']);
|
|
3255
|
+
data.price = parseFloat(json['12']); // eller 201 för tradeyield
|
|
3209
3256
|
data.quantity += typeof json['13'] === 'undefined' ? 0 : parseInt(json['13']);
|
|
3210
3257
|
if (_this.scaleinfoY.type == 'trades') update = true;
|
|
3211
3258
|
} else {
|
|
3212
|
-
if (instr.pricetype == '
|
|
3259
|
+
if (instr.pricetype == 'yield') {
|
|
3213
3260
|
if (data.price != parseFloat(json['201']))
|
|
3214
3261
|
calcAnalyizis = true;
|
|
3215
|
-
data.price = parseFloat(json['201']);
|
|
3262
|
+
data.price = parseFloat(json['201']); // eller 201 för tradeyield
|
|
3216
3263
|
data.quantity += typeof json['13'] === 'undefined' ? 0 : parseInt(json['13']);
|
|
3217
3264
|
if (_this.scaleinfoY.type == 'trades') update = true;
|
|
3218
3265
|
}
|
|
3219
|
-
|
|
3266
|
+
// TODo: updatera med quantity, open , high,low osv?
|
|
3220
3267
|
}
|
|
3221
3268
|
}
|
|
3222
3269
|
}
|
|
3223
3270
|
if (calcAnalyizis && insref == _this.instruments[0].insref) {
|
|
3224
3271
|
for (var i = 0; i < _this.settings.indicators.length; i++) {
|
|
3225
|
-
|
|
3272
|
+
//for (const [key, a] of m_analyzisMethod.entries()) {
|
|
3226
3273
|
switch (_this.settings.indicators[i].method) {
|
|
3227
3274
|
case 'sma':
|
|
3228
3275
|
_this.settings.indicators[i].trades = [];
|
|
@@ -3237,7 +3284,7 @@ function Milli_Chart(settings) {
|
|
|
3237
3284
|
_this.settings.indicators[i].trades = bollingerBands(_this.instruments[0].trades, _this.settings.indicators[i].method_length, _this.settings.indicators[i].stddev | 2);
|
|
3238
3285
|
break;
|
|
3239
3286
|
default:
|
|
3240
|
-
|
|
3287
|
+
// draw custom added?
|
|
3241
3288
|
break;
|
|
3242
3289
|
}
|
|
3243
3290
|
}
|
|
@@ -3246,18 +3293,19 @@ function Milli_Chart(settings) {
|
|
|
3246
3293
|
_this.drawChart();
|
|
3247
3294
|
}
|
|
3248
3295
|
return;
|
|
3249
|
-
}
|
|
3250
|
-
}
|
|
3296
|
+
}
|
|
3297
|
+
};
|
|
3251
3298
|
|
|
3252
|
-
|
|
3299
|
+
// used by trader
|
|
3253
3300
|
_this.exportData = function() {
|
|
3254
3301
|
let ret = [];
|
|
3255
|
-
|
|
3302
|
+
var i;
|
|
3303
|
+
var date, datestr;
|
|
3256
3304
|
if (_this.scaleinfoY.type == 'trades') {
|
|
3257
3305
|
if (_this.instruments.length > 0) {
|
|
3258
|
-
for (
|
|
3259
|
-
|
|
3260
|
-
|
|
3306
|
+
for (i = 0; i < _this.instruments[0].trades.length; i++) {
|
|
3307
|
+
date = new Date(_this.instruments[0].trades[i].timestamp - new Date().getTimezoneOffset() * 60000); // tz_offset in minutes
|
|
3308
|
+
datestr = date.toISOString();
|
|
3261
3309
|
|
|
3262
3310
|
ret.push([datestr.substring(0, 10), datestr.substring(11, 23), _this.instruments[0].trades[i].price, _this.instruments[0].trades[i].quantity]);
|
|
3263
3311
|
}
|
|
@@ -3269,9 +3317,9 @@ function Milli_Chart(settings) {
|
|
|
3269
3317
|
];
|
|
3270
3318
|
} else {
|
|
3271
3319
|
if (_this.instruments.length > 0) {
|
|
3272
|
-
for (
|
|
3273
|
-
|
|
3274
|
-
|
|
3320
|
+
for (i = 0; i < _this.instruments[0].history.length; i++) {
|
|
3321
|
+
date = new Date(_this.instruments[0].history[i].timestamp);
|
|
3322
|
+
datestr = date.toISOString();
|
|
3275
3323
|
|
|
3276
3324
|
ret.push([datestr.substring(0, 10), "", _this.instruments[0].history[i].price, _this.instruments[0].history[i].quantity]);
|
|
3277
3325
|
}
|
|
@@ -3282,10 +3330,10 @@ function Milli_Chart(settings) {
|
|
|
3282
3330
|
...ret
|
|
3283
3331
|
];
|
|
3284
3332
|
}
|
|
3285
|
-
}
|
|
3333
|
+
};
|
|
3286
3334
|
|
|
3287
3335
|
_this.destroyWidget = function() {
|
|
3288
|
-
|
|
3336
|
+
// if we have subscriptions send in an empty array to unsubscribe all and release it
|
|
3289
3337
|
if (MillistreamWidgetApi_isObjectEmpty(_this.unsubscriptions) == false)
|
|
3290
3338
|
_this.requestid = _this.settings.streaming.MillistreamWidgetStreamingApi_subscribeInstruments(_this, _this.requestid, []);
|
|
3291
3339
|
return 0;
|
|
@@ -3309,23 +3357,25 @@ function Milli_Chart(settings) {
|
|
|
3309
3357
|
}
|
|
3310
3358
|
|
|
3311
3359
|
function fetchHistory(instrument) {
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3360
|
+
if (_this.settings.historylen) {
|
|
3361
|
+
var oldfields = _this.settings.fields;
|
|
3362
|
+
_this.settings.fields = [...['name', 'tradecurrency', 'date', 'closeprice', 'closequantity', 'marketopen', 'marketclose'], ...oldfields];
|
|
3363
|
+
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');
|
|
3364
|
+
if (typeof _this.settings.pricetype !== 'undefined') url += '&pricingtype=' + _this.settings.pricetype;
|
|
3365
|
+
if (_this.settings.adjusted == true) url += '&adjusted=1';
|
|
3366
|
+
_this.settings.fields = oldfields;
|
|
3367
|
+
if (_this.settings.xhr) {
|
|
3368
|
+
getXhrJson(url);
|
|
3369
|
+
} else {
|
|
3370
|
+
millistream_data_api.fetch(url, function(data) {
|
|
3371
|
+
_this.buildwidget(data);
|
|
3372
|
+
});
|
|
3373
|
+
}
|
|
3324
3374
|
}
|
|
3325
3375
|
}
|
|
3326
3376
|
|
|
3327
3377
|
_this.drawWidget = function() {
|
|
3328
|
-
|
|
3378
|
+
// remove standard fields from array, they will be requested anyway
|
|
3329
3379
|
_this.settings.fields = _this.settings.fields.filter(function(obj) {
|
|
3330
3380
|
return ['name', 'tradecurrency', 'time', 'date', 'tradeprice', 'tradequantity', 'marketopen', 'marketclose', 'closeprice1d', 'closeprice', 'closequantity'].indexOf(obj) == -1;
|
|
3331
3381
|
});
|
|
@@ -3351,7 +3401,7 @@ function Milli_Chart(settings) {
|
|
|
3351
3401
|
var e = new Date();
|
|
3352
3402
|
var days = 0;
|
|
3353
3403
|
var newlen = 0;
|
|
3354
|
-
while (days < _this.settings.intradaylen - 1) {
|
|
3404
|
+
while (days < _this.settings.intradaylen - 1) { // include today
|
|
3355
3405
|
d -= 86400000;
|
|
3356
3406
|
e.setTime(d);
|
|
3357
3407
|
if (e.getDay() != 0 && e.getDay() != 6)
|
|
@@ -3394,7 +3444,6 @@ function Milli_Chart(settings) {
|
|
|
3394
3444
|
|
|
3395
3445
|
(function updatePixelRatio() {
|
|
3396
3446
|
matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`).addEventListener('change', updatePixelRatio, { once: true });
|
|
3397
|
-
() => {};
|
|
3398
3447
|
_this.drawChart();
|
|
3399
3448
|
})();
|
|
3400
3449
|
|
|
@@ -3405,7 +3454,7 @@ function Milli_Chart(settings) {
|
|
|
3405
3454
|
}
|
|
3406
3455
|
});
|
|
3407
3456
|
}
|
|
3408
|
-
var milli_data_api_url = 'https://stage.millistream.com/widgets/3.0.
|
|
3457
|
+
var milli_data_api_url = 'https://stage.millistream.com/widgets/3.0.4/data/milli_widget_dataapi.php?';
|
|
3409
3458
|
|
|
3410
3459
|
var millistream_data_api = {
|
|
3411
3460
|
callbackcounter: 0,
|
|
@@ -3453,14 +3502,14 @@ function MillistreamWidgetApi_buildQuery(widget, type) {
|
|
|
3453
3502
|
if (typeof widget.settings.instrumenttype !== 'object') {
|
|
3454
3503
|
throw new Error(widget.constructor.name + ': instrumenttype is not valid');
|
|
3455
3504
|
}
|
|
3456
|
-
|
|
3505
|
+
//if (widget.settings.instrument == null) // removed 2021-10-12 for "mylist" functionality
|
|
3457
3506
|
url += '&instrumenttypes=' + widget.settings.instrumenttype.join();
|
|
3458
3507
|
}
|
|
3459
3508
|
if (widget.settings.instrumentsubtype != null) {
|
|
3460
3509
|
if (typeof widget.settings.instrumentsubtype !== 'object') {
|
|
3461
3510
|
throw new Error(widget.constructor.name + ': instrumentsubtype is not valid');
|
|
3462
3511
|
}
|
|
3463
|
-
|
|
3512
|
+
//if (widget.settings.instrument == null) // removed 2021-10-12 for "mylist" functionality
|
|
3464
3513
|
url += '&instrumentsubtypes=' + widget.settings.instrumentsubtype.join();
|
|
3465
3514
|
}
|
|
3466
3515
|
if (widget.settings.derivativeindicator != null) {
|
|
@@ -3809,12 +3858,12 @@ function MillistreamWidgetApi_addPagination(widget) {
|
|
|
3809
3858
|
li.onclick = function() {
|
|
3810
3859
|
MillistreamWidgetApi_getPaginationPage(widget, 'next');
|
|
3811
3860
|
};
|
|
3812
|
-
if (widget.pagination.numPages < max + 1) li.style.display = 'none';
|
|
3861
|
+
if (widget.pagination.numPages < max + 1) li.style.display = 'none'; // dont show if less than 6 pages
|
|
3813
3862
|
li = MillistreamWidgetApi_addElement(widget, 'li', 'millistream-list-pagination-li', widget.pagination.ul, null, '>>');
|
|
3814
3863
|
li.onclick = function() {
|
|
3815
3864
|
MillistreamWidgetApi_getPaginationPage(widget, 'last');
|
|
3816
3865
|
};
|
|
3817
|
-
if (widget.pagination.numPages < max + 1) li.style.display = 'none';
|
|
3866
|
+
if (widget.pagination.numPages < max + 1) li.style.display = 'none'; // dont show if less than 6 pages
|
|
3818
3867
|
}
|
|
3819
3868
|
} else
|
|
3820
3869
|
if (widget.settings.pagination > 0 && widget.pagination.numPages < 2) {
|
|
@@ -3882,11 +3931,11 @@ function MillistreamWidgetApi_getPaginationPage(widget, page) {
|
|
|
3882
3931
|
startno = 1;
|
|
3883
3932
|
} else
|
|
3884
3933
|
if (widget.pagination.selectedPage > widget.pagination.numPages - 2) {
|
|
3885
|
-
startno = widget.pagination.numPages - (max - 1);
|
|
3934
|
+
startno = widget.pagination.numPages - (max - 1); //4;
|
|
3886
3935
|
|
|
3887
3936
|
} else {
|
|
3888
3937
|
startno = widget.pagination.selectedPage - 2 < 1 ? 1 : widget.pagination.selectedPage - (max - Math.ceil(max / 2));
|
|
3889
|
-
|
|
3938
|
+
//startno = widget.pagination.selectedPage - 1;
|
|
3890
3939
|
}
|
|
3891
3940
|
for (i = 2; i < items.length - 2; i++) {
|
|
3892
3941
|
items[i].innerHTML = (startno);
|
|
@@ -3925,15 +3974,15 @@ function MillistreamWidgetApi_getElementHeight(el) {
|
|
|
3925
3974
|
return rect.height + s;
|
|
3926
3975
|
}
|
|
3927
3976
|
|
|
3928
|
-
|
|
3977
|
+
// Push blipp funktioner
|
|
3929
3978
|
function MillistreamWidgetApi_clearFlash(el) {
|
|
3930
|
-
|
|
3979
|
+
//internal and external
|
|
3931
3980
|
el.classList.remove('millistream-flash-up');
|
|
3932
3981
|
el.classList.remove('millistream-flash-down');
|
|
3933
3982
|
}
|
|
3934
3983
|
|
|
3935
3984
|
function milli_clearValuedFlash(widget, el, oldValue) {
|
|
3936
|
-
|
|
3985
|
+
// internal borde gå att bygga bort
|
|
3937
3986
|
var currentValue = MillistreamWidgetApi_getElementNumber(widget, el);
|
|
3938
3987
|
if (currentValue == oldValue || currentValue == 0) {
|
|
3939
3988
|
MillistreamWidgetApi_clearFlash(el);
|
|
@@ -3941,7 +3990,7 @@ function milli_clearValuedFlash(widget, el, oldValue) {
|
|
|
3941
3990
|
}
|
|
3942
3991
|
|
|
3943
3992
|
function MillistreamWidgetApi_flashElement(widget, el, newValue, oldValue) {
|
|
3944
|
-
|
|
3993
|
+
// internal
|
|
3945
3994
|
if (newValue == oldValue) return;
|
|
3946
3995
|
MillistreamWidgetApi_clearFlash(el);
|
|
3947
3996
|
if (newValue == '' || !newValue) return;
|
|
@@ -3960,7 +4009,7 @@ function MillistreamWidgetApi_flashElement(widget, el, newValue, oldValue) {
|
|
|
3960
4009
|
}
|
|
3961
4010
|
|
|
3962
4011
|
|
|
3963
|
-
|
|
4012
|
+
// numeriska funktioner
|
|
3964
4013
|
function MillistreamWidgetApi_isNumber(widget, testsubject) {
|
|
3965
4014
|
if (!testsubject) return;
|
|
3966
4015
|
var n = testsubject.replace(widget.settings.decimalseparator, '.').split(widget.settings.thousandseparator).join('');
|
|
@@ -3973,7 +4022,7 @@ function MillistreamWidgetApi_getNumDecimals(widget, value, current, validfields
|
|
|
3973
4022
|
if (value == null || MillistreamWidgetApi_isNumber(widget, value) == false) return current;
|
|
3974
4023
|
var parts = value.toString().split('.');
|
|
3975
4024
|
if (parts.length == 2) {
|
|
3976
|
-
while (parts[1].charAt(parts[1].length - 1) == "0") {
|
|
4025
|
+
while (parts[1].charAt(parts[1].length - 1) == "0") { // remove trailing zeros
|
|
3977
4026
|
parts[1] = parts[1].slice(0, -1);
|
|
3978
4027
|
}
|
|
3979
4028
|
return current > parts[1].length ? current : parts[1].length;
|
|
@@ -3982,7 +4031,7 @@ function MillistreamWidgetApi_getNumDecimals(widget, value, current, validfields
|
|
|
3982
4031
|
}
|
|
3983
4032
|
|
|
3984
4033
|
function MillistreamWidgetApi_getElementNumber(widget, el) {
|
|
3985
|
-
|
|
4034
|
+
// internal and Orderbook
|
|
3986
4035
|
var res = parseFloat(el.innerHTML.replace(widget.settings.decimalseparator, '.').split(widget.settings.thousandseparator).join(''));
|
|
3987
4036
|
if (!isNaN(parseFloat(res)) && isFinite(res)) return res;
|
|
3988
4037
|
return 0;
|
|
@@ -4013,7 +4062,7 @@ function MillistreamWidgetApi_colorCell(widget, element, info) {
|
|
|
4013
4062
|
MillistreamWidgetApi_setCellColor(widget, element, v);
|
|
4014
4063
|
}
|
|
4015
4064
|
} else
|
|
4016
|
-
if (widget.settings.controlcolumn || widget.settings.controlcolumn == 0) {
|
|
4065
|
+
if (widget.settings.controlcolumn || widget.settings.controlcolumn == 0) { // works for tables
|
|
4017
4066
|
if (widget.settings.stylecolumn === null) return;
|
|
4018
4067
|
var tr = element.parentNode;
|
|
4019
4068
|
while (tr.tagName.toLowerCase() != 'tr') {
|
|
@@ -4022,13 +4071,13 @@ function MillistreamWidgetApi_colorCell(widget, element, info) {
|
|
|
4022
4071
|
if (tr.cells.length > widget.settings.controlcolumn) {
|
|
4023
4072
|
v = MillistreamWidgetApi_getElementNumber(widget, tr.cells[widget.settings.controlcolumn]);
|
|
4024
4073
|
var el;
|
|
4025
|
-
if (widget.settings.stylecolumn && widget.settings.stylecolumn[0] == -1) {
|
|
4026
|
-
el = tr;
|
|
4074
|
+
if (widget.settings.stylecolumn && widget.settings.stylecolumn[0] == -1) { // color row
|
|
4075
|
+
el = tr; //element.parentNode;
|
|
4027
4076
|
MillistreamWidgetApi_setCellColor(widget, tr, v);
|
|
4028
4077
|
|
|
4029
4078
|
} else {
|
|
4030
4079
|
for (var s = 0; s < widget.settings.stylecolumn.length; s++) {
|
|
4031
|
-
el = tr.cells[widget.settings.stylecolumn[s]];
|
|
4080
|
+
el = tr.cells[widget.settings.stylecolumn[s]]; //element.parentNode.cells[widget.stylecolumn[s]];
|
|
4032
4081
|
if (el) {
|
|
4033
4082
|
MillistreamWidgetApi_setCellColor(widget, el, v);
|
|
4034
4083
|
}
|
|
@@ -4036,17 +4085,17 @@ function MillistreamWidgetApi_colorCell(widget, element, info) {
|
|
|
4036
4085
|
}
|
|
4037
4086
|
}
|
|
4038
4087
|
} else
|
|
4039
|
-
if (widget.settings.positiveclass && widget.settings.negativeclass) {
|
|
4088
|
+
if (widget.settings.positiveclass && widget.settings.negativeclass) { // non table elements
|
|
4040
4089
|
v = MillistreamWidgetApi_getElementNumber(widget, element);
|
|
4041
4090
|
MillistreamWidgetApi_setCellColor(widget, element, v);
|
|
4042
4091
|
}
|
|
4043
4092
|
}
|
|
4044
4093
|
|
|
4045
4094
|
function print_field(widget, element, field, value, overridedecimals) {
|
|
4046
|
-
|
|
4095
|
+
// internal and external
|
|
4047
4096
|
var f = parseInt(field);
|
|
4048
4097
|
var info = MillistreamWidgetApi_getColumnInfo(widget, f.toString());
|
|
4049
|
-
if (typeof value === 'undefined' || value == null || (!value && isNaN(value) == true)) {
|
|
4098
|
+
if (typeof value === 'undefined' || value == null || (!value && isNaN(value) == true)) { // kolla field?
|
|
4050
4099
|
if (info[4] & 16) {
|
|
4051
4100
|
value = '0.0';
|
|
4052
4101
|
} else {
|
|
@@ -4092,7 +4141,7 @@ function print_field(widget, element, field, value, overridedecimals) {
|
|
|
4092
4141
|
else
|
|
4093
4142
|
element.innerHTML = formatFactorNumber(value, widget.settings.factor, widget.settings.num_decimals, widget.settings.thousandseparator, widget.settings.decimalseparator);
|
|
4094
4143
|
} else if (info[4] & 4)
|
|
4095
|
-
element.innerHTML = formatNiceNumber(value, widget.settings.thousandseparator, widget.settings.decimalseparator, 0);
|
|
4144
|
+
element.innerHTML = formatNiceNumber(value, widget.settings.thousandseparator, widget.settings.decimalseparator, 0); // no decimals
|
|
4096
4145
|
else if (info[4] & 1 && overridedecimals)
|
|
4097
4146
|
element.innerHTML = formatNiceNumber(value, widget.settings.thousandseparator, widget.settings.decimalseparator, overridedecimals || widget.settings.num_decimals);
|
|
4098
4147
|
else {
|
|
@@ -4110,8 +4159,8 @@ function print_field(widget, element, field, value, overridedecimals) {
|
|
|
4110
4159
|
}
|
|
4111
4160
|
|
|
4112
4161
|
function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
4113
|
-
|
|
4114
|
-
|
|
4162
|
+
// internal and external
|
|
4163
|
+
// 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
4164
|
switch (name) {
|
|
4116
4165
|
case '222':
|
|
4117
4166
|
case 'accountsreceivable':
|
|
@@ -4202,7 +4251,7 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
|
4202
4251
|
return [232, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
|
|
4203
4252
|
case '404':
|
|
4204
4253
|
case 'd1':
|
|
4205
|
-
return [404, 'date', 'right', widget.get_lang_text(name) || name, 0];
|
|
4254
|
+
return [404, 'date', 'right', widget.get_lang_text(name) || name, 0]; // Security type
|
|
4206
4255
|
case '3':
|
|
4207
4256
|
case 'date':
|
|
4208
4257
|
return [3, 'date', 'right', widget.get_lang_text(name) || name, 0];
|
|
@@ -4456,10 +4505,10 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
|
4456
4505
|
return [229, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
|
|
4457
4506
|
case '395':
|
|
4458
4507
|
case 'n2':
|
|
4459
|
-
return [395, 'numeric', 'left', widget.get_lang_text(name) || name, 0];
|
|
4508
|
+
return [395, 'numeric', 'left', widget.get_lang_text(name) || name, 0]; // Security type
|
|
4460
4509
|
case '396':
|
|
4461
4510
|
case 'n3':
|
|
4462
|
-
return [396, 'numeric', 'left', widget.get_lang_text(name) || name, 0];
|
|
4511
|
+
return [396, 'numeric', 'left', widget.get_lang_text(name) || name, 0]; // Security type
|
|
4463
4512
|
case '22':
|
|
4464
4513
|
case 'name':
|
|
4465
4514
|
return [22, 'string', 'left', widget.get_lang_text(name) || name, 0];
|
|
@@ -4471,10 +4520,10 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
|
4471
4520
|
return [138, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
|
|
4472
4521
|
case '48':
|
|
4473
4522
|
case 'newsid':
|
|
4474
|
-
return [48, 'string', 'left', 'newsid', 0];
|
|
4523
|
+
return [48, 'string', 'left', 'newsid', 0]; // hardoded should not be used by any display
|
|
4475
4524
|
case 'newstype':
|
|
4476
4525
|
case '86':
|
|
4477
|
-
return [86, 'string', 'left', 'newstype', 0];
|
|
4526
|
+
return [86, 'string', 'left', 'newstype', 0]; // hardoded should not be used by any display
|
|
4478
4527
|
case '219':
|
|
4479
4528
|
case 'noncurrentasset':
|
|
4480
4529
|
return [219, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
|
|
@@ -4534,13 +4583,13 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
|
4534
4583
|
return [98, 'string', 'left', widget.get_lang_text(name) || name, 0];
|
|
4535
4584
|
case '180':
|
|
4536
4585
|
case 's3':
|
|
4537
|
-
return [180, 'string', 'left', widget.get_lang_text(name) || name, 0];
|
|
4586
|
+
return [180, 'string', 'left', widget.get_lang_text(name) || name, 0]; // Position
|
|
4538
4587
|
case '181':
|
|
4539
4588
|
case 's4':
|
|
4540
|
-
return [181, 'string', 'left', widget.get_lang_text(name) || name, 0];
|
|
4589
|
+
return [181, 'string', 'left', widget.get_lang_text(name) || name, 0]; // Position
|
|
4541
4590
|
case '393':
|
|
4542
4591
|
case 's10':
|
|
4543
|
-
return [393, 'string', 'left', widget.get_lang_text(name) || name, 0];
|
|
4592
|
+
return [393, 'string', 'left', widget.get_lang_text(name) || name, 0]; // comment
|
|
4544
4593
|
case '127':
|
|
4545
4594
|
case 'sales':
|
|
4546
4595
|
return [127, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
|
|
@@ -4577,7 +4626,7 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
|
4577
4626
|
case '227':
|
|
4578
4627
|
case 'totalassets':
|
|
4579
4628
|
return [227, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
|
|
4580
|
-
case '1023':
|
|
4629
|
+
case '1023': // TODO, define this with correct value
|
|
4581
4630
|
case 'totalnumberofshares':
|
|
4582
4631
|
return [1023, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
|
|
4583
4632
|
case '233':
|
|
@@ -4626,7 +4675,7 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
|
4626
4675
|
case 'vega':
|
|
4627
4676
|
return [703, 'numeric', 'right', widget.get_lang_text(name) || name, 0];
|
|
4628
4677
|
|
|
4629
|
-
|
|
4678
|
+
// brokerstats
|
|
4630
4679
|
case '3000':
|
|
4631
4680
|
case 'boughtquantity':
|
|
4632
4681
|
return [3000, 'numeric', 'right', widget.get_lang_text(name) || name, 4];
|
|
@@ -4814,7 +4863,7 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
|
4814
4863
|
case '3060':
|
|
4815
4864
|
case 'soldturnoverytd':
|
|
4816
4865
|
return [3060, 'numeric', 'left', widget.get_lang_text(name) || name, 4];
|
|
4817
|
-
|
|
4866
|
+
// key ratios egen definerade
|
|
4818
4867
|
case 'per_last':
|
|
4819
4868
|
case '3100':
|
|
4820
4869
|
return [3100, 'numeric', 'right', widget.get_lang_text(name) || name, 0];
|
|
@@ -4935,7 +4984,7 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
|
4935
4984
|
case 'latestreport':
|
|
4936
4985
|
case '3140':
|
|
4937
4986
|
return [3140, 'date', 'right', widget.get_lang_text(name) || name, 0];
|
|
4938
|
-
|
|
4987
|
+
// basicdata join fields
|
|
4939
4988
|
case 'fundcompanyname':
|
|
4940
4989
|
case '3200':
|
|
4941
4990
|
return [3200, 'string', 'left', widget.get_lang_text(name) || name, 0];
|
|
@@ -4954,17 +5003,17 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
|
4954
5003
|
case '3205':
|
|
4955
5004
|
case 'underlyingsymbol':
|
|
4956
5005
|
return [3204, 'string', 'left', widget.get_lang_text(name) || name, 0];
|
|
4957
|
-
case '3206':
|
|
5006
|
+
case '3206': // tmcwatch
|
|
4958
5007
|
case 'multiplier':
|
|
4959
5008
|
return [3206, 'string', 'left', widget.get_lang_text(name) || name, 0];
|
|
4960
|
-
case '3207':
|
|
5009
|
+
case '3207': // tmcwach
|
|
4961
5010
|
case 'type':
|
|
4962
5011
|
return [3207, 'string', 'left', widget.get_lang_text(name) || name, 0];
|
|
4963
|
-
case '3208':
|
|
5012
|
+
case '3208': // tmcwach
|
|
4964
5013
|
case 'direction':
|
|
4965
5014
|
return [3208, 'string', 'left', widget.get_lang_text(name) || name, 0];
|
|
4966
5015
|
|
|
4967
|
-
|
|
5016
|
+
// optionwatch
|
|
4968
5017
|
case '3300':
|
|
4969
5018
|
case 'iv30d':
|
|
4970
5019
|
case 'ivXXd':
|
|
@@ -5007,8 +5056,8 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
|
5007
5056
|
}
|
|
5008
5057
|
}
|
|
5009
5058
|
|
|
5010
|
-
function set_hashed_element(widget, insref, info, json, num_dec) {
|
|
5011
|
-
|
|
5059
|
+
function set_hashed_element(widget, insref, info, json, num_dec) { // called from push
|
|
5060
|
+
// external : list
|
|
5012
5061
|
var key = insref + '_' + info[0];
|
|
5013
5062
|
var arr = widget.cell_map.get(key);
|
|
5014
5063
|
if (arr !== undefined) {
|
|
@@ -5018,9 +5067,9 @@ function set_hashed_element(widget, insref, info, json, num_dec) {
|
|
|
5018
5067
|
}
|
|
5019
5068
|
}
|
|
5020
5069
|
|
|
5021
|
-
|
|
5070
|
+
// Create Element functions
|
|
5022
5071
|
function MillistreamWidgetApi_addElementToMap(insref, field, element, widget) {
|
|
5023
|
-
|
|
5072
|
+
// internal
|
|
5024
5073
|
if (insref && field && widget && widget.cell_map) {
|
|
5025
5074
|
var key = insref + '_' + field;
|
|
5026
5075
|
var arr = widget.cell_map.get(key);
|
|
@@ -5036,7 +5085,7 @@ function MillistreamWidgetApi_addElementToMap(insref, field, element, widget) {
|
|
|
5036
5085
|
}
|
|
5037
5086
|
|
|
5038
5087
|
function MillistreamWidgetApi_addElement(widget, el, cl, parent, field, value, overridedecimals) {
|
|
5039
|
-
|
|
5088
|
+
// external
|
|
5040
5089
|
var element = document.createElement(el);
|
|
5041
5090
|
if (cl)
|
|
5042
5091
|
element.setAttribute('class', cl);
|
|
@@ -5119,7 +5168,7 @@ function MillistreamWidgetApi_addTableCell(widget, key, cl, parent, json, decima
|
|
|
5119
5168
|
widget.settings.link_field.forEach(function(element) {
|
|
5120
5169
|
hrefparam[element] = json[element];
|
|
5121
5170
|
});
|
|
5122
|
-
if (info[0] == 1) {
|
|
5171
|
+
if (info[0] == 1) { // headline, borde inte behövas i list
|
|
5123
5172
|
td.onclick = function(e) {
|
|
5124
5173
|
hrefparam.event = e;
|
|
5125
5174
|
hrefparam.source = widget;
|
|
@@ -5235,7 +5284,7 @@ function fabs(value) {
|
|
|
5235
5284
|
}
|
|
5236
5285
|
|
|
5237
5286
|
function zeroPad(number, width) {
|
|
5238
|
-
|
|
5287
|
+
//internal
|
|
5239
5288
|
if (number <= 9.9999999 * Math.pow(10, width)) return ("0000000" + number).slice(-width);
|
|
5240
5289
|
return number;
|
|
5241
5290
|
}
|
|
@@ -5280,7 +5329,7 @@ function formatNiceNumber(y, thousandSeparator, decimalSeparator, precision, add
|
|
|
5280
5329
|
}
|
|
5281
5330
|
|
|
5282
5331
|
function formatDate(date, format, widget) {
|
|
5283
|
-
|
|
5332
|
+
// internal
|
|
5284
5333
|
var timeStamp, mon, day;
|
|
5285
5334
|
if (format == 'yyyy-mm-dd') {
|
|
5286
5335
|
timeStamp = new Date(date);
|
|
@@ -5294,66 +5343,66 @@ function formatDate(date, format, widget) {
|
|
|
5294
5343
|
day = timeStamp.getDate();
|
|
5295
5344
|
return timeStamp.getFullYear() % 100 + '-' + (mon <= 9 ? '0' + mon : mon) + '-' + (day <= 9 ? '0' + day : day);
|
|
5296
5345
|
}
|
|
5297
|
-
if (format == 'b dd') {
|
|
5346
|
+
if (format == 'b dd') { // Jan 01
|
|
5298
5347
|
timeStamp = new Date(date);
|
|
5299
5348
|
mon = timeStamp.toDateString().split(' ');
|
|
5300
5349
|
day = timeStamp.getDate();
|
|
5301
5350
|
return mon[1] + ' ' + (day <= 9 ? '0' + day : day);
|
|
5302
5351
|
}
|
|
5303
|
-
if (format == 'b dd yyyy') {
|
|
5352
|
+
if (format == 'b dd yyyy') { // Jan 01 2017
|
|
5304
5353
|
timeStamp = new Date(date);
|
|
5305
5354
|
mon = timeStamp.toDateString().split(' ');
|
|
5306
5355
|
day = timeStamp.getDate();
|
|
5307
5356
|
return mon[1] + ' ' + (day <= 9 ? '0' + day : day) + ' ' + timeStamp.getFullYear();
|
|
5308
5357
|
}
|
|
5309
|
-
if (format == 'dd/mm') {
|
|
5358
|
+
if (format == 'dd/mm') { // Jan 01 2017
|
|
5310
5359
|
timeStamp = new Date(date);
|
|
5311
5360
|
mon = timeStamp.getMonth() + 1;
|
|
5312
5361
|
day = timeStamp.getDate();
|
|
5313
5362
|
return (day <= 9 ? '0' + day : day) + '/' + (mon <= 9 ? '0' + mon : mon);
|
|
5314
5363
|
}
|
|
5315
|
-
if (format == 'd/m') {
|
|
5364
|
+
if (format == 'd/m') { // Jan 01 2017
|
|
5316
5365
|
timeStamp = new Date(date);
|
|
5317
5366
|
return (timeStamp.getDate() + '/' + (timeStamp.getMonth() + 1));
|
|
5318
5367
|
}
|
|
5319
5368
|
if (format == 'd mmm yyyy') {
|
|
5320
5369
|
timeStamp = new Date(date);
|
|
5321
|
-
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3);
|
|
5370
|
+
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3); // lang....
|
|
5322
5371
|
day = timeStamp.getDate();
|
|
5323
5372
|
return day + ' ' + mon + ' ' + timeStamp.getFullYear();
|
|
5324
5373
|
}
|
|
5325
5374
|
if (format == 'dd mmm yyyy') {
|
|
5326
5375
|
timeStamp = new Date(date);
|
|
5327
|
-
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3);
|
|
5376
|
+
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3); // lang....
|
|
5328
5377
|
day = timeStamp.getDate();
|
|
5329
5378
|
return (day <= 9 ? '0' + day : day) + ' ' + mon + ' ' + timeStamp.getFullYear();
|
|
5330
5379
|
}
|
|
5331
5380
|
if (format == 'dd mmm') {
|
|
5332
5381
|
timeStamp = new Date(date);
|
|
5333
|
-
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3);
|
|
5382
|
+
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3); // lang....
|
|
5334
5383
|
day = timeStamp.getDate();
|
|
5335
5384
|
return (day <= 9 ? '0' + day : day) + ' ' + mon;
|
|
5336
5385
|
}
|
|
5337
5386
|
if (format == 'd mmm') {
|
|
5338
5387
|
timeStamp = new Date(date);
|
|
5339
|
-
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3);
|
|
5388
|
+
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3); // lang....
|
|
5340
5389
|
day = timeStamp.getDate();
|
|
5341
5390
|
return day + ' ' + mon;
|
|
5342
5391
|
}
|
|
5343
5392
|
if (format == 'mmm yyyy') {
|
|
5344
5393
|
timeStamp = new Date(date);
|
|
5345
|
-
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3);
|
|
5394
|
+
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3); // lang....
|
|
5346
5395
|
timeStamp = mon + ' ' + timeStamp.getFullYear();
|
|
5347
5396
|
return timeStamp;
|
|
5348
5397
|
}
|
|
5349
5398
|
if (format == 'mmm yy') {
|
|
5350
5399
|
timeStamp = new Date(date);
|
|
5351
|
-
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3);
|
|
5400
|
+
mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3); // lang
|
|
5352
5401
|
timeStamp = mon + ' ' + (timeStamp.getFullYear() % 100 < 9 ? '0' + timeStamp.getFullYear() % 100 : timeStamp.getFullYear() % 100);
|
|
5353
5402
|
return timeStamp;
|
|
5354
5403
|
}
|
|
5355
5404
|
|
|
5356
|
-
|
|
5405
|
+
// default yyyy-mm-dd
|
|
5357
5406
|
timeStamp = new Date(date);
|
|
5358
5407
|
mon = timeStamp.getMonth() + 1;
|
|
5359
5408
|
day = timeStamp.getDate();
|
|
@@ -5361,7 +5410,7 @@ function formatDate(date, format, widget) {
|
|
|
5361
5410
|
}
|
|
5362
5411
|
|
|
5363
5412
|
function formatTime(value, format) {
|
|
5364
|
-
|
|
5413
|
+
// internal
|
|
5365
5414
|
if (typeof value !== 'string') return "";
|
|
5366
5415
|
var datetime = new Date();
|
|
5367
5416
|
var tz_offset = datetime.getTimezoneOffset();
|
|
@@ -5438,7 +5487,10 @@ Number.prototype.countDecimals = function() {
|
|
|
5438
5487
|
//if (isNaN(this.valueOf()) || Math.floor(this.valueOf()) === this.valueOf()) return 0;
|
|
5439
5488
|
if (isNaN(this.valueOf())) return 0;
|
|
5440
5489
|
if (Math.floor(this.valueOf()) === this.valueOf()) return 0;
|
|
5441
|
-
|
|
5490
|
+
var parts = this.toString().split(".");
|
|
5491
|
+
if (parts.length > 1) return parts[1].length;
|
|
5492
|
+
return 0;
|
|
5493
|
+
//return this.toString().split(".")[1].length || 0;
|
|
5442
5494
|
};
|
|
5443
5495
|
|
|
5444
5496
|
|
|
@@ -5590,7 +5642,7 @@ function MillistreamWidgetApi_scrollIntoView(scrollarea, elem, xalign, yalign) {
|
|
|
5590
5642
|
scrollarea.scrollLeft = elem.offsetLeft - scrollarea.getBoundingClientRect().width / 2;
|
|
5591
5643
|
}
|
|
5592
5644
|
|
|
5593
|
-
|
|
5645
|
+
// scrollIntoView : replace this, breaks apps
|
|
5594
5646
|
}
|
|
5595
5647
|
|
|
5596
5648
|
var MillistreamWidgetSettings = {
|
|
@@ -5610,9 +5662,9 @@ function MillistreamWidgetStreamingApi(settings) {
|
|
|
5610
5662
|
server: 'wss://stage.millistream.com:8900',
|
|
5611
5663
|
alarmClient: null
|
|
5612
5664
|
};
|
|
5613
|
-
var m_requestid = 1;
|
|
5665
|
+
var m_requestid = 1; // 0 is invalid
|
|
5614
5666
|
var m_socket = null;
|
|
5615
|
-
var m_requests = [];
|
|
5667
|
+
var m_requests = []; // queued requests not sent
|
|
5616
5668
|
var m_requestcallbacks = new Map();
|
|
5617
5669
|
|
|
5618
5670
|
|
|
@@ -5645,7 +5697,7 @@ function MillistreamWidgetStreamingApi(settings) {
|
|
|
5645
5697
|
req = new Object({
|
|
5646
5698
|
"widget": widget,
|
|
5647
5699
|
});
|
|
5648
|
-
m_requestcallbacks.set(requestid.toString(), req);
|
|
5700
|
+
m_requestcallbacks.set(requestid.toString(), req); // this requestid will be forarded to this widget
|
|
5649
5701
|
}
|
|
5650
5702
|
var request = '';
|
|
5651
5703
|
if (MillistreamWidgetApi_isObjectEmpty(widget.unsubscriptions) == false) {
|
|
@@ -5707,7 +5759,7 @@ function MillistreamWidgetStreamingApi(settings) {
|
|
|
5707
5759
|
|
|
5708
5760
|
|
|
5709
5761
|
widget.unsubscriptions.type = 'insrefs';
|
|
5710
|
-
widget.unsubscriptions.insrefs = insrefs.slice(0);
|
|
5762
|
+
widget.unsubscriptions.insrefs = insrefs.slice(0); // copy array
|
|
5711
5763
|
widget.unsubscriptions.messagetypes = widget.settings.messagetypes;
|
|
5712
5764
|
widget.unsubscriptions.requestid = requestid;
|
|
5713
5765
|
|
|
@@ -5720,7 +5772,7 @@ function MillistreamWidgetStreamingApi(settings) {
|
|
|
5720
5772
|
|
|
5721
5773
|
function reconnect() {
|
|
5722
5774
|
if (!m_socket.CLOSED) {
|
|
5723
|
-
|
|
5775
|
+
//console.log('not closed');
|
|
5724
5776
|
return;
|
|
5725
5777
|
}
|
|
5726
5778
|
m_requests.forEach(function(request) {
|
|
@@ -5739,21 +5791,21 @@ function MillistreamWidgetStreamingApi(settings) {
|
|
|
5739
5791
|
try {
|
|
5740
5792
|
m_socket = new WebSocket(_this.settings.server);
|
|
5741
5793
|
m_socket.onopen = function() {
|
|
5742
|
-
(
|
|
5794
|
+
console.log('Connected to millistream push'); /*RemoveLogging:skip*/
|
|
5743
5795
|
if (m_requests.length > 0) {
|
|
5744
5796
|
m_requests.forEach(function(request) {
|
|
5745
5797
|
if (request.send == 0) {
|
|
5746
|
-
|
|
5798
|
+
//console.log('rerequest:', request.request);
|
|
5747
5799
|
m_socket.send('{ "token":"' + _this.settings.token + '",' + request.request);
|
|
5748
5800
|
}
|
|
5749
5801
|
});
|
|
5750
5802
|
}
|
|
5751
5803
|
};
|
|
5752
5804
|
m_socket.onerror = function() {
|
|
5753
|
-
()
|
|
5805
|
+
console.log('Error, disconnected'); /*RemoveLogging:skip*/
|
|
5754
5806
|
};
|
|
5755
5807
|
m_socket.onclose = function() {
|
|
5756
|
-
()
|
|
5808
|
+
console.log('Disconnected'); /*RemoveLogging:skip*/
|
|
5757
5809
|
reconnect();
|
|
5758
5810
|
};
|
|
5759
5811
|
|
|
@@ -5762,9 +5814,9 @@ function MillistreamWidgetStreamingApi(settings) {
|
|
|
5762
5814
|
try {
|
|
5763
5815
|
jsondata = JSON.parse(msg.data);
|
|
5764
5816
|
} catch (e) {
|
|
5765
|
-
(
|
|
5817
|
+
console.log('invalid data', msg.data); /*RemoveLogging:skip*/
|
|
5766
5818
|
}
|
|
5767
|
-
|
|
5819
|
+
//console.log(JSON.stringify(jsondata));
|
|
5768
5820
|
if (typeof jsondata.instruments !== 'undefined') {
|
|
5769
5821
|
for (var s = 0; s < jsondata.instruments.length; s++) {
|
|
5770
5822
|
var insref = jsondata.instruments[s].insref;
|
|
@@ -5790,16 +5842,16 @@ function MillistreamWidgetStreamingApi(settings) {
|
|
|
5790
5842
|
if (_this.settings.statusCallback !== null) _this.settings.statusCallback(jsondata);
|
|
5791
5843
|
} else
|
|
5792
5844
|
if (typeof jsondata.alarm !== 'undefined') {
|
|
5793
|
-
(
|
|
5845
|
+
console.log('Alarm: ' + JSON.stringify(jsondata));
|
|
5794
5846
|
if (null != _this.settings.alarmClient) {
|
|
5795
5847
|
_this.settings.alarmClient(jsondata);
|
|
5796
5848
|
}
|
|
5797
5849
|
|
|
5798
5850
|
} else
|
|
5799
|
-
()
|
|
5851
|
+
console.log(JSON.stringify(jsondata)); /*RemoveLogging:skip*/
|
|
5800
5852
|
};
|
|
5801
5853
|
} catch (exception) {
|
|
5802
|
-
(
|
|
5854
|
+
console.log('Exception error: ' + exception); /*RemoveLogging:skip*/
|
|
5803
5855
|
reconnect();
|
|
5804
5856
|
}
|
|
5805
5857
|
}
|