@millistream/millistream-widgets 0.0.10 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +128 -0
- package/millistream-widgets.js +507 -83
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Millistream Widgets
|
|
2
|
+
Millistream financial data widgets for websites.
|
|
3
|
+
|
|
4
|
+
## Installation
|
|
5
|
+
```bash
|
|
6
|
+
$ npm install @millistream/millistream-widgets
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Angular example
|
|
10
|
+
```html
|
|
11
|
+
<button (click)="loadChart()">Load</button>
|
|
12
|
+
<div id="chart" style="millistream-chart-target"></div>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
...
|
|
17
|
+
loadChart) {
|
|
18
|
+
(async function () {
|
|
19
|
+
const {
|
|
20
|
+
MillistreamWidgetStreamingApi,
|
|
21
|
+
Milli_Chart,
|
|
22
|
+
MillistreamWidgetSettings,
|
|
23
|
+
} = await import(
|
|
24
|
+
// @ts-ignore
|
|
25
|
+
'@millistream/millistream-widgets'
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
MillistreamWidgetSettings.token = 'xxx';
|
|
29
|
+
|
|
30
|
+
let pushapi = new MillistreamWidgetStreamingApi({
|
|
31
|
+
token: MillistreamWidgetSettings.token,
|
|
32
|
+
server: 'wss://push.millistream.com',
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
let ml = new Milli_Chart({
|
|
36
|
+
instrument: [6485],
|
|
37
|
+
target: document.getElementById('chart'),
|
|
38
|
+
autodraw: true,
|
|
39
|
+
intradaylen: '5',
|
|
40
|
+
historylen: '5y',
|
|
41
|
+
gridHorizontalLines: 0,
|
|
42
|
+
gridHorizontalLinesStyle: 'normal',
|
|
43
|
+
gridVerticalLines: 1,
|
|
44
|
+
chartlen: '1y',
|
|
45
|
+
dateformat: 'b dd',
|
|
46
|
+
drawyaxis: true,
|
|
47
|
+
fillchart: true,
|
|
48
|
+
timeformat: 'HH:mm',
|
|
49
|
+
streaming: pushapi,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
})();
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
```css
|
|
57
|
+
/* Global Styles */
|
|
58
|
+
.millistream-chart-target {
|
|
59
|
+
position: relative;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.millistream-chart-target {
|
|
63
|
+
position: relative;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.millistream-chart {
|
|
67
|
+
margin-bottom: 30px;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.millistream-chart-instrument {
|
|
71
|
+
color: #f90;
|
|
72
|
+
background-image: linear-gradient(
|
|
73
|
+
rgba(255, 153, 0, 0.6),
|
|
74
|
+
rgba(255, 153, 0, 0)
|
|
75
|
+
);
|
|
76
|
+
width: 2px;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.millistream-chart-tooltip {
|
|
80
|
+
position: absolute;
|
|
81
|
+
background: #ffffff;
|
|
82
|
+
border: 1px solid lightblue;
|
|
83
|
+
border-radius: 2px;
|
|
84
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
85
|
+
font-size: 11px;
|
|
86
|
+
padding: 2px;
|
|
87
|
+
height: 14px;
|
|
88
|
+
pointer-events: none;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.millistream-chart-pointer {
|
|
92
|
+
width: 5px;
|
|
93
|
+
height: 5px;
|
|
94
|
+
border-radius: 50%;
|
|
95
|
+
box-shadow: 0px 0px 10px 2px #f90;
|
|
96
|
+
pointer-events: none;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.millistream-chart-x-legend {
|
|
100
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
101
|
+
font-size: 11px;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.millistream-chart-y-legend {
|
|
105
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
106
|
+
font-size: 11px;
|
|
107
|
+
float: left;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.millistream-chart-y2-legend {
|
|
111
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
112
|
+
font-size: 11px;
|
|
113
|
+
float: right;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.millistream-chart-zoombox {
|
|
117
|
+
position: absolute;
|
|
118
|
+
background: rgb(255, 153, 0, 0.1);
|
|
119
|
+
pointer-events: none;
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Widget documentation
|
|
124
|
+
Please refer to non npm-version documentation on widget customization.
|
|
125
|
+
https://widgets.millistream.com/3.0.3/doc/widgets.html
|
|
126
|
+
|
|
127
|
+
## Support
|
|
128
|
+
https://www.millistream.com
|
package/millistream-widgets.js
CHANGED
|
@@ -41,7 +41,7 @@ function Milli_Chart(settings) {
|
|
|
41
41
|
hcurve: false,
|
|
42
42
|
adjusted: true,
|
|
43
43
|
nochartlabel: "No data to draw on",
|
|
44
|
-
|
|
44
|
+
yearLabelsPos: 'bottom'
|
|
45
45
|
};
|
|
46
46
|
_this.unsubscriptions = {};
|
|
47
47
|
var m_dummyDiv = null; // dummy div For chartclasses
|
|
@@ -161,12 +161,10 @@ function Milli_Chart(settings) {
|
|
|
161
161
|
}
|
|
162
162
|
*/
|
|
163
163
|
MillistreamWidgetApi_AssignObject(MillistreamWidgetSettings, _this.settings);
|
|
164
|
-
|
|
165
164
|
if (settings) {
|
|
166
165
|
MillistreamWidgetApi_AssignObject(settings, _this.settings);
|
|
167
166
|
}
|
|
168
167
|
|
|
169
|
-
|
|
170
168
|
_this.get_lang_text = function(string) {
|
|
171
169
|
return string;
|
|
172
170
|
};
|
|
@@ -248,6 +246,32 @@ function Milli_Chart(settings) {
|
|
|
248
246
|
return parseInt(obj['font-size']);
|
|
249
247
|
}
|
|
250
248
|
|
|
249
|
+
function getMaxTimeWidth() {
|
|
250
|
+
switch (_this.settings.dateformat) {
|
|
251
|
+
case 'HH:mm':
|
|
252
|
+
return m_ctx.measureText('88:88').width;
|
|
253
|
+
default:
|
|
254
|
+
return m_ctx.measureText('88:88').width;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function getMaxDateWidth() {
|
|
259
|
+
switch (_this.settings.dateformat) {
|
|
260
|
+
case 'yyyy-mm-dd':
|
|
261
|
+
return m_ctx.measureText("8888-88-88").width;
|
|
262
|
+
case 'b dd':
|
|
263
|
+
return m_ctx.measureText("MMM 88").width;
|
|
264
|
+
case 'b dd yyyy':
|
|
265
|
+
return m_ctx.measureText("MMM 88 8888").width;
|
|
266
|
+
case 'dd/mm':
|
|
267
|
+
case 'd/m':
|
|
268
|
+
return m_ctx.measureText("88/88").width;
|
|
269
|
+
default:
|
|
270
|
+
return m_ctx.measureText(_this.settings.dateformat).width;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
|
|
251
275
|
function getStringWidth(ctx, format) {
|
|
252
276
|
switch (format) {
|
|
253
277
|
case 'yyyy-mm-dd':
|
|
@@ -680,6 +704,7 @@ function Milli_Chart(settings) {
|
|
|
680
704
|
}
|
|
681
705
|
|
|
682
706
|
function calcXScale(starttime, endtime) {
|
|
707
|
+
// vad är detta?
|
|
683
708
|
_this.scaleinfoX.startDate = new Date(starttime);
|
|
684
709
|
_this.scaleinfoX.endDate = new Date(endtime);
|
|
685
710
|
_this.scaleinfoX.days = getNumberOfDays(starttime, endtime);
|
|
@@ -715,6 +740,18 @@ function Milli_Chart(settings) {
|
|
|
715
740
|
return;
|
|
716
741
|
}
|
|
717
742
|
|
|
743
|
+
function getDatePosition(x) {
|
|
744
|
+
var timestamp = _this.scaleinfoX.startDate.getTime();
|
|
745
|
+
for (var i = 0; i < 1000; i++) {
|
|
746
|
+
var xx = getXPosition(new Date(timestamp));
|
|
747
|
+
if (xx >= x) return timestamp;
|
|
748
|
+
timestamp += 86400000;
|
|
749
|
+
}
|
|
750
|
+
//var timestamp = (x - Math.round(parseInt(m_chartCss['margin-left'] + offset)) * _this.scaleinfoX.timePerPixel) - _this.scaleinfoX.startDate.getTime();
|
|
751
|
+
|
|
752
|
+
return 0;
|
|
753
|
+
}
|
|
754
|
+
|
|
718
755
|
function getXPosition(timestamp) {
|
|
719
756
|
var offset = (timestamp.getTime() - _this.scaleinfoX.startDate.getTime()) / (86400000 * 7); // veckor
|
|
720
757
|
offset = offset * 86400000 * 2 / _this.scaleinfoX.timePerPixel;
|
|
@@ -745,16 +782,15 @@ function Milli_Chart(settings) {
|
|
|
745
782
|
x = getXPosition(new Date(year + '-01-01T00:00:00Z'));
|
|
746
783
|
draw = true;
|
|
747
784
|
for (i = 0; i < legendItems.length; i++) {
|
|
748
|
-
if (
|
|
749
|
-
//if (x < _this.scaleinfoX.lineLength + parseInt(m_chartCss['margin-left']) - (_this.scaleinfoX.itemwidth / 2)) {
|
|
785
|
+
if (legendItems[i].x + (m_ctx.measureText('8888').width / 2) > (x - (m_ctx.measureText('8888').width))) {
|
|
750
786
|
draw = false;
|
|
751
787
|
}
|
|
752
788
|
}
|
|
753
789
|
if (draw) {
|
|
754
790
|
drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) });
|
|
755
791
|
text = year;
|
|
756
|
-
if (_this.scaleinfoX.lineLength >
|
|
757
|
-
if (_this.settings.
|
|
792
|
+
if (_this.scaleinfoX.lineLength + parseInt(m_chartCss['margin-left']) > x - m_ctx.measureText(text).width) { // not to far right?
|
|
793
|
+
if (_this.settings.yearLabelsPos == 'top') {
|
|
758
794
|
m_ctx.save(); // flip and write new years on top
|
|
759
795
|
var fontMetrix = m_ctx.measureText(text);
|
|
760
796
|
x = x + fontMetrix.actualBoundingBoxAscent + fontMetrix.actualBoundingBoxDescent + 2;
|
|
@@ -767,35 +803,38 @@ function Milli_Chart(settings) {
|
|
|
767
803
|
m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 10);
|
|
768
804
|
}
|
|
769
805
|
numItems++;
|
|
806
|
+
legendItems.push({ text: year.toString(), timestamp: new Date(year + '-01-01T00:00:00Z'), 'x': x });
|
|
770
807
|
}
|
|
771
|
-
legendItems.push({ text: year.toString(), timestamp: new Date(year + '-01-01T00:00:00Z'), 'x': x });
|
|
772
808
|
year++;
|
|
773
809
|
}
|
|
810
|
+
if (numItems * m_ctx.measureText('8888').width / _this.scaleinfoX.lineLength > 0.3) numItems = 11; // keep it clean
|
|
774
811
|
// draw half year
|
|
775
|
-
if (numItems < 10) { // max 10 items här för att skriva
|
|
776
|
-
year = new Date(_this.scaleinfoX.startDate.getFullYear() + '-07-01T00:00:00Z');
|
|
812
|
+
if (numItems < 10) { // max 10 items här för att skriva halvår
|
|
813
|
+
year = new Date(_this.scaleinfoX.startDate.getFullYear() + '-07-01T00:00:00Z');
|
|
777
814
|
if (year.getTime() < _this.scaleinfoX.startDate.getTime())
|
|
778
|
-
year = new Date(_this.scaleinfoX.startDate.getFullYear() + 1 + '-07-01T00:00:00Z');
|
|
815
|
+
year = new Date(_this.scaleinfoX.startDate.getFullYear() + 1 + '-07-01T00:00:00Z');
|
|
779
816
|
while (year < _this.scaleinfoX.endDate) {
|
|
780
817
|
x = getXPosition(new Date(year.getFullYear() + '-07-01T00:00:00Z')); // 7
|
|
781
818
|
draw = true;
|
|
782
819
|
for (i = 0; i < legendItems.length; i++) {
|
|
783
|
-
if (Math.abs(legendItems[i].x - x) < (
|
|
784
|
-
|
|
820
|
+
//if (Math.abs(legendItems[i].x - x) < (getMaxDateWidth() / 2)) {
|
|
821
|
+
if (Math.abs(legendItems[i].x - x) < getMaxDateWidth()) {
|
|
785
822
|
draw = false;
|
|
786
823
|
}
|
|
787
824
|
}
|
|
788
825
|
if (draw) {
|
|
789
826
|
drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) });
|
|
790
|
-
text = formatDate(year.getFullYear() + '-07-01', _this.settings.dateformat);
|
|
827
|
+
text = formatDate(year.getFullYear() + '-07-01', _this.settings.dateformat);
|
|
828
|
+
// ingen if som på year???
|
|
791
829
|
m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 10);
|
|
792
830
|
numItems++;
|
|
831
|
+
legendItems.push({ 'text': text, timestamp: new Date(year + '-07-01T00:00:00Z'), 'x': x });
|
|
793
832
|
}
|
|
794
|
-
|
|
795
|
-
year = new Date((year.getFullYear() + 1) + '-07-01T00:00:00Z'); // 7
|
|
833
|
+
year = new Date((year.getFullYear() + 1) + '-07-01T00:00:00Z');
|
|
796
834
|
}
|
|
797
835
|
}
|
|
798
836
|
// draw Quarter
|
|
837
|
+
if (numItems * m_ctx.measureText('8888').width / _this.scaleinfoX.lineLength > 0.3) numItems = 11; // keep it clean
|
|
799
838
|
if (numItems < 10) { // max 10 items här för att skriva kvartal
|
|
800
839
|
year = new Date(_this.scaleinfoX.startDate.getFullYear() + '-04-01T00:00:00Z');
|
|
801
840
|
if (year.getTime() < _this.scaleinfoX.startDate.getTime())
|
|
@@ -805,8 +844,7 @@ function Milli_Chart(settings) {
|
|
|
805
844
|
x = getXPosition(new Date(year.getFullYear() + '-04-01T00:00:00Z'));
|
|
806
845
|
draw = true;
|
|
807
846
|
for (i = 0; i < legendItems.length; i++) {
|
|
808
|
-
if (Math.abs(legendItems[i].x - x) < (
|
|
809
|
-
//if (x < _this.scaleinfoX.lineLength + parseInt(m_chartCss['margin-left']) - (_this.scaleinfoX.itemwidth / 2)) {
|
|
847
|
+
if (Math.abs(legendItems[i].x - x) < getMaxDateWidth()) {
|
|
810
848
|
draw = false;
|
|
811
849
|
dontPrint = true;
|
|
812
850
|
}
|
|
@@ -829,8 +867,7 @@ function Milli_Chart(settings) {
|
|
|
829
867
|
x = getXPosition(new Date(year.getFullYear() + '-10-01T00:00:00Z'));
|
|
830
868
|
draw = true;
|
|
831
869
|
for (i = 0; i < legendItems.length; i++) {
|
|
832
|
-
if (Math.abs(legendItems[i].x - x) < (
|
|
833
|
-
//if (x < _this.scaleinfoX.lineLength + parseInt(m_chartCss['margin-left']) - (_this.scaleinfoX.itemwidth / 2)) {
|
|
870
|
+
if (Math.abs(legendItems[i].x - x) < getMaxDateWidth()) {
|
|
834
871
|
draw = false;
|
|
835
872
|
}
|
|
836
873
|
}
|
|
@@ -849,6 +886,61 @@ function Milli_Chart(settings) {
|
|
|
849
886
|
}
|
|
850
887
|
|
|
851
888
|
function drawXAxisMonth(starttime, endtime) {
|
|
889
|
+
starttime -= starttime % 8640000;
|
|
890
|
+
endtime -= starttime % 8640000;
|
|
891
|
+
m_ctx.save();
|
|
892
|
+
m_ctx.font = m_xLegendCss['font-weight'] + ' ' + m_xLegendCss['font-size'] + ' ' + m_xLegendCss['font-family'];
|
|
893
|
+
m_ctx.strokeStyle = m_gridHorizontalCss.color;
|
|
894
|
+
m_ctx.fillStyle = m_xLegendCss.color;
|
|
895
|
+
calcXScale(starttime, endtime);
|
|
896
|
+
if (_this.settings.drawxaxis != 0) { // draw line
|
|
897
|
+
m_ctx.beginPath();
|
|
898
|
+
m_ctx.moveTo(parseInt(m_chartCss['margin-left']), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 0.5);
|
|
899
|
+
m_ctx.lineTo(m_canvas.width - parseInt(m_chartCss['margin-right']), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 0.5);
|
|
900
|
+
m_ctx.stroke();
|
|
901
|
+
m_ctx.closePath();
|
|
902
|
+
}
|
|
903
|
+
m_ctx.textAlign = "left";
|
|
904
|
+
var currentDate = new Date(starttime);
|
|
905
|
+
var x;
|
|
906
|
+
var lastx = 0;
|
|
907
|
+
var draw = true;
|
|
908
|
+
var offset = 0;
|
|
909
|
+
while (currentDate.getTime() < _this.scaleinfoX.endTimeStamp) { // oklart om det skall vara så här 2021-06-01
|
|
910
|
+
draw = true;
|
|
911
|
+
while (currentDate.getDay() == 0 || currentDate.getDay() == 6) { // move past weekends , maybe skip this if date is available in data
|
|
912
|
+
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
913
|
+
offset += 86400000 / _this.scaleinfoX.timePerPixel;
|
|
914
|
+
}
|
|
915
|
+
x = Math.round(parseInt(m_chartCss['margin-left']) + ((currentDate.getTime() - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel) - offset);
|
|
916
|
+
if (lastx == 0 && parseInt(m_chartCss['margin-left']) > (x - (getMaxDateWidth() / 2))) { // do not print left of y legend
|
|
917
|
+
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
918
|
+
continue;
|
|
919
|
+
}
|
|
920
|
+
console.log(x, lastx);
|
|
921
|
+
if (lastx + (getMaxDateWidth() / 2) > (x - getMaxDateWidth())) {
|
|
922
|
+
draw = false;
|
|
923
|
+
}
|
|
924
|
+
if (draw) {
|
|
925
|
+
lastx = x;
|
|
926
|
+
var text = formatDate(currentDate.toISOString().substring(0, 10), _this.settings.dateformat);
|
|
927
|
+
if (_this.scaleinfoX.lineLength + parseInt(m_chartCss['margin-left']) > x - getMaxDateWidth()) // not to far right?
|
|
928
|
+
m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 10);
|
|
929
|
+
drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) });
|
|
930
|
+
}
|
|
931
|
+
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
932
|
+
}
|
|
933
|
+
// vad är detta?
|
|
934
|
+
if (typeof m_chartCss['box-shadow'] !== 'undefined') {
|
|
935
|
+
var boxshadow = m_chartCss['box-shadow'].split(' ');
|
|
936
|
+
if (parseInt(boxshadow[1]) == 0) drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) }, false);
|
|
937
|
+
|
|
938
|
+
} else
|
|
939
|
+
drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) }, false);
|
|
940
|
+
m_ctx.restore();
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
function drawXAxisMonth2(starttime, endtime) {
|
|
852
944
|
// month axis
|
|
853
945
|
starttime -= starttime % 8640000;
|
|
854
946
|
endtime -= starttime % 8640000;
|
|
@@ -871,68 +963,31 @@ function Milli_Chart(settings) {
|
|
|
871
963
|
var endDate = new Date(endtime);
|
|
872
964
|
var p = { x: 0, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) };
|
|
873
965
|
var offset = 0; // timeoffset for closed hours,and weekends
|
|
874
|
-
var newday = true;
|
|
875
966
|
var last = 0;
|
|
876
|
-
var nextYear = currentDate.getFullYear() + 1;
|
|
877
967
|
var olddate = '';
|
|
878
|
-
//while (p.x < (_this.scaleinfoX.lineLength + parseInt(m_chartCss['margin-left']) - (_this.scaleinfoX.itemwidth / 2))) {
|
|
879
968
|
while (currentDate.getTime() < _this.scaleinfoX.endTimeStamp) { // oklart om det skall vara så här 2021-06-01
|
|
880
969
|
while (currentDate.getDay() == 0 || currentDate.getDay() == 6) { // move past weekends , maybe skip this if date is available in data
|
|
881
970
|
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
882
971
|
offset += 86400000 / _this.scaleinfoX.timePerPixel;
|
|
883
|
-
if (nextYear == currentDate.getFullYear()) {
|
|
884
|
-
lastDate = currentDate;
|
|
885
|
-
drawXAxisGridlines(p, true); //, '#FF0000');
|
|
886
|
-
datum = nextYear;
|
|
887
|
-
|
|
888
|
-
if (_this.settings.yearLablesPos == 'top') {
|
|
889
|
-
m_ctx.save();
|
|
890
|
-
var fontMetrix = m_ctx.measureText(datum);
|
|
891
|
-
var x = p.x + fontMetrix.actualBoundingBoxAscent + fontMetrix.actualBoundingBoxDescent + 2;
|
|
892
|
-
var y = parseInt(m_chartCss['margin-top']); // + m_ctx.measureText(datum).width;
|
|
893
|
-
m_ctx.translate(x, y);
|
|
894
|
-
m_ctx.rotate(90 * Math.PI / 180);
|
|
895
|
-
m_ctx.fillText(datum, 0, 0);
|
|
896
|
-
m_ctx.restore();
|
|
897
|
-
} else
|
|
898
|
-
m_ctx.fillText(datum, p.x - (m_ctx.measureText(datum).width / 2), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 10);
|
|
899
|
-
last = p.x;
|
|
900
|
-
nextYear = currentDate.getFullYear() + 1;
|
|
901
|
-
}
|
|
902
972
|
}
|
|
903
|
-
//oldx = p.x;
|
|
904
973
|
p.x = Math.round(parseInt(m_chartCss['margin-left']) + ((currentDate.getTime() - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel) - offset);
|
|
905
974
|
var datum;
|
|
906
975
|
var dash = false;
|
|
907
|
-
newday = false;
|
|
908
|
-
if (nextYear == currentDate.getFullYear()) {
|
|
909
|
-
//drawXAxisGridlines(p, true);
|
|
910
|
-
datum = nextYear;
|
|
911
|
-
//datum = formatDate(nextYear + '-01-01', _this.settings.dateformat);
|
|
912
|
-
// m_ctx.fillText(datum, p.x - (m_ctx.measureText(datum).width / 2), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 10);
|
|
913
|
-
//last = p.x;
|
|
914
|
-
nextYear = currentDate.getFullYear() + 1;
|
|
915
|
-
}
|
|
916
|
-
//datum = currentDate.getDate() + '/' + (currentDate.getMonth() + 1); // format date
|
|
917
976
|
datum = formatDate(currentDate.toISOString().substring(0, 10), _this.settings.dateformat);
|
|
918
|
-
//dash = true;
|
|
919
977
|
offset += ((86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel); // * dateDiffInDays(lastdate, currentDate); // varför?
|
|
920
978
|
currentDate = new Date(currentDate.getTime() + _this.scaleinfoX.ticksize);
|
|
979
|
+
if (parseInt(m_chartCss['margin-left']) + (getMaxDateWidth() / 2) > (p.x - (getMaxDateWidth()))) {
|
|
980
|
+
continue;
|
|
981
|
+
}
|
|
982
|
+
|
|
921
983
|
lastDate = new Date(currentDate);
|
|
922
984
|
lastDate.setHours(endDate.getHours());
|
|
923
985
|
lastDate.setMinutes(endDate.getMinutes());
|
|
924
986
|
lastDate.setSeconds(endDate.getSeconds());
|
|
925
|
-
newday = true;
|
|
926
987
|
var printLegendItem = true;
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
if (nextYearX - p.x < (Math.floor(_this.scaleinfoX.itemwidth))) {
|
|
988
|
+
|
|
989
|
+
if (p.x != parseInt(m_chartCss['margin-left']) && p.x - last < (Math.floor(_this.scaleinfoX.itemwidth))) {
|
|
930
990
|
printLegendItem = false;
|
|
931
|
-
} else {
|
|
932
|
-
//var nextx = Math.round(parseInt(m_chartCss['margin-left']) + ((currentDate.getTime() - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel) - offset);
|
|
933
|
-
if (p.x != parseInt(m_chartCss['margin-left']) && p.x - last < (Math.floor(_this.scaleinfoX.itemwidth))) {
|
|
934
|
-
printLegendItem = false;
|
|
935
|
-
}
|
|
936
991
|
}
|
|
937
992
|
if (printLegendItem) {
|
|
938
993
|
if (olddate != datum) {
|
|
@@ -1054,6 +1109,380 @@ function Milli_Chart(settings) {
|
|
|
1054
1109
|
}
|
|
1055
1110
|
|
|
1056
1111
|
function drawXAxisTick(starttime, endtime) {
|
|
1112
|
+
m_ctx.save();
|
|
1113
|
+
m_ctx.font = m_xLegendCss['font-weight'] + ' ' + m_xLegendCss['font-size'] + ' ' + m_xLegendCss['font-family'];
|
|
1114
|
+
|
|
1115
|
+
m_ctx.strokeStyle = m_gridHorizontalCss.color;
|
|
1116
|
+
m_ctx.fillStyle = m_xLegendCss.color;
|
|
1117
|
+
m_ctx.textAlign = "left";
|
|
1118
|
+
calcXScaleTick(starttime, endtime);
|
|
1119
|
+
if (_this.settings.drawxaxis != 0) { // draw line for legend
|
|
1120
|
+
m_ctx.beginPath();
|
|
1121
|
+
m_ctx.moveTo(parseInt(m_chartCss['margin-left']), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 0.5);
|
|
1122
|
+
m_ctx.lineTo(m_canvas.width - parseInt(m_chartCss['margin-right']), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 0.5);
|
|
1123
|
+
m_ctx.stroke();
|
|
1124
|
+
m_ctx.closePath();
|
|
1125
|
+
}
|
|
1126
|
+
// if(startime.date == endtime.date && starttime > open || endtime < close ) // no date
|
|
1127
|
+
|
|
1128
|
+
var currentDate = new Date(starttime);
|
|
1129
|
+
console.log('startdate', currentDate);
|
|
1130
|
+
var x;
|
|
1131
|
+
var lastx = 0;
|
|
1132
|
+
var draw = true;
|
|
1133
|
+
var offset = 0;
|
|
1134
|
+
var legendItems = [];
|
|
1135
|
+
// add days (daychanges)
|
|
1136
|
+
//currentDate = new Date(currentDate.getTime() + currentDate.getTime() % 3600000); // START om full hour (if modulo == 0 then + 3600000 kanske)
|
|
1137
|
+
if (currentDate.getTime() % 3600000 != 0) // if not full hour, move up to next full hour
|
|
1138
|
+
currentDate = new Date(currentDate.getTime() - currentDate.getTime() % 3600000 + 3600000); // START om full hour (if modulo == 0 then + 3600000 kanske)
|
|
1139
|
+
console.log(currentDate);
|
|
1140
|
+
while (currentDate.getTime() < _this.scaleinfoX.endTimeStamp) {
|
|
1141
|
+
draw = true;
|
|
1142
|
+
while (currentDate.getDay() == 0 || currentDate.getDay() == 6) { // move past weekends , maybe skip this if date is available in data
|
|
1143
|
+
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
1144
|
+
offset += 86400000 / _this.scaleinfoX.timePerPixel;
|
|
1145
|
+
}
|
|
1146
|
+
//currentDate = new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z');
|
|
1147
|
+
x = Math.round(parseInt(m_chartCss['margin-left']) + ((currentDate.getTime() - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel) - offset);
|
|
1148
|
+
if (lastx != 0 && lastx + (getMaxTimeWidth() / 2) > (x - getMaxTimeWidth())) {
|
|
1149
|
+
draw = false;
|
|
1150
|
+
}
|
|
1151
|
+
if (draw) {
|
|
1152
|
+
lastx = x;
|
|
1153
|
+
x += 0.5;
|
|
1154
|
+
var text = formatChartTime(currentDate.toTimeString().substring(0, 8), _this.settings.timeformat);
|
|
1155
|
+
// if day change and setting print on top as well
|
|
1156
|
+
if (_this.scaleinfoX.lineLength + parseInt(m_chartCss['margin-left']) > x - getMaxTimeWidth()) { // not to far right?
|
|
1157
|
+
m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 10);
|
|
1158
|
+
legendItems.push({ x: x, type: 0, text: text });
|
|
1159
|
+
}
|
|
1160
|
+
drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) }); // dash?
|
|
1161
|
+
}
|
|
1162
|
+
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
1163
|
+
offset += (86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel;
|
|
1164
|
+
//offset += (86400000 - _this.scaleinfoX.milliPerDay);
|
|
1165
|
+
}
|
|
1166
|
+
var currentDate = new Date(starttime);
|
|
1167
|
+
console.log(currentDate);
|
|
1168
|
+
//currentDate = new Date(currentDate.getTime() + currentDate.getTime() % 3600000); // START om full hour (if modulo == 0 then + 3600000 kanske)
|
|
1169
|
+
if (currentDate.getTime() % 3600000 != 0) // if not full hour, move up to next full hour
|
|
1170
|
+
currentDate = new Date(currentDate.getTime() - currentDate.getTime() % 3600000 + 3600000); // START om full hour (if modulo == 0 then + 3600000 kanske)
|
|
1171
|
+
console.log(currentDate);
|
|
1172
|
+
|
|
1173
|
+
var maxHourLegends;
|
|
1174
|
+
console.log(legendItems);
|
|
1175
|
+
if (legendItems.length == 0)
|
|
1176
|
+
maxHourLegends = Math.floor((_this.scaleinfoX.lineLength - parseInt(m_chartCss['margin-left']) - getMaxTimeWidth()) / (getMaxTimeWidth() * 3));
|
|
1177
|
+
else
|
|
1178
|
+
if (legendItems.length == 1)
|
|
1179
|
+
maxHourLegends = Math.floor((_this.scaleinfoX.lineLength - legendItems[0].x - getMaxTimeWidth()) / (getMaxTimeWidth() * 3));
|
|
1180
|
+
else
|
|
1181
|
+
maxHourLegends = Math.floor((legendItems[1].x - legendItems[0].x - getMaxTimeWidth()) / (getMaxTimeWidth() * 3));
|
|
1182
|
+
var tickSize = new Date(new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z') - new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z'));
|
|
1183
|
+
tickSize = tickSize.getTime() / 3600000;
|
|
1184
|
+
var interval = Math.floor(tickSize / (maxHourLegends + 1)) * 3600000;
|
|
1185
|
+
console.log('MAX', maxHourLegends, tickSize, interval);
|
|
1186
|
+
// print other times
|
|
1187
|
+
offset = 0;
|
|
1188
|
+
lastx = 0;
|
|
1189
|
+
var closeTime = new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
|
|
1190
|
+
var workDate = new Date(currentDate);
|
|
1191
|
+
console.log('workdate', workDate);
|
|
1192
|
+
while (currentDate.getTime() < _this.scaleinfoX.endTimeStamp) {
|
|
1193
|
+
console.log('workdate', workDate);
|
|
1194
|
+
draw = true;
|
|
1195
|
+
while (currentDate.getDay() == 0 || currentDate.getDay() == 6) { // move past weekends , maybe skip this if date is available in data
|
|
1196
|
+
console.log('Helg', currentDate);
|
|
1197
|
+
closeTime = new Date(closeTime.getTime() + 86400000);
|
|
1198
|
+
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
1199
|
+
//currentDate = new Date(currentDate.getTime() + currentDate.getTime() % 3600000); // START om full hour (if modulo == 0 then + 3600000 kanske)
|
|
1200
|
+
if (currentDate.getTime() % 3600000 != 0) // if not full hour, move up to next full hour
|
|
1201
|
+
currentDate = new Date(currentDate.getTime() - currentDate.getTime() % 3600000 + 3600000); // START om full hour (if modulo == 0 then + 3600000 kanske)
|
|
1202
|
+
var workDate = new Date(workDate.getTime() + 86400000);
|
|
1203
|
+
offset += 86400000 / _this.scaleinfoX.timePerPixel;
|
|
1204
|
+
}
|
|
1205
|
+
console.log(currentDate, closeTime);
|
|
1206
|
+
if (currentDate.getTime() > closeTime.getTime()) {
|
|
1207
|
+
// draw DayEnd(start) dash line
|
|
1208
|
+
var dayStart = new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z')
|
|
1209
|
+
x = Math.round(parseInt(m_chartCss['margin-left']) + ((currentDate.getTime() - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel) - offset);
|
|
1210
|
+
drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) }); // dash?
|
|
1211
|
+
|
|
1212
|
+
|
|
1213
|
+
closeTime = new Date(closeTime.getTime() + 86400000);
|
|
1214
|
+
workDate = new Date(workDate.getTime() + 86400000);
|
|
1215
|
+
currentDate = new Date(workDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z');
|
|
1216
|
+
//currentDate = new Date(currentDate.getTime() + currentDate.getTime() % 3600000); // START om full hour (if modulo == 0 then + 3600000 kanske)
|
|
1217
|
+
if (currentDate.getTime() % 3600000 != 0) // if not full hour, move up to next full hour
|
|
1218
|
+
currentDate = new Date(currentDate.getTime() - currentDate.getTime() % 3600000 + 3600000); // START om full hour (if modulo == 0 then + 3600000 kanske)
|
|
1219
|
+
offset += (86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel;
|
|
1220
|
+
console.log('CLOSED', currentDate, closeTime);
|
|
1221
|
+
continue;
|
|
1222
|
+
}
|
|
1223
|
+
console.log(currentDate, closeTime);
|
|
1224
|
+
x = Math.round(parseInt(m_chartCss['margin-left']) + ((currentDate.getTime() - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel) - offset);
|
|
1225
|
+
for (var i = 0; i < legendItems.length; i++) {
|
|
1226
|
+
console.log('loop', x, legendItems[i].x);
|
|
1227
|
+
if (x < legendItems[i].x && x + (getMaxTimeWidth() / 2) > (legendItems[i].x - getMaxTimeWidth())) {
|
|
1228
|
+
draw = false;
|
|
1229
|
+
console.log('False1');
|
|
1230
|
+
break;
|
|
1231
|
+
}
|
|
1232
|
+
if (x > legendItems[i].x && legendItems[i].x + (getMaxTimeWidth() / 2) > (x - getMaxTimeWidth())) {
|
|
1233
|
+
draw = false;
|
|
1234
|
+
console.log('False2');
|
|
1235
|
+
break;
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
console.log(x, lastx, offset);
|
|
1239
|
+
if (lastx + (getMaxTimeWidth() / 2) > (x - getMaxTimeWidth())) {
|
|
1240
|
+
//draw = false;
|
|
1241
|
+
console.log('false');
|
|
1242
|
+
}
|
|
1243
|
+
if (draw) {
|
|
1244
|
+
lastx = x;
|
|
1245
|
+
var text = formatChartTime(currentDate.toTimeString().substring(0, 8), _this.settings.timeformat);
|
|
1246
|
+
// if day change and setting print on top as well
|
|
1247
|
+
if (_this.scaleinfoX.lineLength + parseInt(m_chartCss['margin-left']) > x - getMaxTimeWidth()) { // not to far right?
|
|
1248
|
+
m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 10);
|
|
1249
|
+
legendItems.push({ x: x, type: 0 });
|
|
1250
|
+
}
|
|
1251
|
+
drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) });
|
|
1252
|
+
}
|
|
1253
|
+
currentDate = new Date(currentDate.getTime() + interval);
|
|
1254
|
+
//currentDate = new Date(currentDate.getTime() + 3600000);
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
// vad är detta?
|
|
1258
|
+
if (typeof m_chartCss['box-shadow'] !== 'undefined') {
|
|
1259
|
+
var boxshadow = m_chartCss['box-shadow'].split(' ');
|
|
1260
|
+
if (parseInt(boxshadow[1]) == 0) drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) }, false);
|
|
1261
|
+
|
|
1262
|
+
} else
|
|
1263
|
+
drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) }, false);
|
|
1264
|
+
m_ctx.restore();
|
|
1265
|
+
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
function drawXAxisTickBra(starttime, endtime) {
|
|
1269
|
+
m_ctx.save();
|
|
1270
|
+
m_ctx.font = m_xLegendCss['font-weight'] + ' ' + m_xLegendCss['font-size'] + ' ' + m_xLegendCss['font-family'];
|
|
1271
|
+
|
|
1272
|
+
m_ctx.strokeStyle = m_gridHorizontalCss.color;
|
|
1273
|
+
m_ctx.fillStyle = m_xLegendCss.color;
|
|
1274
|
+
m_ctx.textAlign = "left";
|
|
1275
|
+
calcXScaleTick(starttime, endtime);
|
|
1276
|
+
if (_this.settings.drawxaxis != 0) { // draw line for legend
|
|
1277
|
+
m_ctx.beginPath();
|
|
1278
|
+
m_ctx.moveTo(parseInt(m_chartCss['margin-left']), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 0.5);
|
|
1279
|
+
m_ctx.lineTo(m_canvas.width - parseInt(m_chartCss['margin-right']), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 0.5);
|
|
1280
|
+
m_ctx.stroke();
|
|
1281
|
+
m_ctx.closePath();
|
|
1282
|
+
}
|
|
1283
|
+
// if(startime.date == endtime.date && starttime > open || endtime < close ) // no date
|
|
1284
|
+
|
|
1285
|
+
var currentDate = new Date(starttime);
|
|
1286
|
+
console.log('startdate', currentDate);
|
|
1287
|
+
var x;
|
|
1288
|
+
var lastx = 0;
|
|
1289
|
+
var draw = true;
|
|
1290
|
+
var offset = 0;
|
|
1291
|
+
var legendItems = [];
|
|
1292
|
+
// add days (daychanges)
|
|
1293
|
+
currentDate = new Date(currentDate.getTime() + currentDate.getTime() % 3600000); // START om full hour (if modulo == 0 then + 3600000 kanske)
|
|
1294
|
+
console.log(currentDate);
|
|
1295
|
+
while (currentDate.getTime() < _this.scaleinfoX.endTimeStamp) {
|
|
1296
|
+
draw = true;
|
|
1297
|
+
while (currentDate.getDay() == 0 || currentDate.getDay() == 6) { // move past weekends , maybe skip this if date is available in data
|
|
1298
|
+
// console.log('Helg', currentDate);
|
|
1299
|
+
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
1300
|
+
offset += 86400000 / _this.scaleinfoX.timePerPixel;
|
|
1301
|
+
}
|
|
1302
|
+
//currentDate = new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z');
|
|
1303
|
+
x = Math.round(parseInt(m_chartCss['margin-left']) + ((currentDate.getTime() - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel) - offset);
|
|
1304
|
+
if (lastx != 0 && lastx + (getMaxTimeWidth() / 2) > (x - getMaxTimeWidth())) {
|
|
1305
|
+
draw = false;
|
|
1306
|
+
}
|
|
1307
|
+
if (draw) {
|
|
1308
|
+
lastx = x;
|
|
1309
|
+
x += 0.5;
|
|
1310
|
+
var text = formatChartTime(currentDate.toTimeString().substring(0, 8), _this.settings.timeformat);
|
|
1311
|
+
// if day change and setting print on top as well
|
|
1312
|
+
if (_this.scaleinfoX.lineLength + parseInt(m_chartCss['margin-left']) > x - getMaxTimeWidth()) { // not to far right?
|
|
1313
|
+
m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 10);
|
|
1314
|
+
legendItems.push({ x: x, type: 0, text: text });
|
|
1315
|
+
}
|
|
1316
|
+
drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) }); // dash?
|
|
1317
|
+
}
|
|
1318
|
+
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
1319
|
+
offset += (86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel;
|
|
1320
|
+
}
|
|
1321
|
+
var currentDate = new Date(starttime);
|
|
1322
|
+
console.log(currentDate);
|
|
1323
|
+
currentDate = new Date(currentDate.getTime() + currentDate.getTime() % 3600000); // START om full hour (if modulo == 0 then + 3600000 kanske)
|
|
1324
|
+
|
|
1325
|
+
var maxHourLegends;
|
|
1326
|
+
console.log(legendItems);
|
|
1327
|
+
if (legendItems.length == 0)
|
|
1328
|
+
maxHourLegends = Math.floor((_this.scaleinfoX.lineLength - parseInt(m_chartCss['margin-left']) - getMaxTimeWidth()) / (getMaxTimeWidth() * 3));
|
|
1329
|
+
else
|
|
1330
|
+
if (legendItems.length == 1)
|
|
1331
|
+
maxHourLegends = Math.floor((_this.scaleinfoX.lineLength - legendItems[0].x - getMaxTimeWidth()) / (getMaxTimeWidth() * 3));
|
|
1332
|
+
else
|
|
1333
|
+
maxHourLegends = Math.floor((legendItems[1].x - legendItems[0].x - getMaxTimeWidth()) / (getMaxTimeWidth() * 3));
|
|
1334
|
+
var tickSize = new Date(new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z') - new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z'));
|
|
1335
|
+
var tickSize = tickSize.getTime() / 3600000;
|
|
1336
|
+
var interval = Math.floor(tickSize / (maxHourLegends + 1)) * 3600000;
|
|
1337
|
+
|
|
1338
|
+
// print other times
|
|
1339
|
+
offset = 0;
|
|
1340
|
+
lastx = 0;
|
|
1341
|
+
var closeTime = new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
|
|
1342
|
+
var workDate = new Date(currentDate);
|
|
1343
|
+
console.log('workdate', workDate);
|
|
1344
|
+
while (currentDate.getTime() < _this.scaleinfoX.endTimeStamp) {
|
|
1345
|
+
console.log('workdate', workDate);
|
|
1346
|
+
draw = true;
|
|
1347
|
+
while (currentDate.getDay() == 0 || currentDate.getDay() == 6) { // move past weekends , maybe skip this if date is available in data
|
|
1348
|
+
console.log('Helg', currentDate);
|
|
1349
|
+
closeTime = new Date(closeTime.getTime() + 86400000);
|
|
1350
|
+
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
1351
|
+
currentDate = new Date(currentDate.getTime() + currentDate.getTime() % 3600000); // START om full hour (if modulo == 0 then + 3600000 kanske)
|
|
1352
|
+
var workDate = new Date(workDate.getTime() + 86400000);
|
|
1353
|
+
offset += 86400000 / _this.scaleinfoX.timePerPixel;
|
|
1354
|
+
}
|
|
1355
|
+
console.log(currentDate, closeTime);
|
|
1356
|
+
if (currentDate.getTime() > closeTime.getTime()) {
|
|
1357
|
+
closeTime = new Date(closeTime.getTime() + 86400000);
|
|
1358
|
+
workDate = new Date(workDate.getTime() + 86400000);
|
|
1359
|
+
currentDate = new Date(workDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z');
|
|
1360
|
+
currentDate = new Date(currentDate.getTime() + currentDate.getTime() % 3600000); // START om full hour (if modulo == 0 then + 3600000 kanske)
|
|
1361
|
+
offset += (86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel;
|
|
1362
|
+
console.log('CLOSED', currentDate, closeTime);
|
|
1363
|
+
continue;
|
|
1364
|
+
}
|
|
1365
|
+
console.log(currentDate, closeTime);
|
|
1366
|
+
x = Math.round(parseInt(m_chartCss['margin-left']) + ((currentDate.getTime() - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel) - offset);
|
|
1367
|
+
for (var i = 0; i < legendItems.length; i++) {
|
|
1368
|
+
console.log('loop', x, legendItems[i].x);
|
|
1369
|
+
if (x < legendItems[i].x && x + (getMaxTimeWidth() / 2) > (legendItems[i].x - getMaxTimeWidth())) {
|
|
1370
|
+
draw = false;
|
|
1371
|
+
console.log('False1');
|
|
1372
|
+
break;
|
|
1373
|
+
}
|
|
1374
|
+
if (x > legendItems[i].x && legendItems[i].x + (getMaxTimeWidth() / 2) > (x - getMaxTimeWidth())) {
|
|
1375
|
+
draw = false;
|
|
1376
|
+
console.log('False2');
|
|
1377
|
+
break;
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
console.log(x, lastx, offset);
|
|
1381
|
+
if (lastx + (getMaxTimeWidth() / 2) > (x - getMaxTimeWidth())) {
|
|
1382
|
+
//draw = false;
|
|
1383
|
+
console.log('false');
|
|
1384
|
+
}
|
|
1385
|
+
if (draw) {
|
|
1386
|
+
lastx = x;
|
|
1387
|
+
var text = formatChartTime(currentDate.toTimeString().substring(0, 8), _this.settings.timeformat);
|
|
1388
|
+
// if day change and setting print on top as well
|
|
1389
|
+
if (_this.scaleinfoX.lineLength + parseInt(m_chartCss['margin-left']) > x - getMaxTimeWidth()) { // not to far right?
|
|
1390
|
+
m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 10);
|
|
1391
|
+
legendItems.push({ x: x, type: 0 });
|
|
1392
|
+
}
|
|
1393
|
+
drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) });
|
|
1394
|
+
}
|
|
1395
|
+
currentDate = new Date(currentDate.getTime() + interval);
|
|
1396
|
+
//currentDate = new Date(currentDate.getTime() + 3600000);
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
// vad är detta?
|
|
1400
|
+
if (typeof m_chartCss['box-shadow'] !== 'undefined') {
|
|
1401
|
+
var boxshadow = m_chartCss['box-shadow'].split(' ');
|
|
1402
|
+
if (parseInt(boxshadow[1]) == 0) drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) }, false);
|
|
1403
|
+
|
|
1404
|
+
} else
|
|
1405
|
+
drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) }, false);
|
|
1406
|
+
m_ctx.restore();
|
|
1407
|
+
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
function drawXAxisTickTest(starttime, endtime) {
|
|
1411
|
+
m_ctx.save();
|
|
1412
|
+
m_ctx.font = m_xLegendCss['font-weight'] + ' ' + m_xLegendCss['font-size'] + ' ' + m_xLegendCss['font-family'];
|
|
1413
|
+
|
|
1414
|
+
m_ctx.strokeStyle = m_gridHorizontalCss.color;
|
|
1415
|
+
m_ctx.fillStyle = m_xLegendCss.color;
|
|
1416
|
+
m_ctx.textAlign = "left";
|
|
1417
|
+
calcXScaleTick(starttime, endtime);
|
|
1418
|
+
if (_this.settings.drawxaxis != 0) { // draw line for legend
|
|
1419
|
+
m_ctx.beginPath();
|
|
1420
|
+
m_ctx.moveTo(parseInt(m_chartCss['margin-left']), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 0.5);
|
|
1421
|
+
m_ctx.lineTo(m_canvas.width - parseInt(m_chartCss['margin-right']), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 0.5);
|
|
1422
|
+
m_ctx.stroke();
|
|
1423
|
+
m_ctx.closePath();
|
|
1424
|
+
}
|
|
1425
|
+
// if(startime.date == endtime.date && starttime > open || endtime < close ) // no date
|
|
1426
|
+
|
|
1427
|
+
var currentDate = new Date(starttime);
|
|
1428
|
+
console.log('startdate', currentDate);
|
|
1429
|
+
var x;
|
|
1430
|
+
var lastx = 0;
|
|
1431
|
+
var draw = true;
|
|
1432
|
+
var offset = 0;
|
|
1433
|
+
var legendItems = [];
|
|
1434
|
+
// add days (daychanges)
|
|
1435
|
+
while (currentDate.getTime() < _this.scaleinfoX.endTimeStamp) {
|
|
1436
|
+
draw = true;
|
|
1437
|
+
while (currentDate.getDay() == 0 || currentDate.getDay() == 6) { // move past weekends , maybe skip this if date is available in data
|
|
1438
|
+
console.log('Helg', currentDate);
|
|
1439
|
+
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
1440
|
+
offset += 86400000 / _this.scaleinfoX.timePerPixel;
|
|
1441
|
+
}
|
|
1442
|
+
var closeTime = new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z');
|
|
1443
|
+
if (currentDate.getTime() > closeTime.getTime()) {
|
|
1444
|
+
currentDate = new Date(currentDate.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z');
|
|
1445
|
+
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
1446
|
+
// offset += 86400000 / _this.scaleinfoX.timePerPixel;
|
|
1447
|
+
offset += (86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel;
|
|
1448
|
+
console.log('STÄNGT', currentDate);
|
|
1449
|
+
continue;
|
|
1450
|
+
}
|
|
1451
|
+
console.log(currentDate);
|
|
1452
|
+
x = Math.round(parseInt(m_chartCss['margin-left']) + ((currentDate.getTime() - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel) - offset);
|
|
1453
|
+
/*if (lastx == 0 && parseInt(m_chartCss['margin-left']) > (x - (getMaxTimeWidth() / 2))) { // do not print left of y legend
|
|
1454
|
+
console.log('ftst', currentDate);
|
|
1455
|
+
currentDate = new Date(currentDate.getTime() + 86400000);
|
|
1456
|
+
continue;
|
|
1457
|
+
}*/
|
|
1458
|
+
console.log(x, lastx, offset);
|
|
1459
|
+
if (lastx + (getMaxDateWidth() / 2) > (x - getMaxDateWidth())) {
|
|
1460
|
+
draw = false;
|
|
1461
|
+
console.log('false');
|
|
1462
|
+
}
|
|
1463
|
+
if (draw) {
|
|
1464
|
+
lastx = x;
|
|
1465
|
+
var text = formatChartTime(currentDate.toTimeString().substring(0, 8), _this.settings.timeformat);
|
|
1466
|
+
// if day change and setting print on top as well
|
|
1467
|
+
if (_this.scaleinfoX.lineLength + parseInt(m_chartCss['margin-left']) > x - getMaxDateWidth()) // not to far right?
|
|
1468
|
+
m_ctx.fillText(text, x - (m_ctx.measureText(text).width / 2), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 10);
|
|
1469
|
+
drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) });
|
|
1470
|
+
}
|
|
1471
|
+
//currentDate = new Date(currentDate.getTime() + 86400000);
|
|
1472
|
+
currentDate = new Date(currentDate.getTime() + _this.scaleinfoX.ticksize);
|
|
1473
|
+
}
|
|
1474
|
+
// vad är detta?
|
|
1475
|
+
if (typeof m_chartCss['box-shadow'] !== 'undefined') {
|
|
1476
|
+
var boxshadow = m_chartCss['box-shadow'].split(' ');
|
|
1477
|
+
if (parseInt(boxshadow[1]) == 0) drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) }, false);
|
|
1478
|
+
|
|
1479
|
+
} else
|
|
1480
|
+
drawXAxisGridlines({ 'x': x, y: m_canvas.height - parseInt(m_chartCss['margin-bottom']) }, false);
|
|
1481
|
+
m_ctx.restore();
|
|
1482
|
+
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1485
|
+
function drawXAxisTick2(starttime, endtime) {
|
|
1057
1486
|
// day and month axis
|
|
1058
1487
|
m_ctx.save();
|
|
1059
1488
|
m_ctx.font = m_xLegendCss['font-weight'] + ' ' + m_xLegendCss['font-size'] + ' ' + m_xLegendCss['font-family'];
|
|
@@ -1086,7 +1515,6 @@ function Milli_Chart(settings) {
|
|
|
1086
1515
|
while (p.x < (_this.scaleinfoX.lineLength + parseInt(m_chartCss['margin-left']) - (_this.scaleinfoX.itemwidth / 2))) { // && oldx != p.x) {
|
|
1087
1516
|
var dayChange = false;
|
|
1088
1517
|
if (currentDate.getTime() > endtime) {
|
|
1089
|
-
//console.log('larget than endtime', currentDate, new Date(endtime));
|
|
1090
1518
|
break;
|
|
1091
1519
|
}
|
|
1092
1520
|
oldx = p.x;
|
|
@@ -1118,16 +1546,7 @@ function Milli_Chart(settings) {
|
|
|
1118
1546
|
}
|
|
1119
1547
|
//console.log(currentDate, _this.scaleinfoX.endDate);
|
|
1120
1548
|
if (currentDate.getTime() > _this.scaleinfoX.endDate.getTime()) {
|
|
1121
|
-
//console.log('break out', currentDate, _this.scaleinfoX.endDate);
|
|
1122
|
-
// draw the last item on the scale (ie closetime for trades)
|
|
1123
1549
|
break;
|
|
1124
|
-
/*if (p.x < m_canvas.width - m_ctx.measureText(datum).width) {
|
|
1125
|
-
//console.log('3', datum, 'Kolla om den är för nära den innan också');
|
|
1126
|
-
m_ctx.fillText(datum, p.x - (m_ctx.measureText(datum).width / 2), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 10);
|
|
1127
|
-
}
|
|
1128
|
-
drawXAxisGridlines(p, dash);
|
|
1129
|
-
//console.log('breaking out', currentDate.getTime(), _this.scaleinfoX.endDate.getTime());
|
|
1130
|
-
break;*/
|
|
1131
1550
|
}
|
|
1132
1551
|
offset += (86400000 - _this.scaleinfoX.milliPerDay) / _this.scaleinfoX.timePerPixel;
|
|
1133
1552
|
lastDate = new Date(currentDate);
|
|
@@ -1136,8 +1555,9 @@ function Milli_Chart(settings) {
|
|
|
1136
1555
|
}
|
|
1137
1556
|
var fontMetrix;
|
|
1138
1557
|
var nextx = Math.round(parseInt(m_chartCss['margin-left']) + ((currentDate.getTime() - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel) - offset);
|
|
1139
|
-
//
|
|
1140
|
-
|
|
1558
|
+
//if ((nextx - p.x < Math.floor(_this.scaleinfoX.itemwidth)) && new Date(currentDate.getTime() + _this.scaleinfoX.ticksize).getDate() != drawDate.getDate()) { // skriv bara ut om utrymmet får plats innan nästa punkt kommer skrivas (dagbrytningar)
|
|
1559
|
+
console.log(nextx, p.x, currentDate);
|
|
1560
|
+
if ((nextx - p.x < m_ctx.measureText('88:88').width) && new Date(currentDate.getTime() + _this.scaleinfoX.ticksize).getDate() != drawDate.getDate()) { // skriv bara ut om utrymmet får plats innan nästa punkt kommer skrivas (dagbrytningar)
|
|
1141
1561
|
//console.log('1', datum, 'Skall nog skrivas ut men för nära sista....',nextx,_this.scaleinfoX.lineLength + parseInt(m_chartCss['margin-left']) - (_this.scaleinfoX.itemwidth / 1));
|
|
1142
1562
|
if (nextx < _this.scaleinfoX.lineLength + parseInt(m_chartCss['margin-left']) - (_this.scaleinfoX.itemwidth / 1)) { // is it too close to next?
|
|
1143
1563
|
//console.log('HIDE');
|
|
@@ -1191,7 +1611,8 @@ function Milli_Chart(settings) {
|
|
|
1191
1611
|
drawXAxisGridlines(p, p.x == parseInt(m_chartCss['margin-left']) ? false : dash);
|
|
1192
1612
|
}
|
|
1193
1613
|
lastDrawX = p.x;
|
|
1194
|
-
}
|
|
1614
|
+
}
|
|
1615
|
+
//else
|
|
1195
1616
|
if (p.x < m_canvas.width - m_ctx.measureText(datum).width) { // if text will be cropped do not print
|
|
1196
1617
|
m_ctx.fillText(datum, p.x - (m_ctx.measureText(datum).width / 2), m_canvas.height - parseInt(m_chartCss['margin-bottom']) + 10);
|
|
1197
1618
|
if (drawGridline) {
|
|
@@ -1305,6 +1726,7 @@ function Milli_Chart(settings) {
|
|
|
1305
1726
|
m_toolTip.dateDiv.innerHTML += ':' + zeroPad(d.getMinutes(), 2);
|
|
1306
1727
|
m_toolTip.dateDiv.innerHTML += ':' + zeroPad(d.getSeconds(), 2);
|
|
1307
1728
|
}
|
|
1729
|
+
m_toolTip.dateDiv.innerHTML += 'X:' + x;
|
|
1308
1730
|
m_toolTip.dateDiv.setAttribute('class', 'millistream-chart-tooltip'); // set class so we can measure it might change below depending on position
|
|
1309
1731
|
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
|
|
1310
1732
|
|
|
@@ -1406,7 +1828,7 @@ function Milli_Chart(settings) {
|
|
|
1406
1828
|
m_toolTip.arrowDiv[k].style.position = 'absolute';
|
|
1407
1829
|
color = m_instrumentCss[k].color;
|
|
1408
1830
|
m_toolTip.arrowDiv[k].style.backgroundColor = color;
|
|
1409
|
-
m_toolTip.arrowDiv[k].style.
|
|
1831
|
+
m_toolTip.arrowDiv[k].style.pointerEvents = 'none';
|
|
1410
1832
|
}
|
|
1411
1833
|
if (posy > highy) highy = posy;
|
|
1412
1834
|
if (posy < lowy) lowy = posy;
|
|
@@ -1849,6 +2271,7 @@ function Milli_Chart(settings) {
|
|
|
1849
2271
|
m_resizeing = false;
|
|
1850
2272
|
m_canvas.setAttribute('height', _this.settings.target.offsetHeight + 'px');
|
|
1851
2273
|
m_canvas.setAttribute('width', _this.settings.target.offsetWidth + 'px'); // läs från css?
|
|
2274
|
+
console.log('Width:', _this.settings.target.offsetWidth);
|
|
1852
2275
|
_this.drawChart();
|
|
1853
2276
|
};
|
|
1854
2277
|
|
|
@@ -2016,8 +2439,11 @@ function Milli_Chart(settings) {
|
|
|
2016
2439
|
//console.log(startpoint.x);
|
|
2017
2440
|
|
|
2018
2441
|
// TODO: här blir det fel när det är från 00:00: 23:59 men göms av tmpx < startpoint.x
|
|
2019
|
-
if (_this.scaleinfoY.type == 'trades' && tmpx < startpoint.x)
|
|
2442
|
+
if (_this.scaleinfoY.type == 'trades' && tmpx < startpoint.x) {
|
|
2020
2443
|
m_ctx.lineTo(startpoint.x, startpoint.y);
|
|
2444
|
+
}
|
|
2445
|
+
|
|
2446
|
+
//m_ctx.lineTo(startpoint.x, startpoint.y);
|
|
2021
2447
|
|
|
2022
2448
|
}
|
|
2023
2449
|
//p.x = Math.round(parseInt(m_chartCss['margin-left']) + ((currentDate.getTime() - _this.scaleinfoX.startDate.getTime()) / _this.scaleinfoX.timePerPixel) - offset); // from drawXaxis
|
|
@@ -2045,6 +2471,8 @@ function Milli_Chart(settings) {
|
|
|
2045
2471
|
if (tmpx < startpoint.x) {
|
|
2046
2472
|
if (_this.settings.hcurve) m_ctx.lineTo(startpoint.x, endpoint.y);
|
|
2047
2473
|
m_ctx.lineTo(startpoint.x, startpoint.y);
|
|
2474
|
+
//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"
|
|
2475
|
+
|
|
2048
2476
|
if (instrument == 0) {
|
|
2049
2477
|
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) };
|
|
2050
2478
|
if (typeof data[i].dividend !== 'undefined') point.dividend = data[i].dividend;
|
|
@@ -2270,12 +2698,9 @@ function Milli_Chart(settings) {
|
|
|
2270
2698
|
}
|
|
2271
2699
|
//console.log('onmouseup', m_zoom.mousedown.timestamp, m_zoom.mouseup.timestamp)
|
|
2272
2700
|
}
|
|
2273
|
-
//m_zoom.mousedown.timestamp = null;
|
|
2274
|
-
//m_zoom.mouseup.timestamp = null;
|
|
2275
2701
|
if (m_zoom.div) m_canvas.parentNode.removeChild(m_zoom.div);
|
|
2276
2702
|
m_zoom.div = null;
|
|
2277
2703
|
m_zoom.isZooming = false;
|
|
2278
|
-
//console.log('CLEAR');
|
|
2279
2704
|
});
|
|
2280
2705
|
} else {
|
|
2281
2706
|
//m_ctx.clearRect(0, 0, m_canvas.width, m_canvas.height);
|
|
@@ -2534,7 +2959,6 @@ function Milli_Chart(settings) {
|
|
|
2534
2959
|
});
|
|
2535
2960
|
|
|
2536
2961
|
}
|
|
2537
|
-
|
|
2538
2962
|
var milli_data_api_url = 'https://stage.millistream.com/widgets/3.0.3/data/milli_widget_dataapi.php?';
|
|
2539
2963
|
|
|
2540
2964
|
var millistream_data_api = {
|
|
@@ -4708,7 +5132,6 @@ var MillistreamWidgetSettings = {
|
|
|
4708
5132
|
thousandseparator: ' ',
|
|
4709
5133
|
streaming: false
|
|
4710
5134
|
};
|
|
4711
|
-
|
|
4712
5135
|
function MillistreamWidgetStreamingApi(settings) {
|
|
4713
5136
|
var _this = this;
|
|
4714
5137
|
_this.settings = {
|
|
@@ -5108,4 +5531,5 @@ function MillistreamWidgetStreamingApi(settings) {
|
|
|
5108
5531
|
milli_stream_connect();
|
|
5109
5532
|
}
|
|
5110
5533
|
exports.Milli_Chart = Milli_Chart;
|
|
5534
|
+
exports.MillistreamWidgetSettings = MillistreamWidgetSettings;
|
|
5111
5535
|
exports.MillistreamWidgetStreamingApi = MillistreamWidgetStreamingApi;
|