UNPKG

8.34 kBJavaScriptView Raw
1"use strict";
2var __extends = (this && this.__extends) || (function () {
3 var extendStatics = Object.setPrototypeOf ||
4 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
6 return function (d, b) {
7 extendStatics(d, b);
8 function __() { this.constructor = d; }
9 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
10 };
11})();
12var __assign = (this && this.__assign) || Object.assign || function(t) {
13 for (var s, i = 1, n = arguments.length; i < n; i++) {
14 s = arguments[i];
15 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
16 t[p] = s[p];
17 }
18 return t;
19};
20Object.defineProperty(exports, "__esModule", { value: true });
21var React = require("react");
22var d3array = require("d3-array");
23var d3scale = require("d3-scale");
24var d3shape = require("d3-shape");
25var _ = require("lodash");
26var moment = require("moment");
27var constants_1 = require("./constants");
28var helpers_1 = require("./helpers");
29var HKGrid_1 = require("./HKGrid");
30var HKLine_1 = require("./HKLine");
31var HKTooltip_1 = require("./HKTooltip");
32var HKLineChartData = /** @class */ (function (_super) {
33 __extends(HKLineChartData, _super);
34 function HKLineChartData(props) {
35 var _this = _super.call(this, props) || this;
36 _this.handleMouseMove = function (e) {
37 var _a = _this.state, measurements = _a.measurements, xScale = _a.xScale;
38 if (!_this.ref) {
39 return null;
40 }
41 // TODO: Optimize rendering performance here
42 var hoverIndex = e.clientX - _this.ref.getBoundingClientRect().left - constants_1.ChartPadding.Horizontal;
43 var bisectX = d3array.bisector(function (d) { return d.x; }).left;
44 var newIdx = bisectX(measurements, xScale.invert(hoverIndex));
45 _this.setState({ idx: newIdx, hoverIndex: hoverIndex });
46 if (measurements[newIdx]) {
47 var values = measurements[newIdx].y; // Remember to figure out empty case
48 _this.props.onHover(values);
49 }
50 };
51 _this.handleMouseLeave = function (e) {
52 var _a = _this.props, onHover = _a.onHover, data = _a.data;
53 _this.setState({ hoverIndex: -1, idx: -1 });
54 onHover(helpers_1.getMaxValues(data));
55 };
56 _this.state = {
57 height: props.height,
58 width: props.width,
59 hoverIndex: -1,
60 idx: -1,
61 /* Initializes in getDerivedStateFromProps**/
62 data: null,
63 measurements: null,
64 area: null,
65 line: null,
66 xScale: null,
67 yScale: null,
68 };
69 return _this;
70 }
71 // setState based on new props passed
72 HKLineChartData.getDerivedStateFromProps = function (newProps, prevState) {
73 if (['data', 'width', 'height'].every(function (o) { return newProps[o] === prevState[o]; })) {
74 return null;
75 }
76 var width = newProps.width, height = newProps.height, data = newProps.data;
77 var chartHeight = height - constants_1.ChartPadding.Vertical;
78 var chartWidth = width - constants_1.ChartPadding.Horizontal;
79 var values = _.flatMap(data.map(function (d) { return d[1]; }));
80 // Cleanse data into valid format(date and values)
81 // Make sure our coordinates are sorted by date asscending
82 var measurements = formatData(data)
83 .sort(function (a, b) { return moment(a.x).diff(moment(b.x)); });
84 // Domain of x coordinates (date)
85 var timeExtent = [
86 _.head(measurements).x,
87 _.last(measurements).x,
88 ];
89 // Domain of y coordinates (value)
90 var valueExtent = d3array.extent(values);
91 var xScale = d3scale.scaleTime()
92 .domain(timeExtent)
93 .range([0, chartWidth]);
94 var yScale = d3scale.scaleLinear()
95 .domain([Math.min(valueExtent[0], 0), valueExtent[1]])
96 .range([chartHeight, 0]);
97 var line = d3shape.line()
98 .x(function (d) { return xScale(d.x); })
99 .y(function (d) { return yScale(d.y); })
100 .curve(d3shape.curveStepBefore);
101 var area = d3shape.area()
102 .x(function (d) { return xScale(d.x); })
103 .y0(yScale(valueExtent[0] < 0 ? yScale(valueExtent) : 0))
104 .y1(function (d) { return yScale(d.y); })
105 .curve(d3shape.curveStepBefore);
106 return {
107 data: data,
108 measurements: measurements,
109 height: height,
110 width: width,
111 area: area,
112 line: line,
113 xScale: xScale,
114 yScale: yScale,
115 };
116 };
117 HKLineChartData.prototype.render = function () {
118 var _this = this;
119 var _a = this.state, height = _a.height, width = _a.width, xScale = _a.xScale, yScale = _a.yScale, line = _a.line, area = _a.area, measurements = _a.measurements, idx = _a.idx, hoverIndex = _a.hoverIndex;
120 var _b = this.props, toggleInfo = _b.toggleInfo, labels = _b.labels;
121 var isHovering = hoverIndex > 0; // we only want to hover if onMouseMove is on the chart (exclude axis)
122 var hoverPos = hoverIndex + constants_1.ChartPadding.Horizontal; // hover positioning taking into account padding from axis
123 var valueIndexes = [];
124 labels.forEach(function (label, i) {
125 if (toggleInfo[label + "-" + i]) {
126 valueIndexes.push(i);
127 }
128 });
129 var timeseries = valueIndexes.map(function (i) {
130 var lineProps = {
131 area: area,
132 data: measurements.map(function (m) { return ({
133 x: m.x,
134 y: m.y[i],
135 }); }),
136 line: line,
137 };
138 return React.createElement(HKLine_1.default, __assign({ key: i }, lineProps));
139 });
140 var indicatorPoints = valueIndexes.map(function (v) {
141 // check if y-values exist and check if specific line is toggled on
142 return measurements[idx] && Object.keys(toggleInfo).map(function (key) { return toggleInfo[key]; })[v]
143 ? (React.createElement("circle", { key: v, className: 'indicatorPoints', cx: hoverIndex + constants_1.ChartPadding.Horizontal, cy: yScale(measurements[idx].y[v]) + constants_1.ChartPadding.Vertical, r: 2 })) : null;
144 });
145 var timeStamp = moment(xScale.invert(hoverIndex)).format('llll');
146 var indicator = isHovering && (React.createElement("g", null,
147 React.createElement("line", { x1: hoverPos, y1: '0', x2: hoverPos, y2: height, stroke: '#79589f', strokeWidth: '1' }),
148 indicatorPoints));
149 return (React.createElement("div", null,
150 isHovering && (React.createElement(HKTooltip_1.default, { xPos: hoverPos, yPos: height / 3, children: "" + timeStamp })),
151 React.createElement("svg", { preserveAspectRatio: 'none', width: width, height: height, viewBox: "0 0 " + width + " " + height, onMouseMove: this.handleMouseMove, onMouseLeave: this.handleMouseLeave, ref: function (ref) { return _this.ref = ref; } },
152 indicator,
153 React.createElement("g", { transform: "translate(" + constants_1.ChartPadding.Horizontal + ", 0)" },
154 React.createElement(HKGrid_1.default, { type: 'line', height: height, width: width, xScale: xScale, yScale: yScale }),
155 React.createElement("rect", { x: '0', y: '0', width: width - constants_1.ChartPadding.Horizontal, height: height, className: 'br0 ba b--silver z-1', fill: 'none', stroke: 'silver' }),
156 React.createElement("g", { transform: "translate(0, " + constants_1.ChartPadding.Vertical + ")" }, timeseries)))));
157 };
158 return HKLineChartData;
159}(React.PureComponent));
160exports.default = HKLineChartData;
161function formatData(dataSet) {
162 if (!dataSet) {
163 return null;
164 }
165 return dataSet.map(function (d) { return ({
166 x: moment.utc(d[0]).toDate(),
167 y: d[1].map(function (v) { return _.isFinite(v) ? v : 0; }),
168 }); });
169}
170//# sourceMappingURL=HKLineChartData.js.map
\No newline at end of file