@millistream/millistream-widgets 0.0.17 → 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,42 +492,50 @@ 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
- console.log(m_chartspaces.lowerChart.width, m_datapoints.length);
497
497
  if (width < 2) width = 2;
498
498
  else if (width > 20) width = 20;
499
- if (width * (m_datapoints.length + 1) >= m_chartspaces.lowerChart.width) console.log('test');
500
499
  m_ctx.lineWidth = width;
501
- console.log(width);
502
500
  for (var i = 0; i < m_datapoints.length; i++) {
503
- var x = Math.round(m_datapoints[i].x);
504
- if (x - width < m_chartspaces.lowerChart.left) {
505
- 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) {
506
504
  m_ctx.lineWidth = width / 2;
505
+ x += m_ctx.lineWidth / 2;
507
506
  } else
508
- if (x + width > m_chartspaces.lowerChart.right) {
509
- x -= width / 4;
507
+ if (x + width >= m_chartspaces.lowerChart.right) {
510
508
  m_ctx.lineWidth = width / 2;
509
+ x -= m_ctx.lineWidth / 2 + 1;
511
510
  }
512
-
513
- m_ctx.moveTo(x + 0.5, m_chartspaces.lowerChart.bottom);
514
- var y = Math.round(m_chartspaces.lowerChart.bottom - (m_datapoints[i].quantity * valuePerPixel));
515
- 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);
516
516
  m_ctx.stroke();
517
517
  }
518
- m_ctx.closePath();
519
518
  m_ctx.restore();
520
519
  }
521
520
 
522
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;
523
534
  m_ctx.strokeStyle = m_gridHorizontalCss.color;
524
535
  m_ctx.fillStyle = m_yLegendCss.color;
525
536
 
526
537
  m_ctx.textAlign = 'right';
527
538
  var tickSize = getTickValue(_this.scaleinfoY.lowLowerChart, _this.scaleinfoY.highLowerChart, numticks);
528
- console.log(_this.scaleinfoY.highLowerChart, tickSize, lineLength);
529
539
  var maxValue = _this.scaleinfoY.highLowerChart == 0 ? 100 : _this.scaleinfoY.highLowerChart + (tickSize * 0.2);
530
540
  var valuePerPixel = lineLength / maxValue;
531
541
  if (isNaN(valuePerPixel) || !isFinite(valuePerPixel)) {
@@ -533,9 +543,8 @@ function Milli_Chart(settings) {
533
543
  return false;
534
544
  }
535
545
  var value = 0;
536
- for (;;) {
546
+ for (i = 0; i < numticks; i++) {
537
547
  var y = Math.round(m_chartspaces.lowerChart.bottom - (value * valuePerPixel));
538
- console.log(value, y, tickSize, maxValue);
539
548
 
540
549
  if (y <= m_chartspaces.lowerChart.top) break;
541
550
  if (y <= m_chartspaces.lowerChart.bottom) {
@@ -544,21 +553,25 @@ function Milli_Chart(settings) {
544
553
  if (_this.settings.gridHorizontalLinesStyle == 'dash') {
545
554
  m_ctx.setLineDash([3, 3]);
546
555
  }
556
+ m_ctx.beginPath();
547
557
  m_ctx.moveTo(m_chartspaces.lowerChart.left, y + 0.5);
548
558
  m_ctx.lineTo(m_chartspaces.lowerChart.right, y + 0.5);
549
559
  m_ctx.stroke();
560
+ m_ctx.closePath();
550
561
  m_ctx.restore();
551
562
  } else
552
563
  if (_this.settings.drawyaxis == true && markers == true) { // draw legenditem markers for price
564
+ m_ctx.beginPath();
553
565
  m_ctx.moveTo(m_chartspaces.lowerChart.left, y + 0.5);
554
566
  m_ctx.lineTo(m_chartspaces.lowerChart.left + 3, y + 0.5);
555
567
  m_ctx.stroke();
568
+ m_ctx.closePath();
556
569
  }
557
570
 
558
571
  if (markers == true && _this.settings.drawyaxis == true) {
559
572
  var label = formatLargeNumber(value, 0, _this);
560
573
  var textpos = x - 5;
561
- if (m_yLegendCss['vertical-align'] == 'top') {
574
+ if (m_yLegendCss.verticalAlign == 'top') {
562
575
  if (y - (getFontSize(m_yLegendCss)) > 0) // dont draw if cropped
563
576
  m_ctx.fillText(label, textpos, y - ((getFontSize(m_yLegendCss) + 2)));
564
577
  } else
@@ -572,32 +585,30 @@ function Milli_Chart(settings) {
572
585
  }
573
586
 
574
587
  function drawYAxisLower() {
575
- //m_ctx.save();
576
- m_ctx.strokeStyle = m_gridHorizontalCss.color;
577
- m_ctx.font = m_yLegendCss['font-weight'] + ' ' + m_yLegendCss['font-size'] + ' ' + m_yLegendCss['font-family'];
578
- console.log(m_yLegendCss.color, m_gridHorizontalCss.color);
588
+ m_ctx.save();
589
+ m_ctx.font = m_yLegendCss.fontWeight + ' ' + m_yLegendCss.fontSize + ' ' + m_yLegendCss.fontFamily;
579
590
  m_ctx.fillStyle = m_yLegendCss.color;
580
591
  var lineLen = m_chartspaces.lowerChart.bottom - m_chartspaces.lowerChart.top;
581
592
  var numticks = lineLen / (getFontSize(m_yLegendCss) * 2);
582
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
583
594
 
595
+ m_ctx.beginPath();
596
+ m_ctx.strokeStyle = m_gridVerticalCss.color;
584
597
  m_ctx.moveTo(m_chartspaces.lowerChart.left + 0.5, m_chartspaces.lowerChart.top);
585
598
  m_ctx.lineTo(m_chartspaces.lowerChart.left + 0.5, m_chartspaces.lowerChart.bottom);
586
599
  m_ctx.stroke();
600
+ m_ctx.closePath();
601
+ //m_ctx.strokeStyle = m_gridHorizontalCss.color;
587
602
  var x = m_chartspaces.lowerChart.left - 3;
588
-
589
603
  drawYLegendLower(x, numticks, lineLen, true);
590
- //m_ctx.restore();
591
-
604
+ m_ctx.restore();
592
605
  }
593
606
 
594
607
  function drawYLegend(si, x, side, gridHorizontalLines, number) {
595
608
  var value;
596
- if (si.highValue == si.lowValue) console.log(si.tickSize);
597
609
  si.maxValue = si.highValue + (si.tickSize * 0.2);
598
610
  si.minValue = si.lowValue - (si.tickSize * 0.2);
599
- m_ctx.font = m_yLegendCss['font-weight'] + ' ' + m_yLegendCss['font-size'] + ' ' + m_yLegendCss['font-family'];
600
- // console.log('drawYLegend in 2,', si.highValue, si.lowValue, si.tickSize);
611
+ m_ctx.font = m_yLegendCss.fontWeight + ' ' + m_yLegendCss.fontSize + ' ' + m_yLegendCss.fontFamily;
601
612
  if (si.highValue == si.lowValue) { // only have one value so set values for 1 line only
602
613
  si.maxValue = si.maxValue + si.tickSize;
603
614
  si.minValue = si.minValue - si.tickSize;
@@ -653,7 +664,7 @@ function Milli_Chart(settings) {
653
664
  label = formatNiceNumber(value, _this.settings.thousandseparator, _this.settings.decimalseparator, si.decimals, false);
654
665
  var textpos = x - 5;
655
666
  if (side == 'right') textpos = x + 7;
656
- if (m_yLegendCss['vertical-align'] == 'top') {
667
+ if (m_yLegendCss.verticalAlign == 'top') {
657
668
  if (y - (getFontSize(m_yLegendCss)) > 0) // dont draw if cropped
658
669
  m_ctx.fillText(label, textpos, y - ((getFontSize(m_yLegendCss) + 2)));
659
670
  } else
@@ -668,7 +679,7 @@ function Milli_Chart(settings) {
668
679
  function drawYAxis() {
669
680
  m_ctx.save();
670
681
  m_ctx.strokeStyle = m_gridHorizontalCss.color;
671
- 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;
672
683
  m_ctx.fillStyle = m_yLegendCss.color;
673
684
  //if (_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d') firstvalue = _this.instruments[0].closeprice1d;
674
685
 
@@ -688,7 +699,7 @@ function Milli_Chart(settings) {
688
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å?
689
700
  m_chartspaces.lowerChart.left = m_chartspaces.chart.left;
690
701
  } else {
691
- if (m_yLegendCss['text-align'] == 'right') {
702
+ if (m_yLegendCss.textAlign == 'right') {
692
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å?
693
704
  m_chartspaces.lowerChart.right = m_chartspaces.chart.right;
694
705
  }
@@ -704,7 +715,7 @@ function Milli_Chart(settings) {
704
715
  label = formatNiceNumber(_this.scaleinfoY2.highValue, _this.settings.thousandseparator, _this.settings.decimalseparator, _this.scaleinfoY2.decimals) + ' %';
705
716
  if (m_y2LegendCss.float != 'right') {
706
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å?
707
- m_chartspaces.lowerChart.left = m_chartspaces.chart.left
718
+ m_chartspaces.lowerChart.left = m_chartspaces.chart.left;
708
719
  } else {
709
720
  // kolla setting om den skall vara "i diagrammet"
710
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å?
@@ -713,19 +724,21 @@ function Milli_Chart(settings) {
713
724
  }
714
725
  if (m_yLegendCss.float != 'right' && _this.settings.drawyaxis) {
715
726
  m_ctx.save();
716
- 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;
717
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;
718
729
  m_ctx.restore();
719
730
  }
731
+ m_ctx.strokeStyle = m_gridVerticalCss.color;
720
732
  m_ctx.beginPath();
721
733
  m_ctx.moveTo(m_chartspaces.chart.left + 0.5, m_chartspaces.chart.top);
722
- 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);
723
735
  m_ctx.stroke();
724
736
  m_ctx.closePath();
737
+ m_ctx.strokeStyle = m_gridHorizontalCss.color;
725
738
 
726
739
  var x;
727
740
  if (m_yLegendCss.float == 'right') {
728
- if (m_yLegendCss['text-align'] == 'right')
741
+ if (m_yLegendCss.textAlign == 'right')
729
742
  x = m_chartspaces.chart.right;
730
743
  else
731
744
  x = m_chartspaces.chart.right + 3;
@@ -734,7 +747,7 @@ function Milli_Chart(settings) {
734
747
  }
735
748
 
736
749
  m_ctx.textAlign = 'right';
737
- if (m_yLegendCss['text-align'] == 'right') {
750
+ if (m_yLegendCss.textAlign == 'right') {
738
751
  m_ctx.textAlign = 'left';
739
752
  drawYLegend(_this.scaleinfoY, x, 'right', _this.settings.gridHorizontalLines, 1);
740
753
  } else
@@ -754,10 +767,10 @@ function Milli_Chart(settings) {
754
767
  function drawXAxisGridlines(p, newday) {
755
768
  // draws the vertical grid or dots
756
769
  m_ctx.save();
757
- m_ctx.strokeStyle = m_gridHorizontalCss.color;
758
- if (_this.settings.gridVerticalLines > 0) {
770
+ m_ctx.strokeStyle = m_gridVerticalCss.color;
771
+ if (_this.settings.gridVerticalLines) {
759
772
  if (_this.settings.drawy2axis == false || p.x != m_chartspaces.chart.left) {
760
- if (_this.settings.gridHorizontalLinesStyle == 'dash') {
773
+ if (_this.settings.gridVerticalLinesStyle == 'dash') {
761
774
  m_ctx.setLineDash([3, 3]);
762
775
  }
763
776
  if (newday) m_ctx.setLineDash([3, 3]);
@@ -841,15 +854,15 @@ function Milli_Chart(settings) {
841
854
  function drawXAxisYears(starttime, endtime) {
842
855
  if (getNumberOfDays(starttime, endtime) < 366) return drawXAxisMonth(starttime, endtime);
843
856
  m_ctx.save();
844
- m_ctx.font = m_xLegendCss['font-weight'] + ' ' + m_xLegendCss['font-size'] + ' ' + m_xLegendCss['font-family'];
845
- 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;
846
859
  m_ctx.fillStyle = m_xLegendCss.color;
847
860
  m_ctx.textAlign = "left";
848
861
  calcXScale(starttime, endtime);
849
862
  if (_this.settings.drawxaxis != 0) {
850
863
  m_ctx.beginPath();
851
- m_ctx.moveTo(m_chartspaces.chart.left, m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']) + 0.5);
852
- 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);
853
866
  m_ctx.stroke();
854
867
  m_ctx.closePath();
855
868
  }
@@ -867,8 +880,8 @@ function Milli_Chart(settings) {
867
880
  }
868
881
  }
869
882
  if (draw) {
870
- //drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) });
871
- 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 });
872
885
  text = year;
873
886
  if (_this.scaleinfoX.lineLength + m_chartspaces.chart.left > x - m_ctx.measureText(text).width) { // not to far right?
874
887
  if (_this.settings.yearLabelsPos == 'top') {
@@ -881,8 +894,8 @@ function Milli_Chart(settings) {
881
894
  m_ctx.fillText(text, 0, 0);
882
895
  m_ctx.restore();
883
896
  } else {
884
- //m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 10);
885
- 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);
886
899
  }
887
900
  }
888
901
  numItems++;
@@ -906,12 +919,10 @@ function Milli_Chart(settings) {
906
919
  }
907
920
  }
908
921
  if (draw) {
909
- //drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) });
910
- 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 });
911
923
  text = formatDate(year.getFullYear() + '-07-01', _this.settings.dateformat);
912
924
  // ingen if som på year???
913
- //m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 10);
914
- 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);
915
926
  numItems++;
916
927
  legendItems.push({ 'text': text, timestamp: new Date(year + '-07-01T00:00:00Z'), 'x': x });
917
928
  }
@@ -936,11 +947,9 @@ function Milli_Chart(settings) {
936
947
  }
937
948
  if (dontPrint) break;
938
949
  if (draw) {
939
- //drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) });
940
- 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 });
941
951
  text = formatDate(year.getFullYear() + '-' + (year.getMonth() + 1) + '-01', _this.settings.dateformat);
942
- //m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 10);
943
- 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);
944
953
  }
945
954
  legendItems.push({ 'text': text, timestamp: new Date(year + '-04-01T00:00:00Z'), 'x': x });
946
955
  year = new Date((year.getFullYear() + 1) + '-04-01T00:00:00Z');
@@ -959,11 +968,9 @@ function Milli_Chart(settings) {
959
968
  }
960
969
  }
961
970
  if (draw) {
962
- //drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) });
963
- 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 });
964
972
  text = formatDate(year.getFullYear() + '-' + (year.getMonth() + 1) + '-01', _this.settings.dateformat);
965
- //m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 10);
966
- 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);
967
974
  }
968
975
  legendItems.push({ 'text': text, timestamp: new Date(year + '-10-01T00:00:00Z'), 'x': x });
969
976
  year = new Date((year.getFullYear() + 1) + '-10-01T00:00:00Z');
@@ -978,14 +985,14 @@ function Milli_Chart(settings) {
978
985
  starttime -= starttime % 8640000;
979
986
  endtime -= starttime % 8640000;
980
987
  m_ctx.save();
981
- m_ctx.font = m_xLegendCss['font-weight'] + ' ' + m_xLegendCss['font-size'] + ' ' + m_xLegendCss['font-family'];
982
- 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;
983
990
  m_ctx.fillStyle = m_xLegendCss.color;
984
991
  calcXScale(starttime, endtime);
985
992
  if (_this.settings.drawxaxis != 0) { // draw line
986
993
  m_ctx.beginPath();
987
- m_ctx.moveTo(m_chartspaces.chart.left, m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']) + 0.5);
988
- 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);
989
996
  m_ctx.stroke();
990
997
  m_ctx.closePath();
991
998
  }
@@ -1020,10 +1027,8 @@ function Milli_Chart(settings) {
1020
1027
  currentDate = new Date(currentDate.getTime() + 86400000);
1021
1028
  }
1022
1029
  // vad är detta?
1023
- if (typeof m_chartCss.boxShadow !== 'undefined') {
1024
- var boxshadow = m_chartCss.boxShadow.split(' ');
1025
- if (parseInt(boxshadow[1]) == 0) drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, false);
1026
-
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);
1027
1032
  } else {
1028
1033
  drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, false);
1029
1034
  }
@@ -1097,12 +1102,10 @@ function Milli_Chart(settings) {
1097
1102
  // internal
1098
1103
  if (typeof value !== 'string') return "";
1099
1104
  var datetime = new Date();
1100
- //var tz_offset = datetime.getTimezoneOffset();
1101
1105
  datetime.setHours(parseInt(value));
1102
1106
  datetime.setMinutes(parseInt(value.substring(3)));
1103
1107
  datetime.setSeconds(parseInt(value.substring(6)));
1104
1108
  datetime = datetime.getTime();
1105
- //datetime -= tz_offset * 60000; // tz_offset in minutes
1106
1109
  datetime = new Date(datetime);
1107
1110
  switch (format) {
1108
1111
  case 'HH:mm':
@@ -1130,8 +1133,9 @@ function Milli_Chart(settings) {
1130
1133
  }
1131
1134
 
1132
1135
  function drawXAxisTickLowerChart() {
1136
+
1133
1137
  m_ctx.save();
1134
- 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;
1135
1139
 
1136
1140
  m_ctx.strokeStyle = m_gridHorizontalCss.color;
1137
1141
  m_ctx.fillStyle = m_xLegendCss.color;
@@ -1146,10 +1150,11 @@ function Milli_Chart(settings) {
1146
1150
  }
1147
1151
 
1148
1152
  function drawXAxisTick(starttime, endtime) {
1153
+ // in unixtime
1149
1154
  m_ctx.save();
1150
- 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;
1151
1156
 
1152
- m_ctx.strokeStyle = m_gridHorizontalCss.color;
1157
+ m_ctx.strokeStyle = m_gridVerticalCss.color;
1153
1158
  m_ctx.fillStyle = m_xLegendCss.color;
1154
1159
  m_ctx.textAlign = "left";
1155
1160
  calcXScaleTick(starttime, endtime);
@@ -1160,6 +1165,7 @@ function Milli_Chart(settings) {
1160
1165
  m_ctx.stroke();
1161
1166
  m_ctx.closePath();
1162
1167
  }
1168
+ var dayLightChange = (new Date(starttime).getTimezoneOffset() - new Date().getTimezoneOffset()) * 60000;
1163
1169
  var currentDate = new Date(starttime);
1164
1170
  var x;
1165
1171
  var lastx = 0;
@@ -1193,6 +1199,17 @@ function Milli_Chart(settings) {
1193
1199
  if (_this.scaleinfoX.lineLength + m_chartspaces.chart.left > x - getMaxTimeWidth()) { // not to far right?
1194
1200
  m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_chartspaces.chart.bottom + 10);
1195
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
+ }
1196
1213
  }
1197
1214
  if (x != m_chartspaces.chart.left + 0.5) { // do not draw the first line, it is already drawn
1198
1215
  if (openhour == currentDate.getTime() % 86400000) {
@@ -1211,7 +1228,7 @@ function Milli_Chart(settings) {
1211
1228
  }
1212
1229
  }
1213
1230
  // add timestamps
1214
- var currentDate = new Date(starttime);
1231
+ currentDate = new Date(starttime);
1215
1232
  if (currentDate.getTime() % 3600000 != 0) // if not full hour, move up to next full hour
1216
1233
  currentDate = new Date(currentDate.getTime() - currentDate.getTime() % 3600000 + 3600000); // START om full hour (if modulo == 0 then + 3600000 kanske)
1217
1234
 
@@ -1236,7 +1253,7 @@ function Milli_Chart(settings) {
1236
1253
  if (days == 1) {
1237
1254
  // use start and endtime as ticksize
1238
1255
  tickSize = new Date(endtime - starttime);
1239
- } 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
1240
1257
  // use the day with most time as tickSize
1241
1258
  var tmpDate = new Date(starttime);
1242
1259
  tickSize = new Date(new Date(tmpDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z') - new Date(starttime)).getTime();
@@ -1270,13 +1287,21 @@ function Milli_Chart(settings) {
1270
1287
  tickSize = tickSize.getTime() / 3600000;
1271
1288
  interval = Math.floor(tickSize / (maxHourLegends + 1)) * 3600000;
1272
1289
  }
1273
- if (interval == 0) interval = 300000;
1274
- if (interval % 60000 != 0)
1290
+ if (interval == 0) {
1291
+ // default 1h
1292
+ interval = 3600000;
1293
+ modularvalue = 3600000;
1294
+ }
1295
+ if (interval % 60000 != 0) {
1275
1296
  interval = (interval - interval % 60000) + 60000; // remove sekunder
1297
+ }
1276
1298
  // print other times
1277
1299
  offset = 0;
1278
1300
  lastx = 0;
1279
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
+
1280
1305
  var workDate = new Date(currentDate);
1281
1306
  currentDate = new Date(starttime);
1282
1307
  if (currentDate.getTime() % modularvalue != 0) // if not full hour, move up to next full hour
@@ -1284,28 +1309,31 @@ function Milli_Chart(settings) {
1284
1309
 
1285
1310
  var count = 0;
1286
1311
  while (currentDate.getTime() <= _this.scaleinfoX.endTimeStamp) {
1312
+ dayLightChange = (closeTime.getTimezoneOffset() - new Date().getTimezoneOffset()) * 60000;
1287
1313
  if (count++ > 100) {
1288
1314
  break; // just make sure we dont do an infinity loop
1289
1315
 
1290
1316
  }
1291
1317
  draw = true;
1292
1318
  while (currentDate.getDay() == 0 || currentDate.getDay() == 6) { // move past weekends , maybe skip this if date is available in data
1293
- closeTime = new Date(closeTime.getTime() + 86400000);
1319
+ //closeTime = new Date(closeTime.getTime() + 86400000);
1294
1320
  currentDate = new Date(currentDate.getTime() + 86400000);
1321
+ closeTime = new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
1295
1322
  if (currentDate.getTime() % modularvalue != 0) // if not full hour, move up to next full hour
1296
1323
  currentDate = new Date(currentDate.getTime() - currentDate.getTime() % modularvalue + modularvalue); // START om full hour (if modulo == 0 then + 3600000 kanske)
1297
- var workDate = new Date(workDate.getTime() + 86400000);
1324
+ workDate = new Date(workDate.getTime() + 86400000);
1298
1325
  offset += 86400000 / _this.scaleinfoX.timePerPixel;
1299
1326
  }
1300
1327
  if (currentDate.getTime() > closeTime.getTime()) {
1301
1328
  // draw DayEnd(start) dash line
1302
- 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');
1303
1330
  x = Math.round(m_chartspaces.chart.left + ((dayStart.getTime() - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel) - offset);
1304
1331
  drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, true); // dash?
1305
1332
 
1306
1333
  closeTime = new Date(closeTime.getTime() + 86400000);
1307
1334
  workDate = new Date(workDate.getTime() + 86400000);
1308
1335
  currentDate = new Date(workDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z');
1336
+
1309
1337
  if (currentDate.getTime() % modularvalue != 0) // if not full hour, move up to next full hour
1310
1338
  currentDate = new Date(currentDate.getTime() - currentDate.getTime() % modularvalue + modularvalue); // START om full hour (if modulo == 0 then + 3600000 kanske)
1311
1339
  offset += (86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel;
@@ -1329,12 +1357,12 @@ function Milli_Chart(settings) {
1329
1357
  if (lastx + (getMaxTimeWidth() / 2) > (x - getMaxTimeWidth())) {
1330
1358
  //draw = false;
1331
1359
  }
1332
- var text = formatChartTime(currentDate.toTimeString().substring(0, 8), _this.settings.timeformat);
1333
1360
  if (draw) {
1334
1361
  lastx = x;
1335
1362
  // if day change and setting print on top as well
1336
1363
  if (_this.scaleinfoX.lineLength + m_chartspaces.chart.left > x - getMaxTimeWidth()) { // not to far right?
1337
- 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);
1338
1366
  legendItems.push({ x: x, type: 0 });
1339
1367
  }
1340
1368
  drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, false);
@@ -1343,9 +1371,8 @@ function Milli_Chart(settings) {
1343
1371
  }
1344
1372
 
1345
1373
  // vad är detta?
1346
- if (typeof m_chartCss.boxShadow !== 'undefined') {
1347
- var boxshadow = m_chartCss.boxShadow.split(' ');
1348
- 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);
1349
1376
 
1350
1377
  } else {
1351
1378
  drawXAxisGridlines({ 'x': x, y: m_chartspaces.chart.bottom }, false);
@@ -1354,22 +1381,14 @@ function Milli_Chart(settings) {
1354
1381
  }
1355
1382
 
1356
1383
  function onMouseOut(evt) {
1357
- if (m_toolTip.dateDiv) {
1358
- m_toolTip.dateDiv.parentNode.removeChild(m_toolTip.dateDiv);
1359
- m_toolTip.dateDiv = null;
1360
- }
1361
- for (var i = 0; i < m_toolTip.instrDiv.length; i++) {
1362
- if (m_toolTip.instrDiv[i]) {
1363
- m_toolTip.instrDiv[i].parentNode.removeChild(m_toolTip.instrDiv[i]);
1364
- m_toolTip.instrDiv[i] = null;
1365
- }
1366
- if (m_toolTip.arrowDiv[i]) {
1367
- m_toolTip.arrowDiv[i].parentNode.removeChild(m_toolTip.arrowDiv[i]);
1368
- 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;
1369
1390
  }
1370
1391
  }
1371
- m_toolTip.instrDiv = [];
1372
- m_toolTip.arrowDiv = [];
1373
1392
  }
1374
1393
 
1375
1394
  function clearZoom() {
@@ -1393,16 +1412,18 @@ function Milli_Chart(settings) {
1393
1412
  m_zoom.div = document.createElement('div');
1394
1413
  m_canvas.parentNode.appendChild(m_zoom.div);
1395
1414
  m_zoom.div.setAttribute('class', 'millistream-chart-zoombox');
1415
+ m_zoom.div.style.pointerEvents = 'none';
1416
+ m_zoom.div.style.position = 'absolute';
1396
1417
  }
1397
1418
  if (x < m_chartspaces.chart.left) x = m_chartspaces.chart.left;
1398
1419
  m_zoom.div.style.top = m_chartspaces.chart.top + 'px';
1399
1420
  m_zoom.div.style.left = (m_zoom.mousedown.pos > x ? x : m_zoom.mousedown.pos) + 'px';
1400
1421
  if (x > m_chartspaces.chart.right) x = m_chartspaces.chart.right;
1401
- 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';
1402
1423
  m_zoom.div.style.width = (m_zoom.mousedown.pos > x ? m_zoom.mousedown.pos - x : x - m_zoom.mousedown.pos) + 'px';
1403
1424
  }
1404
- if (_this.settings.enablehover == false) return;
1405
- 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) {
1406
1427
  onMouseOut();
1407
1428
  return;
1408
1429
  }
@@ -1421,134 +1442,71 @@ function Milli_Chart(settings) {
1421
1442
  if (obj == null) {
1422
1443
  return;
1423
1444
  }
1424
- // datetime
1425
- if (m_toolTip.dateDiv == null) {
1426
- m_toolTip.dateDiv = document.createElement('div');
1427
- m_canvas.parentNode.appendChild(m_toolTip.dateDiv);
1428
- }
1429
- var d = new Date(obj.timestamp);
1430
- m_toolTip.dateDiv.innerHTML = zeroPad(d.getFullYear(), 2);
1431
- m_toolTip.dateDiv.innerHTML += '-' + zeroPad(d.getMonth() + 1, 2);
1432
- m_toolTip.dateDiv.innerHTML += '-' + zeroPad(d.getDate(), 2) + '&nbsp'; // fixa dateformatet
1433
- if (_this.settings.chartlen != 'ytd' && _this.settings.chartlen.charAt(_this.settings.chartlen.length - 1) == 'd') { // TODO: change to tickchart
1434
- m_toolTip.dateDiv.innerHTML += zeroPad(d.getHours(), 2);
1435
- m_toolTip.dateDiv.innerHTML += ':' + zeroPad(d.getMinutes(), 2);
1436
- m_toolTip.dateDiv.innerHTML += ':' + zeroPad(d.getSeconds(), 2);
1437
- }
1438
- m_toolTip.dateDiv.innerHTML += 'X:' + x;
1439
- m_toolTip.dateDiv.setAttribute('class', 'millistream-chart-tooltip'); // set class so we can measure it might change below depending on position
1440
- 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
1441
-
1442
- // prices
1443
- var highy = -1000;
1444
- var lowy = 1000000; // hmm
1445
- var priceorder = [];
1446
- var num = 0;
1447
- for (x = 0; x < _this.instruments.length; x++) {
1448
- if (typeof m_toolTip.instrDiv[x] === 'undefined') {
1449
- m_toolTip.instrDiv[x] = document.createElement('div');
1450
- m_canvas.parentNode.appendChild(m_toolTip.instrDiv[x]);
1451
- }
1452
- if (typeof obj.instruments[x] === 'undefined') {
1453
- m_toolTip.instrDiv[x].style.display = 'none';
1454
- continue;
1455
- }
1456
- m_toolTip.instrDiv[x].style.display = 'block';
1457
- priceorder[num] = {};
1458
- priceorder[num].price = obj.instruments[x].price * _this.instruments[x].factor;
1459
- priceorder[num].instrument = x;
1460
- num++;
1461
- }
1462
- if (priceorder.length > 1) {
1463
- priceorder.sort(function(a, b) {
1464
- return b.price - a.price;
1465
- });
1466
- }
1467
- var keys = Object.keys(priceorder);
1468
- var left = 0;
1469
- for (x = 0; x < keys.length; x++) {
1470
- var k = priceorder[x].instrument;
1471
- if (typeof obj.instruments[k] !== 'undefined') {
1472
- 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);
1473
1483
  var tmp = Math.abs(posy - parseFloat(highy));
1474
- if (tmp < 30) {
1475
- posy = parseFloat(highy) + 20;
1484
+ var height = _this.instruments[x].toolTip.offsetHeight;
1485
+ if (tmp < height) {
1486
+ posy = parseFloat(highy) + height;
1476
1487
  }
1477
1488
  tmp = Math.abs(posy - parseFloat(lowy));
1478
1489
  if (tmp < 30) {
1479
1490
  // hur gör vi här? behövs det när vi sätter dom i ordning?
1480
1491
  //posy = parseFloat(highy) + 20;
1481
1492
  }
1482
- m_toolTip.instrDiv[k].innerHTML = formatNiceNumber(obj.instruments[k].price, _this.settings.thousandseparator, _this.settings.decimalseparator, obj.instruments[k].price.countDecimals());
1483
- if (typeof obj.instruments[k].diff !== 'undefined') m_toolTip.instrDiv[k].innerHTML += ', diff:' + formatNiceNumber(obj.instruments[k].diff, ' ', ',', m_y2settings.decimals);
1484
- m_toolTip.instrDiv[k].setAttribute('class', 'millistream-chart-tooltip'); // set class so we can measure it might change below depending on position
1485
- 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
1486
- 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
1487
1494
  // draw the hover to the left
1488
- m_toolTip.instrDiv[k].setAttribute('class', 'millistream-chart-tooltip');
1489
- 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';
1490
1496
  } else {
1491
1497
  // draw hover to the right
1492
- m_toolTip.instrDiv[k].style.left = (m_dataPoints.arr[i] + 10) + 'px'; //+ parseInt(m_tooltipLeftCss['border-left-width']) - 1 + 'px';
1493
- m_toolTip.instrDiv[k].setAttribute('class', 'millistream-chart-tooltip');
1494
- }
1495
- left = m_toolTip.instrDiv[k].style.left;
1496
- //m_toolTip.instrDiv[x].style.display = 'block';
1497
- //m_toolTip.instrDiv[x].style.height = '14px';
1498
- // draw arrow
1499
- var arrow = false;
1500
- var color;
1501
- if (arrow) {
1502
- if (typeof m_toolTip.arrowDiv[k] === 'undefined') {
1503
- m_toolTip.arrowDiv[k] = document.createElement('div');
1504
- m_canvas.parentNode.appendChild(m_toolTip.arrowDiv[k]);
1505
- }
1506
- var thickness = 2;
1507
- var x1 = m_dataPoints.arr[i];
1508
- var x2 = parseInt(m_toolTip.instrDiv[k].style.left);
1509
- var y1 = obj.instruments[k].y;
1510
- var y2 = parseInt(m_toolTip.instrDiv[k].style.top) + (parseInt(m_toolTip.instrDiv[k].style.height) / 2);
1511
- var length = Math.sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)));
1512
- var cx = ((x1 + x2) / 2) - (length / 2);
1513
- var cy = ((y1 + y2) / 2) - (thickness / 2);
1514
- // angle
1515
- var angle = Math.atan2((y1 - y2), (x1 - x2)) * (180 / Math.PI);
1516
- color = m_instrumentCss[k].color;
1517
- m_toolTip.arrowDiv[k].style.padding = '0px';
1518
- m_toolTip.arrowDiv[k].style.margin = '0px';
1519
- m_toolTip.arrowDiv[k].style.height = thickness + 'px';
1520
- m_toolTip.arrowDiv[k].style.backgroundColor = color;
1521
- m_toolTip.arrowDiv[k].style.lineHeight = '1px';
1522
- m_toolTip.arrowDiv[k].style.position = 'absolute';
1523
- m_toolTip.arrowDiv[k].style.left = cx + 'px';
1524
- m_toolTip.arrowDiv[k].style.top = cy + 'px';
1525
- m_toolTip.arrowDiv[k].style.width = length + 'px';
1526
- m_toolTip.arrowDiv[k].style.pointerEvents = 'none';
1527
- m_toolTip.arrowDiv[k].style.transform = 'rotate(' + angle + 'deg)';
1528
- } else {
1529
- if (typeof m_toolTip.arrowDiv[k] === 'undefined') {
1530
- m_toolTip.arrowDiv[k] = document.createElement('div');
1531
- m_canvas.parentNode.appendChild(m_toolTip.arrowDiv[k]);
1532
- }
1533
- m_toolTip.arrowDiv[k].setAttribute('class', 'millistream-chart-pointer');
1534
- m_toolTip.arrowDiv[k].style.left = (m_dataPoints.arr[i] - (m_toolTip.arrowDiv[k].clientWidth / 2)) + 'px';
1535
- m_toolTip.arrowDiv[k].style.top = (obj.instruments[k].y - (m_toolTip.arrowDiv[k].clientHeight / 2)) + 'px';
1536
- m_toolTip.arrowDiv[k].style.position = 'absolute';
1537
- color = m_instrumentCss[k].color;
1538
- m_toolTip.arrowDiv[k].style.backgroundColor = color;
1539
- m_toolTip.arrowDiv[k].style.pointerEvents = 'none';
1498
+ _this.instruments[x].toolTip.style.left = (obj.instruments[x].x + (pointerWidth / 2)) + 'px';
1540
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';
1541
1504
  if (posy > highy) highy = posy;
1542
1505
  if (posy < lowy) lowy = posy;
1543
- } else {
1544
- console.log('No instrument error');
1506
+
1545
1507
  }
1546
1508
  }
1547
- if (m_toolTip.instrDiv.length > 0) {
1548
- m_toolTip.dateDiv.style.left = left;
1549
- m_toolTip.dateDiv.style.top = parseInt(m_toolTip.instrDiv[0].style.top) - m_toolTip.dateDiv.offsetHeight - 5 + 'px'; // datepos
1550
- m_toolTip.dateDiv.style.top = lowy - m_toolTip.dateDiv.offsetHeight - 5 + 'px'; // datepos
1551
- }
1509
+ return;
1552
1510
  }
1553
1511
 
1554
1512
  function setTimeSpanData() {
@@ -1567,33 +1525,13 @@ function Milli_Chart(settings) {
1567
1525
  enddate = enddate.replaceAll('\/', '-');
1568
1526
  m_zoom.mousedown.timestamp = new Date(startdate + 'T00:00:00Z');
1569
1527
  m_zoom.mouseup.timestamp = new Date(enddate + 'T00:00:00Z');
1570
- // _this.scaleinfoX.endTimeStamp = m_zoom.mouseup.timestamp > m_zoom.mousedown.timestamp ? m_zoom.mouseup.timestamp : m_zoom.mousedown.timestamp;
1571
- // _this.scaleinfoX.startTimeStamp = m_zoom.mouseup.timestamp < m_zoom.mousedown.timestamp ? m_zoom.mouseup.timestamp : m_zoom.mousedown.timestamp;
1572
1528
  _this.drawChart();
1573
1529
  };
1574
1530
 
1575
1531
  function calcCompareFactors(type) {
1576
1532
  var i, s;
1577
- if (type == 'history2') {
1578
- if (_this.instruments.length > 1) {
1579
- if (_this.instruments[s].insref != 0) {
1580
- for (i = 0; i < _this.instruments[0].history.length; i++) {
1581
- if (_this.instruments[0].history[i].timestamp >= _this.scaleinfoX.startTimeStamp) {
1582
- instrumentprice = _this.instruments[0].history[i].price;
1583
- break;
1584
- }
1585
- }
1586
- for (s = 1; s < _this.instruments.length; s++) {
1587
- for (i = 0; i < _this.instruments[s].history.length; i++) {
1588
- if (_this.instruments[s].history[i].timestamp >= _this.scaleinfoX.startTimeStamp) {
1589
- _this.instruments[s].factor = instrumentprice / _this.instruments[s].history[i].price;
1590
- break;
1591
- }
1592
- }
1593
- }
1594
- }
1595
- }
1596
- }
1533
+ var instrumentprice;
1534
+
1597
1535
  if (_this.instruments.length > 1) {
1598
1536
  for (s = 1; s < _this.instruments.length; s++) {
1599
1537
  if (_this.instruments[s].insref != 0) {
@@ -1615,7 +1553,6 @@ function Milli_Chart(settings) {
1615
1553
  }
1616
1554
 
1617
1555
  function checkChartData(data) {
1618
- // _this.instruments[0].history / _this.instruments[0].trades
1619
1556
  var count = 0;
1620
1557
  for (var i = 0; i < data.length; i++) {
1621
1558
  if (data[i].timestamp >= _this.scaleinfoX.startTimeStamp && data[i].timestamp <= _this.scaleinfoX.endTimeStamp) {
@@ -1628,8 +1565,8 @@ function Milli_Chart(settings) {
1628
1565
  var y = m_chartspaces.chart.bottom - m_chartspaces.chart.top / 2 + m_chartspaces.chart.top;
1629
1566
  var x = m_chartspaces.chart.right - m_chartspaces.chart.left / 2 + m_chartspaces.chart.left;
1630
1567
  m_ctx.save();
1631
- m_ctx.font = 'bold ' + m_xLegendCss['font-size'] + ' ' + m_xLegendCss['font-family'];
1632
- 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;
1633
1570
  m_ctx.strokeStyle = m_gridHorizontalCss.color;
1634
1571
  m_ctx.fillStyle = m_xLegendCss.color;
1635
1572
  m_ctx.textAlign = "left";
@@ -1641,16 +1578,16 @@ function Milli_Chart(settings) {
1641
1578
 
1642
1579
  function calcChartSpaces() {
1643
1580
  m_chartspaces.chart.height = Math.round(m_canvas.height * (m_chartspaces.chart.percent / 100));
1644
- m_chartspaces.chart.top = parseInt(m_chartCss['margin-top']);
1645
- m_chartspaces.chart.left = parseInt(m_chartCss['margin-left']);
1646
- m_chartspaces.chart.right = m_canvas.width - parseInt(m_chartCss['margin-right']);
1647
- 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;
1648
1585
  m_chartspaces.chart.width = m_canvas.width;
1649
1586
  m_chartspaces.lowerChart.height = m_canvas.height * (m_chartspaces.lowerChart.percent / 100);
1650
- 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);
1651
1588
  m_chartspaces.lowerChart.left = m_chartspaces.chart.left;
1652
1589
  m_chartspaces.lowerChart.right = m_chartspaces.chart.right;
1653
- m_chartspaces.lowerChart.bottom = m_canvas.height - parseInt(m_chartCss['margin-bottom']);
1590
+ m_chartspaces.lowerChart.bottom = m_canvas.height - m_chartCss.marginBottom;
1654
1591
  m_chartspaces.lowerChart.width = m_canvas.width;
1655
1592
  }
1656
1593
 
@@ -1666,7 +1603,6 @@ function Milli_Chart(settings) {
1666
1603
  }
1667
1604
  m_lastDrawnInstrument = _this.instruments[0].insref;
1668
1605
  if (m_ctx == null) return;
1669
- //console.clear();
1670
1606
  m_datapoints = [];
1671
1607
  if (m_dataPoints.map) m_dataPoints.map.clear();
1672
1608
  m_dataPoints.map = new Map();
@@ -1680,13 +1616,12 @@ function Milli_Chart(settings) {
1680
1616
  var period = _this.settings.chartlen.substring(_this.settings.chartlen.length - 1);
1681
1617
  var len = parseInt(_this.settings.chartlen.substring(0, _this.settings.chartlen.length - 1));
1682
1618
  m_ctx.clearRect(0, 0, m_canvas.width, m_canvas.height);
1683
- m_ctx.fillStyle = m_chartCss['background-color'];
1619
+ m_ctx.fillStyle = m_chartCss.backgroundColor;
1684
1620
  m_ctx.fillRect(0, 0, m_canvas.width, m_canvas.height);
1685
1621
  m_ctx.lineWidth = 1;
1686
1622
  m_ctx.textBaseline = 'top'; // important!
1687
1623
  var i;
1688
1624
  if (period == 'd' && _this.instruments[0].trades.length != 0 && _this.settings.chartlen != 'ytd') {
1689
- _this.settings.graphvalue = 'price'; // om man får nav kanske man skall ta det från datan?
1690
1625
  if (m_zoom.mousedown.timestamp) {
1691
1626
  _this.scaleinfoX.endTimeStamp = m_zoom.mouseup.timestamp > m_zoom.mousedown.timestamp ? m_zoom.mouseup.timestamp : m_zoom.mousedown.timestamp;
1692
1627
  _this.scaleinfoX.startTimeStamp = m_zoom.mouseup.timestamp < m_zoom.mousedown.timestamp ? m_zoom.mouseup.timestamp : m_zoom.mousedown.timestamp;
@@ -1728,6 +1663,7 @@ function Milli_Chart(settings) {
1728
1663
  _this.scaleinfoY.type = 'trades';
1729
1664
  if (_this.instruments.length > 1) {
1730
1665
  // calc factors
1666
+ var instrumentprice;
1731
1667
  for (i = 0; i < _this.instruments[0].trades.length; i++) {
1732
1668
  if (_this.instruments[0].trades[i].timestamp >= _this.scaleinfoX.startTimeStamp) {
1733
1669
  instrumentprice = _this.instruments[0].trades[i].price;
@@ -1769,7 +1705,6 @@ function Milli_Chart(settings) {
1769
1705
  _this.scaleinfoX.endTimeStamp = new Date(_this.scaleinfoX.endTimeStamp.toISOString().substring(0, 10) + 'T' + '00:00:00Z').getTime();
1770
1706
  }
1771
1707
  setTimeSpanData();
1772
- _this.settings.graphvalue = 'price';
1773
1708
  _this.scaleinfoY.type = 'history';
1774
1709
  calcCompareFactors('history');
1775
1710
  _this.instruments[0].factor = 1;
@@ -1793,7 +1728,6 @@ function Milli_Chart(settings) {
1793
1728
  var startdate;
1794
1729
  if (_this.settings.chartlen == 'max' && _this.instruments[0].history.length > 1) {
1795
1730
  startdate = _this.instruments[0].history[0].timestamp;
1796
- //console.log('max', new Date(startdate));
1797
1731
  } else
1798
1732
  if (_this.settings.chartlen == 'ytd') {
1799
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?
@@ -1808,7 +1742,6 @@ function Milli_Chart(settings) {
1808
1742
  }
1809
1743
  setTimeSpanData();
1810
1744
  _this.scaleinfoY.type = 'history';
1811
- _this.settings.graphvalue = 'price';
1812
1745
  calcCompareFactors('history');
1813
1746
 
1814
1747
  _this.instruments[0].factor = 1;
@@ -1827,28 +1760,22 @@ function Milli_Chart(settings) {
1827
1760
  drawYAxisLower();
1828
1761
  drawBoxShadow(m_chartspaces.lowerChart);
1829
1762
  }
1830
- onMouseOut();
1763
+ //onMouseOut();
1831
1764
  };
1832
1765
 
1833
1766
  function drawBoxShadow(space) {
1834
- if (typeof m_chartCss.boxShadow === 'undefined') return;
1835
- var boxShadow = m_chartCss.boxShadow;
1836
- if (boxShadow.indexOf(')') != -1) {
1837
- boxShadow = boxShadow.substring(boxShadow.indexOf(')') + 2);
1838
- }
1839
- var boxshadow = boxShadow.split(' ');
1767
+ if (typeof m_chartCss.boxShadow === 'undefined' && typeof m_chartCss.boxShadow.color !== 'undefined') return;
1840
1768
  m_ctx.save();
1841
1769
  m_ctx.beginPath();
1842
- if (parseInt(boxshadow[0]) > 0) {
1843
- m_ctx.strokeStyle = m_chartCss['border-top-color'];
1844
- 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;
1845
1773
  m_ctx.moveTo(space.left, space.top);
1846
1774
  m_ctx.lineTo(space.right, space.top);
1847
1775
  m_ctx.stroke();
1848
1776
  }
1849
- if (parseInt(boxshadow[1]) > 0) {
1850
- m_ctx.strokeStyle = m_chartCss['border-right-color'];
1851
- 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;
1852
1779
  m_ctx.moveTo(space.right, space.top + 0.5);
1853
1780
  m_ctx.lineTo(space.right, space.bottom);
1854
1781
  m_ctx.stroke();
@@ -1862,8 +1789,11 @@ function Milli_Chart(settings) {
1862
1789
  return item.insref == data.insref;
1863
1790
  });
1864
1791
  if (instr == null) return;
1865
- var last = 0;
1792
+ /*var last = 0;*/
1866
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
+
1867
1797
  if (typeof data.tradecurrency !== 'undefined') instr.tradecurrency = data.tradecurrency;
1868
1798
  if (data.marketopen && data.marketclose) {
1869
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
@@ -1904,8 +1834,8 @@ function Milli_Chart(settings) {
1904
1834
  item = [];
1905
1835
  item.timestamp = data.trades[i].timestamp - (data.trades[i].timestamp % 60000);
1906
1836
 
1907
- if (last > item.timestamp) //console.log('ERROR', item.timestamp);
1908
- last = item.timestamp;
1837
+ /*if (last > item.timestamp)
1838
+ last = item.timestamp;*/
1909
1839
  if (typeof data.trades[i].tradeprice !== 'undefined') item.price = parseFloat(data.trades[i].tradeprice) * factor;
1910
1840
  if (typeof data.trades[i].tradequantity !== 'undefined' && data.trades[i].tradequantity != null) {
1911
1841
  item.quantity = parseInt(data.trades[i].tradequantity);
@@ -1957,8 +1887,6 @@ function Milli_Chart(settings) {
1957
1887
  _this.drawChart();
1958
1888
  return;
1959
1889
  }
1960
- /*if (m_modules.quantity == null)
1961
- m_modules.quantity = new MilliChart_Quantity(_this, m_canvas);*/
1962
1890
  _this.drawChart();
1963
1891
  };
1964
1892
 
@@ -2037,9 +1965,9 @@ function Milli_Chart(settings) {
2037
1965
  // TODO: här blir det fel när det är från 00:00: 23:59 men göms av tmpx < startpoint.x
2038
1966
 
2039
1967
  }
2040
- //startpoint.y = Math.round(m_canvas.height - parseInt(m_chartCss['margin-bottom']) - (((data[i].price * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2041
- 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;
2042
- 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;
2043
1971
 
2044
1972
  startpoint.x = Math.round(m_chartspaces.chart.left + ((data[i].timestamp - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel)) + 0.5;
2045
1973
  startpoint.x -= offset;
@@ -2054,7 +1982,6 @@ function Milli_Chart(settings) {
2054
1982
  }
2055
1983
 
2056
1984
  function plotData(data, instrument) {
2057
- //console.log('plotting',instrument,_this.instruments[instrument],_this.instruments);
2058
1985
  m_ctx.save();
2059
1986
  m_ctx.strokeStyle = m_instrumentCss[instrument].color;
2060
1987
  var factor = _this.instruments[instrument].factor;
@@ -2062,7 +1989,7 @@ function Milli_Chart(settings) {
2062
1989
  var endpoint = { x: 0, y: 0 };
2063
1990
  var startDate = _this.scaleinfoX.startTimeStamp;
2064
1991
  var len = data.length;
2065
- m_ctx.lineWidth = parseInt(m_instrumentCss[instrument].width);
1992
+ m_ctx.lineWidth = m_instrumentCss[instrument].width;
2066
1993
  m_ctx.beginPath();
2067
1994
 
2068
1995
  var startx = 0;
@@ -2072,6 +1999,7 @@ function Milli_Chart(settings) {
2072
1999
  var addedcloseprice1d = false;
2073
2000
  var maxy = 0;
2074
2001
  var hCurveLastPoint = null;
2002
+ var quantity = 0;
2075
2003
  for (var i = 0; i < len; i++) {
2076
2004
  var currentDate;
2077
2005
  var lastItem = data[i];
@@ -2082,7 +2010,6 @@ function Milli_Chart(settings) {
2082
2010
  continue;
2083
2011
  }
2084
2012
  if (data[i].timestamp > _this.scaleinfoX.endTimeStamp) {
2085
- //console.log('break', data[i].timestamp, _this.scaleinfoX.endTimeStamp);
2086
2013
  break; // continue?
2087
2014
  }
2088
2015
 
@@ -2091,11 +2018,11 @@ function Milli_Chart(settings) {
2091
2018
  continue;
2092
2019
  }
2093
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
2094
2022
  if (_this.scaleinfoY.type != 'history') {
2095
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
2096
2024
  }
2097
2025
  if (data[i].timestamp > endtimeToday.getTime()) {
2098
- console.log('no plot');
2099
2026
  continue; // dataticks efter stängning ritas inte
2100
2027
  }
2101
2028
 
@@ -2103,32 +2030,15 @@ function Milli_Chart(settings) {
2103
2030
  //var point = { price: data[i].price, open: null, x: endpoint.x - 0.5, y: endpoint.y - 0.5, timestamp: data[i].timestamp };
2104
2031
  //m_datapoints.push(point);
2105
2032
  } else
2106
- 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
2107
2034
  currentDate = new Date(data[i].timestamp);
2108
2035
  offset = ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel) * dateDiffInDays(new Date(startDate), currentDate);
2109
2036
  tmp = new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z');
2110
2037
  endpoint.x = Math.round(m_chartspaces.chart.left + ((tmp.getTime() - startDate) / _this.scaleinfoX.timePerPixel)) + 0.5 - offset;
2111
2038
  if (_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d') { // plot the closeprice1d
2112
- //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;
2113
- 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;
2114
2040
  } else {
2115
- //endpoint.y = Math.round(m_canvas.height - parseInt(m_chartCss['margin-bottom']) - (((parseFloat(lastItem.price) * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2116
- 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;
2117
- // do not add closeprice to hover array
2118
- /*
2119
- var x = Math.round(endpoint.x);
2120
- if (!m_dataPoints.arr.includes(x)) {
2121
- m_dataPoints.arr.push(x);
2122
- }
2123
- var obj = m_dataPoints.map.get(x);
2124
- if (obj == null) {
2125
- obj = {};
2126
- obj.timestamp = data[i].timestamp;
2127
- obj.instruments = [];
2128
- m_dataPoints.map.set(x, obj);
2129
- }
2130
- 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 };
2131
- */
2041
+ endpoint.y = Math.round(m_chartspaces.chart.height - m_chartCss.marginBottom - (((parseFloat(lastItem.price) * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2132
2042
  }
2133
2043
  m_ctx.moveTo(endpoint.x, endpoint.y);
2134
2044
  lastdate = new Date(data[i].timestamp);
@@ -2140,7 +2050,6 @@ function Milli_Chart(settings) {
2140
2050
  currentDate.setHours(lastdate.getHours());
2141
2051
  currentDate.setMinutes(lastdate.getMinutes());
2142
2052
  currentDate.setSeconds(lastdate.getSeconds());
2143
-
2144
2053
  if (lastdate.toISOString().substring(0, 10) != currentDate.toISOString().substring(0, 10)) { // new date
2145
2054
  tmp = new Date(lastdate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
2146
2055
  // draw Day separator?
@@ -2167,12 +2076,13 @@ function Milli_Chart(settings) {
2167
2076
  }
2168
2077
  //m_ctx.lineTo(startpoint.x, startpoint.y);
2169
2078
  }
2170
- //startpoint.y = Math.round(m_canvas.height - parseInt(m_chartCss['margin-bottom']) - (((data[i].price * factor) - _this.scaleinfoY.minValue) * _this.scaleinfoY.valuePerPixel)) + 0.5;
2171
- 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;
2172
2081
  maxy = maxy > startpoint.y ? maxy : startpoint.y;
2173
2082
 
2174
2083
  startpoint.x = Math.round(m_chartspaces.chart.left + ((data[i].timestamp - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel)) + 0.5;
2175
2084
  startpoint.x -= offset;
2085
+ quantity += data[i].quantity;
2176
2086
  if (startpoint.x != endpoint.x || startpoint.y != endpoint.y) {
2177
2087
  var x = Math.round(startpoint.x);
2178
2088
  if (!m_dataPoints.arr.includes(x)) {
@@ -2183,7 +2093,6 @@ function Milli_Chart(settings) {
2183
2093
  obj = {};
2184
2094
  obj.timestamp = data[i].timestamp;
2185
2095
  obj.instruments = [];
2186
- //m_dataPoints.map.set(data[i].timestamp,obj);
2187
2096
  m_dataPoints.map.set(x, obj);
2188
2097
  }
2189
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 };
@@ -2195,36 +2104,38 @@ function Milli_Chart(settings) {
2195
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"
2196
2105
 
2197
2106
  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), 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 };
2199
2108
  if (typeof data[i].dividend !== 'undefined') point.dividend = data[i].dividend;
2200
2109
  if (typeof data[i].diff !== 'undefined') point.diff = data[i].diff;
2110
+ point.quantity = quantity;
2201
2111
  m_datapoints.push(point);
2112
+ quantity = 0;
2202
2113
  }
2203
2114
  }
2204
2115
  } else {
2205
2116
  if (instrument == 0) {
2206
- 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 };
2207
- // 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 };
2208
2118
  m_datapoints.push(point);
2209
2119
  if (_this.settings.hcurve && _this.scaleinfoY.type == 'history') {
2210
2120
  if (isToday(currentDate)) {
2211
2121
  // only 1 point in hcurve chart, draw line from start of chart to end date
2212
2122
  m_ctx.moveTo(m_chartspaces.chart.left, startpoint.y);
2213
2123
  m_ctx.lineTo(startpoint.x, startpoint.y);
2214
- 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 };
2215
2125
  m_datapoints.push(point);
2216
- 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 };
2217
2127
  m_datapoints.push(point);
2218
2128
  startx = m_chartspaces.chart.left;
2219
2129
  starty = startpoint.y;
2220
2130
  // last point so break out and store startx and starty from fake point
2221
2131
  break;
2222
2132
  } else if (hCurveLastPoint) {
2223
- /* 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;
2224
2134
  m_ctx.moveTo(m_chartspaces.chart.left, y);
2225
2135
  m_ctx.lineTo(startpoint.x, y);*/
2226
2136
  }
2227
2137
  }
2138
+ quantity = 0;
2228
2139
  }
2229
2140
  m_ctx.moveTo(startpoint.x, startpoint.y);
2230
2141
  startx = startpoint.x;
@@ -2242,49 +2153,28 @@ function Milli_Chart(settings) {
2242
2153
  });
2243
2154
  m_ctx.stroke();
2244
2155
  if (_this.settings.fillchart == true && instrument == 0) {
2245
- // m_ctx.lineTo(startpoint.x, m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 0.5);
2246
- // m_ctx.lineTo(startx, m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 0.5);
2247
- m_ctx.lineTo(startpoint.x, m_chartspaces.chart.height - parseInt(m_chartCss['margin-bottom']) + 0.5);
2248
- 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);
2249
2158
  m_ctx.lineTo(startx, starty);
2250
2159
  m_ctx.closePath();
2251
- if (true == m_instrumentCss[0]['background-image'].startsWith('linear-gradient')) {
2252
- var colors = m_instrumentCss[0]['background-image'].substring(m_instrumentCss[0]['background-image'].indexOf('(') + 1);
2253
- var col0; // = 'rgba(0,200,0,1)';
2254
- var col1; // = 'rgba(0,200,0,0)';
2255
- if (typeof colors === 'string') {
2256
- col0 = colors.substring(0, colors.lastIndexOf('rgba'));
2257
- col0 = col0.substring(0, col0.lastIndexOf(','));
2258
- col1 = colors.substring(colors.lastIndexOf('rgba'), colors.lastIndexOf(')'));
2259
- }
2260
- var grd = m_ctx.createLinearGradient(0, 0, 0, m_chartspaces.chart.height - m_chartspaces.chart.top - parseInt(m_chartCss['margin-bottom']));
2261
- grd.addColorStop(0, col0);
2262
- 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);
2263
2164
  m_ctx.fillStyle = grd;
2264
2165
  } else {
2265
- m_ctx.fillStyle = m_instrumentCss[0]['background-image'];
2166
+ if (typeof m_instrumentCss[0].backgroundColor !== 'undefined')
2167
+ m_ctx.fillStyle = m_instrumentCss[0].backgroundColor;
2266
2168
  }
2267
2169
  m_ctx.fill();
2268
2170
  } else
2269
2171
  m_ctx.closePath();
2270
- // 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???
2271
2173
  plotExternalHistoricalData(data);
2272
- /*for (var i = 0; i < m_datapoints.length; i++) {
2273
- if (m_datapoints[i].dividend) {
2274
- console.log(m_datapoints[i]);
2275
- m_ctx.beginPath();
2276
- m_ctx.arc(m_datapoints[i].x, m_datapoints[i].y - 20, 10, 0, 2 * Math.PI, false);
2277
- m_ctx.fillStyle = 'green';
2278
- m_ctx.fill();
2279
- m_ctx.stroke()
2280
- }
2281
- }*/
2282
-
2283
2174
  m_ctx.restore();
2284
2175
  }
2285
2176
 
2286
2177
  function drawCompare(resp) {
2287
- var factor;
2288
2178
  parseData(resp[0], 1);
2289
2179
  _this.drawChart();
2290
2180
  return;
@@ -2342,11 +2232,11 @@ function Milli_Chart(settings) {
2342
2232
 
2343
2233
  _this.instruments[pos] = instr;
2344
2234
  if (_this.settings.compare1 != '') {
2345
- 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;
2346
2236
  millistream_data_api.fetch(url, function(data) {
2347
2237
  drawCompare(data);
2348
2238
  });
2349
- 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";
2350
2240
  millistream_data_api.fetch(url, function(data) {
2351
2241
  drawCompare(data);
2352
2242
  });
@@ -2439,9 +2329,9 @@ function Milli_Chart(settings) {
2439
2329
  _this.drawChart();
2440
2330
 
2441
2331
  if (_this.settings.streaming != false && typeof resp[0].trades !== 'undefined') {
2442
- if (MillistreamWidgetApi_isObjectEmpty(_this.unsubscriptions) == false) {
2332
+ /*if (MillistreamWidgetApi_isObjectEmpty(_this.unsubscriptions) == false) {
2443
2333
  _this.settings.streaming.MillistreamWidgetStreamingApi_unsubscribe(_this);
2444
- }
2334
+ }*/
2445
2335
  m_requestid = _this.settings.streaming.MillistreamWidgetStreamingApi_subscribeInstruments(_this, m_requestid, [_this.settings.instrument]);
2446
2336
  //_this.requestid = _this.settings.streaming.MillistreamWidgetStreamingApi_subscribeInstruments(_this, _this.requestid, m_insrefs);
2447
2337
  }
@@ -2457,7 +2347,7 @@ function Milli_Chart(settings) {
2457
2347
  return;
2458
2348
  }
2459
2349
  if (json['3'] && json['36'] && json['13'] && (json['12'] || json['201'])) {
2460
- 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();
2461
2351
 
2462
2352
  // TODO hash/strangle with YYYY-mm-dd hh:mm:00 trades and only draw once per minute
2463
2353
  var data = instr.hashmap.get(timestamp);
@@ -2468,122 +2358,51 @@ function Milli_Chart(settings) {
2468
2358
  data.timestamp = timestamp;
2469
2359
  instr.hashmap.set(data.timestamp, data);
2470
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
2471
2364
  data.quantity = parseInt(json['13']);
2472
2365
  if (instr.trades.length != 0 && data.timestamp < instr.trades[instr.trades.length - 1].timestamp) {
2473
2366
  //console.log("pushtrade is older than last trade ignoring, should file it on correct postition");
2474
2367
  } else
2475
2368
  instr.trades.push(data);
2476
2369
  } else {
2477
- //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;
2478
2373
  // updatera med quantity, open , high,low osv?
2479
2374
  }
2480
2375
  }
2481
- if (update) _this.drawChart();
2376
+ if (update) _this.drawChart(); // hover försvinner... (harris också)
2482
2377
  };
2483
2378
 
2484
- function readCss() {
2485
- //console.log("read css in");
2486
- var test = document.querySelector('.millistream-chart');
2487
- var properties = getComputedStyle(test);
2488
- m_chartCss['background-color'] = properties.backgroundColor;
2489
- m_chartCss['margin-top'] = properties.marginTop;
2490
- m_chartCss['margin-bottom'] = properties.marginBottom;
2491
- m_chartCss['margin-left'] = properties.marginLeft;
2492
- m_chartCss['margin-right'] = properties.marginRight;
2493
- //m_chartCss['box-shadow'] = properties.boxShadow;
2494
- m_chartCss.boxShadow = properties.boxShadow;
2495
- m_chartCss['border-right-color'] = properties.borderRightColor;
2496
- m_chartCss['border-left-color'] = properties.borderLeftColor;
2497
-
2498
- //console.log(properties.marginTop, properties.marginBottom, properties.marginLeft, properties.marginRight);
2499
- var siteURL = new URL(document.URL);
2500
- var cssURL;
2501
- for (var i = 0; i < document.styleSheets.length; i++) {
2502
- if (document.styleSheets[i].href != null)
2503
- cssURL = new URL(document.styleSheets[i].href);
2504
- else cssURL = null;
2505
- // console.log(document.styleSheets,cssURL);
2506
- // if(typeof document.styleSheets[i].host ==='undefined' ) continue;
2507
- if (cssURL != null && siteURL.host != cssURL.host) continue; // cssURL can be null on localhost
2508
- if (typeof document.styleSheets[i] === 'undefined') continue;
2509
- var yLeg = false;
2510
- for (var s = 0; s < document.styleSheets[i].cssRules.length; s++) {
2511
- // console.log(document.styleSheets[i].cssRules[s]);
2512
- if (typeof document.styleSheets[i].cssRules[s].selectorText !== 'undefined') {
2513
- var rules = document.styleSheets[i].cssRules[s].selectorText.split(',');
2514
- for (var ss = 0; ss < rules.length; ss++) {
2515
- // console.log(rules[ss]);
2516
- var ref = null;
2517
- rules[ss] = rules[ss].split(' ').join('');
2518
- switch (rules[ss]) {
2519
- case '.millistream-chart-x-legend':
2520
- ref = m_xLegendCss;
2521
- break;
2522
- case '.millistream-chart-y-legend':
2523
- yLeg = true;
2524
- ref = m_yLegendCss;
2525
- break;
2526
- case '.millistream-chart-y2-legend':
2527
- ref = m_y2LegendCss;
2528
- break;
2529
- case '.millistream-chart-legend':
2530
- // ref = m_LegendCss;
2531
- break;
2532
- case '.millistream-chart':
2533
- //ref = m_chartCss;
2534
- break;
2535
- case '.millistream-chart-horizontal-grid':
2536
- ref = m_gridHorizontalCss;
2537
- break;
2538
- case '.millistream-chart-vertical-grid':
2539
- ref = m_gridVerticalCss;
2540
- break;
2541
- case '.millistream-chart-instrument':
2542
- //console.log('chart');
2543
- ref = m_instrumentCss[0];
2544
- break;
2545
- case '.millistream-chart-compare1':
2546
- ref = m_instrumentCss[1];
2547
- break;
2548
- case '.millistream-chart-compare2':
2549
- ref = m_instrumentCss[2];
2550
- break;
2551
- case '.millistream-chart-compare3':
2552
- ref = m_instrumentCss[3];
2553
- break;
2554
- }
2555
- //console.log(ref);
2556
- if (ref != null) {
2557
- for (var r = 0; r < document.styleSheets[i].cssRules[s].style.length; r++) {
2558
- ref[document.styleSheets[i].cssRules[s].style[r]] = document.styleSheets[i].cssRules[s].style[document.styleSheets[i].cssRules[s].style[r]];
2559
- }
2560
- }
2561
- }
2562
- }
2563
- }
2564
- }
2565
- //console.log("read css out");
2566
-
2567
- }
2568
-
2569
2379
  function changeOrientation() {
2570
2380
  if (m_canvas == null) return;
2571
- console.log('resize');
2572
2381
  // set size 0 so target div does not expand due to chartsize
2573
- readCss();
2574
- //m_canvas.setAttribute('height', '0');
2575
- //m_canvas.setAttribute('width', '0');
2382
+ //readCss(); // TODO
2576
2383
 
2577
2384
  m_canvas.setAttribute('height', _this.settings.target.getBoundingClientRect().height);
2578
- m_canvas.setAttribute('width', _this.settings.target.getBoundingClientRect().width); // läs från css?
2579
- //m_canvas.setAttribute('height', _this.settings.target.offsetHeight);
2580
- //m_canvas.setAttribute('width', _this.settings.target.offsetWidth); // läs från css?
2385
+ m_canvas.setAttribute('width', _this.settings.target.getBoundingClientRect().width);
2581
2386
  _this.drawChart();
2582
2387
  }
2583
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
+
2584
2401
  this.drawWidget = function() {
2585
2402
  // remove standard fields from array, they will be requested anyway
2586
- _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
+ });
2587
2406
  //_this.settings.drawy2axis = false;
2588
2407
  m_tradedates = [];
2589
2408
  _this.settings.scaleinfoY = {};
@@ -2591,8 +2410,6 @@ function Milli_Chart(settings) {
2591
2410
  m_dummyDiv.style.display = 'none';
2592
2411
  m_dummyDiv.setAttribute('class', 'millistream-chart');
2593
2412
  _this.settings.target.appendChild(m_dummyDiv);
2594
- readCss();
2595
- m_tz_offset = new Date().getTimezoneOffset() * 60000;
2596
2413
  _this.instruments = []; // Hmm
2597
2414
  var instr = {
2598
2415
  insref: _this.settings.instrument,
@@ -2602,26 +2419,33 @@ function Milli_Chart(settings) {
2602
2419
  intradayQuantity: []
2603
2420
  };
2604
2421
  _this.instruments.push(instr);
2605
- var d, url;
2422
+ var d, url, oldfields;
2606
2423
  if (_this.settings.intradaylen) {
2607
2424
  d = new Date().getTime();
2608
2425
  var e = new Date();
2609
2426
  var days = 0;
2427
+ var newlen = 0;
2610
2428
  while (days < _this.settings.intradaylen - 1) { // include today
2611
2429
  d -= 86400000;
2612
2430
  e.setTime(d);
2613
2431
  if (e.getDay() != 0 && e.getDay() != 6)
2614
2432
  days++;
2433
+ newlen++;
2615
2434
  }
2616
- var oldfields = _this.settings.fields;
2435
+ _this.settings.intradaylen = newlen.toString();
2436
+ oldfields = _this.settings.fields;
2617
2437
  _this.settings.fields = [...['name', 'tradecurrency', 'time', 'date', 'tradeprice', 'tradequantity', 'marketopen', 'marketclose', 'closeprice1d'], ...oldfields];
2618
2438
  _this.settings.startdate = e.getFullYear() + '-' + zeroPad(e.getMonth() + 1, 2) + '-' + zeroPad(e.getDate(), 2);
2619
- _this.settings.startdateintraday = _this.settings.startdate;
2439
+ //_this.settings.startdateintraday = _this.settings.startdate;
2620
2440
  url = MillistreamWidgetApi_buildQuery(_this, 'intradaychart');
2621
2441
  _this.settings.fields = oldfields;
2622
- millistream_data_api.fetch(url, function(data) {
2623
- _this.buildwidget(data);
2624
- });
2442
+ if (_this.settings.xhr) {
2443
+ getXhrJson(url);
2444
+ } else {
2445
+ millistream_data_api.fetch(url, function(data) {
2446
+ _this.buildwidget(data);
2447
+ });
2448
+ }
2625
2449
  }
2626
2450
  if (_this.settings.historylen) {
2627
2451
  var len = _this.settings.historylen.substring(0, _this.settings.historylen.length - 1);
@@ -2667,22 +2491,24 @@ function Milli_Chart(settings) {
2667
2491
  }
2668
2492
  // must be reset when changing from intraday -> history and vice versa
2669
2493
  startdate = new Date(startdate);
2670
- var oldfields = _this.settings.fields;
2494
+ oldfields = _this.settings.fields;
2671
2495
  _this.settings.fields = [...['name', 'tradecurrency', 'date', 'closeprice', 'closequantity', 'marketopen', 'marketclose'], ...oldfields];
2672
2496
  _this.settings.startdate = startdate.getFullYear() + '-' + zeroPad(startdate.getMonth() + 1, 2) + '-' + zeroPad(startdate.getDate(), 2);
2673
2497
  url = MillistreamWidgetApi_buildQuery(_this, 'historychart');
2674
2498
  _this.settings.fields = oldfields;
2675
- console.log(_this.settings.fields);
2676
- millistream_data_api.fetch(url, function(data) {
2677
- _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);
2678
2504
 
2679
- });
2505
+ });
2506
+ }
2680
2507
  }
2681
2508
  };
2682
2509
  if (this.settings.autodraw == true) this.drawWidget();
2683
2510
 
2684
2511
  window.addEventListener('resize', function() {
2685
- //console.log('2');
2686
2512
  if (m_canvas != null)
2687
2513
  changeOrientation();
2688
2514
 
@@ -3027,6 +2853,10 @@ function MillistreamWidgetApi_buildQuery(widget, type) {
3027
2853
  if (typeof widget.settings.intradaylen !== 'string' && widget.settings.intradaylen !== null) throw new Error(widget.constructor.name + ': intradaylen is not valid');
3028
2854
  url += '&intradaylen=' + widget.settings.intradaylen;
3029
2855
  }
2856
+ if (typeof widget.settings.xhr !== 'undefined' && widget.settings.xhr == true) {
2857
+ url += '&xhr=1';
2858
+ }
2859
+
3030
2860
  return url;
3031
2861
  }
3032
2862
 
@@ -5261,5 +5091,8 @@ function MillistreamWidgetStreamingApi(settings) {
5261
5091
  }
5262
5092
  exports.Milli_Chart = Milli_Chart;
5263
5093
  exports.MillistreamWidgetSettings = MillistreamWidgetSettings;
5264
- exports.milli_data_api_url = milli_data_api_url;
5265
5094
  exports.MillistreamWidgetStreamingApi = MillistreamWidgetStreamingApi;
5095
+
5096
+ exports.setDataApiUrl = function(url) {
5097
+ milli_data_api_url = url;
5098
+ };