@axdspub/axiom-charts 0.0.10 → 0.0.12

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,5 +1,5 @@
1
1
  import { RequestItem } from '@axdspub/axiom-ui-data-services';
2
- import { extent, sum } from 'd3-array';
2
+ import { extent, bisectCenter, sum } from 'd3-array';
3
3
  import { groupBy, debounce } from 'lodash';
4
4
  import { create } from 'd3-selection';
5
5
  import { scaleUtc, scaleLinear, scaleRadial } from 'd3-scale';
@@ -123,6 +123,7 @@ var PlotRoot = /** @class */ (function (_super) {
123
123
  _this.chart = props.chart;
124
124
  _this.dimensions = props.dimensions;
125
125
  _this.style = props.style;
126
+ _this.scrubbing = props.scrubbing;
126
127
  _this.axisSettings = props.axisSettings;
127
128
  _this.runtime = {};
128
129
  return _this;
@@ -249,6 +250,13 @@ var PlotRoot = /** @class */ (function (_super) {
249
250
  });
250
251
  });
251
252
  };
253
+ PlotRoot.prototype.drawScrubbing = function (mouseX) {
254
+ console.log('drawScrubbing not implemented');
255
+ };
256
+ PlotRoot.prototype.getScrubPosition = function (mouseX) {
257
+ console.log('getScrubPosition not implemented');
258
+ return undefined;
259
+ };
252
260
  PlotRoot.prototype.destroy = function () {
253
261
  };
254
262
  return PlotRoot;
@@ -259,6 +267,7 @@ var ChartRoot = /** @class */ (function () {
259
267
  this.plots = props.plots.map(function (p) { return (__assign({}, p)); });
260
268
  this.settings = props.settings;
261
269
  this.element = props.element;
270
+ this.onScrub = props.onScrub;
262
271
  this.runtime = {
263
272
  prevWidth: 0,
264
273
  prevHeight: 0
@@ -434,7 +443,6 @@ var ChartRoot = /** @class */ (function () {
434
443
  case 1:
435
444
  _a.sent();
436
445
  this.showYAxes(yAxes);
437
- this.showYLabels(yAxes, this.plots);
438
446
  yAxesWidth = this.getYAxesWidth();
439
447
  chartWidth = this.getChartWidth();
440
448
  xRange = this.getXRange(chartWidth);
@@ -492,10 +500,10 @@ var ChartRoot = /** @class */ (function () {
492
500
  };
493
501
  ChartRoot.prototype.showYAxes = function (yAxes) {
494
502
  };
495
- ChartRoot.prototype.showYLabels = function (yAxes, plots) {
496
- };
497
503
  ChartRoot.prototype.showXAxes = function (xAxes) {
498
504
  };
505
+ ChartRoot.prototype.adjustYAxis = function () {
506
+ };
499
507
  ChartRoot.prototype.draw = function () {
500
508
  return __awaiter(this, void 0, void 0, function () {
501
509
  var plotImplementations;
@@ -552,7 +560,9 @@ var AxiomPlotRoot = /** @class */ (function (_super) {
552
560
  var AxiomLine = /** @class */ (function (_super) {
553
561
  __extends(AxiomLine, _super);
554
562
  function AxiomLine() {
555
- return _super !== null && _super.apply(this, arguments) || this;
563
+ var _this = _super !== null && _super.apply(this, arguments) || this;
564
+ _this.addedScrubbingListener = false;
565
+ return _this;
556
566
  }
557
567
  AxiomLine.prototype.getDomainAccessor = function (axis) {
558
568
  var _a, _b, _c;
@@ -567,15 +577,19 @@ var AxiomLine = /** @class */ (function (_super) {
567
577
  AxiomLine.prototype.draw = function () {
568
578
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
569
579
  return __awaiter(this, void 0, void 0, function () {
570
- var style, data, parsedData, xAccessor, yAccessor, chart, ctx, xAxisScale, yAxisScale, offset, xScale, xPosition, yScale, yPosition, isDefined, line$1;
580
+ var style, data, xAccessor, yAccessor, chart, ctx, xAxisScale, yAxisScale, xPosition, yPosition, isDefined, line$1;
581
+ var _this = this;
571
582
  return __generator(this, function (_m) {
572
583
  switch (_m.label) {
573
584
  case 0:
574
585
  style = this.style !== undefined ? this.style : {};
586
+ if (!(this.parsedData === undefined)) return [3 /*break*/, 2];
575
587
  return [4 /*yield*/, this.getData()];
576
588
  case 1:
577
589
  data = _m.sent();
578
- parsedData = (_a = data === null || data === void 0 ? void 0 : data.parsed) === null || _a === void 0 ? void 0 : _a.data;
590
+ this.parsedData = (_a = data === null || data === void 0 ? void 0 : data.parsed) === null || _a === void 0 ? void 0 : _a.data;
591
+ _m.label = 2;
592
+ case 2:
579
593
  xAccessor = this.getAccessorAtAxis('x');
580
594
  yAccessor = this.getAccessorAtAxis('y');
581
595
  chart = this.chart;
@@ -585,33 +599,36 @@ var AxiomLine = /** @class */ (function (_super) {
585
599
  }
586
600
  xAxisScale = (_c = (_b = this === null || this === void 0 ? void 0 : this.axes) === null || _b === void 0 ? void 0 : _b.x) === null || _c === void 0 ? void 0 : _c.scale;
587
601
  yAxisScale = (_e = (_d = this === null || this === void 0 ? void 0 : this.axes) === null || _d === void 0 ? void 0 : _d.y) === null || _e === void 0 ? void 0 : _e.scale;
588
- if (xAxisScale === undefined || yAxisScale === undefined || parsedData === undefined || xAccessor === undefined || yAccessor === undefined) {
602
+ if (xAxisScale === undefined || yAxisScale === undefined || this.parsedData === undefined || xAccessor === undefined || yAccessor === undefined) {
589
603
  return [2 /*return*/, undefined];
590
604
  }
591
- offset = {
605
+ this.offset = {
592
606
  x: ((_h = (_g = (_f = this === null || this === void 0 ? void 0 : this.axes) === null || _f === void 0 ? void 0 : _f.x) === null || _g === void 0 ? void 0 : _g.offset) === null || _h === void 0 ? void 0 : _h.x) !== undefined ? this.axes.x.offset.x : 0,
593
607
  y: ((_l = (_k = (_j = this === null || this === void 0 ? void 0 : this.axes) === null || _j === void 0 ? void 0 : _j.y) === null || _k === void 0 ? void 0 : _k.offset) === null || _l === void 0 ? void 0 : _l.y) !== undefined ? this.axes.y.offset.y : 0
594
608
  };
595
- xScale = chart.getD3XScale(xAxisScale);
609
+ this.xScale = chart.getD3XScale(xAxisScale);
596
610
  xPosition = function (d) {
611
+ if (_this.xScale === undefined || _this.offset === undefined)
612
+ return 0;
597
613
  var v = xAccessor(d);
598
- var p = xScale(v);
599
- return p === undefined ? 0 : (p + offset.x);
614
+ var p = _this.xScale(v);
615
+ return p === undefined ? 0 : (p + _this.offset.x);
600
616
  };
601
- yScale = chart.getD3YScale(yAxisScale);
617
+ this.yScale = chart.getD3YScale(yAxisScale);
602
618
  yPosition = function (d) {
619
+ if (_this.yScale === undefined || _this.offset === undefined)
620
+ return 0;
603
621
  var v = yAccessor(d);
604
- var p = yScale(v);
605
- return p === undefined ? 0 : (p + offset.y);
622
+ var p = _this.yScale(v);
623
+ return p === undefined ? 0 : (p + _this.offset.y);
606
624
  };
607
625
  isDefined = function (d) {
608
626
  var v = yAccessor(d);
609
627
  return !!((v !== undefined && v !== null && !isNaN(+v)));
610
628
  };
611
- // settings?.style?.strokeColor !== undefined ? settings.style.strokeColor :
612
- // settings?.style?.strokeWidth ||
613
- ctx.strokeStyle = style.strokeColor !== undefined ? style.strokeColor : '#333';
614
- ctx.lineWidth = style.strokeWidth !== undefined ? style.strokeWidth : 1;
629
+ ctx.strokeStyle = this.getStrokeStyle();
630
+ ctx.lineWidth = this.getLineWidth();
631
+ ctx.setLineDash([]);
615
632
  line$1 = line()
616
633
  .x(xPosition)
617
634
  .y(yPosition)
@@ -621,13 +638,65 @@ var AxiomLine = /** @class */ (function (_super) {
621
638
  if ((style === null || style === void 0 ? void 0 : style.strokeDash) !== undefined) {
622
639
  ctx.setLineDash(style.strokeDash);
623
640
  }
624
- line$1(parsedData);
641
+ line$1(this.parsedData);
625
642
  ctx.stroke();
626
643
  return [2 /*return*/];
627
644
  }
628
645
  });
629
646
  });
630
647
  };
648
+ AxiomLine.prototype.getScrubPosition = function (mouseX) {
649
+ if (this.xScale === undefined || this.yScale === undefined || this.parsedData === undefined || this.offset === undefined)
650
+ return undefined;
651
+ var newDate = this.xScale.invert(mouseX - this.offset.x);
652
+ var i = bisectCenter(this.parsedData.map(function (row) { return row.time; }), newDate);
653
+ var lineX = this.xScale(this.parsedData[i].time) + this.offset.x;
654
+ var yValue = this.parsedData[i].value;
655
+ var yPx = this.yScale(yValue) + this.offset.y;
656
+ return {
657
+ xPosition: lineX,
658
+ xValue: newDate,
659
+ yPosition: yPx,
660
+ yValue: yValue
661
+ };
662
+ };
663
+ AxiomLine.prototype.drawScrubbing = function (mouseX) {
664
+ var chart = this.chart;
665
+ var ctx = chart.getCanvasContext();
666
+ if (ctx === null) {
667
+ return undefined;
668
+ }
669
+ var scrubPosition = this.getScrubPosition(mouseX);
670
+ if (scrubPosition === undefined)
671
+ return;
672
+ var xPosition = scrubPosition.xPosition, yPosition = scrubPosition.yPosition;
673
+ this.drawScrubCircle(xPosition, yPosition, ctx);
674
+ this.drawScrubLine(xPosition, ctx);
675
+ };
676
+ AxiomLine.prototype.drawScrubCircle = function (x, y, ctx) {
677
+ ctx.beginPath();
678
+ ctx.setLineDash([]);
679
+ ctx.arc(x, y, 6, 0, 2 * Math.PI, true);
680
+ ctx.strokeStyle = this.getStrokeStyle();
681
+ ctx.lineWidth = this.getLineWidth();
682
+ ctx.stroke();
683
+ };
684
+ AxiomLine.prototype.drawScrubLine = function (x, ctx) {
685
+ var lineHeight = this.chart.settings.height - this.chart.settings.margin.bottom;
686
+ ctx.setLineDash([1, 1]);
687
+ ctx.beginPath();
688
+ ctx.moveTo(x, 0);
689
+ ctx.lineTo(x, lineHeight);
690
+ ctx.stroke();
691
+ };
692
+ AxiomLine.prototype.getStrokeStyle = function () {
693
+ var style = this.style !== undefined ? this.style : {};
694
+ return style.strokeColor !== undefined ? style.strokeColor : '#333';
695
+ };
696
+ AxiomLine.prototype.getLineWidth = function () {
697
+ var style = this.style !== undefined ? this.style : {};
698
+ return style.strokeWidth !== undefined ? style.strokeWidth : 1;
699
+ };
631
700
  return AxiomLine;
632
701
  }(AxiomPlotRoot));
633
702
 
@@ -745,6 +814,13 @@ var AxiomArea = /** @class */ (function (_super) {
745
814
  });
746
815
  });
747
816
  };
817
+ AxiomArea.prototype.drawScrubbing = function (mouseX) {
818
+ console.error('AxiomArea.drawScrubbing not implemented');
819
+ };
820
+ AxiomArea.prototype.getScrubPosition = function (mouseX) {
821
+ console.error('AxiomArea.getScrubPosition not implemented');
822
+ return undefined;
823
+ };
748
824
  return AxiomArea;
749
825
  }(AxiomPlotRoot));
750
826
 
@@ -826,6 +902,12 @@ var AxiomScatter = /** @class */ (function (_super) {
826
902
  });
827
903
  });
828
904
  };
905
+ AxiomScatter.prototype.getScrubPosition = function (mouseX) {
906
+ throw new Error('Method not implemented.');
907
+ };
908
+ AxiomScatter.prototype.drawScrubbing = function (mouseX) {
909
+ throw new Error('Method not implemented.');
910
+ };
829
911
  return AxiomScatter;
830
912
  }(AxiomPlotRoot));
831
913
 
@@ -932,6 +1014,22 @@ var AxiomChart = /** @class */ (function (_super) {
932
1014
  };
933
1015
  return axisG;
934
1016
  };
1017
+ AxiomChart.prototype.adjustYAxis = function () {
1018
+ console.log('here');
1019
+ var chartElements = this.getChartElements();
1020
+ if (chartElements === undefined)
1021
+ return;
1022
+ var svg = chartElements.svg, canvas = chartElements.canvas;
1023
+ var node = svg.selectAll('.y-axis').nodes()[0];
1024
+ if (node === null || node === undefined)
1025
+ return;
1026
+ node = node;
1027
+ // const yAxisWidth = node.getBoundingClientRect()
1028
+ console.log(node);
1029
+ svg.selectAll('.y-axis').attr('translate', 'transform(100px, 100px)').attr('width', 100);
1030
+ canvas.attr('width', this.getWidth() - 45.7);
1031
+ canvas.attr('transform', "translate(".concat(45.7, ", 0)"));
1032
+ };
935
1033
  AxiomChart.prototype.showYAxes = function (axes) {
936
1034
  var _this = this;
937
1035
  var chartElements = this.getChartElements();
@@ -947,29 +1045,39 @@ var AxiomChart = /** @class */ (function (_super) {
947
1045
  axisSelection.append('g').call(axisG);
948
1046
  }
949
1047
  });
1048
+ this.showYLabels(axes, this.plots);
950
1049
  };
951
- AxiomChart.prototype.showYLabels = function (axes, plots) {
1050
+ AxiomChart.prototype.getAxisLabel = function (axis, dimensionKey) {
952
1051
  var _a;
953
- if (plots.length > 1) {
954
- return;
955
- }
956
- if (plots[0].type !== EPlotTypes.line) {
1052
+ return (_a = axis.plots[0]) === null || _a === void 0 ? void 0 : _a.dimensions[dimensionKey].label;
1053
+ };
1054
+ AxiomChart.prototype.showYLabels = function (axes, plots) {
1055
+ var _this = this;
1056
+ var yLabelsAreSupportedForPlotType = [EPlotTypes.line, EPlotTypes.scatter, EPlotTypes.seasonal, EPlotTypes.area]
1057
+ .find(function (type) { return type === plots[0].type; }) !== undefined;
1058
+ if (plots.length === 0 || !yLabelsAreSupportedForPlotType) {
957
1059
  return;
958
1060
  }
959
1061
  var chartElements = this.getChartElements();
960
- var label = (_a = axes[0].plots[0].dimensions.y.label) !== null && _a !== void 0 ? _a : '';
961
1062
  if (chartElements === undefined) {
962
- return undefined;
1063
+ return;
963
1064
  }
964
1065
  var svg = chartElements.svg;
965
1066
  var axisSelection = svg.select('.y-axis').size() > 0 ? svg.select('.y-axis') : svg.append('g').attr('class', 'y-axis axis');
966
- axisSelection.append('text')
967
- .attr('class', 'y-label')
968
- .attr('text-anchor', 'end')
969
- .attr('dy', '.75rem')
970
- .attr('font-size', '.75rem')
971
- .attr('transform', 'rotate(-90)')
972
- .text(label);
1067
+ // TODO: Don't hardcode these two vars
1068
+ var axisWidth = 24;
1069
+ var labelMargin = 3;
1070
+ axes.forEach(function (axis) {
1071
+ var _a;
1072
+ axisSelection.append('text')
1073
+ .attr('class', 'y-label')
1074
+ .attr('transform', 'rotate(-90)')
1075
+ .style('text-anchor', 'middle')
1076
+ .attr('x', -1 * Math.floor(_this.getChartHeight() / 2))
1077
+ .attr('y', "".concat(_this.getyAxisOffset(axis).x - axisWidth - labelMargin))
1078
+ .attr('font-size', '.75rem')
1079
+ .text((_a = _this.getAxisLabel(axis, 'y')) !== null && _a !== void 0 ? _a : '');
1080
+ });
973
1081
  };
974
1082
  AxiomChart.prototype.getXAxisOffset = function (axis) {
975
1083
  return __assign({ x: this.settings.margin.left, y: this.settings.height - this.settings.margin.bottom }, axis.offset);
@@ -1070,6 +1178,8 @@ var AxiomChart = /** @class */ (function (_super) {
1070
1178
  this.element.append(canvasNode);
1071
1179
  }
1072
1180
  }
1181
+ // TODO: conditional
1182
+ this.addScrubbing();
1073
1183
  };
1074
1184
  AxiomChart.prototype.createPlot = function (plot) {
1075
1185
  var props = this.getPlotImplementationProps(plot);
@@ -1084,6 +1194,65 @@ var AxiomChart = /** @class */ (function (_super) {
1084
1194
  }
1085
1195
  return new PlotRoot(props);
1086
1196
  };
1197
+ AxiomChart.prototype.clearCanvas = function () {
1198
+ var ctx = this.getCanvasContext();
1199
+ if (ctx !== null) {
1200
+ ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
1201
+ }
1202
+ };
1203
+ AxiomChart.prototype.addScrubbing = function () {
1204
+ var _this = this;
1205
+ var ctx = this.getCanvasContext();
1206
+ if (ctx === null) {
1207
+ return;
1208
+ }
1209
+ ctx.canvas.addEventListener('touchmove', function (event) {
1210
+ var touch = event.touches[0];
1211
+ var touchOffset = 20; // TODO: figure out why touch.clientX is always off to the right
1212
+ _this.onScrubTriggered(touch.clientX - touchOffset);
1213
+ });
1214
+ ctx.canvas.addEventListener('mousemove', function (event) { _this.onScrubTriggered(event.offsetX); });
1215
+ };
1216
+ AxiomChart.prototype.onScrubTriggered = function (cursorX) {
1217
+ var _this = this;
1218
+ if (this.plotImplementations === undefined)
1219
+ return;
1220
+ var plotsWithScrubbingEnabled = this.plotImplementations.filter(function (plot) { var _a; return ((_a = plot.scrubbing) !== null && _a !== void 0 ? _a : false) && plot.type === EPlotTypes.line; });
1221
+ var plotScrubPositions = this.getScrubPositions(cursorX, plotsWithScrubbingEnabled);
1222
+ // console.log(plotScrubPositions)
1223
+ if (this.onScrub !== undefined) {
1224
+ this.onScrub(plotScrubPositions);
1225
+ }
1226
+ this.runtime.busy = true;
1227
+ this.clearCanvas();
1228
+ var drawPromises = this.plotImplementations.map(function (plot) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
1229
+ switch (_a.label) {
1230
+ case 0: return [4 /*yield*/, plot.draw()];
1231
+ case 1:
1232
+ _a.sent();
1233
+ return [2 /*return*/];
1234
+ }
1235
+ }); }); });
1236
+ Promise.all(drawPromises).then(function () {
1237
+ plotsWithScrubbingEnabled.forEach(function (plot) {
1238
+ var position = plotScrubPositions[plot.id];
1239
+ plot.drawScrubbing(position.xPosition);
1240
+ });
1241
+ _this.runtime.busy = false;
1242
+ }).catch(function (error) {
1243
+ console.error(error);
1244
+ });
1245
+ };
1246
+ AxiomChart.prototype.getScrubPositions = function (mouseX, plots) {
1247
+ var plotScrubPositions = {};
1248
+ plots.forEach(function (plot) {
1249
+ var scrubPosition = plot.getScrubPosition(mouseX);
1250
+ if (scrubPosition !== undefined) {
1251
+ plotScrubPositions[plot.id] = scrubPosition;
1252
+ }
1253
+ });
1254
+ return plotScrubPositions;
1255
+ };
1087
1256
  AxiomChart.prototype.init = function (drawImmediately) {
1088
1257
  if (drawImmediately === void 0) { drawImmediately = false; }
1089
1258
  return __awaiter(this, void 0, void 0, function () {
@@ -1311,6 +1480,13 @@ var AxiomRadialArea = /** @class */ (function (_super) {
1311
1480
  });
1312
1481
  });
1313
1482
  };
1483
+ AxiomRadialArea.prototype.drawScrubbing = function (mouseX) {
1484
+ console.error('AxiomRadialArea.drawScrubbing not implemented');
1485
+ };
1486
+ AxiomRadialArea.prototype.getScrubPosition = function (mouseX) {
1487
+ console.error('AxiomRadialArea.getScrubPosition not implemented');
1488
+ return undefined;
1489
+ };
1314
1490
  return AxiomRadialArea;
1315
1491
  }(AxiomArea));
1316
1492