@millistream/millistream-widgets 1.0.18 → 1.0.19

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.
Files changed (2) hide show
  1. package/millistream-widgets.js +370 -373
  2. package/package.json +1 -1
@@ -1,24 +1,24 @@
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
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
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 ||
@@ -62,8 +62,7 @@
62
62
  _this.oBackingStorePixelRatio ||
63
63
  _this.backingStorePixelRatio || 1;
64
64
  return (window.devicePixelRatio || 1) / backingStore;
65
- */
66
- return 1;
65
+
67
66
  };
68
67
 
69
68
  forEach(ratioArgs, function(value, key) {
@@ -71,7 +70,7 @@
71
70
  return function() {
72
71
  var i, len,
73
72
  args = Array.prototype.slice.call(arguments);
74
- if (key == 'lineTo' || key == 'moveTo') {
73
+ if (key == 'lineTo' || key == 'moveTo') { // PF
75
74
  args = args.map(function(a) {
76
75
  return a;
77
76
  });
@@ -91,7 +90,7 @@
91
90
  })(prototype[key]);
92
91
  });
93
92
 
94
-
93
+ // Stroke lineWidth adjustment
95
94
  prototype.stroke = (function(_super) {
96
95
  return function() {
97
96
  this.lineWidth *= getPixelRatio(this);
@@ -115,12 +114,12 @@
115
114
  var i = _super.apply(this, args);
116
115
 
117
116
  this.font = tmp;
118
-
119
-
120
-
121
-
122
-
123
-
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
+ );*/
124
123
  return i;
125
124
  };
126
125
  })(prototype.measureText);
@@ -146,8 +145,8 @@
146
145
  return function() {
147
146
  var args = Array.prototype.slice.call(arguments);
148
147
 
149
- args[1] *= getPixelRatio(this);
150
- args[2] *= getPixelRatio(this);
148
+ args[1] *= getPixelRatio(this); // x
149
+ args[2] *= getPixelRatio(this); // y
151
150
  var tmp = this.font;
152
151
  var _this = this;
153
152
  this.font = this.font.replace(
@@ -159,12 +158,12 @@
159
158
 
160
159
  _super.apply(this, args);
161
160
  this.font = tmp;
162
-
163
-
164
-
165
-
166
-
167
-
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
+ );*/
168
167
  };
169
168
  })(prototype.strokeText);
170
169
 
@@ -186,17 +185,17 @@
186
185
  }
187
186
  prototype.getContext = (function(_super) {
188
187
  return function(type) {
189
-
188
+ //var backingStore, ratio;
190
189
  context = _super.call(this, type);
191
190
 
192
191
  if (type === '2d') {
193
192
 
194
-
195
-
196
-
197
-
198
-
199
-
193
+ /*backingStore = context.backingStorePixelRatio ||
194
+ context.webkitBackingStorePixelRatio ||
195
+ context.mozBackingStorePixelRatio ||
196
+ context.msBackingStorePixelRatio ||
197
+ context.oBackingStorePixelRatio ||
198
+ context.backingStorePixelRatio || 1;*/
200
199
 
201
200
  var ratio = getPixelRatio();
202
201
  if (ratio > 1) {
@@ -212,8 +211,6 @@
212
211
  })(prototype.getContext);
213
212
 
214
213
  prototype.setRect = (function(height, width) {
215
- console.log(context, this);
216
- console.log(getPixelRatio());
217
214
  if (context == null) return;
218
215
  this.style.height = height + 'px';
219
216
  this.style.width = width + 'px';
@@ -223,7 +220,7 @@
223
220
 
224
221
  })(HTMLCanvasElement.prototype);
225
222
 
226
-
223
+ // Millistream Chart
227
224
  function Milli_Chart(settings) {
228
225
  "use strict";
229
226
  var _this = this;
@@ -245,13 +242,13 @@ function Milli_Chart(settings) {
245
242
  compress: 1,
246
243
  curveOnTop: true,
247
244
  dateformat: 'd/m',
248
- drawxaxis: true,
245
+ drawxaxis: true, // TODO: 0 no, 1 yes, 2 yeas with markers (3px lines)
249
246
  drawyaxis: true,
250
247
  drawy2axis: false,
251
248
  enablezoom: true,
252
249
  fields: ['name', 'tradecurrency', 'time', 'date', 'tradeprice', 'tradequantity', 'marketopen', 'marketclose'],
253
250
  fillchart: false,
254
- gridVerticalLines: true,
251
+ gridVerticalLines: true, // 0 off, 1 draw grid lines ,2 fillrect modulo
255
252
  gridVerticalLinesStyle: 'line',
256
253
  gridHorizontalLines: true,
257
254
  gridHorizontalLinesStyle: 'dash',
@@ -260,7 +257,7 @@ function Milli_Chart(settings) {
260
257
  instrument: null,
261
258
  intradayDatePos: { x: 'center', y: 'bottom', orientation: 'horizontal', dateformat: 'd mmm' },
262
259
  intradaylen: null,
263
- messagetypes: 1030,
260
+ messagetypes: 1030, // quote,trades and performance
264
261
  nochartlabel: 'No data to draw on',
265
262
  onreadyCallback: null,
266
263
  previousDayClose: true,
@@ -275,8 +272,8 @@ function Milli_Chart(settings) {
275
272
  display: 'block'
276
273
  },
277
274
  xAxisSpacing: 0,
278
- yAxisSpacing: 4,
279
- xAxisModulo: 1
275
+ yAxisSpacing: 4, // undocumented
276
+ xAxisModulo: 1 // undocumented
280
277
  };
281
278
  var m_startdate = null;
282
279
  var m_chartspaces = {
@@ -289,10 +286,10 @@ function Milli_Chart(settings) {
289
286
  height: 0
290
287
  }
291
288
  };
292
- var m_dummyDiv = null;
289
+ var m_dummyDiv = null; // dummy div For chartclasses
293
290
  var m_canvas = null;
294
291
  var m_ctx = null;
295
- var m_datapoints = [];
292
+ var m_datapoints = []; // for mouseover
296
293
  var m_dataPoints = {
297
294
  arr: [],
298
295
  map: new Map()
@@ -381,7 +378,7 @@ function Milli_Chart(settings) {
381
378
  }
382
379
  var m_instrumentCss = [{
383
380
  color: '#E2507A',
384
-
381
+ //backgroundImage: 'linear-gradient(rgba(226, 80, 122, 0.6),rgba(226, 80, 122, 0))',
385
382
  width: 1
386
383
  }, {
387
384
  color: '#ff0000',
@@ -430,10 +427,10 @@ function Milli_Chart(settings) {
430
427
  }
431
428
 
432
429
  function dateDiffInDays(a, b) {
433
-
430
+ // Discard the time and time-zone information.
434
431
  const utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
435
432
  const utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
436
- return Math.floor((utc2 - utc1) / 86400000);
433
+ return Math.floor((utc2 - utc1) / 86400000); // ms per day
437
434
  }
438
435
 
439
436
  function findFirstWeekDay(date) {
@@ -447,7 +444,7 @@ function Milli_Chart(settings) {
447
444
  }
448
445
 
449
446
  function getFontSize(obj) {
450
-
447
+ //return parseInt(obj.fontSize) * window.devicePixelRatio;
451
448
  return parseInt(obj.fontSize);
452
449
  }
453
450
 
@@ -616,7 +613,7 @@ function Milli_Chart(settings) {
616
613
  var quantity = 0;
617
614
 
618
615
  for (i = 0; i < data.length; i++) {
619
-
616
+ // only calc on visible data
620
617
  var price = data[i].price * _this.instruments[s].factor;
621
618
  quantity = 0;
622
619
  if (data[i].quantity !== 'undefined') {
@@ -634,7 +631,7 @@ function Milli_Chart(settings) {
634
631
  }
635
632
 
636
633
  if (_this.scaleinfoY.type != 'history' && (data[i].timestamp % 86400000 < _this.instruments[0].opentimestamp || data[i].timestamp % 86400000 > _this.instruments[0].closetimestamp)) {
637
-
634
+ // stämmer detta kan det bli överlapp vid sommartid/vintertid?
638
635
  continue;
639
636
  }
640
637
 
@@ -661,7 +658,7 @@ function Milli_Chart(settings) {
661
658
  if (_this.scaleinfoY.lowLowerChart == null || _this.scaleinfoY.lowLowerChart > quantity) _this.scaleinfoY.lowLowerChart = quantity;
662
659
  if (_this.scaleinfoY.highLowerChart == null || _this.scaleinfoY.highLowerChart < quantity) _this.scaleinfoY.highLowerChart = quantity;
663
660
  }
664
- if ((_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d') && !m_zoom.mousedown.timestamp) {
661
+ if ((_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d') && !m_zoom.mousedown.timestamp) { // if closeprice is used calch high/low on it
665
662
  var cp = parseFloat(_this.instruments[s].closeprice1d) * _this.instruments[s].factor;
666
663
  if (_this.scaleinfoY.lowValue > cp) _this.scaleinfoY.lowValue = cp;
667
664
  else
@@ -690,7 +687,7 @@ function Milli_Chart(settings) {
690
687
  _this.scaleinfoY.lowValue -= 1;
691
688
  _this.scaleinfoY.highValue += 1;
692
689
  }
693
-
690
+ // do we have any analyzis we need to take into account
694
691
  for (i = 0; i < _this.settings.indicators.length; i++) {
695
692
  if (_this.scaleinfoY.type == 'history') data = _this.settings.indicators[i].history;
696
693
  else data = _this.settings.indicators[i].trades;
@@ -763,7 +760,7 @@ function Milli_Chart(settings) {
763
760
  var maxValue = _this.scaleinfoY.highLowerChart == 0 ? 100 : _this.scaleinfoY.highLowerChart + (tickSize * 0.2);
764
761
  var valuePerPixel = lineLength / maxValue;
765
762
  if (isNaN(valuePerPixel) || !isFinite(valuePerPixel)) {
766
- () => {};
763
+ console.log('cant draw valuePerPixel' + valuePerPixel, lineLength, maxValue);
767
764
  return false;
768
765
  }
769
766
  var value = 0;
@@ -784,7 +781,7 @@ function Milli_Chart(settings) {
784
781
  m_ctx.closePath();
785
782
  m_ctx.restore();
786
783
  } else
787
- if (_this.settings.drawyaxis == true && markers == true) {
784
+ if (_this.settings.drawyaxis == true && markers == true) { // draw legenditem markers for price
788
785
  m_ctx.beginPath();
789
786
  m_ctx.moveTo(m_chartspaces.lowerChart.left, y + 0.5);
790
787
  m_ctx.lineTo(m_chartspaces.lowerChart.left + 3, y + 0.5);
@@ -796,7 +793,7 @@ function Milli_Chart(settings) {
796
793
  var label = formatLargeNumber(value, 0, _this);
797
794
  var textpos = x - 5;
798
795
  if (m_yLegendCss.verticalAlign == 'top') {
799
- if (y - (getFontSize(m_yLegendCss)) > 0)
796
+ if (y - (getFontSize(m_yLegendCss)) > 0) // dont draw if cropped
800
797
  m_ctx.fillText(label, textpos, y - ((getFontSize(m_yLegendCss) + 2)));
801
798
  } else
802
799
  m_ctx.fillText(label, textpos, y - (getFontSize(m_yLegendCss) / 2));
@@ -814,7 +811,7 @@ function Milli_Chart(settings) {
814
811
  m_ctx.fillStyle = m_yLegendCss.color;
815
812
  var lineLen = m_chartspaces.lowerChart.bottom - m_chartspaces.lowerChart.top;
816
813
  var numticks = lineLen / (getFontSize(m_yLegendCss) * 2);
817
- if (numticks > 8) numticks = 8;
814
+ if (numticks > 8) numticks = 8; // limit to 8 items on Y legend ( this is not an absolut count, since we calculate nice legend numbers
818
815
 
819
816
  m_ctx.beginPath();
820
817
  m_ctx.strokeStyle = m_gridVerticalCss.color;
@@ -828,13 +825,13 @@ function Milli_Chart(settings) {
828
825
  }
829
826
 
830
827
  function checkYLegendSpace(y, text) {
831
-
828
+ //if (y - (getFontSize(m_yLegendCss) / 2) - m_chartspaces.chart.top < 0) return false;
832
829
  if (y - (getFontSize(m_yLegendCss)) - m_chartspaces.chart.top < 0) return false;
833
830
  if (y > m_chartspaces.chart.bottom) return false;
834
831
  return true;
835
832
  }
836
833
 
837
- function drawY2Legend(x) {
834
+ function drawY2Legend(x) { // percent
838
835
  if (_this.settings.absoluteScaling == true) {
839
836
  for (var s = 1; s < _this.instruments.length; s++) {
840
837
  if (_this.instruments[s].insref != 0) return;
@@ -862,7 +859,7 @@ function Milli_Chart(settings) {
862
859
  var count = 0;
863
860
  for (;;) {
864
861
  if (count++ > 10) {
865
- () => {};
862
+ console.log('break out');
866
863
  break;
867
864
  }
868
865
  var v;
@@ -873,9 +870,9 @@ function Milli_Chart(settings) {
873
870
  var y = Math.round(m_chartspaces.chart.height - getScaledSetting(m_chartCss.marginBottom) - ((v - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel));
874
871
 
875
872
  if (y <= m_chartspaces.chart.top) break;
876
-
873
+ //if (y > m_chartspaces.chart.bottom) break;
877
874
  if (y <= m_chartspaces.chart.bottom) {
878
- if (_this.settings.drawy2axis == true) {
875
+ if (_this.settings.drawy2axis == true) { // draw legenditem markers for diff
879
876
  m_ctx.beginPath();
880
877
  m_ctx.moveTo(x, y + 0.5);
881
878
  if ((m_y2LegendCss.float == 'left' && m_y2LegendCss.textAlign == 'left') || (m_y2LegendCss.float == 'right' && m_y2LegendCss.textAlign == 'left')) {
@@ -908,7 +905,7 @@ function Milli_Chart(settings) {
908
905
  si.maxValue = si.highValue + (si.tickSize * 0.2);
909
906
  si.minValue = si.lowValue - (si.tickSize * 0.2);
910
907
  m_ctx.font = m_yLegendCss.fontWeight + ' ' + m_yLegendCss.fontSize + ' ' + m_yLegendCss.fontFamily;
911
- if (si.highValue == si.lowValue) {
908
+ if (si.highValue == si.lowValue) { // only have one value so set values for 1 line only
912
909
  si.maxValue = si.maxValue + si.tickSize;
913
910
  si.minValue = si.minValue - si.tickSize;
914
911
  value = Math.abs(si.lowValue);
@@ -920,14 +917,14 @@ function Milli_Chart(settings) {
920
917
  }
921
918
  si.valuePerPixel = si.lineLength / (si.maxValue - si.minValue);
922
919
  if (isNaN(si.valuePerPixel) || !isFinite(si.valuePerPixel)) {
923
- () => {};
920
+ console.log('cant draw valuePerPixel', si.valuePerPixel, si.lineLength, si.maxValue, si.minValue);
924
921
  return false;
925
922
  }
926
923
  var textpos;
927
924
  var count = 0;
928
925
  for (;;) {
929
926
  if (count++ > 10) {
930
- () => {};
927
+ console.log('failsafe break');
931
928
  break;
932
929
  }
933
930
  var y = Math.round(m_chartspaces.chart.height - getScaledSetting(m_chartCss.marginBottom) - ((value - si.minValue) * si.valuePerPixel));
@@ -951,7 +948,7 @@ function Milli_Chart(settings) {
951
948
  }
952
949
 
953
950
  } else
954
- if (_this.settings.drawyaxis == true && number == 1 && draw) {
951
+ if (_this.settings.drawyaxis == true && number == 1 && draw) { // draw legenditem markers for price
955
952
  if (!draw) return;
956
953
  m_ctx.beginPath();
957
954
  m_ctx.moveTo(m_chartspaces.chart.left, y + 0.5);
@@ -989,35 +986,35 @@ function Milli_Chart(settings) {
989
986
  m_ctx.fillStyle = m_yLegendCss.color;
990
987
  if (0 == calcHighLow()) {
991
988
  m_ctx.restore();
992
- () => {};
989
+ console.log('fail highlow');
993
990
  return;
994
991
  }
995
992
  _this.scaleinfoY.lineLength = m_chartspaces.chart.bottom - m_chartspaces.chart.top;
996
993
  _this.scaleinfoY2.lineLength = _this.scaleinfoY.lineLength;
997
-
994
+ //var numticks = (_this.scaleinfoY.lineLength / window.devicePixelRatio) / (getFontSize(m_yLegendCss) * _this.settings.yAxisSpacing);
998
995
  var numticks = _this.scaleinfoY.lineLength / (getFontSize(m_yLegendCss) * _this.settings.yAxisSpacing);
999
- if (numticks > 8) numticks = 8;
996
+ if (numticks > 8) numticks = 8; // limit to 8 items on Y legend ( this is not an absolut count, since we calculate nice legend numbers
1000
997
  _this.scaleinfoY.tickSize = getTickValue(_this.scaleinfoY.lowValue, _this.scaleinfoY.highValue, numticks);
1001
- _this.scaleinfoY.decimals = _this.scaleinfoY.tickSize.countDecimals();
998
+ _this.scaleinfoY.decimals = _this.scaleinfoY.tickSize.countDecimals(); // räkna på diffen mellan high low kanske?
1002
999
  _this.scaleinfoY.decimals = _this.scaleinfoY.decimals > 4 ? 4 : _this.scaleinfoY.decimals;
1003
1000
  _this.scaleinfoY.decimals = _this.scaleinfoY.decimals < 2 ? 2 : _this.scaleinfoY.decimals;
1004
1001
  var label = formatNiceNumber(_this.scaleinfoY.highValue, _this.settings.thousandseparator, _this.settings.decimalseparator, _this.scaleinfoY.decimals);
1005
1002
  if (_this.settings.drawyaxis) {
1006
1003
  if (m_yLegendCss.float != 'right') {
1007
- m_chartspaces.chart.left = 10 + Math.round(m_ctx.measureText(label).width);
1004
+ 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å?
1008
1005
  m_chartspaces.lowerChart.left = m_chartspaces.chart.left;
1009
1006
  } else {
1010
1007
  if (m_yLegendCss.textAlign == 'right') {
1011
- m_chartspaces.chart.right = m_canvas.width - (10 + Math.round(m_ctx.measureText(label).width));
1008
+ 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å?
1012
1009
  m_chartspaces.lowerChart.right = m_chartspaces.chart.right;
1013
1010
  }
1014
1011
  }
1015
1012
  }
1016
- if (_this.settings.drawy2axis) {
1017
-
1013
+ if (_this.settings.drawy2axis) { // calc space for y2
1014
+ //var numticks = _this.scaleinfoY2.lineLength / (getFontSize(m_yLegendCss) * _this.settings.yAxisSpacing);
1018
1015
  _this.scaleinfoY2.tickSize = getTickValue(_this.scaleinfoY2.lowValue, _this.scaleinfoY2.highValue, numticks);
1019
1016
 
1020
- _this.scaleinfoY2.decimals = _this.scaleinfoY2.tickSize.countDecimals();
1017
+ _this.scaleinfoY2.decimals = _this.scaleinfoY2.tickSize.countDecimals(); // räkna på diffen mellan high low kanske?
1021
1018
  _this.scaleinfoY2.decimals = _this.scaleinfoY2.decimals > 4 ? 4 : _this.scaleinfoY2.decimals;
1022
1019
  _this.scaleinfoY2.decimals = _this.scaleinfoY2.decimals < 0 ? 0 : _this.scaleinfoY2.decimals;
1023
1020
 
@@ -1025,12 +1022,12 @@ function Milli_Chart(settings) {
1025
1022
  label = formatNiceNumber(widestDiff, _this.settings.thousandseparator, _this.settings.decimalseparator, _this.scaleinfoY2.decimals) + ' %';
1026
1023
  if (m_y2LegendCss.float != 'right') {
1027
1024
  if (m_y2LegendCss.textAlign == 'left')
1028
- m_chartspaces.chart.left = 10 + Math.round(m_ctx.measureText(label).width);
1025
+ 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å?
1029
1026
  m_chartspaces.lowerChart.left = m_chartspaces.chart.left;
1030
1027
  } else {
1031
-
1028
+ // kolla setting om den skall vara "i diagrammet"
1032
1029
  if (m_y2LegendCss.textAlign == 'right')
1033
- m_chartspaces.chart.right = m_canvas.width - (10 + Math.round(m_ctx.measureText(label).width));
1030
+ 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å?
1034
1031
  m_chartspaces.lowerChart.right = m_chartspaces.chart.right;
1035
1032
  }
1036
1033
  }
@@ -1078,7 +1075,7 @@ function Milli_Chart(settings) {
1078
1075
  }
1079
1076
 
1080
1077
  function drawXAxisGridlines(p, newday) {
1081
-
1078
+ // draws the vertical grid or dots
1082
1079
  m_ctx.save();
1083
1080
  m_ctx.strokeStyle = m_gridVerticalCss.color;
1084
1081
  if (_this.settings.gridVerticalLines) {
@@ -1101,7 +1098,7 @@ function Milli_Chart(settings) {
1101
1098
  m_ctx.closePath();
1102
1099
  }
1103
1100
  } else
1104
- if (_this.settings.drawxaxis != 0) {
1101
+ if (_this.settings.drawxaxis != 0) { // if no grid but drawxaxis , add markers for date/time
1105
1102
  m_ctx.beginPath();
1106
1103
  m_ctx.moveTo(p.x + 0.5, p.y);
1107
1104
  m_ctx.lineTo(p.x + 0.5, p.y + 3);
@@ -1112,13 +1109,13 @@ function Milli_Chart(settings) {
1112
1109
  }
1113
1110
 
1114
1111
  function calcXScale(starttime, endtime) {
1115
-
1112
+ // vad är detta?
1116
1113
  _this.scaleinfoX.startDate = new Date(starttime);
1117
1114
  _this.scaleinfoX.endDate = new Date(endtime);
1118
1115
  _this.scaleinfoX.days = getNumberOfDays(starttime, endtime);
1119
1116
  _this.scaleinfoX.lineLength = m_chartspaces.chart.right - m_chartspaces.chart.left;
1120
- var datesize = new Date('2888-12-28');
1121
- _this.scaleinfoX.itemwidth = getStringWidth(m_ctx, formatDate(datesize, _this.settings.dateformat, _this)) * 2;
1117
+ var datesize = new Date('2888-12-28'); // bredaste datum jag kan komma på
1118
+ _this.scaleinfoX.itemwidth = getStringWidth(m_ctx, formatDate(datesize, _this.settings.dateformat, _this)) * 2; // kolla rätt format en 8a för varje tecken
1122
1119
 
1123
1120
  var maxLegendItems = _this.scaleinfoX.lineLength / (_this.scaleinfoX.itemwidth * 2);
1124
1121
 
@@ -1140,7 +1137,7 @@ function Milli_Chart(settings) {
1140
1137
  var tmp = 60;
1141
1138
  while (tmp < x) {
1142
1139
  tmp += 60;
1143
- if (x - tmp < 20) break;
1140
+ if (x - tmp < 20) break; // if less than 20 mins to next hour breakout
1144
1141
  }
1145
1142
  _this.scaleinfoX.ticksize = tmp * 60000;
1146
1143
  }
@@ -1148,22 +1145,22 @@ function Milli_Chart(settings) {
1148
1145
  }
1149
1146
 
1150
1147
  function getXPosition(timestamp) {
1151
- var offset = (timestamp.getTime() - _this.scaleinfoX.startDate.getTime()) / (86400000 * 7);
1148
+ var offset = (timestamp.getTime() - _this.scaleinfoX.startDate.getTime()) / (86400000 * 7); // veckor
1152
1149
  offset = offset * 86400000 * 2 / _this.scaleinfoX.timePerPixel;
1153
1150
  return Math.round(m_chartspaces.chart.left + ((timestamp.getTime() - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel) - offset);
1154
1151
  }
1155
1152
 
1156
1153
  function checkXLegendSides(x, text) {
1157
-
1154
+ // right
1158
1155
  if (_this.scaleinfoX.lineLength + m_chartspaces.chart.left < x + (m_ctx.measureText(text).width / 2)) return false;
1159
-
1156
+ // left
1160
1157
  if (m_chartspaces.chart.left > x - (m_ctx.measureText(text).width / 2)) return false;
1161
1158
  return true;
1162
1159
 
1163
1160
  }
1164
1161
 
1165
1162
  function drawXAxisYears(starttime, endtime) {
1166
- if (getNumberOfDays(starttime, endtime) < 250) return drawXAxisMonth(starttime, endtime);
1163
+ if (getNumberOfDays(starttime, endtime) < 250) return drawXAxisMonth(starttime, endtime); // exchange days
1167
1164
  m_ctx.save();
1168
1165
  m_ctx.font = m_xLegendCss.fontWeight + ' ' + m_xLegendCss.fontSize + ' ' + m_xLegendCss.fontFamily;
1169
1166
  m_ctx.strokeStyle = m_gridHorizontalCss.color;
@@ -1179,7 +1176,7 @@ function Milli_Chart(settings) {
1179
1176
  }
1180
1177
  m_ctx.strokeStyle = m_gridVerticalCss.color;
1181
1178
  var legendItems = [];
1182
-
1179
+ // draw Years
1183
1180
  var year = _this.scaleinfoX.startDate.getFullYear() + 1;
1184
1181
  var numItems = 0,
1185
1182
  x, draw, i, text;
@@ -1196,7 +1193,7 @@ function Milli_Chart(settings) {
1196
1193
  text = year;
1197
1194
  if (checkXLegendSides(x, text)) {
1198
1195
  if (_this.settings.yearLabelsPos == 'top') {
1199
- m_ctx.save();
1196
+ m_ctx.save(); // flip and write new years on top
1200
1197
  var fontMetrix = m_ctx.measureText(text);
1201
1198
  x = x + fontMetrix.actualBoundingBoxAscent + fontMetrix.actualBoundingBoxDescent + 2;
1202
1199
  var y = m_chartspaces.chart.top;
@@ -1213,14 +1210,14 @@ function Milli_Chart(settings) {
1213
1210
  }
1214
1211
  year++;
1215
1212
  }
1216
- if (numItems * m_ctx.measureText('8888').width / _this.scaleinfoX.lineLength > 0.3) numItems = 11;
1217
-
1218
- if (numItems < 10) {
1213
+ if (numItems * m_ctx.measureText('8888').width / _this.scaleinfoX.lineLength > 0.3) numItems = 11; // keep it clean
1214
+ // draw half year
1215
+ if (numItems < 10) { // max 10 items här för att skriva halvår
1219
1216
  year = new Date(_this.scaleinfoX.startDate.getFullYear() + '-07-01T00:00:00Z');
1220
1217
  if (year.getTime() < _this.scaleinfoX.startDate.getTime())
1221
1218
  year = new Date(_this.scaleinfoX.startDate.getFullYear() + 1 + '-07-01T00:00:00Z');
1222
1219
  while (year < _this.scaleinfoX.endDate) {
1223
- x = getXPosition(new Date(year.getFullYear() + '-07-01T00:00:00Z'));
1220
+ x = getXPosition(new Date(year.getFullYear() + '-07-01T00:00:00Z')); // 7
1224
1221
  draw = true;
1225
1222
  for (i = 0; i < legendItems.length; i++) {
1226
1223
  if (Math.abs(legendItems[i].x - x) < getMaxDateWidth()) {
@@ -1239,13 +1236,13 @@ function Milli_Chart(settings) {
1239
1236
  year = new Date((year.getFullYear() + 1) + '-07-01T00:00:00Z');
1240
1237
  }
1241
1238
  }
1242
-
1243
- if (numItems * m_ctx.measureText('8888').width / _this.scaleinfoX.lineLength > 0.3) numItems = 11;
1244
- if (numItems < 10) {
1239
+ // draw Quarter
1240
+ if (numItems * m_ctx.measureText('8888').width / _this.scaleinfoX.lineLength > 0.3) numItems = 11; // keep it clean
1241
+ if (numItems < 10) { // max 10 items här för att skriva kvartal
1245
1242
  year = new Date(_this.scaleinfoX.startDate.getFullYear() + '-04-01T00:00:00Z');
1246
1243
  if (year.getTime() < _this.scaleinfoX.startDate.getTime())
1247
1244
  year = new Date(_this.scaleinfoX.startDate.getFullYear() + 1 + '-04-01T00:00:00Z');
1248
- var dontPrint = false;
1245
+ var dontPrint = false; // if no space for first quarter dont print second either
1249
1246
  while (year < _this.scaleinfoX.endDate) {
1250
1247
  x = getXPosition(new Date(year.getFullYear() + '-04-01T00:00:00Z'));
1251
1248
  draw = true;
@@ -1266,7 +1263,7 @@ function Milli_Chart(settings) {
1266
1263
  legendItems.push({ 'text': text, timestamp: new Date(year + '-04-01T00:00:00Z'), 'x': x });
1267
1264
  year = new Date((year.getFullYear() + 1) + '-04-01T00:00:00Z');
1268
1265
  }
1269
-
1266
+ // Draw Quarter 2
1270
1267
  if (dontPrint == false) {
1271
1268
  year = new Date(_this.scaleinfoX.startDate.getFullYear() + '-10-01T00:00:00Z');
1272
1269
  if (year.getTime() < _this.scaleinfoX.startDate.getTime())
@@ -1303,7 +1300,7 @@ function Milli_Chart(settings) {
1303
1300
  m_ctx.strokeStyle = m_gridHorizontalCss.color;
1304
1301
  m_ctx.fillStyle = m_xLegendCss.color;
1305
1302
  calcXScale(starttime, endtime);
1306
- if (_this.settings.drawxaxis != 0) {
1303
+ if (_this.settings.drawxaxis != 0) { // draw line
1307
1304
  m_ctx.beginPath();
1308
1305
  m_ctx.moveTo(m_chartspaces.chart.left, m_chartspaces.chart.height - getScaledSetting(m_chartCss.marginBottom) + 0.5);
1309
1306
  m_ctx.lineTo(m_chartspaces.chart.right, m_chartspaces.chart.height - getScaledSetting(m_chartCss.marginBottom) + 0.5);
@@ -1318,14 +1315,14 @@ function Milli_Chart(settings) {
1318
1315
  var draw = true;
1319
1316
  var offset = 0;
1320
1317
  var count = 0;
1321
- while (currentDate.getTime() < _this.scaleinfoX.endTimeStamp) {
1318
+ while (currentDate.getTime() < _this.scaleinfoX.endTimeStamp) { // oklart om det skall vara så här 2021-06-01
1322
1319
  draw = true;
1323
- while (currentDate.getDay() == 0 || currentDate.getDay() == 6) {
1320
+ while (currentDate.getDay() == 0 || currentDate.getDay() == 6) { // move past weekends , maybe skip this if date is available in data
1324
1321
  currentDate = new Date(currentDate.getTime() + 86400000);
1325
1322
  offset += 86400000 / _this.scaleinfoX.timePerPixel;
1326
1323
  }
1327
1324
  x = Math.round(m_chartspaces.chart.left + ((currentDate.getTime() - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel) - offset);
1328
- if (lastx == 0 && m_chartspaces.chart.left > (x - (getMaxDateWidth() / 2))) {
1325
+ if (lastx == 0 && m_chartspaces.chart.left > (x - (getMaxDateWidth() / 2))) { // do not print left of y legend
1329
1326
  currentDate = new Date(currentDate.getTime() + 86400000);
1330
1327
  continue;
1331
1328
  }
@@ -1343,7 +1340,7 @@ function Milli_Chart(settings) {
1343
1340
  }
1344
1341
  currentDate = new Date(currentDate.getTime() + 86400000);
1345
1342
  }
1346
-
1343
+ // vad är detta?
1347
1344
  if (typeof m_chartCss.boxShadow !== 'undefined' && typeof m_chartCss.boxShadow.rightWidth !== 'undefined') {
1348
1345
  if (m_chartCss.boxShadow.rightWidth == 0) drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, false);
1349
1346
  } else {
@@ -1355,9 +1352,9 @@ function Milli_Chart(settings) {
1355
1352
  function calcXScaleTick(starttime, endtime) {
1356
1353
  _this.scaleinfoX.startDate = new Date(starttime);
1357
1354
  _this.scaleinfoX.endDate = new Date(endtime);
1358
- _this.scaleinfoX.days = getNumberOfDays(starttime, endtime);
1359
- _this.scaleinfoX.lineLength = m_chartspaces.chart.right - m_chartspaces.chart.left;
1360
- _this.scaleinfoX.itemwidth = getStringWidth(m_ctx, '88:88') * 2;
1355
+ _this.scaleinfoX.days = getNumberOfDays(starttime, endtime); // kan vi nog skita i
1356
+ _this.scaleinfoX.lineLength = m_chartspaces.chart.right - m_chartspaces.chart.left; // daybreaks can have 88/88
1357
+ _this.scaleinfoX.itemwidth = getStringWidth(m_ctx, '88:88') * 2; // kolla rätt format en 8a för varje tecken
1361
1358
  var maxLegendItems = Math.floor(_this.scaleinfoX.lineLength / (_this.scaleinfoX.itemwidth * 2));
1362
1359
 
1363
1360
  if (_this.scaleinfoY.type != 'history') {
@@ -1394,28 +1391,28 @@ function Milli_Chart(settings) {
1394
1391
 
1395
1392
  var factor = 60;
1396
1393
  if (numticks < 1)
1397
- _this.scaleinfoX.ticksize = 86400000;
1394
+ _this.scaleinfoX.ticksize = 86400000; // öhh?
1398
1395
  else {
1399
1396
  if (numticks < 2) numticks = 2;
1400
1397
  x = _this.scaleinfoX.milliPerDay / numticks / 60000;
1401
- if (totalmilli > 4 * 3600000) factor = 60;
1398
+ if (totalmilli > 4 * 3600000) factor = 60; // 4 timmar
1402
1399
  else
1403
- if (totalmilli > 2 * 3600000) factor = 30;
1400
+ if (totalmilli > 2 * 3600000) factor = 30; // 2 timmar
1404
1401
  else
1405
- if (totalmilli > 3600000) factor = 20;
1402
+ if (totalmilli > 3600000) factor = 20; // 1 timma
1406
1403
  else
1407
- if (totalmilli > 3600000 / 2) factor = 10;
1404
+ if (totalmilli > 3600000 / 2) factor = 10; // 30 min
1408
1405
  else
1409
- if (totalmilli > 3600000 / 4) factor = 5;
1406
+ if (totalmilli > 3600000 / 4) factor = 5; // 15 min
1410
1407
  else factor = 1;
1411
- _this.scaleinfoX.ticksize = factor * 60000;
1408
+ _this.scaleinfoX.ticksize = factor * 60000; // time to add to next legenditem
1412
1409
  }
1413
1410
  return;
1414
1411
  }
1415
1412
  }
1416
1413
 
1417
1414
  function formatChartTime(value, format) {
1418
-
1415
+ // internal
1419
1416
  if (typeof value !== 'string') return "";
1420
1417
  var datetime = new Date();
1421
1418
  datetime.setHours(parseInt(value));
@@ -1474,7 +1471,7 @@ function Milli_Chart(settings) {
1474
1471
  m_ctx.fillStyle = m_xLegendCss.color;
1475
1472
  m_ctx.textAlign = "left";
1476
1473
  calcXScaleTick(starttime, endtime);
1477
- if (_this.settings.drawxaxis != 0) {
1474
+ if (_this.settings.drawxaxis != 0) { // draw line for legend
1478
1475
  m_ctx.beginPath();
1479
1476
  m_ctx.moveTo(m_chartspaces.chart.left, m_chartspaces.chart.bottom + 0.5);
1480
1477
  m_ctx.lineTo(m_chartspaces.chart.right, m_chartspaces.chart.bottom + 0.5);
@@ -1491,20 +1488,20 @@ function Milli_Chart(settings) {
1491
1488
  var legendItems = [];
1492
1489
  var openhour = new Date(new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z')).getTime() % 86400000;
1493
1490
  var closehour = new Date(new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z')).getTime() % 86400000;
1494
-
1491
+ // add daysstarts
1495
1492
  var middleOfDay = new Date(currentDate.getTime() - (currentDate.getTime() % 86400000) + ((openhour + closehour) / 2));
1496
1493
  if (_this.settings.intradayDatePos.x == 'left' && (_this.settings.intradayDatePos.y == 'scale' || _this.settings.intradayDatePos.y == 'top')) {
1497
1494
  middleOfDay = new Date(currentDate.getTime());
1498
1495
  }
1499
- if (currentDate.getTime() % 3600000 != 0)
1500
- currentDate = new Date(currentDate.getTime() - currentDate.getTime() % 3600000 + 3600000);
1496
+ if (currentDate.getTime() % 3600000 != 0) // if not full hour, move up to next full hour
1497
+ currentDate = new Date(currentDate.getTime() - currentDate.getTime() % 3600000 + 3600000); // START om full hour (if modulo == 0 then + 3600000 kanske)
1501
1498
 
1502
1499
  var firstDate = new Date(currentDate);
1503
1500
  var days = calcTimeSpanInDays(starttime, endtime);
1504
1501
  if (m_zoom.mouseup.timestamp == null || (m_zoom.mouseup.timestamp != null && days > 1)) {
1505
1502
  while (currentDate.getTime() < _this.scaleinfoX.endTimeStamp) {
1506
1503
  draw = true;
1507
- while (currentDate.getDay() == 0 || currentDate.getDay() == 6) {
1504
+ while (currentDate.getDay() == 0 || currentDate.getDay() == 6) { // move past weekends , maybe skip this if date is available in data
1508
1505
  currentDate = new Date(currentDate.getTime() + 86400000);
1509
1506
  if (_this.settings.intradayDatePos.x == 'left' && (_this.settings.intradayDatePos.y == 'scale' || _this.settings.intradayDatePos.y == 'top')) {
1510
1507
  middleOfDay = new Date(currentDate.getTime());
@@ -1523,14 +1520,14 @@ function Milli_Chart(settings) {
1523
1520
  lastx = x + 0.5;
1524
1521
  var text = formatChartTime(currentDate.toTimeString().substring(0, 8), _this.settings.timeformat);
1525
1522
  var date = formatDate(currentDate, _this.settings.intradayDatePos.dateformat, _this);
1526
- if (_this.scaleinfoX.lineLength + m_chartspaces.chart.left > x - getMaxTimeWidth()) {
1523
+ if (_this.scaleinfoX.lineLength + m_chartspaces.chart.left > x - getMaxTimeWidth()) { // not to far right?
1527
1524
  if (_this.settings.intradayDatePos.y == 'scale' && _this.settings.chartlen != '0d' && _this.settings.chartlen != '1d') {
1528
-
1525
+ // draw date on under time, todo fix setting name
1529
1526
  m_ctx.fillText(date, middleX - (m_ctx.measureText(date).width / 2), m_chartspaces.chart.bottom + getScaledSetting(m_xLegendCss.paddingTop));
1530
1527
  legendItems.push({ x: middleX, type: 0, text: date, width: m_ctx.measureText(date) });
1531
1528
  } else if (_this.settings.intradayDatePos.y == 'bottom' && _this.settings.chartlen != '0d' && _this.settings.chartlen != '1d') {
1532
1529
  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);
1533
-
1530
+ // VA FAN DETTA KAN INTE VA RÄTT?
1534
1531
  m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_chartspaces.chart.bottom + getScaledSetting(m_xLegendCss.paddingTop));
1535
1532
  legendItems.push({ x: x, type: 0, text: text });
1536
1533
  } else {
@@ -1550,7 +1547,7 @@ function Milli_Chart(settings) {
1550
1547
  if (_this.settings.intradayDatePos.x == 'center') {
1551
1548
  m_ctx.fillText(date, middleX - (m_ctx.measureText(date).width / 2), getScaledSetting(m_chartCss.marginTop));
1552
1549
  } else {
1553
-
1550
+ //m_ctx.fillText(date, x - (m_ctx.measureText(date).width / 2), getScaledSetting(m_chartCss.marginTop));
1554
1551
  m_ctx.fillText(date, middleX + 1, getScaledSetting(m_chartCss.marginTop));
1555
1552
  }
1556
1553
  }
@@ -1558,17 +1555,17 @@ function Milli_Chart(settings) {
1558
1555
  }
1559
1556
  }
1560
1557
  }
1561
- if (x != m_chartspaces.chart.left + 0.5) {
1558
+ if (x != m_chartspaces.chart.left + 0.5) { // do not draw the first line, it is already drawn
1562
1559
  if (_this.settings.intradayDatePos.y != 'bottom') {
1563
1560
  if (openhour == currentDate.getTime() % 86400000) {
1564
- drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, true);
1561
+ drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, true); // dash?
1565
1562
  } else {
1566
- drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, false);
1563
+ drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, false); // dash?
1567
1564
  }
1568
1565
  }
1569
1566
  }
1570
1567
  }
1571
-
1568
+ // Move to next day and set starting hour correct if we have open at half hour
1572
1569
  currentDate = new Date(currentDate.getTime() + 86400000);
1573
1570
  currentDate = new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z');
1574
1571
  middleOfDay = new Date(currentDate.getTime() - (currentDate.getTime() % 86400000) + ((openhour + closehour) / 2));
@@ -1576,23 +1573,23 @@ function Milli_Chart(settings) {
1576
1573
  middleOfDay = new Date(currentDate);
1577
1574
  }
1578
1575
 
1579
- if (currentDate.getTime() % 3600000 != 0)
1580
- currentDate = new Date(currentDate.getTime() - currentDate.getTime() % 3600000 + 3600000);
1581
-
1576
+ if (currentDate.getTime() % 3600000 != 0) // if not full hour, move up to next full hour
1577
+ currentDate = new Date(currentDate.getTime() - currentDate.getTime() % 3600000 + 3600000); // START om full hour (if modulo == 0 then + 3600000 kanske)
1578
+ //}
1582
1579
  offset += (86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel;
1583
1580
  }
1584
1581
  }
1585
-
1582
+ // add timestamps
1586
1583
  currentDate = new Date(starttime);
1587
- if (currentDate.getTime() % 3600000 != 0)
1588
- currentDate = new Date(currentDate.getTime() - currentDate.getTime() % 3600000 + 3600000);
1584
+ if (currentDate.getTime() % 3600000 != 0) // if not full hour, move up to next full hour
1585
+ currentDate = new Date(currentDate.getTime() - currentDate.getTime() % 3600000 + 3600000); // START om full hour (if modulo == 0 then + 3600000 kanske)
1589
1586
 
1590
1587
  var maxHourLegends;
1591
1588
  if (legendItems.length == 0)
1592
- maxHourLegends = Math.floor((_this.scaleinfoX.lineLength - m_chartspaces.chart.left - getMaxTimeWidth()) / (getMaxTimeWidth() * 3));
1589
+ maxHourLegends = Math.floor((_this.scaleinfoX.lineLength - m_chartspaces.chart.left - getMaxTimeWidth()) / (getMaxTimeWidth() * 3)); // varför tar vi bort margin???
1593
1590
  else if (legendItems.length == 1) {
1594
1591
  if (m_zoom.mouseup.timestamp && days == 2) {
1595
-
1592
+ // ta den största delen av linjen och mät på
1596
1593
  if (_this.scaleinfoX.lineLength / 2 < legendItems[0].x + m_chartspaces.chart.left)
1597
1594
  maxHourLegends = Math.floor((_this.scaleinfoX.lineLength - (_this.scaleinfoX.lineLength - legendItems[0].x) - getMaxTimeWidth()) / (getMaxTimeWidth() * 3));
1598
1595
  else
@@ -1600,15 +1597,15 @@ function Milli_Chart(settings) {
1600
1597
  } else
1601
1598
  maxHourLegends = Math.floor((_this.scaleinfoX.lineLength - legendItems[0].x - getMaxTimeWidth()) / (getMaxTimeWidth() * 3));
1602
1599
  } else {
1603
- maxHourLegends = Math.floor((legendItems[legendItems.length - 1].x - legendItems[legendItems.length - 2].x - getMaxTimeWidth()) / (getMaxTimeWidth() * 3));
1600
+ maxHourLegends = Math.floor((legendItems[legendItems.length - 1].x - legendItems[legendItems.length - 2].x - getMaxTimeWidth()) / (getMaxTimeWidth() * 3)); // calculate with the last days length
1604
1601
  }
1605
1602
 
1606
- var tickSize;
1603
+ var tickSize; // per day
1607
1604
  if (days == 1) {
1608
-
1605
+ // use start and endtime as ticksize
1609
1606
  tickSize = new Date(endtime - starttime);
1610
- } else if (m_zoom.mouseup.timestamp && days == 2) {
1611
-
1607
+ } else if (m_zoom.mouseup.timestamp && days == 2) { // zoom with 2 days
1608
+ // use the day with most time as tickSize
1612
1609
  var tmpDate = new Date(starttime);
1613
1610
  tickSize = new Date(new Date(tmpDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z') - new Date(starttime)).getTime();
1614
1611
  var firstDay = tickSize;
@@ -1617,13 +1614,13 @@ function Milli_Chart(settings) {
1617
1614
  tickSize += new Date(endtime - new Date(tmpDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z').getTime()).getTime();
1618
1615
  tickSize = new Date(Math.max(firstDay, secondDay));
1619
1616
  } else {
1620
-
1617
+ // use full day as tickSize
1621
1618
  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'));
1622
1619
  }
1623
1620
  var interval;
1624
1621
  var modularvalue = 3600000;
1625
1622
 
1626
-
1623
+ // calc the ticksize to add to time(interval) when drawing and the modulu value
1627
1624
  if (tickSize.getTime() < 1800000) {
1628
1625
  tickSize = tickSize.getTime() / 60000;
1629
1626
  interval = Math.floor(tickSize / (maxHourLegends + 1)) * 60000;
@@ -1642,14 +1639,14 @@ function Milli_Chart(settings) {
1642
1639
  interval = Math.floor(tickSize / (maxHourLegends + 1)) * 3600000;
1643
1640
  }
1644
1641
  if (interval == 0) {
1645
-
1642
+ // default 1h
1646
1643
  interval = 3600000;
1647
1644
  modularvalue = 3600000;
1648
1645
  }
1649
1646
  if (interval % 60000 != 0) {
1650
- interval = (interval - interval % 60000) + 60000;
1647
+ interval = (interval - interval % 60000) + 60000; // remove sekunder
1651
1648
  }
1652
-
1649
+ // print other times
1653
1650
  offset = 0;
1654
1651
  lastx = 0;
1655
1652
  var closeTime = new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
@@ -1658,38 +1655,38 @@ function Milli_Chart(settings) {
1658
1655
 
1659
1656
  var workDate = new Date(currentDate);
1660
1657
  currentDate = new Date(starttime);
1661
- if (currentDate.getTime() % modularvalue != 0)
1662
- currentDate = new Date(currentDate.getTime() - currentDate.getTime() % modularvalue + modularvalue);
1658
+ if (currentDate.getTime() % modularvalue != 0) // if not full hour, move up to next full hour
1659
+ currentDate = new Date(currentDate.getTime() - currentDate.getTime() % modularvalue + modularvalue); // START om full hour (if modulo == 0 then + 3600000 kanske)
1663
1660
 
1664
1661
  var count = 0;
1665
1662
  while (currentDate.getTime() <= _this.scaleinfoX.endTimeStamp) {
1666
1663
  dayLightChange = (closeTime.getTimezoneOffset() - new Date().getTimezoneOffset()) * 60000;
1667
1664
  if (count++ > 100) {
1668
- break;
1665
+ break; // just make sure we dont do an infinity loop
1669
1666
 
1670
1667
  }
1671
1668
  draw = true;
1672
- while (currentDate.getDay() == 0 || currentDate.getDay() == 6) {
1673
-
1669
+ while (currentDate.getDay() == 0 || currentDate.getDay() == 6) { // move past weekends , maybe skip this if date is available in data
1670
+ //closeTime = new Date(closeTime.getTime() + 86400000);
1674
1671
  currentDate = new Date(currentDate.getTime() + 86400000);
1675
1672
  closeTime = new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
1676
- if (currentDate.getTime() % modularvalue != 0)
1677
- currentDate = new Date(currentDate.getTime() - currentDate.getTime() % modularvalue + modularvalue);
1673
+ if (currentDate.getTime() % modularvalue != 0) // if not full hour, move up to next full hour
1674
+ currentDate = new Date(currentDate.getTime() - currentDate.getTime() % modularvalue + modularvalue); // START om full hour (if modulo == 0 then + 3600000 kanske)
1678
1675
  workDate = new Date(workDate.getTime() + 86400000);
1679
1676
  offset += 86400000 / _this.scaleinfoX.timePerPixel;
1680
1677
  }
1681
1678
  if (currentDate.getTime() > closeTime.getTime()) {
1682
-
1679
+ // draw DayEnd(start) dash line
1683
1680
  var dayStart = new Date(workDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
1684
1681
  x = Math.round(m_chartspaces.chart.left + ((dayStart.getTime() - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel) - offset);
1685
- drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, true);
1682
+ drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, true); // dash?
1686
1683
 
1687
1684
  closeTime = new Date(closeTime.getTime() + 86400000);
1688
1685
  workDate = new Date(workDate.getTime() + 86400000);
1689
1686
  currentDate = new Date(workDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z');
1690
1687
 
1691
- if (currentDate.getTime() % modularvalue != 0)
1692
- currentDate = new Date(currentDate.getTime() - currentDate.getTime() % modularvalue + modularvalue);
1688
+ if (currentDate.getTime() % modularvalue != 0) // if not full hour, move up to next full hour
1689
+ currentDate = new Date(currentDate.getTime() - currentDate.getTime() % modularvalue + modularvalue); // START om full hour (if modulo == 0 then + 3600000 kanske)
1693
1690
  offset += (86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel;
1694
1691
  continue;
1695
1692
  }
@@ -1709,12 +1706,12 @@ function Milli_Chart(settings) {
1709
1706
  }
1710
1707
  }
1711
1708
  if (lastx + (getMaxTimeWidth() / 2) > (x - getMaxTimeWidth())) {
1712
-
1709
+ //draw = false;
1713
1710
  }
1714
1711
  if (draw) {
1715
1712
  lastx = x;
1716
-
1717
- if (_this.scaleinfoX.lineLength + m_chartspaces.chart.left > x - getMaxTimeWidth()) {
1713
+ // if day change and setting print on top as well
1714
+ if (_this.scaleinfoX.lineLength + m_chartspaces.chart.left > x - getMaxTimeWidth()) { // not to far right?
1718
1715
  var label = formatChartTime(currentDate.toTimeString().substring(0, 8), _this.settings.timeformat);
1719
1716
  x = Math.round(x);
1720
1717
  m_ctx.fillText(label, x - (m_ctx.measureText(label).width / 2), m_chartspaces.chart.bottom + getScaledSetting(m_xLegendCss.paddingTop));
@@ -1725,7 +1722,7 @@ function Milli_Chart(settings) {
1725
1722
  currentDate = new Date(currentDate.getTime() + interval);
1726
1723
  }
1727
1724
 
1728
-
1725
+ // vad är detta?
1729
1726
  if (typeof m_chartCss.boxShadow !== 'undefined' && typeof m_chartCss.boxShadow.rightWidth !== 'undefined') {
1730
1727
  if (m_chartCss.boxShadow.rightWidth == 0) drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, false);
1731
1728
 
@@ -1774,7 +1771,7 @@ function Milli_Chart(settings) {
1774
1771
  m_priceIndicator.setAttribute('class', 'millistream-chart-price-indicator');
1775
1772
  }
1776
1773
  m_priceIndicator.innerHTML = newValue;
1777
- 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???
1778
1775
  m_priceIndicator.style.top = obj.instruments[0].y - (m_priceIndicator.offsetHeight / 2) + 'px';
1779
1776
  newValue = MillistreamWidgetApi_getElementNumber(_this, m_priceIndicator);
1780
1777
  MillistreamWidgetApi_flashElement(_this, m_priceIndicator, newValue, oldValue);
@@ -1861,13 +1858,13 @@ function Milli_Chart(settings) {
1861
1858
  instr.data.price = formatNiceNumber(instr.data.price, _this.settings.thousandseparator, _this.settings.decimalseparator, _this.settings.num_decimals, false);
1862
1859
 
1863
1860
  if (typeof _this.instruments[x].toolTip === 'undefined') {
1864
-
1861
+ // add textdiv
1865
1862
  _this.instruments[x].toolTip = document.createElement('div');
1866
1863
  _this.instruments[x].toolTip.style.display = _this.settings.tooltip.display;
1867
- _this.instruments[x].toolTip.setAttribute('class', 'millistream-chart-tooltip');
1864
+ _this.instruments[x].toolTip.setAttribute('class', 'millistream-chart-tooltip'); // set class so we can measure it might change below depending on position
1868
1865
  _this.instruments[x].toolTip.position = 'absolute';
1869
1866
  m_canvas.parentNode.appendChild(_this.instruments[x].toolTip);
1870
-
1867
+ // add pointer div
1871
1868
  _this.instruments[x].toolTipPointer = document.createElement('div');
1872
1869
  m_canvas.parentNode.appendChild(_this.instruments[x].toolTipPointer);
1873
1870
  _this.instruments[x].toolTipPointer.setAttribute('class', 'millistream-chart-pointer');
@@ -1882,16 +1879,16 @@ function Milli_Chart(settings) {
1882
1879
  var pointerWidth = _this.instruments[x].toolTipPointer.offsetWidth + parseInt(pointerStyle.marginLeft) + parseInt(pointerStyle.marginRight);
1883
1880
  var pointerHeight = _this.instruments[x].toolTipPointer.offsetHeight + parseInt(pointerStyle.marginTop) + parseInt(pointerStyle.marginBottom);
1884
1881
  var posy = obj.instruments[x].y - (_this.instruments[x].toolTip.offsetHeight / 2);
1885
- if (m_dataPoints.arr[i] + (_this.instruments[x].toolTip.offsetWidth * 1.5) > m_canvas.width) {
1886
-
1882
+ 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
1883
+ // draw the hover to the left
1887
1884
  _this.instruments[x].toolTip.style.left = (obj.instruments[x].x - _this.instruments[x].toolTip.offsetWidth - (pointerWidth / 2)) + 1 + 'px';
1888
1885
  } else {
1889
-
1886
+ // draw hover to the right
1890
1887
  _this.instruments[x].toolTip.style.left = (obj.instruments[x].x + (pointerWidth / 2)) + 'px';
1891
1888
  }
1892
1889
  _this.instruments[x].toolTip.style.top = posy + 'px';
1893
1890
  toolArray.push({ top: (obj.instruments[x].y - (pointerHeight / 2)), instrument: x });
1894
- _this.instruments[x].toolTipPointer.style.left = (obj.instruments[x].x - (pointerWidth / 2)) + 1 + 'px';
1891
+ _this.instruments[x].toolTipPointer.style.left = (obj.instruments[x].x - (pointerWidth / 2)) + 1 + 'px'; // hmm plus 1??
1895
1892
  _this.instruments[x].toolTipPointer.style.top = (obj.instruments[x].y - (pointerHeight / 2)) + 'px';
1896
1893
  if (posy > highy) highy = posy;
1897
1894
  if (posy < lowy) lowy = posy;
@@ -1941,7 +1938,7 @@ function Milli_Chart(settings) {
1941
1938
  startdate = startdate.replaceAll('\/', '-');
1942
1939
  enddate = enddate.replaceAll('\/', '-');
1943
1940
  m_zoom.mousedown.timestamp = findFirstWeekDay(new Date(startdate + 'T00:00:00Z'));
1944
- () => {};
1941
+ console.log(new Date(startdate + 'T00:00:00Z'), findFirstWeekDay(new Date(startdate + 'T00:00:00Z')), m_zoom.mousedown.timestamp);
1945
1942
 
1946
1943
  m_zoom.mouseup.timestamp = new Date(enddate + 'T00:00:00Z');
1947
1944
 
@@ -1985,7 +1982,7 @@ function Milli_Chart(settings) {
1985
1982
  }
1986
1983
  }
1987
1984
  }
1988
- if (_this.scaleinfoY.type == 'trades' && count > 0 && _this.instruments[0].closeprice1d) return true;
1985
+ if (_this.scaleinfoY.type == 'trades' && count > 0 && _this.instruments[0].closeprice1d) return true; // we can draw on closeprice 1d -> first trade
1989
1986
  var y = (m_chartspaces.chart.bottom - m_chartspaces.chart.top) / 2 + m_chartspaces.chart.top;
1990
1987
  var x = (m_chartspaces.chart.right - m_chartspaces.chart.left) / 2 + m_chartspaces.chart.left;
1991
1988
  m_ctx.save();
@@ -2017,7 +2014,7 @@ function Milli_Chart(settings) {
2017
2014
 
2018
2015
  _this.drawChart = function() {
2019
2016
  if (m_zoom.isZooming) {
2020
- return;
2017
+ return; // prevent redraw due to push updates when zooming
2021
2018
  }
2022
2019
 
2023
2020
  for (var i = 0; i < _this.settings.indicators.length; i++) {
@@ -2060,7 +2057,7 @@ function Milli_Chart(settings) {
2060
2057
  m_dataPoints.map = new Map();
2061
2058
  m_dataPoints.arr = [];
2062
2059
  if (_this.instruments.length < 0) {
2063
- () => {};
2060
+ console.log('no chartdata');
2064
2061
  return;
2065
2062
  }
2066
2063
  calcChartSpaces();
@@ -2069,42 +2066,42 @@ function Milli_Chart(settings) {
2069
2066
  var len = parseInt(_this.settings.chartlen.substring(0, _this.settings.chartlen.length - 1));
2070
2067
  m_ctx.clearRect(0, 0, m_canvas.width, m_canvas.height);
2071
2068
  m_ctx.lineWidth = 1 / window.devicePixelRatio;
2072
- m_ctx.textBaseline = 'top';
2069
+ m_ctx.textBaseline = 'top'; // important!
2073
2070
  var i;
2074
2071
  if (period == 'd' && _this.settings.chartlen != 'ytd') {
2075
2072
  if (m_zoom.mousedown.timestamp) {
2076
2073
  _this.scaleinfoX.endTimeStamp = m_zoom.mouseup.timestamp > m_zoom.mousedown.timestamp ? m_zoom.mouseup.timestamp : m_zoom.mousedown.timestamp;
2077
2074
  _this.scaleinfoX.startTimeStamp = m_zoom.mouseup.timestamp < m_zoom.mousedown.timestamp ? m_zoom.mouseup.timestamp : m_zoom.mousedown.timestamp;
2078
2075
  } else {
2079
- _this.scaleinfoX.startTimeStamp = getTickStartDate(len);
2080
-
2081
-
2076
+ _this.scaleinfoX.startTimeStamp = getTickStartDate(len); // calc not to start with weekends
2077
+ // back up x days from quotedate if needed
2078
+ // TODO if startTimeStamp < quotedate -len borde det vara
2082
2079
  var quoteDate = businessDaysSubtraction(_this.instruments[0].quotedate, len);
2083
- if (_this.scaleinfoX.startTimeStamp - _this.scaleinfoX.startTimeStamp % 86400000 > quoteDate) {
2080
+ if (_this.scaleinfoX.startTimeStamp - _this.scaleinfoX.startTimeStamp % 86400000 > quoteDate) { // if startdate > quotedate back startdate
2084
2081
  _this.scaleinfoX.startTimeStamp -= _this.scaleinfoX.startTimeStamp - _this.scaleinfoX.startTimeStamp % 86400000;
2085
2082
  _this.scaleinfoX.startTimeStamp += quoteDate;
2086
2083
  }
2087
- _this.scaleinfoX.endTimeStamp = new Date();
2084
+ _this.scaleinfoX.endTimeStamp = new Date(); // om helg TODO
2088
2085
  if (len > 1)
2089
2086
  _this.scaleinfoX.endTimeStamp = new Date(_this.scaleinfoX.endTimeStamp.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z').getTime();
2090
2087
  else if (len == 1) {
2091
-
2088
+ // check if startdate is not today (due to exchange is closed f ex DJ)
2092
2089
  if (_this.scaleinfoX.startTimeStamp % 86400000 != new Date().getTime() % 86400) {
2093
2090
  _this.scaleinfoX.endTimeStamp = new Date(new Date(_this.scaleinfoX.startTimeStamp).toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z').getTime();
2094
2091
  } else
2095
2092
  _this.scaleinfoX.endTimeStamp = new Date(_this.scaleinfoX.endTimeStamp.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z').getTime();
2096
2093
  } else {
2097
-
2094
+ // check that the last trade is not later than closetime
2098
2095
  var tradetimestamp = new Date(_this.instruments[0].trades[_this.instruments[0].trades.length - 1].timestamp).getTime();
2099
2096
  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();
2100
2097
  if (closetimestamp < tradetimestamp)
2101
- _this.scaleinfoX.endTimeStamp = new Date(closetimestamp);
2098
+ _this.scaleinfoX.endTimeStamp = new Date(closetimestamp); // borde inte rita med closeprice1d då heller eller spelar det ingen roll?
2102
2099
  else
2103
2100
  _this.scaleinfoX.endTimeStamp = new Date(tradetimestamp);
2104
2101
  }
2105
2102
  if (_this.scaleinfoX.endTimeStamp - (_this.scaleinfoX.endTimeStamp % 86400000) > _this.instruments[0].quotedate) {
2106
2103
  _this.scaleinfoX.endTimeStamp -= _this.scaleinfoX.endTimeStamp - _this.scaleinfoX.endTimeStamp % 86400000;
2107
- _this.scaleinfoX.endTimeStamp += _this.instruments[0].quotedate;
2104
+ _this.scaleinfoX.endTimeStamp += _this.instruments[0].quotedate; // set enddate = last Quotedate
2108
2105
  }
2109
2106
  }
2110
2107
  setTimeSpanData();
@@ -2113,7 +2110,7 @@ function Milli_Chart(settings) {
2113
2110
  for (var s = 1; s < _this.instruments.length; s++) _this.instruments[s].factor = 1;
2114
2111
  } else
2115
2112
  if (_this.instruments.length > 1) {
2116
-
2113
+ // calc factors
2117
2114
  var instrumentprice;
2118
2115
  for (i = 0; i < _this.instruments[0].trades.length; i++) {
2119
2116
  if (_this.instruments[0].trades[i].timestamp >= _this.scaleinfoX.startTimeStamp) {
@@ -2150,7 +2147,7 @@ function Milli_Chart(settings) {
2150
2147
 
2151
2148
  } else
2152
2149
  if (period == 'm') {
2153
- () => {};
2150
+ console.log('mon');
2154
2151
 
2155
2152
  if (m_zoom.mousedown.timestamp) {
2156
2153
  _this.scaleinfoX.startTimeStamp = m_zoom.mousedown.timestamp > m_zoom.mouseup.timestamp ? m_zoom.mouseup.timestamp : m_zoom.mousedown.timestamp;
@@ -2165,7 +2162,7 @@ function Milli_Chart(settings) {
2165
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;
2166
2163
 
2167
2164
  _this.scaleinfoX.endTimeStamp = new Date().getTime();
2168
- _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?
2169
2166
  }
2170
2167
  setTimeSpanData();
2171
2168
  _this.scaleinfoY.type = 'history';
@@ -2200,7 +2197,7 @@ function Milli_Chart(settings) {
2200
2197
  _this.scaleinfoX.startTimeStamp = _this.instruments[0].history[0].timestamp;
2201
2198
  } else
2202
2199
  if (_this.settings.chartlen == 'ytd') {
2203
- _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?
2204
2201
  } else {
2205
2202
  _this.scaleinfoX.startTimeStamp = new Date().getTime() - (86400000 * 365 * (isNaN(len) ? 1 : len));
2206
2203
  }
@@ -2208,7 +2205,7 @@ function Milli_Chart(settings) {
2208
2205
  _this.scaleinfoX.startTimeStamp = findFirstWeekDay(_this.scaleinfoX.startTimeStamp).getTime();
2209
2206
 
2210
2207
  _this.scaleinfoX.endTimeStamp = new Date().getTime();
2211
- _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?
2212
2209
  }
2213
2210
  setTimeSpanData();
2214
2211
  _this.scaleinfoY.type = 'history';
@@ -2230,10 +2227,10 @@ function Milli_Chart(settings) {
2230
2227
 
2231
2228
  }
2232
2229
 
2233
-
2234
-
2235
-
2236
-
2230
+ /*for (const [key, a] of m_analyzisMethod.entries()) {
2231
+ if (a.method == 'bb') plotBollingerBand(a, 'history');
2232
+ else plotMovingAverage(a, 'history');
2233
+ }*/
2237
2234
  }
2238
2235
  drawBoxShadow(m_chartspaces.chart);
2239
2236
 
@@ -2247,11 +2244,11 @@ function Milli_Chart(settings) {
2247
2244
  if (_this.settings.curveOnTop == false)
2248
2245
  m_ctx.globalCompositeOperation = 'destination-over'
2249
2246
  m_ctx.fillStyle = m_chartCss.backgroundColor;
2250
-
2247
+ //m_ctx.fillRect(0, 0, m_canvas.width, m_canvas.height);
2251
2248
  m_ctx.fillRect(0, 0, m_canvas.width, m_canvas.height);
2252
2249
  m_ctx.restore();
2253
2250
  }
2254
-
2251
+ //onMouseOut();
2255
2252
  };
2256
2253
 
2257
2254
  function drawBoxShadow(space) {
@@ -2289,7 +2286,7 @@ function Milli_Chart(settings) {
2289
2286
 
2290
2287
  if (typeof data.tradecurrency !== 'undefined') instr.tradecurrency = data.tradecurrency;
2291
2288
  if (data.marketopen && data.marketclose) {
2292
- if (new Date('2020-01-01T' + data.marketopen + 'Z') > new Date('2020-01-01T' + data.marketclose + 'Z')) {
2289
+ 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
2293
2290
  data.marketopen = '00:00:00';
2294
2291
  data.marketclose = '22:00:00';
2295
2292
  }
@@ -2321,7 +2318,7 @@ function Milli_Chart(settings) {
2321
2318
  instr.trades = [];
2322
2319
  instr.hashmap.clear();
2323
2320
  for (i = 0; i < data.trades.length; i++) {
2324
- if (data.trades[i].tradecode & 16) {
2321
+ if (data.trades[i].tradecode & 16) { // canceltrade
2325
2322
  continue;
2326
2323
  }
2327
2324
  item = [];
@@ -2338,7 +2335,7 @@ function Milli_Chart(settings) {
2338
2335
  }
2339
2336
  instr.trades.push(item);
2340
2337
  instr.hashmap.set(item.timestamp, item);
2341
-
2338
+ // we might have recieved trades from push before dataapi
2342
2339
  instr.trades.sort(function(a, b) {
2343
2340
  return a.timestamp - b.timestamp;
2344
2341
  });
@@ -2351,7 +2348,7 @@ function Milli_Chart(settings) {
2351
2348
  instr.history = [];
2352
2349
  for (i = 0; i < data.history.length; i++) {
2353
2350
  item = [];
2354
- if (typeof data.history[i].date !== 'undefined' && data.history[i].closeprice != null) {
2351
+ 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å
2355
2352
  var timestamp = new Date(data.history[i].date + 'T00:00:00Z').getTime();
2356
2353
  item.timestamp = timestamp;
2357
2354
  } else continue;
@@ -2361,7 +2358,7 @@ function Milli_Chart(settings) {
2361
2358
  if (typeof data.history[i].dividend !== 'undefined') item.dividend = data.history[i].dividend;
2362
2359
  instr.history.push(item);
2363
2360
  }
2364
- if (_this.settings.hcurve && instr.history.length > 0) {
2361
+ if (_this.settings.hcurve && instr.history.length > 0) { // varför på all historik, och inte bara på hcurve
2365
2362
  if (!isToday(new Date(instr.history[instr.history.length - 1].timestamp))) {
2366
2363
  var addItem = {};
2367
2364
  MillistreamWidgetApi_AssignObject(instr.history[instr.history.length - 1], addItem);
@@ -2386,7 +2383,7 @@ function Milli_Chart(settings) {
2386
2383
  };
2387
2384
 
2388
2385
  function plotExternalHistoricalData(data) {
2389
-
2386
+ // används för dividend osv
2390
2387
  m_ctx.save();
2391
2388
  var startpoint = { x: 0, y: 0 };
2392
2389
  var endpoint = { x: 0, y: 0 };
@@ -2410,25 +2407,25 @@ function Milli_Chart(settings) {
2410
2407
  currentDate.setMinutes(lastdate.getMinutes());
2411
2408
  currentDate.setSeconds(lastdate.getSeconds());
2412
2409
 
2413
- if (lastdate.toISOString().substring(0, 10) != currentDate.toISOString().substring(0, 10)) {
2410
+ if (lastdate.toISOString().substring(0, 10) != currentDate.toISOString().substring(0, 10)) { // new date
2414
2411
  var tmp = new Date(lastdate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
2415
2412
  var nextDate = new Date(data[i].timestamp);
2416
- tmp = tmp.getTime() + 86400000 - _this.scaleinfoX.milliPerDay;
2413
+ tmp = tmp.getTime() + 86400000 - _this.scaleinfoX.milliPerDay; // increase to next days starttime
2417
2414
  currentDate = new Date(tmp);
2418
2415
  while (dateDiffInDays(currentDate, nextDate) > 0) {
2419
2416
  if (currentDate.getDay() == 0 || currentDate.getDay() == 6)
2420
2417
  offset += 86400000 / _this.scaleinfoX.timePerPixel;
2421
2418
  else
2422
- offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel);
2419
+ offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel); // * dateDiffInDays(lastdate, currentDate);
2423
2420
  currentDate = new Date(currentDate.getTime() + 86400000);
2424
2421
  }
2425
- offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel);
2422
+ offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel); // * dateDiffInDays(lastdate, currentDate);
2426
2423
  lastdate = currentDate;
2427
2424
  startpoint.x = Math.round(m_chartspaces.chart.left + ((data[i].timestamp - startDate) / _this.scaleinfoX.timePerPixel)) + 0.5 - offset;
2428
-
2425
+ // TODO: här blir det fel när det är från 00:00: 23:59 men göms av tmpx < startpoint.x
2429
2426
 
2430
2427
  }
2431
-
2428
+ //startpoint.y = Math.round(m_canvas.height - getScaledSetting(m_chartCss.marginBottom) - (((data[i].price * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2432
2429
  startpoint.y = Math.round(m_chartspaces.chart.height - getScaledSetting(m_chartCss.marginBottom) - (((data[i].price * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2433
2430
  maxy = maxy > startpoint.y ? maxy : startpoint.y;
2434
2431
 
@@ -2470,19 +2467,19 @@ function Milli_Chart(settings) {
2470
2467
  var endtimeToday = new Date(data[i].timestamp);
2471
2468
  if (endtimeToday.getDay() == 0 || endtimeToday.getDay() == 6) continue;
2472
2469
  if (_this.scaleinfoY.type != 'history') {
2473
- endtimeToday = new Date(endtimeToday.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
2470
+ 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
2474
2471
  }
2475
2472
  if (data[i].timestamp > endtimeToday.getTime()) {
2476
- continue;
2473
+ continue; // dataticks efter stängning ritas inte
2477
2474
  }
2478
2475
  currentDate = new Date(data[i].timestamp);
2479
2476
  currentDate.setHours(lastdate.getHours());
2480
2477
  currentDate.setMinutes(lastdate.getMinutes());
2481
2478
  currentDate.setSeconds(lastdate.getSeconds());
2482
- if (lastdate.toISOString().substring(0, 10) != currentDate.toISOString().substring(0, 10)) {
2479
+ if (lastdate.toISOString().substring(0, 10) != currentDate.toISOString().substring(0, 10)) { // new date
2483
2480
  tmp = new Date(lastdate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
2484
2481
  var nextDate = new Date(data[i].timestamp);
2485
- tmp = tmp.getTime() + 86400000 - _this.scaleinfoX.milliPerDay;
2482
+ tmp = tmp.getTime() + 86400000 - _this.scaleinfoX.milliPerDay; // increase to next days starttime
2486
2483
 
2487
2484
  currentDate = new Date(tmp);
2488
2485
  while (dateDiffInDays(currentDate, nextDate) > 0) {
@@ -2492,11 +2489,11 @@ function Milli_Chart(settings) {
2492
2489
  offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel);
2493
2490
  currentDate = new Date(currentDate.getTime() + 86400000);
2494
2491
  }
2495
- offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel);
2492
+ offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel); // * dateDiffInDays(lastdate, currentDate);
2496
2493
  lastdate = currentDate;
2497
2494
  startpoint.x = Math.round(m_chartspaces.chart.left + ((data[i].timestamp - startDate) / _this.scaleinfoX.timePerPixel)) + 0.5 - offset;
2498
2495
 
2499
-
2496
+ // TODO: här blir det fel när det är från 00:00: 23:59 men göms av tmpx < startpoint.x
2500
2497
  if (_this.scaleinfoY.type == 'trades' && tmpx < startpoint.x) {
2501
2498
  ret.push(startpoint.x, startpoint.y);
2502
2499
  }
@@ -2532,7 +2529,7 @@ function Milli_Chart(settings) {
2532
2529
  if (line.length == 0) return;
2533
2530
  m_ctx.save();
2534
2531
  m_ctx.beginPath();
2535
- m_ctx.closePath();
2532
+ m_ctx.closePath(); // clear path
2536
2533
  m_ctx.moveTo(line[0].x, line[0].y);
2537
2534
  for (var i = 1; i < line.length; i++) {
2538
2535
  m_ctx.lineTo(line[i].x, line[i].y);
@@ -2563,7 +2560,7 @@ function Milli_Chart(settings) {
2563
2560
  }
2564
2561
  var sma = calcAnalyzisLine(data, 2);
2565
2562
  m_ctx.beginPath();
2566
- m_ctx.closePath();
2563
+ m_ctx.closePath(); // clear path
2567
2564
  m_ctx.moveTo(sma[0].x, sma[0].y);
2568
2565
  for (i = 0; i < sma.length; i++) m_ctx.lineTo(sma[i].x, sma[i].y);
2569
2566
  m_ctx.stroke();
@@ -2574,7 +2571,7 @@ function Milli_Chart(settings) {
2574
2571
  function plotData(data, instrument) {
2575
2572
  m_ctx.save();
2576
2573
  if (_this.settings.curveOnTop == false)
2577
- m_ctx.globalCompositeOperation = 'destination-over';
2574
+ m_ctx.globalCompositeOperation = 'destination-over'; // dont draw over labels inside the chart
2578
2575
  m_ctx.strokeStyle = m_instrumentCss[instrument].color;
2579
2576
  var factor = _this.instruments[instrument].factor;
2580
2577
  var startpoint = { x: 0, y: 0 };
@@ -2595,7 +2592,7 @@ function Milli_Chart(settings) {
2595
2592
 
2596
2593
  for (var i = 0; i < len; i++) {
2597
2594
  var currentDate;
2598
-
2595
+ // var lastItem = data[i];
2599
2596
  var tmpx = startpoint.x;
2600
2597
  var tmp;
2601
2598
  if (data[i].timestamp < _this.scaleinfoX.startTimeStamp) {
@@ -2603,42 +2600,42 @@ function Milli_Chart(settings) {
2603
2600
  continue;
2604
2601
  }
2605
2602
  if (data[i].timestamp > _this.scaleinfoX.endTimeStamp) {
2606
- break;
2603
+ break; // continue?
2607
2604
  }
2608
2605
  if (data[i].timestamp > new Date().getTime())
2609
2606
  break;
2610
2607
 
2611
2608
  if (_this.scaleinfoY.type != 'history' && (data[i].timestamp % 86400000 < _this.instruments[0].opentimestamp || data[i].timestamp % 86400000 > _this.instruments[0].closetimestamp)) {
2612
-
2609
+ // stämmer detta kan det bli överlapp vid sommartid/vintertid?
2613
2610
  continue;
2614
2611
  }
2615
2612
  var endtimeToday = new Date(data[i].timestamp);
2616
- if (endtimeToday.getDay() == 0 || endtimeToday.getDay() == 6) continue;
2613
+ 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
2617
2614
  if (_this.scaleinfoY.type != 'history') {
2618
- endtimeToday = new Date(endtimeToday.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
2615
+ 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
2619
2616
  }
2620
2617
  if (data[i].timestamp > endtimeToday.getTime()) {
2621
- continue;
2618
+ continue; // dataticks efter stängning ritas inte
2622
2619
  }
2623
2620
 
2624
2621
  if (_this.scaleinfoY.type == 'history') {
2625
-
2626
-
2622
+ //var point = { price: data[i].price, open: null, x: endpoint.x - 0.5, y: endpoint.y - 0.5, timestamp: data[i].timestamp };
2623
+ //m_datapoints.push(point);
2627
2624
  } else
2628
- if (_this.settings.previousDayClose && addedcloseprice1d == false && m_zoom.mouseup.timestamp == null) {
2625
+ if (_this.settings.previousDayClose && addedcloseprice1d == false && m_zoom.mouseup.timestamp == null) { // only draw closeprice1d on today charts
2629
2626
  currentDate = new Date(data[i].timestamp);
2630
2627
  offset = ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel) * dateDiffInDays(new Date(startDate), currentDate);
2631
2628
  tmp = new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z');
2632
2629
  endpoint.x = Math.round(m_chartspaces.chart.left + ((tmp.getTime() - startDate) / _this.scaleinfoX.timePerPixel)) + 0.5 - offset;
2633
2630
 
2634
-
2631
+ //endpoint.y = Math.round(m_chartspaces.chart.height - getScaledSetting(m_chartCss.marginBottom) - (((parseFloat(_this.instruments[instrument].startValue) * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2635
2632
  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;
2636
2633
 
2637
-
2638
-
2639
-
2640
-
2641
-
2634
+ /*if (_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d') { // plot the closeprice1d
2635
+ endpoint.y = Math.round(m_chartspaces.chart.height - getScaledSetting(m_chartCss.marginBottom) - (((parseFloat(_this.instruments[instrument].closeprice1d) * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2636
+ } else {
2637
+ endpoint.y = Math.round(m_chartspaces.chart.height - getScaledSetting(m_chartCss.marginBottom) - (((parseFloat(lastItem.price) * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2638
+ }*/
2642
2639
  m_ctx.moveTo(endpoint.x, endpoint.y);
2643
2640
  lastdate = new Date(data[i].timestamp);
2644
2641
  addedcloseprice1d = true;
@@ -2649,25 +2646,25 @@ function Milli_Chart(settings) {
2649
2646
  currentDate.setHours(lastdate.getHours());
2650
2647
  currentDate.setMinutes(lastdate.getMinutes());
2651
2648
  currentDate.setSeconds(lastdate.getSeconds());
2652
- if (lastdate.toISOString().substring(0, 10) != currentDate.toISOString().substring(0, 10)) {
2649
+ if (lastdate.toISOString().substring(0, 10) != currentDate.toISOString().substring(0, 10)) { // new date
2653
2650
  tmp = new Date(lastdate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
2654
-
2651
+ // draw Day separator?
2655
2652
  var nextDate = new Date(data[i].timestamp);
2656
- tmp = tmp.getTime() + 86400000 - _this.scaleinfoX.milliPerDay;
2653
+ tmp = tmp.getTime() + 86400000 - _this.scaleinfoX.milliPerDay; // increase to next days starttime
2657
2654
 
2658
2655
  currentDate = new Date(tmp);
2659
2656
  while (dateDiffInDays(currentDate, nextDate) > 0) {
2660
2657
  if (currentDate.getDay() == 0 || currentDate.getDay() == 6)
2661
2658
  offset += 86400000 / _this.scaleinfoX.timePerPixel;
2662
2659
  else
2663
- offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel);
2660
+ offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel); // * dateDiffInDays(lastdate, currentDate);
2664
2661
  currentDate = new Date(currentDate.getTime() + 86400000);
2665
2662
  }
2666
- offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel);
2663
+ offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel); // * dateDiffInDays(lastdate, currentDate);
2667
2664
  lastdate = currentDate;
2668
2665
  startpoint.x = Math.round(m_chartspaces.chart.left + ((data[i].timestamp - startDate) / _this.scaleinfoX.timePerPixel)) + 0.5 - offset;
2669
2666
 
2670
-
2667
+ // TODO: här blir det fel när det är från 00:00: 23:59 men göms av tmpx < startpoint.x
2671
2668
  if (_this.scaleinfoY.type == 'trades' && tmpx < startpoint.x) {
2672
2669
  m_ctx.lineTo(startpoint.x, startpoint.y);
2673
2670
  }
@@ -2696,7 +2693,7 @@ function Milli_Chart(settings) {
2696
2693
  if (tmpx < startpoint.x) {
2697
2694
  if (_this.settings.hcurve) m_ctx.lineTo(startpoint.x, endpoint.y);
2698
2695
  m_ctx.lineTo(startpoint.x, startpoint.y);
2699
-
2696
+ //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"
2700
2697
 
2701
2698
  if (instrument == 0) {
2702
2699
  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 };
@@ -2713,7 +2710,7 @@ function Milli_Chart(settings) {
2713
2710
  m_datapoints.push(point);
2714
2711
  if (_this.settings.hcurve && _this.scaleinfoY.type == 'history') {
2715
2712
  if (isToday(currentDate)) {
2716
-
2713
+ // only 1 point in hcurve chart, draw line from start of chart to end date
2717
2714
  m_ctx.moveTo(m_chartspaces.chart.left, startpoint.y);
2718
2715
  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 };
2719
2716
  m_datapoints.push(point);
@@ -2721,12 +2718,12 @@ function Milli_Chart(settings) {
2721
2718
  m_datapoints.push(point);
2722
2719
  startx = m_chartspaces.chart.left;
2723
2720
  starty = startpoint.y;
2724
-
2721
+ // last point so break out and store startx and starty from fake point
2725
2722
  break;
2726
2723
  } else if (hCurveLastPoint) {
2727
-
2728
-
2729
-
2724
+ /* var y = Math.round(m_canvas.height - getScaledSetting(m_chartCss.marginBottom) - (((hCurveLastPoint.price * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2725
+ m_ctx.moveTo(m_chartspaces.chart.left, y);
2726
+ m_ctx.lineTo(startpoint.x, y);*/
2730
2727
  }
2731
2728
  }
2732
2729
  quantity = 0;
@@ -2739,7 +2736,7 @@ function Milli_Chart(settings) {
2739
2736
  endpoint.y = startpoint.y;
2740
2737
  }
2741
2738
  if (data[i].dividend) {
2742
-
2739
+ //console.log('div', data[i]);
2743
2740
  }
2744
2741
  }
2745
2742
  m_dataPoints.arr.sort(function(a, b) {
@@ -2763,7 +2760,7 @@ function Milli_Chart(settings) {
2763
2760
  m_ctx.fill();
2764
2761
  } else
2765
2762
  m_ctx.closePath();
2766
-
2763
+ // 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???
2767
2764
  if (instrument == 0) {
2768
2765
  drawPriceIndicator();
2769
2766
  drawClosePriceIndicator();
@@ -2772,13 +2769,13 @@ function Milli_Chart(settings) {
2772
2769
  m_ctx.restore();
2773
2770
  }
2774
2771
 
2775
-
2776
-
2777
-
2778
-
2779
-
2780
-
2781
-
2772
+ /* function drawCompare(resp) {
2773
+ parseData(resp[0], 1);
2774
+ _this.drawChart();
2775
+ requestStreaming();
2776
+ return;
2777
+ }
2778
+ */
2782
2779
 
2783
2780
  _this.setChartLength = function(len) {
2784
2781
  _this.settings.chartlen = len;
@@ -2910,7 +2907,7 @@ function Milli_Chart(settings) {
2910
2907
  };
2911
2908
  req.open("GET", url, true);
2912
2909
  req.onerror = function(error) {
2913
- () => {};
2910
+ console.log('Fetch data error', error);
2914
2911
  };
2915
2912
  req.send();
2916
2913
  }
@@ -2922,9 +2919,9 @@ function Milli_Chart(settings) {
2922
2919
  fetchHistory(c.insref);
2923
2920
  }
2924
2921
  });
2925
-
2922
+ //fetch data and redraw ( for no push charts)
2926
2923
  };
2927
-
2924
+ // Compare functions
2928
2925
  _this.removeAllCompares = function() {
2929
2926
  if (_this.instruments.length == 1) return;
2930
2927
  for (var i = 0; i < 3; i++)
@@ -2975,7 +2972,7 @@ function Milli_Chart(settings) {
2975
2972
  fetchHistory(insref);
2976
2973
  return 1;
2977
2974
  };
2978
-
2975
+ // Size functions
2979
2976
 
2980
2977
  function setChartSize() {
2981
2978
  var offset = 0;
@@ -2984,8 +2981,8 @@ function Milli_Chart(settings) {
2984
2981
  }
2985
2982
  _this.settings.target.style.height = (_this.settings.target.parentNode.offsetHeight - offset) + 'px';
2986
2983
  _this.settings.target.style.width = _this.settings.target.parentNode.offsetWidth + 'px';
2987
-
2988
-
2984
+ //_this.settings.target.style.height = (_this.settings.target.parentNode.offsetHeight - offset) * window.devicePixelRatio + 'px';
2985
+ //_this.settings.target.style.width = _this.settings.target.parentNode.offsetWidth * window.devicePixelRatio + 'px';
2989
2986
  m_canvas.setRect(_this.settings.target.offsetHeight, _this.settings.target.offsetWidth);
2990
2987
  }
2991
2988
 
@@ -3005,8 +3002,8 @@ function Milli_Chart(settings) {
3005
3002
  diff = (m_resizing.width - m_canvas.width) / m_canvas.width * 100;
3006
3003
  if (Math.abs(diff) > 1) {
3007
3004
  setChartSize();
3008
-
3009
-
3005
+ //m_canvas.height = Math.floor(_this.settings.target.offsetHeight * window.devicePixelRatio);
3006
+ //m_canvas.width = Math.floor(_this.settings.target.offsetWidth * window.devicePixelRatio);
3010
3007
  m_resizing.width = m_canvas.width;
3011
3008
  m_resizing.height = m_canvas.height;
3012
3009
  _this.drawChart();
@@ -3038,11 +3035,11 @@ function Milli_Chart(settings) {
3038
3035
  m_canvas = MillistreamWidgetApi_addElement(_this, 'canvas', 'millistream-chart-canvas', _this.settings.target);
3039
3036
  m_ctx = m_canvas.getContext("2d");
3040
3037
  setChartSize();
3041
- m_canvas.addEventListener('mousemove', onMouseMove, false);
3038
+ m_canvas.addEventListener('mousemove', onMouseMove, false); // disable while loading and enable on drawReady
3042
3039
  m_canvas.addEventListener('mouseout', onMouseOut, false);
3043
3040
  m_canvas.style.cursor = "crosshair";
3044
3041
  m_canvas.onmousedown = (function(evt) {
3045
- if (!evt.which == 1) return;
3042
+ if (!evt.which == 1) return; // ignore right and middle
3046
3043
  if (_this.settings.enablezoom == false) return;
3047
3044
  if (m_datapoints.length == 0) return;
3048
3045
  var rect = m_canvas.getBoundingClientRect();
@@ -3068,7 +3065,7 @@ function Milli_Chart(settings) {
3068
3065
  clearZoom();
3069
3066
  return;
3070
3067
  }
3071
- if (Math.abs(x - m_zoom.mousedown.pos) > 5) {
3068
+ if (Math.abs(x - m_zoom.mousedown.pos) > 5) { // only handle zoom with 5 pixels width
3072
3069
  var i;
3073
3070
  for (i = m_datapoints.length - 1; i > 0; i--) {
3074
3071
  if (x >= m_datapoints[i].x) {
@@ -3085,7 +3082,7 @@ function Milli_Chart(settings) {
3085
3082
  m_zoom.mousedown.pos = 0;
3086
3083
  m_zoom.mousedown.i = 0;
3087
3084
  if (m_zoom.mousedown.oldtimestamp != null) {
3088
- m_zoom.mousedown.timestamp = m_zoom.mousedown.oldtimestamp;
3085
+ m_zoom.mousedown.timestamp = m_zoom.mousedown.oldtimestamp; // so we do not unzoom if zoomed
3089
3086
  m_zoom.mousedown.oldtimestamp = null;
3090
3087
  } else
3091
3088
  m_zoom.mousedown.timestamp = null;
@@ -3173,27 +3170,27 @@ function Milli_Chart(settings) {
3173
3170
  var data = instr.hashmap.get(timestamp);
3174
3171
  if (typeof data === 'undefined') {
3175
3172
  data = {};
3176
-
3173
+ //data.tradereference = json['14'];
3177
3174
  data.timestamp = timestamp;
3178
3175
  calcAnalyizis = true;
3179
3176
  if (instr.pricetype == 'price') {
3180
3177
  update = true;
3181
- data.price = parseFloat(json['12']);
3182
- data.open = parseFloat(json['12']);
3183
- data.high = parseFloat(json['12']);
3184
- data.low = parseFloat(json['12']);
3178
+ data.price = parseFloat(json['12']); // eller 201 för tradeyield
3179
+ data.open = parseFloat(json['12']); // eller 201 för tradeyield
3180
+ data.high = parseFloat(json['12']); // eller 201 för tradeyield
3181
+ data.low = parseFloat(json['12']); // eller 201 för tradeyield
3185
3182
  data.quantity = typeof json['13'] === 'undefined' ? 0 : parseInt(json['13']);
3186
3183
  } else if (instr.pricetype == 'price') {
3187
- data.price = parseFloat(json['201']);
3188
- data.open = parseFloat(json['201']);
3189
- data.high = parseFloat(json['201']);
3190
- data.low = parseFloat(json['201']);
3184
+ data.price = parseFloat(json['201']); // eller 201 för tradeyield
3185
+ data.open = parseFloat(json['201']); // eller 201 för tradeyield
3186
+ data.high = parseFloat(json['201']); // eller 201 för tradeyield
3187
+ data.low = parseFloat(json['201']); // eller 201 för tradeyield
3191
3188
  data.quantity = typeof json['13'] === 'undefined' ? 0 : parseInt(json['13']);
3192
3189
  update = true;
3193
3190
  }
3194
3191
  if (update) {
3195
3192
  if (instr.trades.length != 0 && data.timestamp < instr.trades[instr.trades.length - 1].timestamp) {
3196
-
3193
+ // TODO console.log("pushtrade is older than last trade ignoring, should file it on correct postition");
3197
3194
  } else
3198
3195
  instr.hashmap.set(data.timestamp, data);
3199
3196
  instr.trades.push(data);
@@ -3202,24 +3199,24 @@ function Milli_Chart(settings) {
3202
3199
  if (instr.pricetype == 'price') {
3203
3200
  if (data.price != parseFloat(json['12']))
3204
3201
  calcAnalyizis = true;
3205
- data.price = parseFloat(json['12']);
3202
+ data.price = parseFloat(json['12']); // eller 201 för tradeyield
3206
3203
  data.quantity += typeof json['13'] === 'undefined' ? 0 : parseInt(json['13']);
3207
3204
  if (_this.scaleinfoY.type == 'trades') update = true;
3208
3205
  } else {
3209
3206
  if (instr.pricetype == 'price') {
3210
3207
  if (data.price != parseFloat(json['201']))
3211
3208
  calcAnalyizis = true;
3212
- data.price = parseFloat(json['201']);
3209
+ data.price = parseFloat(json['201']); // eller 201 för tradeyield
3213
3210
  data.quantity += typeof json['13'] === 'undefined' ? 0 : parseInt(json['13']);
3214
3211
  if (_this.scaleinfoY.type == 'trades') update = true;
3215
3212
  }
3216
-
3213
+ // TODo: updatera med quantity, open , high,low osv?
3217
3214
  }
3218
3215
  }
3219
3216
  }
3220
3217
  if (calcAnalyizis && insref == _this.instruments[0].insref) {
3221
3218
  for (var i = 0; i < _this.settings.indicators.length; i++) {
3222
-
3219
+ //for (const [key, a] of m_analyzisMethod.entries()) {
3223
3220
  switch (_this.settings.indicators[i].method) {
3224
3221
  case 'sma':
3225
3222
  _this.settings.indicators[i].trades = [];
@@ -3234,7 +3231,7 @@ function Milli_Chart(settings) {
3234
3231
  _this.settings.indicators[i].trades = bollingerBands(_this.instruments[0].trades, _this.settings.indicators[i].method_length, _this.settings.indicators[i].stddev | 2);
3235
3232
  break;
3236
3233
  default:
3237
-
3234
+ // draw custom added?
3238
3235
  break;
3239
3236
  }
3240
3237
  }
@@ -3246,14 +3243,14 @@ function Milli_Chart(settings) {
3246
3243
  };
3247
3244
  }
3248
3245
 
3249
-
3246
+ // used by trader
3250
3247
  _this.exportData = function() {
3251
3248
  let ret = [];
3252
3249
 
3253
3250
  if (_this.scaleinfoY.type == 'trades') {
3254
3251
  if (_this.instruments.length > 0) {
3255
3252
  for (var i = 0; i < _this.instruments[0].trades.length; i++) {
3256
- var date = new Date(_this.instruments[0].trades[i].timestamp - new Date().getTimezoneOffset() * 60000);
3253
+ var date = new Date(_this.instruments[0].trades[i].timestamp - new Date().getTimezoneOffset() * 60000); // tz_offset in minutes
3257
3254
  var datestr = date.toISOString();
3258
3255
 
3259
3256
  ret.push([datestr.substring(0, 10), datestr.substring(11, 23), _this.instruments[0].trades[i].price, _this.instruments[0].trades[i].quantity]);
@@ -3282,7 +3279,7 @@ function Milli_Chart(settings) {
3282
3279
  }
3283
3280
 
3284
3281
  _this.destroyWidget = function() {
3285
-
3282
+ // if we have subscriptions send in an empty array to unsubscribe all and release it
3286
3283
  if (MillistreamWidgetApi_isObjectEmpty(_this.unsubscriptions) == false)
3287
3284
  _this.requestid = _this.settings.streaming.MillistreamWidgetStreamingApi_subscribeInstruments(_this, _this.requestid, []);
3288
3285
  return 0;
@@ -3322,7 +3319,7 @@ function Milli_Chart(settings) {
3322
3319
  }
3323
3320
 
3324
3321
  _this.drawWidget = function() {
3325
-
3322
+ // remove standard fields from array, they will be requested anyway
3326
3323
  _this.settings.fields = _this.settings.fields.filter(function(obj) {
3327
3324
  return ['name', 'tradecurrency', 'time', 'date', 'tradeprice', 'tradequantity', 'marketopen', 'marketclose', 'closeprice1d', 'closeprice', 'closequantity'].indexOf(obj) == -1;
3328
3325
  });
@@ -3348,7 +3345,7 @@ function Milli_Chart(settings) {
3348
3345
  var e = new Date();
3349
3346
  var days = 0;
3350
3347
  var newlen = 0;
3351
- while (days < _this.settings.intradaylen - 1) {
3348
+ while (days < _this.settings.intradaylen - 1) { // include today
3352
3349
  d -= 86400000;
3353
3350
  e.setTime(d);
3354
3351
  if (e.getDay() != 0 && e.getDay() != 6)
@@ -3389,7 +3386,7 @@ function Milli_Chart(settings) {
3389
3386
 
3390
3387
  (function updatePixelRatio() {
3391
3388
  matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`).addEventListener('change', updatePixelRatio, { once: true });
3392
- () => {};
3389
+ console.log("devicePixelRatio: " + window.devicePixelRatio);
3393
3390
  _this.drawChart();
3394
3391
  })();
3395
3392
 
@@ -3448,14 +3445,14 @@ function MillistreamWidgetApi_buildQuery(widget, type) {
3448
3445
  if (typeof widget.settings.instrumenttype !== 'object') {
3449
3446
  throw new Error(widget.constructor.name + ': instrumenttype is not valid');
3450
3447
  }
3451
-
3448
+ //if (widget.settings.instrument == null) // removed 2021-10-12 for "mylist" functionality
3452
3449
  url += '&instrumenttypes=' + widget.settings.instrumenttype.join();
3453
3450
  }
3454
3451
  if (widget.settings.instrumentsubtype != null) {
3455
3452
  if (typeof widget.settings.instrumentsubtype !== 'object') {
3456
3453
  throw new Error(widget.constructor.name + ': instrumentsubtype is not valid');
3457
3454
  }
3458
-
3455
+ //if (widget.settings.instrument == null) // removed 2021-10-12 for "mylist" functionality
3459
3456
  url += '&instrumentsubtypes=' + widget.settings.instrumentsubtype.join();
3460
3457
  }
3461
3458
  if (widget.settings.derivativeindicator != null) {
@@ -3804,12 +3801,12 @@ function MillistreamWidgetApi_addPagination(widget) {
3804
3801
  li.onclick = function() {
3805
3802
  MillistreamWidgetApi_getPaginationPage(widget, 'next');
3806
3803
  };
3807
- if (widget.pagination.numPages < max + 1) li.style.display = 'none';
3804
+ if (widget.pagination.numPages < max + 1) li.style.display = 'none'; // dont show if less than 6 pages
3808
3805
  li = MillistreamWidgetApi_addElement(widget, 'li', 'millistream-list-pagination-li', widget.pagination.ul, null, '>>');
3809
3806
  li.onclick = function() {
3810
3807
  MillistreamWidgetApi_getPaginationPage(widget, 'last');
3811
3808
  };
3812
- if (widget.pagination.numPages < max + 1) li.style.display = 'none';
3809
+ if (widget.pagination.numPages < max + 1) li.style.display = 'none'; // dont show if less than 6 pages
3813
3810
  }
3814
3811
  } else
3815
3812
  if (widget.settings.pagination > 0 && widget.pagination.numPages < 2) {
@@ -3877,11 +3874,11 @@ function MillistreamWidgetApi_getPaginationPage(widget, page) {
3877
3874
  startno = 1;
3878
3875
  } else
3879
3876
  if (widget.pagination.selectedPage > widget.pagination.numPages - 2) {
3880
- startno = widget.pagination.numPages - (max - 1);
3877
+ startno = widget.pagination.numPages - (max - 1); //4;
3881
3878
 
3882
3879
  } else {
3883
3880
  startno = widget.pagination.selectedPage - 2 < 1 ? 1 : widget.pagination.selectedPage - (max - Math.ceil(max / 2));
3884
-
3881
+ //startno = widget.pagination.selectedPage - 1;
3885
3882
  }
3886
3883
  for (i = 2; i < items.length - 2; i++) {
3887
3884
  items[i].innerHTML = (startno);
@@ -3920,15 +3917,15 @@ function MillistreamWidgetApi_getElementHeight(el) {
3920
3917
  return rect.height + s;
3921
3918
  }
3922
3919
 
3923
-
3920
+ // Push blipp funktioner
3924
3921
  function MillistreamWidgetApi_clearFlash(el) {
3925
-
3922
+ //internal and external
3926
3923
  el.classList.remove('millistream-flash-up');
3927
3924
  el.classList.remove('millistream-flash-down');
3928
3925
  }
3929
3926
 
3930
3927
  function milli_clearValuedFlash(widget, el, oldValue) {
3931
-
3928
+ // internal borde gå att bygga bort
3932
3929
  var currentValue = MillistreamWidgetApi_getElementNumber(widget, el);
3933
3930
  if (currentValue == oldValue || currentValue == 0) {
3934
3931
  MillistreamWidgetApi_clearFlash(el);
@@ -3936,7 +3933,7 @@ function milli_clearValuedFlash(widget, el, oldValue) {
3936
3933
  }
3937
3934
 
3938
3935
  function MillistreamWidgetApi_flashElement(widget, el, newValue, oldValue) {
3939
-
3936
+ // internal
3940
3937
  if (newValue == oldValue) return;
3941
3938
  MillistreamWidgetApi_clearFlash(el);
3942
3939
  if (newValue == '' || !newValue) return;
@@ -3955,7 +3952,7 @@ function MillistreamWidgetApi_flashElement(widget, el, newValue, oldValue) {
3955
3952
  }
3956
3953
 
3957
3954
 
3958
-
3955
+ // numeriska funktioner
3959
3956
  function MillistreamWidgetApi_isNumber(widget, testsubject) {
3960
3957
  if (!testsubject) return;
3961
3958
  var n = testsubject.replace(widget.settings.decimalseparator, '.').split(widget.settings.thousandseparator).join('');
@@ -3968,7 +3965,7 @@ function MillistreamWidgetApi_getNumDecimals(widget, value, current, validfields
3968
3965
  if (value == null || MillistreamWidgetApi_isNumber(widget, value) == false) return current;
3969
3966
  var parts = value.toString().split('.');
3970
3967
  if (parts.length == 2) {
3971
- while (parts[1].charAt(parts[1].length - 1) == "0") {
3968
+ while (parts[1].charAt(parts[1].length - 1) == "0") { // remove trailing zeros
3972
3969
  parts[1] = parts[1].slice(0, -1);
3973
3970
  }
3974
3971
  return current > parts[1].length ? current : parts[1].length;
@@ -3977,7 +3974,7 @@ function MillistreamWidgetApi_getNumDecimals(widget, value, current, validfields
3977
3974
  }
3978
3975
 
3979
3976
  function MillistreamWidgetApi_getElementNumber(widget, el) {
3980
-
3977
+ // internal and Orderbook
3981
3978
  var res = parseFloat(el.innerHTML.replace(widget.settings.decimalseparator, '.').split(widget.settings.thousandseparator).join(''));
3982
3979
  if (!isNaN(parseFloat(res)) && isFinite(res)) return res;
3983
3980
  return 0;
@@ -4008,7 +4005,7 @@ function MillistreamWidgetApi_colorCell(widget, element, info) {
4008
4005
  MillistreamWidgetApi_setCellColor(widget, element, v);
4009
4006
  }
4010
4007
  } else
4011
- if (widget.settings.controlcolumn || widget.settings.controlcolumn == 0) {
4008
+ if (widget.settings.controlcolumn || widget.settings.controlcolumn == 0) { // works for tables
4012
4009
  if (widget.settings.stylecolumn === null) return;
4013
4010
  var tr = element.parentNode;
4014
4011
  while (tr.tagName.toLowerCase() != 'tr') {
@@ -4017,13 +4014,13 @@ function MillistreamWidgetApi_colorCell(widget, element, info) {
4017
4014
  if (tr.cells.length > widget.settings.controlcolumn) {
4018
4015
  v = MillistreamWidgetApi_getElementNumber(widget, tr.cells[widget.settings.controlcolumn]);
4019
4016
  var el;
4020
- if (widget.settings.stylecolumn && widget.settings.stylecolumn[0] == -1) {
4021
- el = tr;
4017
+ if (widget.settings.stylecolumn && widget.settings.stylecolumn[0] == -1) { // color row
4018
+ el = tr; //element.parentNode;
4022
4019
  MillistreamWidgetApi_setCellColor(widget, tr, v);
4023
4020
 
4024
4021
  } else {
4025
4022
  for (var s = 0; s < widget.settings.stylecolumn.length; s++) {
4026
- el = tr.cells[widget.settings.stylecolumn[s]];
4023
+ el = tr.cells[widget.settings.stylecolumn[s]]; //element.parentNode.cells[widget.stylecolumn[s]];
4027
4024
  if (el) {
4028
4025
  MillistreamWidgetApi_setCellColor(widget, el, v);
4029
4026
  }
@@ -4031,17 +4028,17 @@ function MillistreamWidgetApi_colorCell(widget, element, info) {
4031
4028
  }
4032
4029
  }
4033
4030
  } else
4034
- if (widget.settings.positiveclass && widget.settings.negativeclass) {
4031
+ if (widget.settings.positiveclass && widget.settings.negativeclass) { // non table elements
4035
4032
  v = MillistreamWidgetApi_getElementNumber(widget, element);
4036
4033
  MillistreamWidgetApi_setCellColor(widget, element, v);
4037
4034
  }
4038
4035
  }
4039
4036
 
4040
4037
  function print_field(widget, element, field, value, overridedecimals) {
4041
-
4038
+ // internal and external
4042
4039
  var f = parseInt(field);
4043
4040
  var info = MillistreamWidgetApi_getColumnInfo(widget, f.toString());
4044
- if (typeof value === 'undefined' || value == null || (!value && isNaN(value) == true)) {
4041
+ if (typeof value === 'undefined' || value == null || (!value && isNaN(value) == true)) { // kolla field?
4045
4042
  if (info[4] & 16) {
4046
4043
  value = '0.0';
4047
4044
  } else {
@@ -4087,7 +4084,7 @@ function print_field(widget, element, field, value, overridedecimals) {
4087
4084
  else
4088
4085
  element.innerHTML = formatFactorNumber(value, widget.settings.factor, widget.settings.num_decimals, widget.settings.thousandseparator, widget.settings.decimalseparator);
4089
4086
  } else if (info[4] & 4)
4090
- element.innerHTML = formatNiceNumber(value, widget.settings.thousandseparator, widget.settings.decimalseparator, 0);
4087
+ element.innerHTML = formatNiceNumber(value, widget.settings.thousandseparator, widget.settings.decimalseparator, 0); // no decimals
4091
4088
  else if (info[4] & 1 && overridedecimals)
4092
4089
  element.innerHTML = formatNiceNumber(value, widget.settings.thousandseparator, widget.settings.decimalseparator, overridedecimals || widget.settings.num_decimals);
4093
4090
  else {
@@ -4105,8 +4102,8 @@ function print_field(widget, element, field, value, overridedecimals) {
4105
4102
  }
4106
4103
 
4107
4104
  function MillistreamWidgetApi_getColumnInfo(widget, name) {
4108
-
4109
-
4105
+ // internal and external
4106
+ // 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
4110
4107
  switch (name) {
4111
4108
  case '222':
4112
4109
  case 'accountsreceivable':
@@ -4197,7 +4194,7 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
4197
4194
  return [232, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
4198
4195
  case '404':
4199
4196
  case 'd1':
4200
- return [404, 'date', 'right', widget.get_lang_text(name) || name, 0];
4197
+ return [404, 'date', 'right', widget.get_lang_text(name) || name, 0]; // Security type
4201
4198
  case '3':
4202
4199
  case 'date':
4203
4200
  return [3, 'date', 'right', widget.get_lang_text(name) || name, 0];
@@ -4451,10 +4448,10 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
4451
4448
  return [229, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
4452
4449
  case '395':
4453
4450
  case 'n2':
4454
- return [395, 'numeric', 'left', widget.get_lang_text(name) || name, 0];
4451
+ return [395, 'numeric', 'left', widget.get_lang_text(name) || name, 0]; // Security type
4455
4452
  case '396':
4456
4453
  case 'n3':
4457
- return [396, 'numeric', 'left', widget.get_lang_text(name) || name, 0];
4454
+ return [396, 'numeric', 'left', widget.get_lang_text(name) || name, 0]; // Security type
4458
4455
  case '22':
4459
4456
  case 'name':
4460
4457
  return [22, 'string', 'left', widget.get_lang_text(name) || name, 0];
@@ -4466,10 +4463,10 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
4466
4463
  return [138, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
4467
4464
  case '48':
4468
4465
  case 'newsid':
4469
- return [48, 'string', 'left', 'newsid', 0];
4466
+ return [48, 'string', 'left', 'newsid', 0]; // hardoded should not be used by any display
4470
4467
  case 'newstype':
4471
4468
  case '86':
4472
- return [86, 'string', 'left', 'newstype', 0];
4469
+ return [86, 'string', 'left', 'newstype', 0]; // hardoded should not be used by any display
4473
4470
  case '219':
4474
4471
  case 'noncurrentasset':
4475
4472
  return [219, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
@@ -4529,13 +4526,13 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
4529
4526
  return [98, 'string', 'left', widget.get_lang_text(name) || name, 0];
4530
4527
  case '180':
4531
4528
  case 's3':
4532
- return [180, 'string', 'left', widget.get_lang_text(name) || name, 0];
4529
+ return [180, 'string', 'left', widget.get_lang_text(name) || name, 0]; // Position
4533
4530
  case '181':
4534
4531
  case 's4':
4535
- return [181, 'string', 'left', widget.get_lang_text(name) || name, 0];
4532
+ return [181, 'string', 'left', widget.get_lang_text(name) || name, 0]; // Position
4536
4533
  case '393':
4537
4534
  case 's10':
4538
- return [393, 'string', 'left', widget.get_lang_text(name) || name, 0];
4535
+ return [393, 'string', 'left', widget.get_lang_text(name) || name, 0]; // comment
4539
4536
  case '127':
4540
4537
  case 'sales':
4541
4538
  return [127, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
@@ -4572,7 +4569,7 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
4572
4569
  case '227':
4573
4570
  case 'totalassets':
4574
4571
  return [227, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
4575
- case '1023':
4572
+ case '1023': // TODO, define this with correct value
4576
4573
  case 'totalnumberofshares':
4577
4574
  return [1023, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
4578
4575
  case '233':
@@ -4621,7 +4618,7 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
4621
4618
  case 'vega':
4622
4619
  return [703, 'numeric', 'right', widget.get_lang_text(name) || name, 0];
4623
4620
 
4624
-
4621
+ // brokerstats
4625
4622
  case '3000':
4626
4623
  case 'boughtquantity':
4627
4624
  return [3000, 'numeric', 'right', widget.get_lang_text(name) || name, 4];
@@ -4809,7 +4806,7 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
4809
4806
  case '3060':
4810
4807
  case 'soldturnoverytd':
4811
4808
  return [3060, 'numeric', 'left', widget.get_lang_text(name) || name, 4];
4812
-
4809
+ // key ratios egen definerade
4813
4810
  case 'per_last':
4814
4811
  case '3100':
4815
4812
  return [3100, 'numeric', 'right', widget.get_lang_text(name) || name, 0];
@@ -4930,7 +4927,7 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
4930
4927
  case 'latestreport':
4931
4928
  case '3140':
4932
4929
  return [3140, 'date', 'right', widget.get_lang_text(name) || name, 0];
4933
-
4930
+ // basicdata join fields
4934
4931
  case 'fundcompanyname':
4935
4932
  case '3200':
4936
4933
  return [3200, 'string', 'left', widget.get_lang_text(name) || name, 0];
@@ -4949,17 +4946,17 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
4949
4946
  case '3205':
4950
4947
  case 'underlyingsymbol':
4951
4948
  return [3204, 'string', 'left', widget.get_lang_text(name) || name, 0];
4952
- case '3206':
4949
+ case '3206': // tmcwatch
4953
4950
  case 'multiplier':
4954
4951
  return [3206, 'string', 'left', widget.get_lang_text(name) || name, 0];
4955
- case '3207':
4952
+ case '3207': // tmcwach
4956
4953
  case 'type':
4957
4954
  return [3207, 'string', 'left', widget.get_lang_text(name) || name, 0];
4958
- case '3208':
4955
+ case '3208': // tmcwach
4959
4956
  case 'direction':
4960
4957
  return [3208, 'string', 'left', widget.get_lang_text(name) || name, 0];
4961
4958
 
4962
-
4959
+ // optionwatch
4963
4960
  case '3300':
4964
4961
  case 'iv30d':
4965
4962
  case 'ivXXd':
@@ -5002,8 +4999,8 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
5002
4999
  }
5003
5000
  }
5004
5001
 
5005
- function set_hashed_element(widget, insref, info, json, num_dec) {
5006
-
5002
+ function set_hashed_element(widget, insref, info, json, num_dec) { // called from push
5003
+ // external : list
5007
5004
  var key = insref + '_' + info[0];
5008
5005
  var arr = widget.cell_map.get(key);
5009
5006
  if (arr !== undefined) {
@@ -5013,9 +5010,9 @@ function set_hashed_element(widget, insref, info, json, num_dec) {
5013
5010
  }
5014
5011
  }
5015
5012
 
5016
-
5013
+ // Create Element functions
5017
5014
  function MillistreamWidgetApi_addElementToMap(insref, field, element, widget) {
5018
-
5015
+ // internal
5019
5016
  if (insref && field && widget && widget.cell_map) {
5020
5017
  var key = insref + '_' + field;
5021
5018
  var arr = widget.cell_map.get(key);
@@ -5031,7 +5028,7 @@ function MillistreamWidgetApi_addElementToMap(insref, field, element, widget) {
5031
5028
  }
5032
5029
 
5033
5030
  function MillistreamWidgetApi_addElement(widget, el, cl, parent, field, value, overridedecimals) {
5034
-
5031
+ // external
5035
5032
  var element = document.createElement(el);
5036
5033
  if (cl)
5037
5034
  element.setAttribute('class', cl);
@@ -5114,7 +5111,7 @@ function MillistreamWidgetApi_addTableCell(widget, key, cl, parent, json, decima
5114
5111
  widget.settings.link_field.forEach(function(element) {
5115
5112
  hrefparam[element] = json[element];
5116
5113
  });
5117
- if (info[0] == 1) {
5114
+ if (info[0] == 1) { // headline, borde inte behövas i list
5118
5115
  td.onclick = function(e) {
5119
5116
  hrefparam.event = e;
5120
5117
  hrefparam.source = widget;
@@ -5230,7 +5227,7 @@ function fabs(value) {
5230
5227
  }
5231
5228
 
5232
5229
  function zeroPad(number, width) {
5233
-
5230
+ //internal
5234
5231
  if (number <= 9.9999999 * Math.pow(10, width)) return ("0000000" + number).slice(-width);
5235
5232
  return number;
5236
5233
  }
@@ -5275,7 +5272,7 @@ function formatNiceNumber(y, thousandSeparator, decimalSeparator, precision, add
5275
5272
  }
5276
5273
 
5277
5274
  function formatDate(date, format, widget) {
5278
-
5275
+ // internal
5279
5276
  var timeStamp, mon, day;
5280
5277
  if (format == 'yyyy-mm-dd') {
5281
5278
  timeStamp = new Date(date);
@@ -5289,66 +5286,66 @@ function formatDate(date, format, widget) {
5289
5286
  day = timeStamp.getDate();
5290
5287
  return timeStamp.getFullYear() % 100 + '-' + (mon <= 9 ? '0' + mon : mon) + '-' + (day <= 9 ? '0' + day : day);
5291
5288
  }
5292
- if (format == 'b dd') {
5289
+ if (format == 'b dd') { // Jan 01
5293
5290
  timeStamp = new Date(date);
5294
5291
  mon = timeStamp.toDateString().split(' ');
5295
5292
  day = timeStamp.getDate();
5296
5293
  return mon[1] + ' ' + (day <= 9 ? '0' + day : day);
5297
5294
  }
5298
- if (format == 'b dd yyyy') {
5295
+ if (format == 'b dd yyyy') { // Jan 01 2017
5299
5296
  timeStamp = new Date(date);
5300
5297
  mon = timeStamp.toDateString().split(' ');
5301
5298
  day = timeStamp.getDate();
5302
5299
  return mon[1] + ' ' + (day <= 9 ? '0' + day : day) + ' ' + timeStamp.getFullYear();
5303
5300
  }
5304
- if (format == 'dd/mm') {
5301
+ if (format == 'dd/mm') { // Jan 01 2017
5305
5302
  timeStamp = new Date(date);
5306
5303
  mon = timeStamp.getMonth() + 1;
5307
5304
  day = timeStamp.getDate();
5308
5305
  return (day <= 9 ? '0' + day : day) + '/' + (mon <= 9 ? '0' + mon : mon);
5309
5306
  }
5310
- if (format == 'd/m') {
5307
+ if (format == 'd/m') { // Jan 01 2017
5311
5308
  timeStamp = new Date(date);
5312
5309
  return (timeStamp.getDate() + '/' + (timeStamp.getMonth() + 1));
5313
5310
  }
5314
5311
  if (format == 'd mmm yyyy') {
5315
5312
  timeStamp = new Date(date);
5316
- mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3);
5313
+ mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3); // lang....
5317
5314
  day = timeStamp.getDate();
5318
5315
  return day + ' ' + mon + ' ' + timeStamp.getFullYear();
5319
5316
  }
5320
5317
  if (format == 'dd mmm yyyy') {
5321
5318
  timeStamp = new Date(date);
5322
- mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3);
5319
+ mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3); // lang....
5323
5320
  day = timeStamp.getDate();
5324
5321
  return (day <= 9 ? '0' + day : day) + ' ' + mon + ' ' + timeStamp.getFullYear();
5325
5322
  }
5326
5323
  if (format == 'dd mmm') {
5327
5324
  timeStamp = new Date(date);
5328
- mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3);
5325
+ mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3); // lang....
5329
5326
  day = timeStamp.getDate();
5330
5327
  return (day <= 9 ? '0' + day : day) + ' ' + mon;
5331
5328
  }
5332
5329
  if (format == 'd mmm') {
5333
5330
  timeStamp = new Date(date);
5334
- mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3);
5331
+ mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3); // lang....
5335
5332
  day = timeStamp.getDate();
5336
5333
  return day + ' ' + mon;
5337
5334
  }
5338
5335
  if (format == 'mmm yyyy') {
5339
5336
  timeStamp = new Date(date);
5340
- mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3);
5337
+ mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3); // lang....
5341
5338
  timeStamp = mon + ' ' + timeStamp.getFullYear();
5342
5339
  return timeStamp;
5343
5340
  }
5344
5341
  if (format == 'mmm yy') {
5345
5342
  timeStamp = new Date(date);
5346
- mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3);
5343
+ mon = timeStamp.toLocaleString(widget.settings.locale, { month: 'short' }).substring(0, 3); // lang
5347
5344
  timeStamp = mon + ' ' + (timeStamp.getFullYear() % 100 < 9 ? '0' + timeStamp.getFullYear() % 100 : timeStamp.getFullYear() % 100);
5348
5345
  return timeStamp;
5349
5346
  }
5350
5347
 
5351
-
5348
+ // default yyyy-mm-dd
5352
5349
  timeStamp = new Date(date);
5353
5350
  mon = timeStamp.getMonth() + 1;
5354
5351
  day = timeStamp.getDate();
@@ -5356,7 +5353,7 @@ function formatDate(date, format, widget) {
5356
5353
  }
5357
5354
 
5358
5355
  function formatTime(value, format) {
5359
-
5356
+ // internal
5360
5357
  if (typeof value !== 'string') return "";
5361
5358
  var datetime = new Date();
5362
5359
  var tz_offset = datetime.getTimezoneOffset();
@@ -5585,7 +5582,7 @@ function MillistreamWidgetApi_scrollIntoView(scrollarea, elem, xalign, yalign) {
5585
5582
  scrollarea.scrollLeft = elem.offsetLeft - scrollarea.getBoundingClientRect().width / 2;
5586
5583
  }
5587
5584
 
5588
-
5585
+ // scrollIntoView : replace this, breaks apps
5589
5586
  }
5590
5587
 
5591
5588
  var MillistreamWidgetSettings = {
@@ -5605,9 +5602,9 @@ function MillistreamWidgetStreamingApi(settings) {
5605
5602
  server: 'wss://stage.millistream.com:8900',
5606
5603
  alarmClient: null
5607
5604
  };
5608
- var m_requestid = 1;
5605
+ var m_requestid = 1; // 0 is invalid
5609
5606
  var m_socket = null;
5610
- var m_requests = [];
5607
+ var m_requests = []; // queued requests not sent
5611
5608
  var m_requestcallbacks = new Map();
5612
5609
 
5613
5610
 
@@ -5640,7 +5637,7 @@ function MillistreamWidgetStreamingApi(settings) {
5640
5637
  req = new Object({
5641
5638
  "widget": widget,
5642
5639
  });
5643
- m_requestcallbacks.set(requestid.toString(), req);
5640
+ m_requestcallbacks.set(requestid.toString(), req); // this requestid will be forarded to this widget
5644
5641
  }
5645
5642
  var request = '';
5646
5643
  if (MillistreamWidgetApi_isObjectEmpty(widget.unsubscriptions) == false) {
@@ -5702,7 +5699,7 @@ function MillistreamWidgetStreamingApi(settings) {
5702
5699
 
5703
5700
 
5704
5701
  widget.unsubscriptions.type = 'insrefs';
5705
- widget.unsubscriptions.insrefs = insrefs.slice(0);
5702
+ widget.unsubscriptions.insrefs = insrefs.slice(0); // copy array
5706
5703
  widget.unsubscriptions.messagetypes = widget.settings.messagetypes;
5707
5704
  widget.unsubscriptions.requestid = requestid;
5708
5705
 
@@ -5715,7 +5712,7 @@ function MillistreamWidgetStreamingApi(settings) {
5715
5712
 
5716
5713
  function reconnect() {
5717
5714
  if (!m_socket.CLOSED) {
5718
-
5715
+ //console.log('not closed');
5719
5716
  return;
5720
5717
  }
5721
5718
  m_requests.forEach(function(request) {
@@ -5734,21 +5731,21 @@ function MillistreamWidgetStreamingApi(settings) {
5734
5731
  try {
5735
5732
  m_socket = new WebSocket(_this.settings.server);
5736
5733
  m_socket.onopen = function() {
5737
- () => {};
5734
+ console.log('Connected to millistream push'); /*RemoveLogging:skip*/
5738
5735
  if (m_requests.length > 0) {
5739
5736
  m_requests.forEach(function(request) {
5740
5737
  if (request.send == 0) {
5741
-
5738
+ //console.log('rerequest:', request.request);
5742
5739
  m_socket.send('{ "token":"' + _this.settings.token + '",' + request.request);
5743
5740
  }
5744
5741
  });
5745
5742
  }
5746
5743
  };
5747
5744
  m_socket.onerror = function() {
5748
- () => {};
5745
+ console.log('Error, disconnected'); /*RemoveLogging:skip*/
5749
5746
  };
5750
5747
  m_socket.onclose = function() {
5751
- () => {};
5748
+ console.log('Disconnected'); /*RemoveLogging:skip*/
5752
5749
  reconnect();
5753
5750
  };
5754
5751
 
@@ -5757,9 +5754,9 @@ function MillistreamWidgetStreamingApi(settings) {
5757
5754
  try {
5758
5755
  jsondata = JSON.parse(msg.data);
5759
5756
  } catch (e) {
5760
- () => {};
5757
+ console.log('invalid data', msg.data); /*RemoveLogging:skip*/
5761
5758
  }
5762
-
5759
+ //console.log(JSON.stringify(jsondata));
5763
5760
  if (typeof jsondata.instruments !== 'undefined') {
5764
5761
  for (var s = 0; s < jsondata.instruments.length; s++) {
5765
5762
  var insref = jsondata.instruments[s].insref;
@@ -5785,16 +5782,16 @@ function MillistreamWidgetStreamingApi(settings) {
5785
5782
  if (_this.settings.statusCallback !== null) _this.settings.statusCallback(jsondata);
5786
5783
  } else
5787
5784
  if (typeof jsondata.alarm !== 'undefined') {
5788
- () => {};
5785
+ console.log('Alarm: ' + JSON.stringify(jsondata));
5789
5786
  if (null != _this.settings.alarmClient) {
5790
5787
  _this.settings.alarmClient(jsondata);
5791
5788
  }
5792
5789
 
5793
5790
  } else
5794
- () => {};
5791
+ console.log(JSON.stringify(jsondata)); /*RemoveLogging:skip*/
5795
5792
  };
5796
5793
  } catch (exception) {
5797
- () => {};
5794
+ console.log('Exception error: ' + exception); /*RemoveLogging:skip*/
5798
5795
  reconnect();
5799
5796
  }
5800
5797
  }