@millistream/millistream-widgets 0.0.19 → 0.0.20

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.
@@ -1,6 +1,5 @@
1
- 'use strict';
2
-
3
1
  function Milli_Chart(settings) {
2
+ "use strict";
4
3
  var _this = this;
5
4
  _this.mdf_fields = [];
6
5
  _this.scaleinfoX = {};
@@ -8,38 +7,36 @@ function Milli_Chart(settings) {
8
7
  _this.scaleinfoY2 = {};
9
8
  _this.instruments = [];
10
9
  _this.settings = {
10
+ adjusted: true,
11
11
  autodraw: true,
12
- instrument: null,
13
- messagetypes: 4,
14
- onreadyCallback: null,
15
- streaming: false,
16
- target: null,
17
- startdate: null,
18
- startdateintraday: null,
12
+ chartlen: '1d',
19
13
  compress: 1,
20
-
21
14
  dateformat: 'd/m',
22
- timeformat: 'HH:mm',
23
- graphvalue: 'lastprice',
24
-
25
- intradaylen: null,
26
- historylen: null,
27
15
  drawxaxis: true, // TODO: 0 no, 1 yes, 2 yeas with markers (3px lines)
28
16
  drawyaxis: true,
29
17
  drawy2axis: false,
30
- //gridverticalLines: 2, // 0 off, 1 draw grid lines ,2 fillrect modulo
18
+ enablezoom: true,
19
+ fields: ['name', 'tradecurrency', 'time', 'date', 'tradeprice', 'tradequantity', 'marketopen', 'marketclose'],
20
+ fillchart: false,
21
+ gridVerticalLines: true, // 0 off, 1 draw grid lines ,2 fillrect modulo
22
+ gridVerticalLinesStyle: 'line',
31
23
  gridHorizontalLines: true,
32
24
  gridHorizontalLinesStyle: 'dash',
33
- chartlen: '1d',
34
- fillchart: false,
35
- fields: ['name', 'tradecurrency', 'time', 'date', 'tradeprice', 'tradequantity', 'marketopen', 'marketclose'],
36
- enablehover: true,
37
- enablezoom: true,
38
- intradaydates: false,
39
25
  hcurve: false,
40
- adjusted: true,
41
- nochartlabel: "No data to draw on",
42
- yearLabelsPos: 'bottom'
26
+ historylen: null,
27
+ instrument: null,
28
+ intradaydates: false,
29
+ intradaylen: null,
30
+ messagetypes: 4, // not a setting should always be 4 (trades)
31
+ nochartlabel: 'No data to draw on',
32
+ onreadyCallback: null,
33
+ startdate: null, // no setting, set in request code
34
+ //startdateintraday: null,
35
+ streaming: false,
36
+ target: null,
37
+ timeformat: 'HH:mm',
38
+ xhr: false,
39
+ yearLabelsPos: 'bottom',
43
40
  };
44
41
  _this.unsubscriptions = {};
45
42
  var m_chartspaces = {
@@ -62,14 +59,6 @@ function Milli_Chart(settings) {
62
59
  arr: [],
63
60
  map: new Map()
64
61
  };
65
- var m_tz_offset = 0;
66
- var m_yAxisPrecision = 0;
67
-
68
- var m_toolTip = {
69
- dateDiv: null,
70
- instrDiv: [],
71
- arrowDiv: []
72
- };
73
62
 
74
63
  var m_resizing = {
75
64
  resizing: false,
@@ -78,21 +67,6 @@ function Milli_Chart(settings) {
78
67
  drawing: false
79
68
  };
80
69
 
81
- var m_y2settings = {
82
- decimals: 2
83
- };
84
-
85
- var m_chartCss = {
86
- 'background-color': '#fffcf8',
87
- "margin-top": "20px",
88
- "margin-bottom": "30px",
89
- "margin-left": "40px",
90
- "margin-right": "40px",
91
- //"box-shadow": "2px 2px",
92
- "border-right-color": "#02020230", // box-shadow color
93
- "border-top-color": '#02020230' // box-shadow color
94
- };
95
-
96
70
  var m_zoom = {
97
71
  mousedown: {
98
72
  timestamp: null,
@@ -109,85 +83,98 @@ function Milli_Chart(settings) {
109
83
  };
110
84
  var m_lastDrawnInstrument = -1;
111
85
  var m_months = ['Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'];
86
+
87
+ MillistreamWidgetApi_AssignObject(MillistreamWidgetSettings, _this.settings);
88
+ if (settings) {
89
+ MillistreamWidgetApi_AssignObject(settings, _this.settings);
90
+ }
91
+
92
+ var m_chartCss = {
93
+ backgroundColor: '#fffcf8',
94
+ marginTop: 20,
95
+ marginBottom: 30,
96
+ marginLeft: 40,
97
+ marginRight: 40,
98
+ boxShadow: {
99
+ topWidth: 2,
100
+ rightWidth: 2,
101
+ color: '#02020230'
102
+ },
103
+ };
104
+ if (_this.settings.chartstyle) {
105
+ MillistreamWidgetApi_AssignObject(_this.settings.chartstyle, m_chartCss);
106
+ }
112
107
  var m_xLegendCss = {
113
- 'font-size': '10px',
114
- 'font-weight': 'bolder',
115
- 'font-style': 'normal',
116
- 'font-family': 'SuecaSans',
108
+ fontSize: '10px',
109
+ fontWeight: 'bolder',
110
+ fontFamily: 'SuecaSans',
117
111
  color: 'rgba(37, 45, 64, 0.24)'
118
112
  };
113
+ if (_this.settings.horizontalLegendStyle) {
114
+ MillistreamWidgetApi_AssignObject(_this.settings.horizontalLegendStyle, m_xLegendCss);
115
+ }
119
116
  var m_yLegendCss = {
120
- 'font-size': '10px',
121
- 'font-weight': 'bolder',
122
- 'font-style': 'normal',
123
- 'font-family': 'SuecaSans',
124
- 'font-variant': 'normal',
125
- 'color': 'rgba(37, 45, 64, 0.24)',
126
- float: 'right',
127
- "vertical-align": "top"
117
+ fontSize: '10px',
118
+ fontWeight: 'bolder',
119
+ fontFamily: 'SuecaSans',
120
+ color: 'rgba(37, 45, 64, 0.24)',
121
+ float: 'left',
122
+ verticalAlign: 'center',
123
+ textAlign: 'left'
128
124
  };
125
+ if (_this.settings.verticalLegendStyle) {
126
+ MillistreamWidgetApi_AssignObject(_this.settings.verticalLegendStyle, m_yLegendCss);
127
+ }
129
128
 
130
129
  var m_y2LegendCss = {
131
- 'font-size': '10px',
132
- 'font-weight': 'bold',
133
- 'font-style': 'normal',
134
- 'font-family': 'SuecaSans',
135
- 'font-variant': 'normal',
136
- 'color': 'rgba(37, 45, 64, 0.24)',
137
130
  float: "right",
138
- "vertical-align": "center"
139
131
  };
132
+ if (_this.settings.verticalLegend2Style) {
133
+ MillistreamWidgetApi_AssignObject(_this.settings.verticalLegend2Style, m_y2LegendCss);
134
+ }
135
+ var m_gridVerticalCss = {
136
+ color: 'rgba(37, 45, 64, 0.24)',
137
+ width: '5px'
138
+ };
139
+ if (_this.settings.verticalGridStyle) {
140
+ MillistreamWidgetApi_AssignObject(_this.settings.verticalGridStyle, m_gridVerticalCss);
141
+ }
142
+ var m_gridHorizontalCss = {
143
+ color: 'rgba(37, 45, 64, 0.24)',
144
+ };
145
+ if (_this.settings.horizontalGridStyle) {
146
+ MillistreamWidgetApi_AssignObject(_this.settings.horizontalGridStyle, m_gridHorizontalCss);
147
+ }
140
148
  var m_instrumentCss = [{
141
149
  color: '#E2507A',
142
- 'background-image': 'linear-gradient(rgba(226, 80, 122, 0.6),rgba(226, 80, 122, 0))',
143
- width: '2px'
150
+ //backgroundImage: 'linear-gradient(rgba(226, 80, 122, 0.6),rgba(226, 80, 122, 0))',
151
+ width: 1
144
152
  }, {
145
153
  color: '#ff0000',
146
- width: '1px'
154
+ width: 1
147
155
  }, {
148
156
  color: '#000000',
149
- width: '1px'
157
+ width: 1
150
158
  }, {
151
159
  color: '#00ff00',
152
- width: '1px'
160
+ width: 1
153
161
  }];
154
-
155
- var m_gridVerticalCss = {
156
- color: 'rgba(37, 45, 64, 0.24)',
157
- width: '1px'
158
- };
159
-
160
- var m_gridHorizontalCss = {
161
- color: 'rgba(37, 45, 64, 0.24)',
162
- width: '1px'
163
- };
164
-
165
- /* _this.cssClasses = {
166
- gridVertical: m_gridVerticalCss,
167
- xLegend: m_xLegendCss,
168
- chart: m_chartCss,
169
- instrument: m_instrumentCss
170
- }
171
- */
172
- MillistreamWidgetApi_AssignObject(MillistreamWidgetSettings, _this.settings);
173
- if (settings) {
174
- MillistreamWidgetApi_AssignObject(settings, _this.settings);
162
+ if (_this.settings.instrumentStyle) {
163
+ MillistreamWidgetApi_AssignObject(_this.settings.instrumentStyle, m_instrumentCss[0]);
164
+ }
165
+ if (_this.settings.compare1Style) {
166
+ MillistreamWidgetApi_AssignObject(_this.settings.compare1Style, m_instrumentCss[1]);
167
+ }
168
+ if (_this.settings.compare2Style) {
169
+ MillistreamWidgetApi_AssignObject(_this.settings.compare2Style, m_instrumentCss[2]);
170
+ }
171
+ if (_this.settings.compare3Style) {
172
+ MillistreamWidgetApi_AssignObject(_this.settings.compare3Style, m_instrumentCss[3]);
175
173
  }
176
174
 
177
175
  _this.get_lang_text = function(string) {
178
176
  return string;
179
177
  };
180
- // date and time functions
181
- /*function getWeekdays() {
182
- var startdate = new Date(_this.scaleinfoX.startTimeStamp);
183
- var days = 0;
184
- while (startdate.getTime() < _this.scaleinfoX.endTimeStamp) {
185
- if (startdate.getDay() != 0 && startdate.getDay() != 6)
186
- days++;
187
- startdate = new Date(startdate.getTime() + 86400000);
188
- }
189
- return days;
190
- }*/
191
178
 
192
179
  const isToday = (someDate) => {
193
180
  const today = new Date();
@@ -209,6 +196,19 @@ function Milli_Chart(settings) {
209
196
  // Discard the time and time-zone information.
210
197
  const utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
211
198
  const utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
199
+ /*var start = new Date(utc1);
200
+ var end = new Date(utc2);
201
+ var days = 0;
202
+ console.log(start, end, a, b);
203
+ while (start < end) {
204
+ console.log(start, end);
205
+ if (start.getDay() != 0 && start.getDay() != 6)
206
+ days++;
207
+ start = new Date(start.getTime() + 86400000);
208
+ }
209
+
210
+ console.log(days, Math.floor((utc2 - utc1) / 86400000));
211
+ return days;*/
212
212
  return Math.floor((utc2 - utc1) / 86400000); // ms per day
213
213
  }
214
214
 
@@ -251,7 +251,7 @@ function Milli_Chart(settings) {
251
251
  }
252
252
 
253
253
  function getFontSize(obj) {
254
- return parseInt(obj['font-size']);
254
+ return parseInt(obj.fontSize);
255
255
  }
256
256
 
257
257
  function getMaxTimeWidth() {
@@ -430,12 +430,14 @@ function Milli_Chart(settings) {
430
430
  firstvalue = parseFloat(_this.instruments[s].closeprice1d);
431
431
  }
432
432
  }
433
+ var quantity = 0;
433
434
  for (var i = 0; i < data.length; i++) {
434
435
  // only calc on visible data
435
- var price = data[i][_this.settings.graphvalue] * _this.instruments[s].factor;
436
- var quantity = 0;
437
- if (data[i].quantity !== 'undefined')
436
+ var price = data[i].price * _this.instruments[s].factor;
437
+ quantity = 0;
438
+ if (data[i].quantity !== 'undefined') {
438
439
  quantity = data[i].quantity;
440
+ }
439
441
  if (data[i].timestamp < _this.scaleinfoX.startTimeStamp) {
440
442
  continue;
441
443
  }
@@ -490,33 +492,45 @@ function Milli_Chart(settings) {
490
492
  function plotLower(valuePerPixel, lineLength) {
491
493
  m_ctx.save();
492
494
  m_ctx.strokeStyle = m_instrumentCss[0].color;
493
- m_ctx.lineWidth = parseInt(m_instrumentCss[0].width);
494
- m_ctx.beginPath();
495
+ m_ctx.lineWidth = m_instrumentCss[0].width;
495
496
  var width = Math.round(m_chartspaces.lowerChart.width / (m_datapoints.length + 1) / 2);
496
497
  if (width < 2) width = 2;
497
498
  else if (width > 20) width = 20;
498
499
  m_ctx.lineWidth = width;
499
500
  for (var i = 0; i < m_datapoints.length; i++) {
500
- var x = Math.round(m_datapoints[i].x);
501
- if (x - width < m_chartspaces.lowerChart.left) {
502
- x += width / 4;
501
+ var x = m_datapoints[i].x + 0.5;
502
+ m_ctx.lineWidth = width;
503
+ if (x - width <= m_chartspaces.lowerChart.left) {
503
504
  m_ctx.lineWidth = width / 2;
505
+ x += m_ctx.lineWidth / 2;
504
506
  } else
505
- if (x + width > m_chartspaces.lowerChart.right) {
506
- x -= width / 4;
507
+ if (x + width >= m_chartspaces.lowerChart.right) {
507
508
  m_ctx.lineWidth = width / 2;
509
+ x -= m_ctx.lineWidth / 2 + 1;
508
510
  }
509
-
510
- m_ctx.moveTo(x + 0.5, m_chartspaces.lowerChart.bottom);
511
- var y = Math.round(m_chartspaces.lowerChart.bottom - (m_datapoints[i].quantity * valuePerPixel));
512
- m_ctx.lineTo(x + 0.5, y);
511
+ m_ctx.beginPath();
512
+ m_ctx.moveTo(x, m_chartspaces.lowerChart.bottom - 0.5);
513
+ var y = Math.round(m_chartspaces.lowerChart.bottom - (m_datapoints[i].quantity * valuePerPixel)) - 1;
514
+ m_ctx.closePath();
515
+ m_ctx.lineTo(x, y - 0.5);
513
516
  m_ctx.stroke();
514
517
  }
515
- m_ctx.closePath();
516
518
  m_ctx.restore();
517
519
  }
518
520
 
519
521
  function drawYLegendLower(x, numticks, lineLength, markers) {
522
+ var i;
523
+ _this.scaleinfoY.lowLowerChart = null;
524
+ _this.scaleinfoY.highLowerChart = null;
525
+
526
+ for (i = 0; i < m_datapoints.length; i++) {
527
+ if (typeof m_datapoints[i].quantity !== 'undefined') {
528
+ if (_this.scaleinfoY.lowLowerChart == null || _this.scaleinfoY.lowLowerChart > m_datapoints[i].quantity) _this.scaleinfoY.lowLowerChart = m_datapoints[i].quantity;
529
+ if (_this.scaleinfoY.highLowerChart == null || _this.scaleinfoY.highLowerChart < m_datapoints[i].quantity) _this.scaleinfoY.highLowerChart = m_datapoints[i].quantity;
530
+ }
531
+ }
532
+ if (numticks < 1) return;
533
+ if (numticks > 10) numticks = 10;
520
534
  m_ctx.strokeStyle = m_gridHorizontalCss.color;
521
535
  m_ctx.fillStyle = m_yLegendCss.color;
522
536
 
@@ -529,7 +543,7 @@ function Milli_Chart(settings) {
529
543
  return false;
530
544
  }
531
545
  var value = 0;
532
- for (;;) {
546
+ for (i = 0; i < numticks; i++) {
533
547
  var y = Math.round(m_chartspaces.lowerChart.bottom - (value * valuePerPixel));
534
548
 
535
549
  if (y <= m_chartspaces.lowerChart.top) break;
@@ -539,21 +553,25 @@ function Milli_Chart(settings) {
539
553
  if (_this.settings.gridHorizontalLinesStyle == 'dash') {
540
554
  m_ctx.setLineDash([3, 3]);
541
555
  }
556
+ m_ctx.beginPath();
542
557
  m_ctx.moveTo(m_chartspaces.lowerChart.left, y + 0.5);
543
558
  m_ctx.lineTo(m_chartspaces.lowerChart.right, y + 0.5);
544
559
  m_ctx.stroke();
560
+ m_ctx.closePath();
545
561
  m_ctx.restore();
546
562
  } else
547
563
  if (_this.settings.drawyaxis == true && markers == true) { // draw legenditem markers for price
564
+ m_ctx.beginPath();
548
565
  m_ctx.moveTo(m_chartspaces.lowerChart.left, y + 0.5);
549
566
  m_ctx.lineTo(m_chartspaces.lowerChart.left + 3, y + 0.5);
550
567
  m_ctx.stroke();
568
+ m_ctx.closePath();
551
569
  }
552
570
 
553
571
  if (markers == true && _this.settings.drawyaxis == true) {
554
572
  var label = formatLargeNumber(value, 0, _this);
555
573
  var textpos = x - 5;
556
- if (m_yLegendCss['vertical-align'] == 'top') {
574
+ if (m_yLegendCss.verticalAlign == 'top') {
557
575
  if (y - (getFontSize(m_yLegendCss)) > 0) // dont draw if cropped
558
576
  m_ctx.fillText(label, textpos, y - ((getFontSize(m_yLegendCss) + 2)));
559
577
  } else
@@ -567,29 +585,30 @@ function Milli_Chart(settings) {
567
585
  }
568
586
 
569
587
  function drawYAxisLower() {
570
- //m_ctx.save();
571
- m_ctx.strokeStyle = m_gridHorizontalCss.color;
572
- m_ctx.font = m_yLegendCss['font-weight'] + ' ' + m_yLegendCss['font-size'] + ' ' + m_yLegendCss['font-family'];
588
+ m_ctx.save();
589
+ m_ctx.font = m_yLegendCss.fontWeight + ' ' + m_yLegendCss.fontSize + ' ' + m_yLegendCss.fontFamily;
573
590
  m_ctx.fillStyle = m_yLegendCss.color;
574
591
  var lineLen = m_chartspaces.lowerChart.bottom - m_chartspaces.lowerChart.top;
575
592
  var numticks = lineLen / (getFontSize(m_yLegendCss) * 2);
576
593
  if (numticks > 8) numticks = 8; // limit to 8 items on Y legend ( this is not an absolut count, since we calculate nice legend numbers
577
594
 
595
+ m_ctx.beginPath();
596
+ m_ctx.strokeStyle = m_gridVerticalCss.color;
578
597
  m_ctx.moveTo(m_chartspaces.lowerChart.left + 0.5, m_chartspaces.lowerChart.top);
579
598
  m_ctx.lineTo(m_chartspaces.lowerChart.left + 0.5, m_chartspaces.lowerChart.bottom);
580
599
  m_ctx.stroke();
600
+ m_ctx.closePath();
601
+ //m_ctx.strokeStyle = m_gridHorizontalCss.color;
581
602
  var x = m_chartspaces.lowerChart.left - 3;
582
-
583
603
  drawYLegendLower(x, numticks, lineLen, true);
584
- //m_ctx.restore();
585
-
604
+ m_ctx.restore();
586
605
  }
587
606
 
588
607
  function drawYLegend(si, x, side, gridHorizontalLines, number) {
589
608
  var value;
590
609
  si.maxValue = si.highValue + (si.tickSize * 0.2);
591
610
  si.minValue = si.lowValue - (si.tickSize * 0.2);
592
- m_ctx.font = m_yLegendCss['font-weight'] + ' ' + m_yLegendCss['font-size'] + ' ' + m_yLegendCss['font-family'];
611
+ m_ctx.font = m_yLegendCss.fontWeight + ' ' + m_yLegendCss.fontSize + ' ' + m_yLegendCss.fontFamily;
593
612
  if (si.highValue == si.lowValue) { // only have one value so set values for 1 line only
594
613
  si.maxValue = si.maxValue + si.tickSize;
595
614
  si.minValue = si.minValue - si.tickSize;
@@ -645,7 +664,7 @@ function Milli_Chart(settings) {
645
664
  label = formatNiceNumber(value, _this.settings.thousandseparator, _this.settings.decimalseparator, si.decimals, false);
646
665
  var textpos = x - 5;
647
666
  if (side == 'right') textpos = x + 7;
648
- if (m_yLegendCss['vertical-align'] == 'top') {
667
+ if (m_yLegendCss.verticalAlign == 'top') {
649
668
  if (y - (getFontSize(m_yLegendCss)) > 0) // dont draw if cropped
650
669
  m_ctx.fillText(label, textpos, y - ((getFontSize(m_yLegendCss) + 2)));
651
670
  } else
@@ -660,7 +679,7 @@ function Milli_Chart(settings) {
660
679
  function drawYAxis() {
661
680
  m_ctx.save();
662
681
  m_ctx.strokeStyle = m_gridHorizontalCss.color;
663
- m_ctx.font = m_yLegendCss['font-weight'] + ' ' + m_yLegendCss['font-size'] + ' ' + m_yLegendCss['font-family'];
682
+ m_ctx.font = m_yLegendCss.fontWeight + ' ' + m_yLegendCss.fontSize + ' ' + m_yLegendCss.fontFamily;
664
683
  m_ctx.fillStyle = m_yLegendCss.color;
665
684
  //if (_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d') firstvalue = _this.instruments[0].closeprice1d;
666
685
 
@@ -680,7 +699,7 @@ function Milli_Chart(settings) {
680
699
  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å?
681
700
  m_chartspaces.lowerChart.left = m_chartspaces.chart.left;
682
701
  } else {
683
- if (m_yLegendCss['text-align'] == 'right') {
702
+ if (m_yLegendCss.textAlign == 'right') {
684
703
  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å?
685
704
  m_chartspaces.lowerChart.right = m_chartspaces.chart.right;
686
705
  }
@@ -696,7 +715,7 @@ function Milli_Chart(settings) {
696
715
  label = formatNiceNumber(_this.scaleinfoY2.highValue, _this.settings.thousandseparator, _this.settings.decimalseparator, _this.scaleinfoY2.decimals) + ' %';
697
716
  if (m_y2LegendCss.float != 'right') {
698
717
  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å?
699
- m_chartspaces.lowerChart.left = m_chartspaces.chart.left
718
+ m_chartspaces.lowerChart.left = m_chartspaces.chart.left;
700
719
  } else {
701
720
  // kolla setting om den skall vara "i diagrammet"
702
721
  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å?
@@ -705,19 +724,21 @@ function Milli_Chart(settings) {
705
724
  }
706
725
  if (m_yLegendCss.float != 'right' && _this.settings.drawyaxis) {
707
726
  m_ctx.save();
708
- m_ctx.font = m_xLegendCss['font-weight'] + ' ' + m_xLegendCss['font-size'] + ' ' + m_xLegendCss['font-family'];
727
+ m_ctx.font = m_xLegendCss.fontWeight + ' ' + m_xLegendCss.fontSize + ' ' + m_xLegendCss.fontFamily;
709
728
  if (getStringWidth(m_ctx, _this.settings.dateformat) / 2 + 5 > m_chartspaces.chart.left) m_chartspaces.chart.left = getStringWidth(m_ctx, _this.settings.dateformat) / 2 + 5;
710
729
  m_ctx.restore();
711
730
  }
731
+ m_ctx.strokeStyle = m_gridVerticalCss.color;
712
732
  m_ctx.beginPath();
713
733
  m_ctx.moveTo(m_chartspaces.chart.left + 0.5, m_chartspaces.chart.top);
714
- m_ctx.lineTo(m_chartspaces.chart.left + 0.5, m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']));
734
+ m_ctx.lineTo(m_chartspaces.chart.left + 0.5, m_chartspaces.chart.height - m_chartCss.marginBottom);
715
735
  m_ctx.stroke();
716
736
  m_ctx.closePath();
737
+ m_ctx.strokeStyle = m_gridHorizontalCss.color;
717
738
 
718
739
  var x;
719
740
  if (m_yLegendCss.float == 'right') {
720
- if (m_yLegendCss['text-align'] == 'right')
741
+ if (m_yLegendCss.textAlign == 'right')
721
742
  x = m_chartspaces.chart.right;
722
743
  else
723
744
  x = m_chartspaces.chart.right + 3;
@@ -726,7 +747,7 @@ function Milli_Chart(settings) {
726
747
  }
727
748
 
728
749
  m_ctx.textAlign = 'right';
729
- if (m_yLegendCss['text-align'] == 'right') {
750
+ if (m_yLegendCss.textAlign == 'right') {
730
751
  m_ctx.textAlign = 'left';
731
752
  drawYLegend(_this.scaleinfoY, x, 'right', _this.settings.gridHorizontalLines, 1);
732
753
  } else
@@ -746,10 +767,10 @@ function Milli_Chart(settings) {
746
767
  function drawXAxisGridlines(p, newday) {
747
768
  // draws the vertical grid or dots
748
769
  m_ctx.save();
749
- m_ctx.strokeStyle = m_gridHorizontalCss.color;
750
- if (_this.settings.gridVerticalLines > 0) {
770
+ m_ctx.strokeStyle = m_gridVerticalCss.color;
771
+ if (_this.settings.gridVerticalLines) {
751
772
  if (_this.settings.drawy2axis == false || p.x != m_chartspaces.chart.left) {
752
- if (_this.settings.gridHorizontalLinesStyle == 'dash') {
773
+ if (_this.settings.gridVerticalLinesStyle == 'dash') {
753
774
  m_ctx.setLineDash([3, 3]);
754
775
  }
755
776
  if (newday) m_ctx.setLineDash([3, 3]);
@@ -833,15 +854,15 @@ function Milli_Chart(settings) {
833
854
  function drawXAxisYears(starttime, endtime) {
834
855
  if (getNumberOfDays(starttime, endtime) < 366) return drawXAxisMonth(starttime, endtime);
835
856
  m_ctx.save();
836
- m_ctx.font = m_xLegendCss['font-weight'] + ' ' + m_xLegendCss['font-size'] + ' ' + m_xLegendCss['font-family'];
837
- m_ctx.strokeStyle = m_gridHorizontalCss.color;
857
+ m_ctx.font = m_xLegendCss.fontWeight + ' ' + m_xLegendCss.fontSize + ' ' + m_xLegendCss.fontFamily;
858
+ m_ctx.strokeStyle = m_gridVerticalCss.color;
838
859
  m_ctx.fillStyle = m_xLegendCss.color;
839
860
  m_ctx.textAlign = "left";
840
861
  calcXScale(starttime, endtime);
841
862
  if (_this.settings.drawxaxis != 0) {
842
863
  m_ctx.beginPath();
843
- m_ctx.moveTo(m_chartspaces.chart.left, m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']) + 0.5);
844
- m_ctx.lineTo(m_chartspaces.chart.right, m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']) + 0.5);
864
+ m_ctx.moveTo(m_chartspaces.chart.left, m_chartspaces.chart.height - m_chartCss.marginBottom + 0.5);
865
+ m_ctx.lineTo(m_chartspaces.chart.right, m_chartspaces.chart.height - m_chartCss.marginBottom + 0.5);
845
866
  m_ctx.stroke();
846
867
  m_ctx.closePath();
847
868
  }
@@ -859,8 +880,8 @@ function Milli_Chart(settings) {
859
880
  }
860
881
  }
861
882
  if (draw) {
862
- //drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) });
863
- drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']) });
883
+ //drawXAxisGridlines({ 'x': x, y: m_canvas.height - m_chartCss.marginBottom });
884
+ drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.height - m_chartCss.marginBottom });
864
885
  text = year;
865
886
  if (_this.scaleinfoX.lineLength + m_chartspaces.chart.left > x - m_ctx.measureText(text).width) { // not to far right?
866
887
  if (_this.settings.yearLabelsPos == 'top') {
@@ -873,8 +894,8 @@ function Milli_Chart(settings) {
873
894
  m_ctx.fillText(text, 0, 0);
874
895
  m_ctx.restore();
875
896
  } else {
876
- //m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 10);
877
- m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']) + 10);
897
+ //m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_canvas.height - m_chartCss.marginBottom + 10);
898
+ m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_chartspaces.chart.height - m_chartCss.marginBottom + 10);
878
899
  }
879
900
  }
880
901
  numItems++;
@@ -898,12 +919,10 @@ function Milli_Chart(settings) {
898
919
  }
899
920
  }
900
921
  if (draw) {
901
- //drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) });
902
- drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']) });
922
+ drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.height - m_chartCss.marginBottom });
903
923
  text = formatDate(year.getFullYear() + '-07-01', _this.settings.dateformat);
904
924
  // ingen if som på year???
905
- //m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 10);
906
- m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']) + 10);
925
+ m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_chartspaces.chart.height - m_chartCss.marginBottom + 10);
907
926
  numItems++;
908
927
  legendItems.push({ 'text': text, timestamp: new Date(year + '-07-01T00:00:00Z'), 'x': x });
909
928
  }
@@ -928,11 +947,9 @@ function Milli_Chart(settings) {
928
947
  }
929
948
  if (dontPrint) break;
930
949
  if (draw) {
931
- //drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) });
932
- drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']) });
950
+ drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.height - m_chartCss.marginBottom });
933
951
  text = formatDate(year.getFullYear() + '-' + (year.getMonth() + 1) + '-01', _this.settings.dateformat);
934
- //m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 10);
935
- m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_chartspaces.height - parseInt(m_chartCss['margin-bottom']) + 10);
952
+ m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_chartspaces.chart.height - m_chartCss.marginBottom + 10);
936
953
  }
937
954
  legendItems.push({ 'text': text, timestamp: new Date(year + '-04-01T00:00:00Z'), 'x': x });
938
955
  year = new Date((year.getFullYear() + 1) + '-04-01T00:00:00Z');
@@ -951,11 +968,9 @@ function Milli_Chart(settings) {
951
968
  }
952
969
  }
953
970
  if (draw) {
954
- //drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) });
955
- drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']) });
971
+ drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.height - m_chartCss.marginBottom });
956
972
  text = formatDate(year.getFullYear() + '-' + (year.getMonth() + 1) + '-01', _this.settings.dateformat);
957
- //m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 10);
958
- m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']) + 10);
973
+ m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_chartspaces.chart.height - m_chartCss.marginBottom + 10);
959
974
  }
960
975
  legendItems.push({ 'text': text, timestamp: new Date(year + '-10-01T00:00:00Z'), 'x': x });
961
976
  year = new Date((year.getFullYear() + 1) + '-10-01T00:00:00Z');
@@ -970,14 +985,14 @@ function Milli_Chart(settings) {
970
985
  starttime -= starttime % 8640000;
971
986
  endtime -= starttime % 8640000;
972
987
  m_ctx.save();
973
- m_ctx.font = m_xLegendCss['font-weight'] + ' ' + m_xLegendCss['font-size'] + ' ' + m_xLegendCss['font-family'];
974
- m_ctx.strokeStyle = m_gridHorizontalCss.color;
988
+ m_ctx.font = m_xLegendCss.fontWeight + ' ' + m_xLegendCss.fontSize + ' ' + m_xLegendCss.fontFamily;
989
+ m_ctx.strokeStyle = m_gridVerticalCss.color;
975
990
  m_ctx.fillStyle = m_xLegendCss.color;
976
991
  calcXScale(starttime, endtime);
977
992
  if (_this.settings.drawxaxis != 0) { // draw line
978
993
  m_ctx.beginPath();
979
- m_ctx.moveTo(m_chartspaces.chart.left, m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']) + 0.5);
980
- m_ctx.lineTo(m_chartspaces.chart.right, m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']) + 0.5);
994
+ m_ctx.moveTo(m_chartspaces.chart.left, m_chartspaces.chart.height - m_chartCss.marginBottom + 0.5);
995
+ m_ctx.lineTo(m_chartspaces.chart.right, m_chartspaces.chart.height - m_chartCss.marginBottom + 0.5);
981
996
  m_ctx.stroke();
982
997
  m_ctx.closePath();
983
998
  }
@@ -1012,10 +1027,8 @@ function Milli_Chart(settings) {
1012
1027
  currentDate = new Date(currentDate.getTime() + 86400000);
1013
1028
  }
1014
1029
  // vad är detta?
1015
- if (typeof m_chartCss.boxShadow !== 'undefined') {
1016
- var boxshadow = m_chartCss.boxShadow.split(' ');
1017
- if (parseInt(boxshadow[1]) == 0) drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, false);
1018
-
1030
+ if (typeof m_chartCss.boxShadow !== 'undefined' && typeof m_chartCss.boxShadow.rightWidth !== 'undefined') {
1031
+ if (m_chartCss.boxShadow.rightWidth == 0) drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, false);
1019
1032
  } else {
1020
1033
  drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, false);
1021
1034
  }
@@ -1089,12 +1102,10 @@ function Milli_Chart(settings) {
1089
1102
  // internal
1090
1103
  if (typeof value !== 'string') return "";
1091
1104
  var datetime = new Date();
1092
- //var tz_offset = datetime.getTimezoneOffset();
1093
1105
  datetime.setHours(parseInt(value));
1094
1106
  datetime.setMinutes(parseInt(value.substring(3)));
1095
1107
  datetime.setSeconds(parseInt(value.substring(6)));
1096
1108
  datetime = datetime.getTime();
1097
- //datetime -= tz_offset * 60000; // tz_offset in minutes
1098
1109
  datetime = new Date(datetime);
1099
1110
  switch (format) {
1100
1111
  case 'HH:mm':
@@ -1122,8 +1133,9 @@ function Milli_Chart(settings) {
1122
1133
  }
1123
1134
 
1124
1135
  function drawXAxisTickLowerChart() {
1136
+
1125
1137
  m_ctx.save();
1126
- m_ctx.font = m_xLegendCss['font-weight'] + ' ' + m_xLegendCss['font-size'] + ' ' + m_xLegendCss['font-family'];
1138
+ m_ctx.font = m_xLegendCss.fontWeight + ' ' + m_xLegendCss.fontSize + ' ' + m_xLegendCss.fontFamily;
1127
1139
 
1128
1140
  m_ctx.strokeStyle = m_gridHorizontalCss.color;
1129
1141
  m_ctx.fillStyle = m_xLegendCss.color;
@@ -1138,10 +1150,11 @@ function Milli_Chart(settings) {
1138
1150
  }
1139
1151
 
1140
1152
  function drawXAxisTick(starttime, endtime) {
1153
+ // in unixtime
1141
1154
  m_ctx.save();
1142
- m_ctx.font = m_xLegendCss['font-weight'] + ' ' + m_xLegendCss['font-size'] + ' ' + m_xLegendCss['font-family'];
1155
+ m_ctx.font = m_xLegendCss.fontWeight + ' ' + m_xLegendCss.fontSize + ' ' + m_xLegendCss.fontFamily;
1143
1156
 
1144
- m_ctx.strokeStyle = m_gridHorizontalCss.color;
1157
+ m_ctx.strokeStyle = m_gridVerticalCss.color;
1145
1158
  m_ctx.fillStyle = m_xLegendCss.color;
1146
1159
  m_ctx.textAlign = "left";
1147
1160
  calcXScaleTick(starttime, endtime);
@@ -1152,6 +1165,7 @@ function Milli_Chart(settings) {
1152
1165
  m_ctx.stroke();
1153
1166
  m_ctx.closePath();
1154
1167
  }
1168
+ var dayLightChange = (new Date(starttime).getTimezoneOffset() - new Date().getTimezoneOffset()) * 60000;
1155
1169
  var currentDate = new Date(starttime);
1156
1170
  var x;
1157
1171
  var lastx = 0;
@@ -1185,6 +1199,17 @@ function Milli_Chart(settings) {
1185
1199
  if (_this.scaleinfoX.lineLength + m_chartspaces.chart.left > x - getMaxTimeWidth()) { // not to far right?
1186
1200
  m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_chartspaces.chart.bottom + 10);
1187
1201
  legendItems.push({ x: x, type: 0, text: text });
1202
+ if (_this.settings.intradaydates) { // draw dates on top
1203
+ m_ctx.save();
1204
+ var date = currentDate.getDate() + '/' + (currentDate.getMonth() + 1);
1205
+ var fontMetrix = m_ctx.measureText(date);
1206
+ var dx = x + fontMetrix.actualBoundingBoxAscent + fontMetrix.actualBoundingBoxDescent + 3;
1207
+ var dy = m_chartCss.marginTop; // + m_ctx.measureText(datum).width;
1208
+ m_ctx.translate(dx, dy);
1209
+ m_ctx.rotate(90 * Math.PI / 180);
1210
+ m_ctx.fillText(date, 0, 0);
1211
+ m_ctx.restore();
1212
+ }
1188
1213
  }
1189
1214
  if (x != m_chartspaces.chart.left + 0.5) { // do not draw the first line, it is already drawn
1190
1215
  if (openhour == currentDate.getTime() % 86400000) {
@@ -1203,7 +1228,7 @@ function Milli_Chart(settings) {
1203
1228
  }
1204
1229
  }
1205
1230
  // add timestamps
1206
- var currentDate = new Date(starttime);
1231
+ currentDate = new Date(starttime);
1207
1232
  if (currentDate.getTime() % 3600000 != 0) // if not full hour, move up to next full hour
1208
1233
  currentDate = new Date(currentDate.getTime() - currentDate.getTime() % 3600000 + 3600000); // START om full hour (if modulo == 0 then + 3600000 kanske)
1209
1234
 
@@ -1228,7 +1253,7 @@ function Milli_Chart(settings) {
1228
1253
  if (days == 1) {
1229
1254
  // use start and endtime as ticksize
1230
1255
  tickSize = new Date(endtime - starttime);
1231
- } else if (m_zoom.mouseup.timestamp && days == 2) { // zoom with more than 2 days
1256
+ } else if (m_zoom.mouseup.timestamp && days == 2) { // zoom with 2 days
1232
1257
  // use the day with most time as tickSize
1233
1258
  var tmpDate = new Date(starttime);
1234
1259
  tickSize = new Date(new Date(tmpDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z') - new Date(starttime)).getTime();
@@ -1262,13 +1287,21 @@ function Milli_Chart(settings) {
1262
1287
  tickSize = tickSize.getTime() / 3600000;
1263
1288
  interval = Math.floor(tickSize / (maxHourLegends + 1)) * 3600000;
1264
1289
  }
1265
- if (interval == 0) interval = 300000;
1266
- if (interval % 60000 != 0)
1290
+ if (interval == 0) {
1291
+ // default 1h
1292
+ interval = 3600000;
1293
+ modularvalue = 3600000;
1294
+ }
1295
+ if (interval % 60000 != 0) {
1267
1296
  interval = (interval - interval % 60000) + 60000; // remove sekunder
1297
+ }
1268
1298
  // print other times
1269
1299
  offset = 0;
1270
1300
  lastx = 0;
1271
1301
  var closeTime = new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
1302
+ dayLightChange = (closeTime.getTimezoneOffset() - new Date().getTimezoneOffset()) * 60000;
1303
+ closeTime = new Date(closeTime.getTime() - dayLightChange);
1304
+
1272
1305
  var workDate = new Date(currentDate);
1273
1306
  currentDate = new Date(starttime);
1274
1307
  if (currentDate.getTime() % modularvalue != 0) // if not full hour, move up to next full hour
@@ -1276,28 +1309,31 @@ function Milli_Chart(settings) {
1276
1309
 
1277
1310
  var count = 0;
1278
1311
  while (currentDate.getTime() <= _this.scaleinfoX.endTimeStamp) {
1312
+ dayLightChange = (closeTime.getTimezoneOffset() - new Date().getTimezoneOffset()) * 60000;
1279
1313
  if (count++ > 100) {
1280
1314
  break; // just make sure we dont do an infinity loop
1281
1315
 
1282
1316
  }
1283
1317
  draw = true;
1284
1318
  while (currentDate.getDay() == 0 || currentDate.getDay() == 6) { // move past weekends , maybe skip this if date is available in data
1285
- closeTime = new Date(closeTime.getTime() + 86400000);
1319
+ //closeTime = new Date(closeTime.getTime() + 86400000);
1286
1320
  currentDate = new Date(currentDate.getTime() + 86400000);
1321
+ closeTime = new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
1287
1322
  if (currentDate.getTime() % modularvalue != 0) // if not full hour, move up to next full hour
1288
1323
  currentDate = new Date(currentDate.getTime() - currentDate.getTime() % modularvalue + modularvalue); // START om full hour (if modulo == 0 then + 3600000 kanske)
1289
- var workDate = new Date(workDate.getTime() + 86400000);
1324
+ workDate = new Date(workDate.getTime() + 86400000);
1290
1325
  offset += 86400000 / _this.scaleinfoX.timePerPixel;
1291
1326
  }
1292
1327
  if (currentDate.getTime() > closeTime.getTime()) {
1293
1328
  // draw DayEnd(start) dash line
1294
- var dayStart = new Date(workDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z')
1329
+ var dayStart = new Date(workDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
1295
1330
  x = Math.round(m_chartspaces.chart.left + ((dayStart.getTime() - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel) - offset);
1296
1331
  drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, true); // dash?
1297
1332
 
1298
1333
  closeTime = new Date(closeTime.getTime() + 86400000);
1299
1334
  workDate = new Date(workDate.getTime() + 86400000);
1300
1335
  currentDate = new Date(workDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z');
1336
+
1301
1337
  if (currentDate.getTime() % modularvalue != 0) // if not full hour, move up to next full hour
1302
1338
  currentDate = new Date(currentDate.getTime() - currentDate.getTime() % modularvalue + modularvalue); // START om full hour (if modulo == 0 then + 3600000 kanske)
1303
1339
  offset += (86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel;
@@ -1321,12 +1357,12 @@ function Milli_Chart(settings) {
1321
1357
  if (lastx + (getMaxTimeWidth() / 2) > (x - getMaxTimeWidth())) {
1322
1358
  //draw = false;
1323
1359
  }
1324
- var text = formatChartTime(currentDate.toTimeString().substring(0, 8), _this.settings.timeformat);
1325
1360
  if (draw) {
1326
1361
  lastx = x;
1327
1362
  // if day change and setting print on top as well
1328
1363
  if (_this.scaleinfoX.lineLength + m_chartspaces.chart.left > x - getMaxTimeWidth()) { // not to far right?
1329
- m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_chartspaces.chart.bottom + 10);
1364
+ var label = formatChartTime(currentDate.toTimeString().substring(0, 8), _this.settings.timeformat);
1365
+ m_ctx.fillText(label, x - (m_ctx.measureText(label).width / 2), m_chartspaces.chart.bottom + 10);
1330
1366
  legendItems.push({ x: x, type: 0 });
1331
1367
  }
1332
1368
  drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, false);
@@ -1335,9 +1371,8 @@ function Milli_Chart(settings) {
1335
1371
  }
1336
1372
 
1337
1373
  // vad är detta?
1338
- if (typeof m_chartCss.boxShadow !== 'undefined') {
1339
- var boxshadow = m_chartCss.boxShadow.split(' ');
1340
- if (parseInt(boxshadow[1]) == 0) drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, false);
1374
+ if (typeof m_chartCss.boxShadow !== 'undefined' && typeof m_chartCss.boxShadow.rightWidth !== 'undefined') {
1375
+ if (m_chartCss.boxShadow.rightWidth == 0) drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, false);
1341
1376
 
1342
1377
  } else {
1343
1378
  drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, false);
@@ -1346,22 +1381,14 @@ function Milli_Chart(settings) {
1346
1381
  }
1347
1382
 
1348
1383
  function onMouseOut(evt) {
1349
- if (m_toolTip.dateDiv) {
1350
- m_toolTip.dateDiv.parentNode.removeChild(m_toolTip.dateDiv);
1351
- m_toolTip.dateDiv = null;
1352
- }
1353
- for (var i = 0; i < m_toolTip.instrDiv.length; i++) {
1354
- if (m_toolTip.instrDiv[i]) {
1355
- m_toolTip.instrDiv[i].parentNode.removeChild(m_toolTip.instrDiv[i]);
1356
- m_toolTip.instrDiv[i] = null;
1357
- }
1358
- if (m_toolTip.arrowDiv[i]) {
1359
- m_toolTip.arrowDiv[i].parentNode.removeChild(m_toolTip.arrowDiv[i]);
1360
- m_toolTip.arrowDiv[i] = null;
1384
+ for (var i = 0; i < _this.instruments.length; i++) {
1385
+ if (_this.instruments[i].insref != 0 && typeof _this.instruments[i].toolTip !== 'undefined') {
1386
+ _this.instruments[i].toolTip.parentNode.removeChild(_this.instruments[i].toolTip);
1387
+ _this.instruments[i].toolTipPointer.parentNode.removeChild(_this.instruments[i].toolTipPointer);
1388
+ _this.instruments[i].toolTip = undefined;
1389
+ _this.instruments[i].toolTipPointer = undefined;
1361
1390
  }
1362
1391
  }
1363
- m_toolTip.instrDiv = [];
1364
- m_toolTip.arrowDiv = [];
1365
1392
  }
1366
1393
 
1367
1394
  function clearZoom() {
@@ -1385,16 +1412,18 @@ function Milli_Chart(settings) {
1385
1412
  m_zoom.div = document.createElement('div');
1386
1413
  m_canvas.parentNode.appendChild(m_zoom.div);
1387
1414
  m_zoom.div.setAttribute('class', 'millistream-chart-zoombox');
1415
+ m_zoom.div.style.pointerEvents = 'none';
1416
+ m_zoom.div.style.position = 'absolute';
1388
1417
  }
1389
1418
  if (x < m_chartspaces.chart.left) x = m_chartspaces.chart.left;
1390
1419
  m_zoom.div.style.top = m_chartspaces.chart.top + 'px';
1391
1420
  m_zoom.div.style.left = (m_zoom.mousedown.pos > x ? x : m_zoom.mousedown.pos) + 'px';
1392
1421
  if (x > m_chartspaces.chart.right) x = m_chartspaces.chart.right;
1393
- m_zoom.div.style.height = m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']) - m_chartspaces.chart.top + 'px';
1422
+ m_zoom.div.style.height = m_chartspaces.chart.height - m_chartCss.marginBottom - m_chartspaces.chart.top + 'px';
1394
1423
  m_zoom.div.style.width = (m_zoom.mousedown.pos > x ? m_zoom.mousedown.pos - x : x - m_zoom.mousedown.pos) + 'px';
1395
1424
  }
1396
- if (_this.settings.enablehover == false) return;
1397
- if (x < m_chartspaces.chart.left || x > m_chartspaces.chart.right || y < m_chartspaces.chart.top || y > m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom'])) {
1425
+ if (typeof _this.settings.tooltip != 'object' || typeof _this.settings.tooltip.formatter != 'function') return;
1426
+ if (x < m_chartspaces.chart.left || x > m_chartspaces.chart.right || y < m_chartspaces.chart.top || y > m_chartspaces.chart.height - m_chartCss.marginBottom) {
1398
1427
  onMouseOut();
1399
1428
  return;
1400
1429
  }
@@ -1413,134 +1442,71 @@ function Milli_Chart(settings) {
1413
1442
  if (obj == null) {
1414
1443
  return;
1415
1444
  }
1416
- // datetime
1417
- if (m_toolTip.dateDiv == null) {
1418
- m_toolTip.dateDiv = document.createElement('div');
1419
- m_canvas.parentNode.appendChild(m_toolTip.dateDiv);
1420
- }
1421
- var d = new Date(obj.timestamp);
1422
- m_toolTip.dateDiv.innerHTML = zeroPad(d.getFullYear(), 2);
1423
- m_toolTip.dateDiv.innerHTML += '-' + zeroPad(d.getMonth() + 1, 2);
1424
- m_toolTip.dateDiv.innerHTML += '-' + zeroPad(d.getDate(), 2) + '&nbsp'; // fixa dateformatet
1425
- if (_this.settings.chartlen != 'ytd' && _this.settings.chartlen.charAt(_this.settings.chartlen.length - 1) == 'd') { // TODO: change to tickchart
1426
- m_toolTip.dateDiv.innerHTML += zeroPad(d.getHours(), 2);
1427
- m_toolTip.dateDiv.innerHTML += ':' + zeroPad(d.getMinutes(), 2);
1428
- m_toolTip.dateDiv.innerHTML += ':' + zeroPad(d.getSeconds(), 2);
1429
- }
1430
- m_toolTip.dateDiv.innerHTML += 'X:' + x;
1431
- m_toolTip.dateDiv.setAttribute('class', 'millistream-chart-tooltip'); // set class so we can measure it might change below depending on position
1432
- m_toolTip.dateDiv.style.left = m_dataPoints.arr[i] + 'px'; // TODO: räkna ut 7 px beroende på hur hoverpilen ser ut från höjden på diven
1433
-
1434
- // prices
1435
- var highy = -1000;
1436
- var lowy = 1000000; // hmm
1437
- var priceorder = [];
1438
- var num = 0;
1439
- for (x = 0; x < _this.instruments.length; x++) {
1440
- if (typeof m_toolTip.instrDiv[x] === 'undefined') {
1441
- m_toolTip.instrDiv[x] = document.createElement('div');
1442
- m_canvas.parentNode.appendChild(m_toolTip.instrDiv[x]);
1443
- }
1444
- if (typeof obj.instruments[x] === 'undefined') {
1445
- m_toolTip.instrDiv[x].style.display = 'none';
1446
- continue;
1447
- }
1448
- m_toolTip.instrDiv[x].style.display = 'block';
1449
- priceorder[num] = {};
1450
- priceorder[num].price = obj.instruments[x].price * _this.instruments[x].factor;
1451
- priceorder[num].instrument = x;
1452
- num++;
1453
- }
1454
- if (priceorder.length > 1) {
1455
- priceorder.sort(function(a, b) {
1456
- return b.price - a.price;
1457
- });
1458
- }
1459
- var keys = Object.keys(priceorder);
1460
- var left = 0;
1461
- for (x = 0; x < keys.length; x++) {
1462
- var k = priceorder[x].instrument;
1463
- if (typeof obj.instruments[k] !== 'undefined') {
1464
- var posy = obj.instruments[k].y - 7;
1445
+ var highy = -1;
1446
+ var lowy = m_chartspaces.height;
1447
+ for (var x = 0; x < _this.instruments.length; x++) {
1448
+ if (_this.instruments[x].insref != 0 && typeof obj.instruments[x] !== 'undefined') {
1449
+ var instr = {};
1450
+ instr.chartType = _this.scaleinfoY.type;
1451
+ instr.name = _this.instruments[x].name;
1452
+ if (typeof _this.instruments[x].symbol !== 'undefined')
1453
+ instr.symbol = _this.instruments[x].symbol;
1454
+
1455
+ instr.data = {};
1456
+ MillistreamWidgetApi_AssignObject(obj.instruments[x], instr.data);
1457
+ instr.data.price = formatNiceNumber(instr.data.price, _this.settings.thousandseparator, _this.settings.decimalseparator, _this.settings.num_decimals, false);
1458
+
1459
+ var ttip = _this.settings.tooltip.formatter.call(instr);
1460
+ if (typeof _this.instruments[x].toolTip === 'undefined') {
1461
+ // add textdiv
1462
+ _this.instruments[x].toolTip = document.createElement('div');
1463
+ _this.instruments[x].toolTip.style.display = 'block';
1464
+ _this.instruments[x].toolTip.setAttribute('class', 'millistream-chart-tooltip'); // set class so we can measure it might change below depending on position
1465
+ _this.instruments[x].toolTip.position = 'absolute';
1466
+ m_canvas.parentNode.appendChild(_this.instruments[x].toolTip);
1467
+ // add pointer div
1468
+ _this.instruments[x].toolTipPointer = document.createElement('div');
1469
+ m_canvas.parentNode.appendChild(_this.instruments[x].toolTipPointer);
1470
+ _this.instruments[x].toolTipPointer.setAttribute('class', 'millistream-chart-pointer');
1471
+ _this.instruments[x].toolTipPointer.style.left = (m_dataPoints.arr[i] - (_this.instruments[x].toolTipPointer.clientWidth / 2)) + 'px';
1472
+ _this.instruments[x].toolTipPointer.style.top = (obj.instruments[x].y - (_this.instruments[x].toolTipPointer.clientHeight / 2)) + 'px';
1473
+ _this.instruments[x].toolTipPointer.style.position = 'absolute';
1474
+ _this.instruments[x].toolTipPointer.style.backgroundColor = m_instrumentCss[x].color;
1475
+ _this.instruments[x].toolTipPointer.style.pointerEvents = 'none';
1476
+
1477
+ }
1478
+ var pointerStyle = getComputedStyle(_this.instruments[x].toolTipPointer);
1479
+ var pointerWidth = _this.instruments[x].toolTipPointer.offsetWidth + parseInt(pointerStyle.marginLeft) + parseInt(pointerStyle.marginRight);
1480
+ var pointerHeight = _this.instruments[x].toolTipPointer.offsetHeight + parseInt(pointerStyle.marginTop) + parseInt(pointerStyle.marginBottom);
1481
+ _this.instruments[x].toolTip.innerHTML = ttip;
1482
+ var posy = obj.instruments[x].y - (_this.instruments[x].toolTip.offsetHeight / 2);
1465
1483
  var tmp = Math.abs(posy - parseFloat(highy));
1466
- if (tmp < 30) {
1467
- posy = parseFloat(highy) + 20;
1484
+ var height = _this.instruments[x].toolTip.offsetHeight;
1485
+ if (tmp < height) {
1486
+ posy = parseFloat(highy) + height;
1468
1487
  }
1469
1488
  tmp = Math.abs(posy - parseFloat(lowy));
1470
1489
  if (tmp < 30) {
1471
1490
  // hur gör vi här? behövs det när vi sätter dom i ordning?
1472
1491
  //posy = parseFloat(highy) + 20;
1473
1492
  }
1474
- m_toolTip.instrDiv[k].innerHTML = formatNiceNumber(obj.instruments[k].price, _this.settings.thousandseparator, _this.settings.decimalseparator, obj.instruments[k].price.countDecimals());
1475
- if (typeof obj.instruments[k].diff !== 'undefined') m_toolTip.instrDiv[k].innerHTML += ', diff:' + formatNiceNumber(obj.instruments[k].diff, ' ', ',', m_y2settings.decimals);
1476
- m_toolTip.instrDiv[k].setAttribute('class', 'millistream-chart-tooltip'); // set class so we can measure it might change below depending on position
1477
- m_toolTip.instrDiv[k].style.top = posy + 'px'; // TODO: räkna ut 7 px beroende på hur hoverpilen ser ut från höjden på diven depending on position
1478
- if (m_dataPoints.arr[i] + m_toolTip.instrDiv[k].offsetWidth + 10 > m_canvas.width || m_dataPoints.arr[i] + m_toolTip.dateDiv.offsetWidth + 10 > m_canvas.width) { // TODO +10 should be calculated better
1493
+ 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
1479
1494
  // draw the hover to the left
1480
- m_toolTip.instrDiv[k].setAttribute('class', 'millistream-chart-tooltip');
1481
- m_toolTip.instrDiv[k].style.left = (m_dataPoints.arr[i] - m_toolTip.instrDiv[k].offsetWidth - 10) + 'px'; // - parseInt(m_tooltipLeftCss['border-left-width']) + 'px';
1495
+ _this.instruments[x].toolTip.style.left = (m_dataPoints.arr[i] - _this.instruments[x].toolTip.offsetWidth - (pointerWidth / 2)) + 1 + 'px';
1482
1496
  } else {
1483
1497
  // draw hover to the right
1484
- m_toolTip.instrDiv[k].style.left = (m_dataPoints.arr[i] + 10) + 'px'; //+ parseInt(m_tooltipLeftCss['border-left-width']) - 1 + 'px';
1485
- m_toolTip.instrDiv[k].setAttribute('class', 'millistream-chart-tooltip');
1486
- }
1487
- left = m_toolTip.instrDiv[k].style.left;
1488
- //m_toolTip.instrDiv[x].style.display = 'block';
1489
- //m_toolTip.instrDiv[x].style.height = '14px';
1490
- // draw arrow
1491
- var arrow = false;
1492
- var color;
1493
- if (arrow) {
1494
- if (typeof m_toolTip.arrowDiv[k] === 'undefined') {
1495
- m_toolTip.arrowDiv[k] = document.createElement('div');
1496
- m_canvas.parentNode.appendChild(m_toolTip.arrowDiv[k]);
1497
- }
1498
- var thickness = 2;
1499
- var x1 = m_dataPoints.arr[i];
1500
- var x2 = parseInt(m_toolTip.instrDiv[k].style.left);
1501
- var y1 = obj.instruments[k].y;
1502
- var y2 = parseInt(m_toolTip.instrDiv[k].style.top) + (parseInt(m_toolTip.instrDiv[k].style.height) / 2);
1503
- var length = Math.sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)));
1504
- var cx = ((x1 + x2) / 2) - (length / 2);
1505
- var cy = ((y1 + y2) / 2) - (thickness / 2);
1506
- // angle
1507
- var angle = Math.atan2((y1 - y2), (x1 - x2)) * (180 / Math.PI);
1508
- color = m_instrumentCss[k].color;
1509
- m_toolTip.arrowDiv[k].style.padding = '0px';
1510
- m_toolTip.arrowDiv[k].style.margin = '0px';
1511
- m_toolTip.arrowDiv[k].style.height = thickness + 'px';
1512
- m_toolTip.arrowDiv[k].style.backgroundColor = color;
1513
- m_toolTip.arrowDiv[k].style.lineHeight = '1px';
1514
- m_toolTip.arrowDiv[k].style.position = 'absolute';
1515
- m_toolTip.arrowDiv[k].style.left = cx + 'px';
1516
- m_toolTip.arrowDiv[k].style.top = cy + 'px';
1517
- m_toolTip.arrowDiv[k].style.width = length + 'px';
1518
- m_toolTip.arrowDiv[k].style.pointerEvents = 'none';
1519
- m_toolTip.arrowDiv[k].style.transform = 'rotate(' + angle + 'deg)';
1520
- } else {
1521
- if (typeof m_toolTip.arrowDiv[k] === 'undefined') {
1522
- m_toolTip.arrowDiv[k] = document.createElement('div');
1523
- m_canvas.parentNode.appendChild(m_toolTip.arrowDiv[k]);
1524
- }
1525
- m_toolTip.arrowDiv[k].setAttribute('class', 'millistream-chart-pointer');
1526
- m_toolTip.arrowDiv[k].style.left = (m_dataPoints.arr[i] - (m_toolTip.arrowDiv[k].clientWidth / 2)) + 'px';
1527
- m_toolTip.arrowDiv[k].style.top = (obj.instruments[k].y - (m_toolTip.arrowDiv[k].clientHeight / 2)) + 'px';
1528
- m_toolTip.arrowDiv[k].style.position = 'absolute';
1529
- color = m_instrumentCss[k].color;
1530
- m_toolTip.arrowDiv[k].style.backgroundColor = color;
1531
- m_toolTip.arrowDiv[k].style.pointerEvents = 'none';
1498
+ _this.instruments[x].toolTip.style.left = (obj.instruments[x].x + (pointerWidth / 2)) + 'px';
1532
1499
  }
1500
+ _this.instruments[x].toolTip.style.top = posy + 'px';
1501
+
1502
+ _this.instruments[x].toolTipPointer.style.left = (obj.instruments[x].x - (pointerWidth / 2)) + 1 + 'px'; // hmm plus 1??
1503
+ _this.instruments[x].toolTipPointer.style.top = (obj.instruments[x].y - (pointerHeight / 2)) + 'px';
1533
1504
  if (posy > highy) highy = posy;
1534
1505
  if (posy < lowy) lowy = posy;
1535
- } else {
1536
- console.log('No instrument error');
1506
+
1537
1507
  }
1538
1508
  }
1539
- if (m_toolTip.instrDiv.length > 0) {
1540
- m_toolTip.dateDiv.style.left = left;
1541
- m_toolTip.dateDiv.style.top = parseInt(m_toolTip.instrDiv[0].style.top) - m_toolTip.dateDiv.offsetHeight - 5 + 'px'; // datepos
1542
- m_toolTip.dateDiv.style.top = lowy - m_toolTip.dateDiv.offsetHeight - 5 + 'px'; // datepos
1543
- }
1509
+ return;
1544
1510
  }
1545
1511
 
1546
1512
  function setTimeSpanData() {
@@ -1559,33 +1525,13 @@ function Milli_Chart(settings) {
1559
1525
  enddate = enddate.replaceAll('\/', '-');
1560
1526
  m_zoom.mousedown.timestamp = new Date(startdate + 'T00:00:00Z');
1561
1527
  m_zoom.mouseup.timestamp = new Date(enddate + 'T00:00:00Z');
1562
- // _this.scaleinfoX.endTimeStamp = m_zoom.mouseup.timestamp > m_zoom.mousedown.timestamp ? m_zoom.mouseup.timestamp : m_zoom.mousedown.timestamp;
1563
- // _this.scaleinfoX.startTimeStamp = m_zoom.mouseup.timestamp < m_zoom.mousedown.timestamp ? m_zoom.mouseup.timestamp : m_zoom.mousedown.timestamp;
1564
1528
  _this.drawChart();
1565
1529
  };
1566
1530
 
1567
1531
  function calcCompareFactors(type) {
1568
1532
  var i, s;
1569
- if (type == 'history2') {
1570
- if (_this.instruments.length > 1) {
1571
- if (_this.instruments[s].insref != 0) {
1572
- for (i = 0; i < _this.instruments[0].history.length; i++) {
1573
- if (_this.instruments[0].history[i].timestamp >= _this.scaleinfoX.startTimeStamp) {
1574
- instrumentprice = _this.instruments[0].history[i].price;
1575
- break;
1576
- }
1577
- }
1578
- for (s = 1; s < _this.instruments.length; s++) {
1579
- for (i = 0; i < _this.instruments[s].history.length; i++) {
1580
- if (_this.instruments[s].history[i].timestamp >= _this.scaleinfoX.startTimeStamp) {
1581
- _this.instruments[s].factor = instrumentprice / _this.instruments[s].history[i].price;
1582
- break;
1583
- }
1584
- }
1585
- }
1586
- }
1587
- }
1588
- }
1533
+ var instrumentprice;
1534
+
1589
1535
  if (_this.instruments.length > 1) {
1590
1536
  for (s = 1; s < _this.instruments.length; s++) {
1591
1537
  if (_this.instruments[s].insref != 0) {
@@ -1607,7 +1553,6 @@ function Milli_Chart(settings) {
1607
1553
  }
1608
1554
 
1609
1555
  function checkChartData(data) {
1610
- // _this.instruments[0].history / _this.instruments[0].trades
1611
1556
  var count = 0;
1612
1557
  for (var i = 0; i < data.length; i++) {
1613
1558
  if (data[i].timestamp >= _this.scaleinfoX.startTimeStamp && data[i].timestamp <= _this.scaleinfoX.endTimeStamp) {
@@ -1620,8 +1565,8 @@ function Milli_Chart(settings) {
1620
1565
  var y = m_chartspaces.chart.bottom - m_chartspaces.chart.top / 2 + m_chartspaces.chart.top;
1621
1566
  var x = m_chartspaces.chart.right - m_chartspaces.chart.left / 2 + m_chartspaces.chart.left;
1622
1567
  m_ctx.save();
1623
- m_ctx.font = 'bold ' + m_xLegendCss['font-size'] + ' ' + m_xLegendCss['font-family'];
1624
- m_ctx.font = 'bold 12px ' + m_xLegendCss['font-family'];
1568
+ m_ctx.font = 'bold ' + m_xLegendCss.fontSize + ' ' + m_xLegendCss.fontFamily;
1569
+ m_ctx.font = 'bold 12px ' + m_xLegendCss.fontFamily;
1625
1570
  m_ctx.strokeStyle = m_gridHorizontalCss.color;
1626
1571
  m_ctx.fillStyle = m_xLegendCss.color;
1627
1572
  m_ctx.textAlign = "left";
@@ -1633,16 +1578,16 @@ function Milli_Chart(settings) {
1633
1578
 
1634
1579
  function calcChartSpaces() {
1635
1580
  m_chartspaces.chart.height = Math.round(m_canvas.height * (m_chartspaces.chart.percent / 100));
1636
- m_chartspaces.chart.top = parseInt(m_chartCss['margin-top']);
1637
- m_chartspaces.chart.left = parseInt(m_chartCss['margin-left']);
1638
- m_chartspaces.chart.right = m_canvas.width - parseInt(m_chartCss['margin-right']);
1639
- m_chartspaces.chart.bottom = m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']);
1581
+ m_chartspaces.chart.top = m_chartCss.marginTop;
1582
+ m_chartspaces.chart.left = m_chartCss.marginLeft;
1583
+ m_chartspaces.chart.right = m_canvas.width - m_chartCss.marginRight;
1584
+ m_chartspaces.chart.bottom = m_chartspaces.chart.height - m_chartCss.marginBottom;
1640
1585
  m_chartspaces.chart.width = m_canvas.width;
1641
1586
  m_chartspaces.lowerChart.height = m_canvas.height * (m_chartspaces.lowerChart.percent / 100);
1642
- m_chartspaces.lowerChart.top = Math.round(m_chartspaces.chart.bottom + parseInt(m_chartCss['margin-bottom']) + m_chartspaces.chart.top);
1587
+ m_chartspaces.lowerChart.top = Math.round(m_chartspaces.chart.bottom + m_chartCss.marginBottom + m_chartspaces.chart.top);
1643
1588
  m_chartspaces.lowerChart.left = m_chartspaces.chart.left;
1644
1589
  m_chartspaces.lowerChart.right = m_chartspaces.chart.right;
1645
- m_chartspaces.lowerChart.bottom = m_canvas.height - parseInt(m_chartCss['margin-bottom']);
1590
+ m_chartspaces.lowerChart.bottom = m_canvas.height - m_chartCss.marginBottom;
1646
1591
  m_chartspaces.lowerChart.width = m_canvas.width;
1647
1592
  }
1648
1593
 
@@ -1658,7 +1603,6 @@ function Milli_Chart(settings) {
1658
1603
  }
1659
1604
  m_lastDrawnInstrument = _this.instruments[0].insref;
1660
1605
  if (m_ctx == null) return;
1661
- //console.clear();
1662
1606
  m_datapoints = [];
1663
1607
  if (m_dataPoints.map) m_dataPoints.map.clear();
1664
1608
  m_dataPoints.map = new Map();
@@ -1672,13 +1616,12 @@ function Milli_Chart(settings) {
1672
1616
  var period = _this.settings.chartlen.substring(_this.settings.chartlen.length - 1);
1673
1617
  var len = parseInt(_this.settings.chartlen.substring(0, _this.settings.chartlen.length - 1));
1674
1618
  m_ctx.clearRect(0, 0, m_canvas.width, m_canvas.height);
1675
- m_ctx.fillStyle = m_chartCss['background-color'];
1619
+ m_ctx.fillStyle = m_chartCss.backgroundColor;
1676
1620
  m_ctx.fillRect(0, 0, m_canvas.width, m_canvas.height);
1677
1621
  m_ctx.lineWidth = 1;
1678
1622
  m_ctx.textBaseline = 'top'; // important!
1679
1623
  var i;
1680
1624
  if (period == 'd' && _this.instruments[0].trades.length != 0 && _this.settings.chartlen != 'ytd') {
1681
- _this.settings.graphvalue = 'price'; // om man får nav kanske man skall ta det från datan?
1682
1625
  if (m_zoom.mousedown.timestamp) {
1683
1626
  _this.scaleinfoX.endTimeStamp = m_zoom.mouseup.timestamp > m_zoom.mousedown.timestamp ? m_zoom.mouseup.timestamp : m_zoom.mousedown.timestamp;
1684
1627
  _this.scaleinfoX.startTimeStamp = m_zoom.mouseup.timestamp < m_zoom.mousedown.timestamp ? m_zoom.mouseup.timestamp : m_zoom.mousedown.timestamp;
@@ -1720,6 +1663,7 @@ function Milli_Chart(settings) {
1720
1663
  _this.scaleinfoY.type = 'trades';
1721
1664
  if (_this.instruments.length > 1) {
1722
1665
  // calc factors
1666
+ var instrumentprice;
1723
1667
  for (i = 0; i < _this.instruments[0].trades.length; i++) {
1724
1668
  if (_this.instruments[0].trades[i].timestamp >= _this.scaleinfoX.startTimeStamp) {
1725
1669
  instrumentprice = _this.instruments[0].trades[i].price;
@@ -1761,7 +1705,6 @@ function Milli_Chart(settings) {
1761
1705
  _this.scaleinfoX.endTimeStamp = new Date(_this.scaleinfoX.endTimeStamp.toISOString().substring(0, 10) + 'T' + '00:00:00Z').getTime();
1762
1706
  }
1763
1707
  setTimeSpanData();
1764
- _this.settings.graphvalue = 'price';
1765
1708
  _this.scaleinfoY.type = 'history';
1766
1709
  calcCompareFactors('history');
1767
1710
  _this.instruments[0].factor = 1;
@@ -1785,7 +1728,6 @@ function Milli_Chart(settings) {
1785
1728
  var startdate;
1786
1729
  if (_this.settings.chartlen == 'max' && _this.instruments[0].history.length > 1) {
1787
1730
  startdate = _this.instruments[0].history[0].timestamp;
1788
- //console.log('max', new Date(startdate));
1789
1731
  } else
1790
1732
  if (_this.settings.chartlen == 'ytd') {
1791
1733
  startdate = new Date(new Date().getFullYear() - 1 + '-12-30').getTime(); // TODO, hur skall vi göra här om det inte finns data runt här?
@@ -1800,7 +1742,6 @@ function Milli_Chart(settings) {
1800
1742
  }
1801
1743
  setTimeSpanData();
1802
1744
  _this.scaleinfoY.type = 'history';
1803
- _this.settings.graphvalue = 'price';
1804
1745
  calcCompareFactors('history');
1805
1746
 
1806
1747
  _this.instruments[0].factor = 1;
@@ -1819,28 +1760,22 @@ function Milli_Chart(settings) {
1819
1760
  drawYAxisLower();
1820
1761
  drawBoxShadow(m_chartspaces.lowerChart);
1821
1762
  }
1822
- onMouseOut();
1763
+ //onMouseOut();
1823
1764
  };
1824
1765
 
1825
1766
  function drawBoxShadow(space) {
1826
- if (typeof m_chartCss.boxShadow === 'undefined') return;
1827
- var boxShadow = m_chartCss.boxShadow;
1828
- if (boxShadow.indexOf(')') != -1) {
1829
- boxShadow = boxShadow.substring(boxShadow.indexOf(')') + 2);
1830
- }
1831
- var boxshadow = boxShadow.split(' ');
1767
+ if (typeof m_chartCss.boxShadow === 'undefined' && typeof m_chartCss.boxShadow.color !== 'undefined') return;
1832
1768
  m_ctx.save();
1833
1769
  m_ctx.beginPath();
1834
- if (parseInt(boxshadow[0]) > 0) {
1835
- m_ctx.strokeStyle = m_chartCss['border-top-color'];
1836
- m_ctx.lineWidth = parseInt(boxshadow[1]);
1770
+ m_ctx.strokeStyle = m_chartCss.boxShadow.color;
1771
+ if (typeof m_chartCss.boxShadow.topWidth !== 'undefined' && m_chartCss.boxShadow.topWidth > 0) {
1772
+ m_ctx.lineWidth = m_chartCss.boxShadow.topWidth;
1837
1773
  m_ctx.moveTo(space.left, space.top);
1838
1774
  m_ctx.lineTo(space.right, space.top);
1839
1775
  m_ctx.stroke();
1840
1776
  }
1841
- if (parseInt(boxshadow[1]) > 0) {
1842
- m_ctx.strokeStyle = m_chartCss['border-right-color'];
1843
- m_ctx.lineWidth = parseInt(boxshadow[1]);
1777
+ if (typeof m_chartCss.boxShadow.rightWidth !== 'undefined' && m_chartCss.boxShadow.rightWidth > 0) {
1778
+ m_ctx.lineWidth = m_chartCss.boxShadow.rightWidth;
1844
1779
  m_ctx.moveTo(space.right, space.top + 0.5);
1845
1780
  m_ctx.lineTo(space.right, space.bottom);
1846
1781
  m_ctx.stroke();
@@ -1854,8 +1789,11 @@ function Milli_Chart(settings) {
1854
1789
  return item.insref == data.insref;
1855
1790
  });
1856
1791
  if (instr == null) return;
1857
- var last = 0;
1792
+ /*var last = 0;*/
1858
1793
  if (typeof data.name !== 'undefined') instr.name = data.name;
1794
+ if (typeof data.symbol !== 'undefined') instr.symbol = data.symbol;
1795
+ if (typeof data.ticksize !== 'undefined') _this.settings.num_decimals = data.ticksize;
1796
+
1859
1797
  if (typeof data.tradecurrency !== 'undefined') instr.tradecurrency = data.tradecurrency;
1860
1798
  if (data.marketopen && data.marketclose) {
1861
1799
  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
@@ -1896,8 +1834,8 @@ function Milli_Chart(settings) {
1896
1834
  item = [];
1897
1835
  item.timestamp = data.trades[i].timestamp - (data.trades[i].timestamp % 60000);
1898
1836
 
1899
- if (last > item.timestamp) //console.log('ERROR', item.timestamp);
1900
- last = item.timestamp;
1837
+ /*if (last > item.timestamp)
1838
+ last = item.timestamp;*/
1901
1839
  if (typeof data.trades[i].tradeprice !== 'undefined') item.price = parseFloat(data.trades[i].tradeprice) * factor;
1902
1840
  if (typeof data.trades[i].tradequantity !== 'undefined' && data.trades[i].tradequantity != null) {
1903
1841
  item.quantity = parseInt(data.trades[i].tradequantity);
@@ -1949,8 +1887,6 @@ function Milli_Chart(settings) {
1949
1887
  _this.drawChart();
1950
1888
  return;
1951
1889
  }
1952
- /*if (m_modules.quantity == null)
1953
- m_modules.quantity = new MilliChart_Quantity(_this, m_canvas);*/
1954
1890
  _this.drawChart();
1955
1891
  };
1956
1892
 
@@ -2029,9 +1965,9 @@ function Milli_Chart(settings) {
2029
1965
  // TODO: här blir det fel när det är från 00:00: 23:59 men göms av tmpx < startpoint.x
2030
1966
 
2031
1967
  }
2032
- //startpoint.y = Math.round(m_canvas.height - parseInt(m_chartCss['margin-bottom']) - (((data[i].price * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2033
- startpoint.y = Math.round(m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']) - (((data[i].price * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2034
- var maxy = maxy > startpoint.y ? maxy : startpoint.y;
1968
+ //startpoint.y = Math.round(m_canvas.height - m_chartCss.marginBottom - (((data[i].price * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
1969
+ startpoint.y = Math.round(m_chartspaces.chart.height - m_chartCss.marginBottom - (((data[i].price * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
1970
+ maxy = maxy > startpoint.y ? maxy : startpoint.y;
2035
1971
 
2036
1972
  startpoint.x = Math.round(m_chartspaces.chart.left + ((data[i].timestamp - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel)) + 0.5;
2037
1973
  startpoint.x -= offset;
@@ -2046,7 +1982,6 @@ function Milli_Chart(settings) {
2046
1982
  }
2047
1983
 
2048
1984
  function plotData(data, instrument) {
2049
- //console.log('plotting',instrument,_this.instruments[instrument],_this.instruments);
2050
1985
  m_ctx.save();
2051
1986
  m_ctx.strokeStyle = m_instrumentCss[instrument].color;
2052
1987
  var factor = _this.instruments[instrument].factor;
@@ -2054,7 +1989,7 @@ function Milli_Chart(settings) {
2054
1989
  var endpoint = { x: 0, y: 0 };
2055
1990
  var startDate = _this.scaleinfoX.startTimeStamp;
2056
1991
  var len = data.length;
2057
- m_ctx.lineWidth = parseInt(m_instrumentCss[instrument].width);
1992
+ m_ctx.lineWidth = m_instrumentCss[instrument].width;
2058
1993
  m_ctx.beginPath();
2059
1994
 
2060
1995
  var startx = 0;
@@ -2064,6 +1999,7 @@ function Milli_Chart(settings) {
2064
1999
  var addedcloseprice1d = false;
2065
2000
  var maxy = 0;
2066
2001
  var hCurveLastPoint = null;
2002
+ var quantity = 0;
2067
2003
  for (var i = 0; i < len; i++) {
2068
2004
  var currentDate;
2069
2005
  var lastItem = data[i];
@@ -2074,7 +2010,6 @@ function Milli_Chart(settings) {
2074
2010
  continue;
2075
2011
  }
2076
2012
  if (data[i].timestamp > _this.scaleinfoX.endTimeStamp) {
2077
- //console.log('break', data[i].timestamp, _this.scaleinfoX.endTimeStamp);
2078
2013
  break; // continue?
2079
2014
  }
2080
2015
 
@@ -2083,11 +2018,11 @@ function Milli_Chart(settings) {
2083
2018
  continue;
2084
2019
  }
2085
2020
  var endtimeToday = new Date(data[i].timestamp);
2021
+ 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
2086
2022
  if (_this.scaleinfoY.type != 'history') {
2087
2023
  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
2088
2024
  }
2089
2025
  if (data[i].timestamp > endtimeToday.getTime()) {
2090
- console.log('no plot');
2091
2026
  continue; // dataticks efter stängning ritas inte
2092
2027
  }
2093
2028
 
@@ -2095,32 +2030,15 @@ function Milli_Chart(settings) {
2095
2030
  //var point = { price: data[i].price, open: null, x: endpoint.x - 0.5, y: endpoint.y - 0.5, timestamp: data[i].timestamp };
2096
2031
  //m_datapoints.push(point);
2097
2032
  } else
2098
- if (addedcloseprice1d == false && m_zoom.mouseup.timestamp == null) {
2033
+ if (addedcloseprice1d == false && m_zoom.mouseup.timestamp == null && (_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d')) { // only draw closeprice1d on today charts
2099
2034
  currentDate = new Date(data[i].timestamp);
2100
2035
  offset = ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel) * dateDiffInDays(new Date(startDate), currentDate);
2101
2036
  tmp = new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z');
2102
2037
  endpoint.x = Math.round(m_chartspaces.chart.left + ((tmp.getTime() - startDate) / _this.scaleinfoX.timePerPixel)) + 0.5 - offset;
2103
2038
  if (_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d') { // plot the closeprice1d
2104
- //endpoint.y = Math.round(m_canvas.height - parseInt(m_chartCss['margin-bottom']) - (((parseFloat(_this.instruments[instrument].closeprice1d) * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2105
- endpoint.y = Math.round(m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']) - (((parseFloat(_this.instruments[instrument].closeprice1d) * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2039
+ endpoint.y = Math.round(m_chartspaces.chart.height - m_chartCss.marginBottom - (((parseFloat(_this.instruments[instrument].closeprice1d) * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2106
2040
  } else {
2107
- //endpoint.y = Math.round(m_canvas.height - parseInt(m_chartCss['margin-bottom']) - (((parseFloat(lastItem.price) * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2108
- endpoint.y = Math.round(m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']) - (((parseFloat(lastItem.price) * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2109
- // do not add closeprice to hover array
2110
- /*
2111
- var x = Math.round(endpoint.x);
2112
- if (!m_dataPoints.arr.includes(x)) {
2113
- m_dataPoints.arr.push(x);
2114
- }
2115
- var obj = m_dataPoints.map.get(x);
2116
- if (obj == null) {
2117
- obj = {};
2118
- obj.timestamp = data[i].timestamp;
2119
- obj.instruments = [];
2120
- m_dataPoints.map.set(x, obj);
2121
- }
2122
- obj.instruments[instrument] = { price: data[i].price, open: data[i].openprice, x: startpoint.x - 0.5, y: startpoint.y - 0.5, timestamp: data[i].timestamp, date: new Date(data[i].timestamp), insref: _this.instruments[instrument].insref, diff: data[i].diff };
2123
- */
2041
+ endpoint.y = Math.round(m_chartspaces.chart.height - m_chartCss.marginBottom - (((parseFloat(lastItem.price) * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2124
2042
  }
2125
2043
  m_ctx.moveTo(endpoint.x, endpoint.y);
2126
2044
  lastdate = new Date(data[i].timestamp);
@@ -2132,7 +2050,6 @@ function Milli_Chart(settings) {
2132
2050
  currentDate.setHours(lastdate.getHours());
2133
2051
  currentDate.setMinutes(lastdate.getMinutes());
2134
2052
  currentDate.setSeconds(lastdate.getSeconds());
2135
-
2136
2053
  if (lastdate.toISOString().substring(0, 10) != currentDate.toISOString().substring(0, 10)) { // new date
2137
2054
  tmp = new Date(lastdate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
2138
2055
  // draw Day separator?
@@ -2159,12 +2076,13 @@ function Milli_Chart(settings) {
2159
2076
  }
2160
2077
  //m_ctx.lineTo(startpoint.x, startpoint.y);
2161
2078
  }
2162
- //startpoint.y = Math.round(m_canvas.height - parseInt(m_chartCss['margin-bottom']) - (((data[i].price * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2163
- startpoint.y = Math.round(m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']) - (((data[i].price * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2079
+ //startpoint.y = Math.round(m_canvas.height - m_chartCss.marginBottom - (((data[i].price * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2080
+ startpoint.y = Math.round(m_chartspaces.chart.height - m_chartCss.marginBottom - (((data[i].price * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2164
2081
  maxy = maxy > startpoint.y ? maxy : startpoint.y;
2165
2082
 
2166
2083
  startpoint.x = Math.round(m_chartspaces.chart.left + ((data[i].timestamp - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel)) + 0.5;
2167
2084
  startpoint.x -= offset;
2085
+ quantity += data[i].quantity;
2168
2086
  if (startpoint.x != endpoint.x || startpoint.y != endpoint.y) {
2169
2087
  var x = Math.round(startpoint.x);
2170
2088
  if (!m_dataPoints.arr.includes(x)) {
@@ -2175,7 +2093,6 @@ function Milli_Chart(settings) {
2175
2093
  obj = {};
2176
2094
  obj.timestamp = data[i].timestamp;
2177
2095
  obj.instruments = [];
2178
- //m_dataPoints.map.set(data[i].timestamp,obj);
2179
2096
  m_dataPoints.map.set(x, obj);
2180
2097
  }
2181
2098
  obj.instruments[instrument] = { price: data[i].price, open: data[i].openprice, x: startpoint.x - 0.5, y: startpoint.y - 0.5, timestamp: data[i].timestamp, date: new Date(data[i].timestamp), insref: _this.instruments[instrument].insref, diff: data[i].diff };
@@ -2187,36 +2104,38 @@ function Milli_Chart(settings) {
2187
2104
  //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"
2188
2105
 
2189
2106
  if (instrument == 0) {
2190
- point = { price: data[i].price, open: data[i].openprice, x: startpoint.x - 0.5, y: startpoint.y - 0.5, timestamp: data[i].timestamp, date: new Date(data[i].timestamp), quantity: data[i].quantity };
2107
+ point = { price: data[i].price, open: data[i].openprice, x: startpoint.x - 0.5, y: startpoint.y - 0.5, timestamp: data[i].timestamp, date: new Date(data[i].timestamp), quantity: quantity };
2191
2108
  if (typeof data[i].dividend !== 'undefined') point.dividend = data[i].dividend;
2192
2109
  if (typeof data[i].diff !== 'undefined') point.diff = data[i].diff;
2110
+ point.quantity = quantity;
2193
2111
  m_datapoints.push(point);
2112
+ quantity = 0;
2194
2113
  }
2195
2114
  }
2196
2115
  } else {
2197
2116
  if (instrument == 0) {
2198
- point = { price: data[i].price, open: data[i].openprice, x: startpoint.x - 0.5, y: startpoint.y - 0.5, timestamp: data[i].timestamp, date: new Date(data[i].timestamp), insref: _this.instruments[instrument].insref, diff: data[i].diff };
2199
- // if (typeof data[i].diff !== 'undefined') point.diff = data[i].diff
2117
+ point = { price: data[i].price, open: data[i].openprice, x: startpoint.x - 0.5, y: startpoint.y - 0.5, timestamp: data[i].timestamp, date: new Date(data[i].timestamp), insref: _this.instruments[instrument].insref, diff: data[i].diff, quantity: quantity };
2200
2118
  m_datapoints.push(point);
2201
2119
  if (_this.settings.hcurve && _this.scaleinfoY.type == 'history') {
2202
2120
  if (isToday(currentDate)) {
2203
2121
  // only 1 point in hcurve chart, draw line from start of chart to end date
2204
2122
  m_ctx.moveTo(m_chartspaces.chart.left, startpoint.y);
2205
2123
  m_ctx.lineTo(startpoint.x, startpoint.y);
2206
- point = { price: data[i].price, open: data[i].openprice, x: m_chartspaces.chart.left - 0.5, y: startpoint.y - 0.5, timestamp: data[i].timestamp, date: new Date(data[i].timestamp), insref: _this.instruments[instrument].insref, diff: data[i].diff };
2124
+ point = { price: data[i].price, open: data[i].openprice, x: m_chartspaces.chart.left - 0.5, y: startpoint.y - 0.5, timestamp: data[i].timestamp, date: new Date(data[i].timestamp), insref: _this.instruments[instrument].insref, diff: data[i].diff, quantity: quantity };
2207
2125
  m_datapoints.push(point);
2208
- point = { price: data[i].price, open: data[i].openprice, x: startpoint.x - 0.5, y: startpoint.y - 0.5, timestamp: data[i].timestamp, date: new Date(data[i].timestamp), insref: _this.instruments[instrument].insref, diff: data[i].diff };
2126
+ point = { price: data[i].price, open: data[i].openprice, x: startpoint.x - 0.5, y: startpoint.y - 0.5, timestamp: data[i].timestamp, date: new Date(data[i].timestamp), insref: _this.instruments[instrument].insref, diff: data[i].diff, quantity: quantity };
2209
2127
  m_datapoints.push(point);
2210
2128
  startx = m_chartspaces.chart.left;
2211
2129
  starty = startpoint.y;
2212
2130
  // last point so break out and store startx and starty from fake point
2213
2131
  break;
2214
2132
  } else if (hCurveLastPoint) {
2215
- /* var y = Math.round(m_canvas.height - parseInt(m_chartCss['margin-bottom']) - (((hCurveLastPoint.price * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2133
+ /* var y = Math.round(m_canvas.height - m_chartCss.marginBottom - (((hCurveLastPoint.price * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2216
2134
  m_ctx.moveTo(m_chartspaces.chart.left, y);
2217
2135
  m_ctx.lineTo(startpoint.x, y);*/
2218
2136
  }
2219
2137
  }
2138
+ quantity = 0;
2220
2139
  }
2221
2140
  m_ctx.moveTo(startpoint.x, startpoint.y);
2222
2141
  startx = startpoint.x;
@@ -2234,49 +2153,28 @@ function Milli_Chart(settings) {
2234
2153
  });
2235
2154
  m_ctx.stroke();
2236
2155
  if (_this.settings.fillchart == true && instrument == 0) {
2237
- // m_ctx.lineTo(startpoint.x, m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 0.5);
2238
- // m_ctx.lineTo(startx, m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 0.5);
2239
- m_ctx.lineTo(startpoint.x, m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']) + 0.5);
2240
- m_ctx.lineTo(startx, m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']) + 0.5);
2156
+ m_ctx.lineTo(startpoint.x, m_chartspaces.chart.height - m_chartCss.marginBottom + 0.5);
2157
+ m_ctx.lineTo(startx, m_chartspaces.chart.height - m_chartCss.marginBottom + 0.5);
2241
2158
  m_ctx.lineTo(startx, starty);
2242
2159
  m_ctx.closePath();
2243
- if (true == m_instrumentCss[0]['background-image'].startsWith('linear-gradient')) {
2244
- var colors = m_instrumentCss[0]['background-image'].substring(m_instrumentCss[0]['background-image'].indexOf('(') + 1);
2245
- var col0; // = 'rgba(0,200,0,1)';
2246
- var col1; // = 'rgba(0,200,0,0)';
2247
- if (typeof colors === 'string') {
2248
- col0 = colors.substring(0, colors.lastIndexOf('rgba'));
2249
- col0 = col0.substring(0, col0.lastIndexOf(','));
2250
- col1 = colors.substring(colors.lastIndexOf('rgba'), colors.lastIndexOf(')'));
2251
- }
2252
- var grd = m_ctx.createLinearGradient(0, 0, 0, m_chartspaces.chart.height - m_chartspaces.chart.top - parseInt(m_chartCss['margin-bottom']));
2253
- grd.addColorStop(0, col0);
2254
- grd.addColorStop(1, col1);
2160
+ if (typeof m_instrumentCss[0].backgroundLinearGradient !== 'undefined' && typeof m_instrumentCss[0].backgroundLinearGradient.topColor !== 'undefined' && typeof m_instrumentCss[0].backgroundLinearGradient.bottomColor !== 'undefined') {
2161
+ var grd = m_ctx.createLinearGradient(0, 0, 0, m_chartspaces.chart.height - m_chartspaces.chart.top - m_chartCss.marginBottom);
2162
+ grd.addColorStop(0, m_instrumentCss[0].backgroundLinearGradient.topColor);
2163
+ grd.addColorStop(1, m_instrumentCss[0].backgroundLinearGradient.bottomColor);
2255
2164
  m_ctx.fillStyle = grd;
2256
2165
  } else {
2257
- m_ctx.fillStyle = m_instrumentCss[0]['background-image'];
2166
+ if (typeof m_instrumentCss[0].backgroundColor !== 'undefined')
2167
+ m_ctx.fillStyle = m_instrumentCss[0].backgroundColor;
2258
2168
  }
2259
2169
  m_ctx.fill();
2260
2170
  } else
2261
2171
  m_ctx.closePath();
2262
- // eftersom vi kör med m_datapoints här så missar vi dom som plottas på samma ställe som punkten innan
2172
+ // 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???
2263
2173
  plotExternalHistoricalData(data);
2264
- /*for (var i = 0; i < m_datapoints.length; i++) {
2265
- if (m_datapoints[i].dividend) {
2266
- console.log(m_datapoints[i]);
2267
- m_ctx.beginPath();
2268
- m_ctx.arc(m_datapoints[i].x, m_datapoints[i].y - 20, 10, 0, 2 * Math.PI, false);
2269
- m_ctx.fillStyle = 'green';
2270
- m_ctx.fill();
2271
- m_ctx.stroke()
2272
- }
2273
- }*/
2274
-
2275
2174
  m_ctx.restore();
2276
2175
  }
2277
2176
 
2278
2177
  function drawCompare(resp) {
2279
- var factor;
2280
2178
  parseData(resp[0], 1);
2281
2179
  _this.drawChart();
2282
2180
  return;
@@ -2334,11 +2232,11 @@ function Milli_Chart(settings) {
2334
2232
 
2335
2233
  _this.instruments[pos] = instr;
2336
2234
  if (_this.settings.compare1 != '') {
2337
- var url = milli_data_api_url + "widget=intradaychart&token=" + _this.settings.token + "&target=buildwidget&fields=name,tradecurrency,date,time,tradeprice,tradequantity,marketopen,marketclose&language=sv&startdate=" + _this.settings.startdateintraday + "&compress=1&insref=" + instrument + '&intradaylen=' + _this.settings.intradaylen;
2235
+ var url = milli_data_api_url + "widget=intradaychart&token=" + _this.settings.token + "&target=buildwidget&fields=name,tradecurrency,date,time,tradeprice,tradequantity,marketopen,marketclose&language=sv&compress=1&insref=" + instrument + '&intradaylen=' + _this.settings.intradaylen;
2338
2236
  millistream_data_api.fetch(url, function(data) {
2339
2237
  drawCompare(data);
2340
2238
  });
2341
- url = milli_data_api_url + "widget=historychart&token=" + _this.settings.token + "&target=buildwidget&insref=" + instrument + "&fields=name,tradecurrency,date,closeprice,closequantity,marketopen,marketclose&language=sv&startdate=" + _this.settings.startdate + "&compress=1";
2239
+ url = milli_data_api_url + "widget=historychart&token=" + _this.settings.token + "&target=buildwidget&insref=" + instrument + "&fields=name,tradecurrency,date,closeprice,closequantity,marketopen,marketclose&language=sv&startdate=" + _this.settings.startdate + "&adjusted=1";
2342
2240
  millistream_data_api.fetch(url, function(data) {
2343
2241
  drawCompare(data);
2344
2242
  });
@@ -2431,9 +2329,9 @@ function Milli_Chart(settings) {
2431
2329
  _this.drawChart();
2432
2330
 
2433
2331
  if (_this.settings.streaming != false && typeof resp[0].trades !== 'undefined') {
2434
- if (MillistreamWidgetApi_isObjectEmpty(_this.unsubscriptions) == false) {
2332
+ /*if (MillistreamWidgetApi_isObjectEmpty(_this.unsubscriptions) == false) {
2435
2333
  _this.settings.streaming.MillistreamWidgetStreamingApi_unsubscribe(_this);
2436
- }
2334
+ }*/
2437
2335
  m_requestid = _this.settings.streaming.MillistreamWidgetStreamingApi_subscribeInstruments(_this, m_requestid, [_this.settings.instrument]);
2438
2336
  //_this.requestid = _this.settings.streaming.MillistreamWidgetStreamingApi_subscribeInstruments(_this, _this.requestid, m_insrefs);
2439
2337
  }
@@ -2449,7 +2347,7 @@ function Milli_Chart(settings) {
2449
2347
  return;
2450
2348
  }
2451
2349
  if (json['3'] && json['36'] && json['13'] && (json['12'] || json['201'])) {
2452
- var timestamp = new Date(json['3'] + 'T' + json['36'] + 'Z').getTime(); // - m_tz_offset; // tz_offset in minutes
2350
+ var timestamp = new Date(json['3'] + 'T' + json['36'].substring(0, 6) + '00' + 'Z').getTime();
2453
2351
 
2454
2352
  // TODO hash/strangle with YYYY-mm-dd hh:mm:00 trades and only draw once per minute
2455
2353
  var data = instr.hashmap.get(timestamp);
@@ -2460,122 +2358,51 @@ function Milli_Chart(settings) {
2460
2358
  data.timestamp = timestamp;
2461
2359
  instr.hashmap.set(data.timestamp, data);
2462
2360
  data.price = parseFloat(json['12']); // eller 201 för tradeyield
2361
+ data.open = parseFloat(json['12']); // eller 201 för tradeyield
2362
+ data.high = parseFloat(json['12']); // eller 201 för tradeyield
2363
+ data.low = parseFloat(json['12']); // eller 201 för tradeyield
2463
2364
  data.quantity = parseInt(json['13']);
2464
2365
  if (instr.trades.length != 0 && data.timestamp < instr.trades[instr.trades.length - 1].timestamp) {
2465
2366
  //console.log("pushtrade is older than last trade ignoring, should file it on correct postition");
2466
2367
  } else
2467
2368
  instr.trades.push(data);
2468
2369
  } else {
2469
- //console.log(timestamp, 'old trade', data);
2370
+ data.price = parseFloat(json['12']); // eller 201 för tradeyield
2371
+ data.quantity += parseInt(json['13']);
2372
+ update = true;
2470
2373
  // updatera med quantity, open , high,low osv?
2471
2374
  }
2472
2375
  }
2473
- if (update) _this.drawChart();
2376
+ if (update) _this.drawChart(); // hover försvinner... (harris också)
2474
2377
  };
2475
2378
 
2476
- function readCss() {
2477
- //console.log("read css in");
2478
- var test = document.querySelector('.millistream-chart');
2479
- var properties = getComputedStyle(test);
2480
- m_chartCss['background-color'] = properties.backgroundColor;
2481
- m_chartCss['margin-top'] = properties.marginTop;
2482
- m_chartCss['margin-bottom'] = properties.marginBottom;
2483
- m_chartCss['margin-left'] = properties.marginLeft;
2484
- m_chartCss['margin-right'] = properties.marginRight;
2485
- //m_chartCss['box-shadow'] = properties.boxShadow;
2486
- m_chartCss.boxShadow = properties.boxShadow;
2487
- m_chartCss['border-right-color'] = properties.borderRightColor;
2488
- m_chartCss['border-left-color'] = properties.borderLeftColor;
2489
-
2490
- //console.log(properties.marginTop, properties.marginBottom, properties.marginLeft, properties.marginRight);
2491
- var siteURL = new URL(document.URL);
2492
- var cssURL;
2493
- for (var i = 0; i < document.styleSheets.length; i++) {
2494
- if (document.styleSheets[i].href != null)
2495
- cssURL = new URL(document.styleSheets[i].href);
2496
- else cssURL = null;
2497
- // console.log(document.styleSheets,cssURL);
2498
- // if(typeof document.styleSheets[i].host ==='undefined' ) continue;
2499
- if (cssURL != null && siteURL.host != cssURL.host) continue; // cssURL can be null on localhost
2500
- if (typeof document.styleSheets[i] === 'undefined') continue;
2501
- var yLeg = false;
2502
- for (var s = 0; s < document.styleSheets[i].cssRules.length; s++) {
2503
- // console.log(document.styleSheets[i].cssRules[s]);
2504
- if (typeof document.styleSheets[i].cssRules[s].selectorText !== 'undefined') {
2505
- var rules = document.styleSheets[i].cssRules[s].selectorText.split(',');
2506
- for (var ss = 0; ss < rules.length; ss++) {
2507
- // console.log(rules[ss]);
2508
- var ref = null;
2509
- rules[ss] = rules[ss].split(' ').join('');
2510
- switch (rules[ss]) {
2511
- case '.millistream-chart-x-legend':
2512
- ref = m_xLegendCss;
2513
- break;
2514
- case '.millistream-chart-y-legend':
2515
- yLeg = true;
2516
- ref = m_yLegendCss;
2517
- break;
2518
- case '.millistream-chart-y2-legend':
2519
- ref = m_y2LegendCss;
2520
- break;
2521
- case '.millistream-chart-legend':
2522
- // ref = m_LegendCss;
2523
- break;
2524
- case '.millistream-chart':
2525
- //ref = m_chartCss;
2526
- break;
2527
- case '.millistream-chart-horizontal-grid':
2528
- ref = m_gridHorizontalCss;
2529
- break;
2530
- case '.millistream-chart-vertical-grid':
2531
- ref = m_gridVerticalCss;
2532
- break;
2533
- case '.millistream-chart-instrument':
2534
- //console.log('chart');
2535
- ref = m_instrumentCss[0];
2536
- break;
2537
- case '.millistream-chart-compare1':
2538
- ref = m_instrumentCss[1];
2539
- break;
2540
- case '.millistream-chart-compare2':
2541
- ref = m_instrumentCss[2];
2542
- break;
2543
- case '.millistream-chart-compare3':
2544
- ref = m_instrumentCss[3];
2545
- break;
2546
- }
2547
- //console.log(ref);
2548
- if (ref != null) {
2549
- for (var r = 0; r < document.styleSheets[i].cssRules[s].style.length; r++) {
2550
- ref[document.styleSheets[i].cssRules[s].style[r]] = document.styleSheets[i].cssRules[s].style[document.styleSheets[i].cssRules[s].style[r]];
2551
- }
2552
- }
2553
- }
2554
- }
2555
- }
2556
- }
2557
- //console.log("read css out");
2558
-
2559
- }
2560
-
2561
2379
  function changeOrientation() {
2562
2380
  if (m_canvas == null) return;
2563
- console.log('resize');
2564
2381
  // set size 0 so target div does not expand due to chartsize
2565
- readCss();
2566
- //m_canvas.setAttribute('height', '0');
2567
- //m_canvas.setAttribute('width', '0');
2382
+ //readCss(); // TODO
2568
2383
 
2569
2384
  m_canvas.setAttribute('height', _this.settings.target.getBoundingClientRect().height);
2570
- m_canvas.setAttribute('width', _this.settings.target.getBoundingClientRect().width); // läs från css?
2571
- //m_canvas.setAttribute('height', _this.settings.target.offsetHeight);
2572
- //m_canvas.setAttribute('width', _this.settings.target.offsetWidth); // läs från css?
2385
+ m_canvas.setAttribute('width', _this.settings.target.getBoundingClientRect().width);
2573
2386
  _this.drawChart();
2574
2387
  }
2575
2388
 
2389
+ function getXhrJson(url) {
2390
+ var req = new XMLHttpRequest();
2391
+ req.onload = function() {
2392
+ _this.buildwidget(JSON.parse(this.responseText));
2393
+ }
2394
+ req.open("GET", url, true);
2395
+ req.onerror = function(error) {
2396
+ console.log('Fetch data error', error);
2397
+ }
2398
+ req.send();
2399
+ }
2400
+
2576
2401
  this.drawWidget = function() {
2577
2402
  // remove standard fields from array, they will be requested anyway
2578
- _this.settings.fields = _this.settings.fields.filter(function(obj) { return ['name', 'tradecurrency', 'time', 'date', 'tradeprice', 'tradequantity', 'marketopen', 'marketclose', 'closeprice1d', 'closeprice', 'closequantity'].indexOf(obj) == -1 });
2403
+ _this.settings.fields = _this.settings.fields.filter(function(obj) {
2404
+ return ['name', 'tradecurrency', 'time', 'date', 'tradeprice', 'tradequantity', 'marketopen', 'marketclose', 'closeprice1d', 'closeprice', 'closequantity'].indexOf(obj) == -1;
2405
+ });
2579
2406
  //_this.settings.drawy2axis = false;
2580
2407
  m_tradedates = [];
2581
2408
  _this.settings.scaleinfoY = {};
@@ -2583,8 +2410,6 @@ function Milli_Chart(settings) {
2583
2410
  m_dummyDiv.style.display = 'none';
2584
2411
  m_dummyDiv.setAttribute('class', 'millistream-chart');
2585
2412
  _this.settings.target.appendChild(m_dummyDiv);
2586
- readCss();
2587
- m_tz_offset = new Date().getTimezoneOffset() * 60000;
2588
2413
  _this.instruments = []; // Hmm
2589
2414
  var instr = {
2590
2415
  insref: _this.settings.instrument,
@@ -2594,26 +2419,33 @@ function Milli_Chart(settings) {
2594
2419
  intradayQuantity: []
2595
2420
  };
2596
2421
  _this.instruments.push(instr);
2597
- var d, url;
2422
+ var d, url, oldfields;
2598
2423
  if (_this.settings.intradaylen) {
2599
2424
  d = new Date().getTime();
2600
2425
  var e = new Date();
2601
2426
  var days = 0;
2427
+ var newlen = 0;
2602
2428
  while (days < _this.settings.intradaylen - 1) { // include today
2603
2429
  d -= 86400000;
2604
2430
  e.setTime(d);
2605
2431
  if (e.getDay() != 0 && e.getDay() != 6)
2606
2432
  days++;
2433
+ newlen++;
2607
2434
  }
2608
- var oldfields = _this.settings.fields;
2435
+ _this.settings.intradaylen = newlen.toString();
2436
+ oldfields = _this.settings.fields;
2609
2437
  _this.settings.fields = [...['name', 'tradecurrency', 'time', 'date', 'tradeprice', 'tradequantity', 'marketopen', 'marketclose', 'closeprice1d'], ...oldfields];
2610
2438
  _this.settings.startdate = e.getFullYear() + '-' + zeroPad(e.getMonth() + 1, 2) + '-' + zeroPad(e.getDate(), 2);
2611
- _this.settings.startdateintraday = _this.settings.startdate;
2439
+ //_this.settings.startdateintraday = _this.settings.startdate;
2612
2440
  url = MillistreamWidgetApi_buildQuery(_this, 'intradaychart');
2613
2441
  _this.settings.fields = oldfields;
2614
- millistream_data_api.fetch(url, function(data) {
2615
- _this.buildwidget(data);
2616
- });
2442
+ if (_this.settings.xhr) {
2443
+ getXhrJson(url);
2444
+ } else {
2445
+ millistream_data_api.fetch(url, function(data) {
2446
+ _this.buildwidget(data);
2447
+ });
2448
+ }
2617
2449
  }
2618
2450
  if (_this.settings.historylen) {
2619
2451
  var len = _this.settings.historylen.substring(0, _this.settings.historylen.length - 1);
@@ -2659,22 +2491,24 @@ function Milli_Chart(settings) {
2659
2491
  }
2660
2492
  // must be reset when changing from intraday -> history and vice versa
2661
2493
  startdate = new Date(startdate);
2662
- var oldfields = _this.settings.fields;
2494
+ oldfields = _this.settings.fields;
2663
2495
  _this.settings.fields = [...['name', 'tradecurrency', 'date', 'closeprice', 'closequantity', 'marketopen', 'marketclose'], ...oldfields];
2664
2496
  _this.settings.startdate = startdate.getFullYear() + '-' + zeroPad(startdate.getMonth() + 1, 2) + '-' + zeroPad(startdate.getDate(), 2);
2665
2497
  url = MillistreamWidgetApi_buildQuery(_this, 'historychart');
2666
2498
  _this.settings.fields = oldfields;
2667
- //console.log(_this.settings.fields);
2668
- millistream_data_api.fetch(url, function(data) {
2669
- _this.buildwidget(data);
2499
+ if (_this.settings.xhr) {
2500
+ getXhrJson(url);
2501
+ } else {
2502
+ millistream_data_api.fetch(url, function(data) {
2503
+ _this.buildwidget(data);
2670
2504
 
2671
- });
2505
+ });
2506
+ }
2672
2507
  }
2673
2508
  };
2674
2509
  if (this.settings.autodraw == true) this.drawWidget();
2675
2510
 
2676
2511
  window.addEventListener('resize', function() {
2677
- //console.log('2');
2678
2512
  if (m_canvas != null)
2679
2513
  changeOrientation();
2680
2514
 
@@ -3019,6 +2853,10 @@ function MillistreamWidgetApi_buildQuery(widget, type) {
3019
2853
  if (typeof widget.settings.intradaylen !== 'string' && widget.settings.intradaylen !== null) throw new Error(widget.constructor.name + ': intradaylen is not valid');
3020
2854
  url += '&intradaylen=' + widget.settings.intradaylen;
3021
2855
  }
2856
+ if (typeof widget.settings.xhr !== 'undefined' && widget.settings.xhr == true) {
2857
+ url += '&xhr=1';
2858
+ }
2859
+
3022
2860
  return url;
3023
2861
  }
3024
2862