"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports["default"] = void 0;
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _react = _interopRequireDefault(require("react"));
var _d3Scale = require("d3-scale");
var _d3Array = require("d3-array");
var _d3Shape = require("d3-shape");
var _d3Selection = require("d3-selection");
var _d3Ease = require("d3-ease");
var _ChartTooltip = require("./ChartTooltip");
var _constants = require("./constants");
var _SparklineChartSt = require("./SparklineChart.st.css.js");
require("d3-transition");
var _Tooltip = _interopRequireDefault(require("../Tooltip"));
var _Text = _interopRequireDefault(require("../Text"));
var _jsxFileName = "/home/builduser/work/57e038ea7326c1ec/packages/wix-design-system/dist/cjs/SparklineChart/SparklineChart.jsx";
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
var LINE_WIDTH = 2;
var AREA_MASK_ID = 'areaMaskId';
var TOOLTIP_ELEMENT_RADIUS = 4;
var DEFAULT_GRADIENT_ID = 'DEFAULT_GRADIENT_ID';

/** SparklineChart */
var SparklineChart = /*#__PURE__*/function (_React$PureComponent) {
  function SparklineChart(props) {
    var _this;
    (0, _classCallCheck2["default"])(this, SparklineChart);
    _this = _callSuper(this, SparklineChart, [props]);
    _this._shouldShowTooltip = function () {
      var hoveredLabel = _this.state.hoveredLabel;
      var getTooltipContent = _this.props.getTooltipContent;
      return getTooltipContent && typeof getTooltipContent === 'function' && hoveredLabel;
    };
    _this._useCreateContext = function () {
      var halfWidth = LINE_WIDTH / 2;
      var _this$props = _this.props,
        _this$props$width = _this$props.width,
        width = _this$props$width === void 0 ? 200 : _this$props$width,
        _this$props$height = _this$props.height,
        height = _this$props$height === void 0 ? 40 : _this$props$height,
        data = _this$props.data,
        _this$props$highlight = _this$props.highlightedStartingIndex,
        highlightedStartingIndex = _this$props$highlight === void 0 ? 0 : _this$props$highlight,
        color = _this$props.color;
      var _this$props$highlight2 = _this.props.highlightedEndingIndex,
        highlightedEndingIndex = _this$props$highlight2 === void 0 ? data.length - 1 : _this$props$highlight2;
      var margin = {
        top: halfWidth + 2,
        right: halfWidth,
        bottom: halfWidth,
        left: halfWidth
      };
      var innerTop = margin.top;
      var innerLeft = margin.left;
      var innerHeight = height - innerTop - margin.bottom;
      var innerWidth = width - innerLeft - margin.right;
      var maxValue = (0, _d3Array.max)(_this._getValues(data));
      var firstLabel = _this._getLabelAt(data, 0);
      var lastLabel = _this._getLabelAt(data, data.length - 1);
      var xScale = (0, _d3Scale.scaleTime)().domain([firstLabel, lastLabel]).range([innerLeft, innerWidth]);
      var yScale = (0, _d3Scale.scaleLinear)().domain([0, maxValue]).range([innerHeight, innerTop]);
      var lineGenerator = (0, _d3Shape.line)().x(function (dataPoint, i) {
        return xScale(_this._getLabelAt(data, i));
      }).y(function (dataPoint) {
        return yScale(dataPoint);
      }).curve(_d3Shape.curveMonotoneX);
      var areaGenerator = (0, _d3Shape.area)().x(function (dataPoint, i) {
        return xScale(_this._getLabelAt(data, i));
      }).y0(function () {
        return innerHeight;
      }).y1(function (dataPoint) {
        return yScale(dataPoint);
      }).curve(_d3Shape.curveMonotoneX);
      return {
        margin: margin,
        width: width,
        height: height,
        innerTop: innerTop,
        innerLeft: innerLeft,
        innerBottom: margin.top + innerHeight,
        innerWidth: innerWidth,
        innerHeight: innerHeight,
        data: data,
        xScale: xScale,
        yScale: yScale,
        highlightedStartingIndex: highlightedStartingIndex,
        highlightedEndingIndex: highlightedEndingIndex,
        lineGenerator: lineGenerator,
        areaGenerator: areaGenerator,
        color: color
      };
    };
    _this._getLabelAt = function (data, position) {
      return data[position] && data[position].label;
    };
    _this._getValues = function (data) {
      return data.map(function (pair) {
        return pair.value;
      });
    };
    _this._getLabels = function (data) {
      return data.map(function (pair) {
        return pair.label;
      });
    };
    _this._drawSparkline = function () {
      var _this$chartContext = _this.chartContext,
        width = _this$chartContext.width,
        height = _this$chartContext.height,
        data = _this$chartContext.data;
      var onHover = _this.props.onHover;
      var labels = _this._getLabels(data);
      var container = (0, _d3Selection.select)(_this.svgRef.current);
      container.attr('width', width).attr('height', height);
      var dataContainer = container.select("[data-hook=\"".concat(_constants.dataHooks.dataContainer, "\"]"));
      _this._drawLines(dataContainer);
      (0, _d3Selection.select)(_this.componentRef.current).on('mouseleave', function () {
        _this.setState({
          hoveredLabel: null
        });
      }).on('mousemove', function (d) {
        var dateUnderPointer = _this.chartContext.xScale.invert((0, _d3Selection.pointer)(d)[0]);
        var currentDateIndex = (0, _d3Array.bisector)(function (date) {
          return date;
        }).left(labels, dateUnderPointer, 1);
        var beforeDateIndex = currentDateIndex - 1;
        var beforeDate = labels[beforeDateIndex];
        var afterDate = labels[currentDateIndex];
        var closestDate = +dateUnderPointer - +beforeDate > +afterDate - +dateUnderPointer ? afterDate : beforeDate;
        if (typeof onHover === 'function' && !_this._areDatesEqual(closestDate, _this.state.hoveredLabel)) {
          var labelIndex = labels.indexOf(closestDate);
          onHover(labelIndex);
        }
        _this.setState({
          hoveredLabel: closestDate
        });
      });
    };
    _this._drawLines = function (dataContainer) {
      var _this$chartContext2 = _this.chartContext,
        data = _this$chartContext2.data,
        lineGenerator = _this$chartContext2.lineGenerator,
        areaGenerator = _this$chartContext2.areaGenerator,
        color = _this$chartContext2.color;
      var dataSets = [data];
      dataContainer.selectAll('.chartLines').data(dataSets).join('g').attr('class', 'chartLines').selectAll('g').data(function (dataSet) {
        return [dataSet];
      }).join(function (enter) {
        var group = enter.append('g');
        group.append('path').attr('class', 'innerArea').attr('mask', "url(#".concat(_this._getAreaMaskId(_this.randomComponentId), ")")).attr('fill', function (dataSet) {
          return "url(#".concat(color || DEFAULT_GRADIENT_ID, ")");
        }).attr('d', function (dataSet) {
          return areaGenerator(dataSet.map(function () {
            return 0;
          }));
        });
        group.append('path').attr('class', 'innerLineBack').attr('data-hook', _constants.dataHooks.innerLineBack).attr('fill', 'none').attr('stroke-width', LINE_WIDTH + 4).attr('stroke-linecap', 'round').attr('d', function (dataSet) {
          return lineGenerator(dataSet.map(function () {
            return 0;
          }));
        });
        group.append('path').attr('class', 'innerLine').attr('fill', 'none').attr('stroke-width', LINE_WIDTH).attr('stroke-linecap', 'round').attr('stroke', function (dataSet) {
          return "url(#".concat(_this._getLineColorId(dataSet, _this.randomComponentId), ")");
        }).attr('d', function (dataSet) {
          return lineGenerator(dataSet.map(function () {
            return 0;
          }));
        });
        _this._updateLines(group);
        return group;
      }, function (update) {
        _this._updateLines(update);
        return update;
      });
    };
    _this._updateLines = function (container) {
      var _this$chartContext3 = _this.chartContext,
        lineGenerator = _this$chartContext3.lineGenerator,
        areaGenerator = _this$chartContext3.areaGenerator;
      _this._updateComponent(container, '.innerLine', function (set) {
        return lineGenerator(_this._getValues(set));
      });
      _this._updateComponent(container, '.innerLineBack', function (set) {
        return lineGenerator(_this._getValues(set));
      });
      _this._updateComponent(container, '.innerArea', function (set) {
        return areaGenerator(_this._getValues(set));
      });
    };
    _this._updateComponent = function (container, className, fncUpdater) {
      var animationDuration = _this.props.animationDuration;
      container.select(className).transition().duration(animationDuration).ease(_d3Ease.easeQuadIn).attr('d', fncUpdater);
    };
    _this.randomComponentId = Math.random().toString();
    _this.chartContext = {};
    _this.svgRef = /*#__PURE__*/_react["default"].createRef(null);
    _this.componentRef = /*#__PURE__*/_react["default"].createRef(null);
    _this.state = {
      hoveredLabel: null
    };
    return _this;
  }
  (0, _inherits2["default"])(SparklineChart, _React$PureComponent);
  return (0, _createClass2["default"])(SparklineChart, [{
    key: "_getValueAt",
    value: function _getValueAt(data, position) {
      return data[position] && data[position].value;
    }
  }, {
    key: "_areDatesEqual",
    value: function _areDatesEqual(date1, date2) {
      var date1Time = date1 && date1.getTime();
      var date2Time = date2 && date2.getTime();
      return date1Time === date2Time;
    }
  }, {
    key: "_getLineColorId",
    value: function _getLineColorId(dataSet, componentId) {
      return "".concat(componentId, "color");
    }
  }, {
    key: "_getAreaMaskId",
    value: function _getAreaMaskId(componentId) {
      return "".concat(AREA_MASK_ID).concat(componentId);
    }
  }, {
    key: "componentDidMount",
    value: function componentDidMount() {
      this._drawSparkline();
    }
  }, {
    key: "componentDidUpdate",
    value: function componentDidUpdate(prevProps) {
      if (prevProps.data !== this.props.data) {
        this._drawSparkline();
      }
    }
  }, {
    key: "_updateContext",
    value: function _updateContext() {
      this.chartContext = this._useCreateContext();
    }
  }, {
    key: "render",
    value: function render() {
      this._updateContext();
      var _this$props2 = this.props,
        getTooltipContent = _this$props2.getTooltipContent,
        className = _this$props2.className,
        dataHook = _this$props2.dataHook;
      var hoveredLabel = this.state.hoveredLabel;
      var context = this.chartContext;
      var data = context.data,
        highlightedStartingIndex = context.highlightedStartingIndex,
        highlightedEndingIndex = context.highlightedEndingIndex,
        innerWidth = context.innerWidth,
        height = context.height,
        width = context.width,
        color = context.color;
      var highlightedStart = context.xScale(this._getLabelAt(data, highlightedStartingIndex));
      var highlightedEnd = context.xScale(this._getLabelAt(data, highlightedEndingIndex));
      var highlightedStartRelativeLocation = highlightedStart / innerWidth;
      var highlightedEndRelativeLocation = highlightedEnd / innerWidth;
      var labels = this._getLabels(data);
      var hoveredLabelIndex = (0, _d3Array.bisector)(function (d) {
        return d;
      }).left(labels, hoveredLabel, 0);
      var currentHoveredLabel = this._getLabelAt(data, hoveredLabelIndex);
      var currentHoveredValue = this._getValueAt(data, hoveredLabelIndex);
      var dataPoint = {
        content: getTooltipContent && typeof getTooltipContent === 'function' && getTooltipContent(hoveredLabelIndex),
        xCoordinate: context.xScale(currentHoveredLabel),
        yCoordinate: context.yScale(currentHoveredValue) - TOOLTIP_ELEMENT_RADIUS / 2
      };
      return /*#__PURE__*/_react["default"].createElement("div", {
        style: {
          width: width,
          height: height,
          position: 'relative'
        },
        ref: this.componentRef,
        className: className,
        "data-hook": dataHook,
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 334,
          columnNumber: 7
        }
      }, /*#__PURE__*/_react["default"].createElement("svg", {
        style: {
          overflow: 'visible',
          zIndex: 1
        },
        ref: this.svgRef,
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 340,
          columnNumber: 9
        }
      }, /*#__PURE__*/_react["default"].createElement("defs", {
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 341,
          columnNumber: 11
        }
      }, /*#__PURE__*/_react["default"].createElement("mask", {
        id: this._getAreaMaskId(this.randomComponentId),
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 342,
          columnNumber: 13
        }
      }, /*#__PURE__*/_react["default"].createElement("rect", {
        x: highlightedStart,
        y: "0",
        width: highlightedEnd - highlightedStart,
        height: height,
        fill: "white",
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 343,
          columnNumber: 15
        }
      })), /*#__PURE__*/_react["default"].createElement("linearGradient", {
        gradientUnits: "userSpaceOnUse",
        key: "".concat(this.randomComponentId, "a"),
        id: this._getLineColorId(data, this.randomComponentId),
        x1: "0px",
        y1: "0px",
        x2: "".concat(innerWidth, "px"),
        y2: "0px",
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 352,
          columnNumber: 13
        }
      }, /*#__PURE__*/_react["default"].createElement("stop", {
        offset: highlightedStartRelativeLocation,
        style: {
          stopColor: '#dfe5eb',
          stopOpacity: 1
        },
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 361,
          columnNumber: 15
        }
      }), /*#__PURE__*/_react["default"].createElement("stop", {
        offset: highlightedStartRelativeLocation,
        className: _SparklineChartSt.classes.gradientStop,
        style: {
          stopColor: color
        },
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 365,
          columnNumber: 15
        }
      }), /*#__PURE__*/_react["default"].createElement("stop", {
        offset: highlightedEndRelativeLocation,
        className: _SparklineChartSt.classes.gradientStop,
        style: {
          stopColor: color
        },
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 370,
          columnNumber: 15
        }
      }), /*#__PURE__*/_react["default"].createElement("stop", {
        offset: highlightedEndRelativeLocation,
        style: {
          stopColor: '#dfe5eb',
          stopOpacity: 1
        },
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 377,
          columnNumber: 15
        }
      }), /*#__PURE__*/_react["default"].createElement("stop", {
        offset: 1,
        style: {
          stopColor: '#dfe5eb',
          stopOpacity: 1
        },
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 381,
          columnNumber: 15
        }
      })), /*#__PURE__*/_react["default"].createElement("linearGradient", {
        gradientUnits: "userSpaceOnUse",
        key: this.randomComponentId,
        id: color || DEFAULT_GRADIENT_ID,
        x1: "0px",
        y1: "".concat(context.innerHeight, "px"),
        x2: "0px",
        y2: "0px",
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 387,
          columnNumber: 13
        }
      }, /*#__PURE__*/_react["default"].createElement("stop", {
        offset: "10%",
        className: _SparklineChartSt.classes.gradientStopWithoutOpacity,
        style: {
          stopColor: color
        },
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 396,
          columnNumber: 15
        }
      }), /*#__PURE__*/_react["default"].createElement("stop", {
        offset: "90%",
        className: _SparklineChartSt.classes.gradientStopWithHalfOpacity,
        style: {
          stopColor: color
        },
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 401,
          columnNumber: 15
        }
      }))), /*#__PURE__*/_react["default"].createElement("g", {
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 410,
          columnNumber: 11
        }
      }, /*#__PURE__*/_react["default"].createElement("g", {
        "data-hook": _constants.dataHooks.dataContainer,
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 411,
          columnNumber: 13
        }
      }), this._shouldShowTooltip() && /*#__PURE__*/_react["default"].createElement("g", {
        transform: "translate(".concat(dataPoint.xCoordinate, ", ").concat(dataPoint.yCoordinate + TOOLTIP_ELEMENT_RADIUS / 2, ")"),
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 413,
          columnNumber: 15
        }
      }, /*#__PURE__*/_react["default"].createElement("circle", {
        r: TOOLTIP_ELEMENT_RADIUS,
        className: _SparklineChartSt.classes.tooltipElement,
        fill: color,
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 418,
          columnNumber: 17
        }
      })))), this._shouldShowTooltip() && /*#__PURE__*/_react["default"].createElement(_ChartTooltip.ChartTooltip, {
        dataPoint: dataPoint,
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 427,
          columnNumber: 39
        }
      }));
    }
  }]);
}(_react["default"].PureComponent);
SparklineChart.displayName = 'SparklineChart';
SparklineChart.defaultProps = {
  animationDuration: 300
};
var _default = exports["default"] = SparklineChart;