'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = undefined;

var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

var _createClass2 = require('babel-runtime/helpers/createClass');

var _createClass3 = _interopRequireDefault(_createClass2);

var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');

var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);

var _inherits2 = require('babel-runtime/helpers/inherits');

var _inherits3 = _interopRequireDefault(_inherits2);

var _class, _temp; /* eslint "import/no-extraneous-dependencies": "warn" */


// TODO change the d3 dependency in package.json to match specific modules


var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

var _d3Transition = require('d3-transition');

var _flow = require('lodash/flow');

var _flow2 = _interopRequireDefault(_flow);

var _ScreenReaderContent = require('@instructure/ui-a11y/lib/components/ScreenReaderContent');

var _ScreenReaderContent2 = _interopRequireDefault(_ScreenReaderContent);

var _PresentationContent = require('@instructure/ui-a11y/lib/components/PresentationContent');

var _PresentationContent2 = _interopRequireDefault(_PresentationContent);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var MARGIN_T = 0;
var MARGIN_B = 28;

var D3Component = (_temp = _class = function (_Component) {
  (0, _inherits3.default)(D3Component, _Component);

  function D3Component() {
    (0, _classCallCheck3.default)(this, D3Component);
    return (0, _possibleConstructorReturn3.default)(this, (D3Component.__proto__ || Object.getPrototypeOf(D3Component)).apply(this, arguments));
  }

  (0, _createClass3.default)(D3Component, [{
    key: 'createChart',
    value: function createChart(svg, props) {
      throw new Error("'createChart' must be defined");
    }
  }, {
    key: 'updateChart',
    value: function updateChart(svg, props) {
      this.removeChart();
      this.__svg = this.createChart(this.chart, props);
    }
  }, {
    key: 'removeChart',
    value: function removeChart() {
      if (this.__svg) {
        this.__svg.remove();
        delete this.__svg;
      }
    }
  }, {
    key: 'componentDidMount',
    value: function componentDidMount() {
      this.__svg = this.createChart(this.chart, this.props);
      this.updateChart(this.__svg, this.props);
    }
  }, {
    key: 'shouldComponentUpdate',
    value: function shouldComponentUpdate(nextProps) {
      this.updateChart(this.__svg, nextProps);
      return false;
    }
  }, {
    key: 'componentWillUnmount',
    value: function componentWillUnmount() {
      this.removeChart();
    }
  }, {
    key: 'isAnimated',
    value: function isAnimated() {
      return this.props.animateDelay || this.props.animateDuration;
    }
  }, {
    key: 'getTransition',
    value: function getTransition() {
      this.transition = this.transition || (0, _d3Transition.transition)().delay(this.props.animateDelay || 0).duration(this.props.animateDuration || 0);
      return this.transition;
    }
  }, {
    key: 'applyTransition',
    value: function applyTransition(selection, initialFunc, finalFunc, transitionFunc) {
      var _this2 = this;

      var identity = function identity(s) {
        return s;
      };
      var transition = function transition(s) {
        return s.transition(_this2.getTransition());
      };

      var applicators = [];
      if (this.isAnimated()) {
        applicators.push(initialFunc || identity, transition, transitionFunc || identity);
      }
      applicators.push(finalFunc || identity);

      return (0, _flow2.default)(applicators)(selection);
    }
  }, {
    key: 'renderSummary',
    value: function renderSummary() {
      if (this.summarizeChart) {
        return _react2.default.createElement(
          _ScreenReaderContent2.default,
          null,
          this.summarizeChart()
        );
      }
    }
  }, {
    key: 'renderTable',
    value: function renderTable() {
      return null;
    }
  }, {
    key: 'render',
    value: function render() {
      var _this3 = this;

      var _props = this.props,
          chartWidth = _props.chartWidth,
          chartHeight = _props.chartHeight;

      var viewportHeight = chartHeight + MARGIN_T + MARGIN_B;

      // IE11 sizes svg elements incorrectly, so we render a canvas element to
      // layout space for the chart, then position the svg absolute on top of it.
      return _react2.default.createElement(
        'div',
        null,
        _react2.default.createElement(
          _PresentationContent2.default,
          { as: 'div' },
          _react2.default.createElement(
            'div',
            { style: { position: 'relative' } },
            _react2.default.createElement('canvas', {
              width: chartWidth,
              height: viewportHeight,
              style: { display: 'block', visibility: 'hidden' }
            }),
            _react2.default.createElement('svg', {
              ref: function ref(_ref) {
                _this3.chart = _ref;
              },
              style: { position: 'absolute', top: 0, left: 0 }
            })
          )
        ),
        this.renderSummary(),
        this.renderTable()
      );
    }
  }], [{
    key: 'addTitle',
    value: function addTitle(svg, title) {
      return svg.append('title').text(title);
    }
  }]);
  return D3Component;
}(_react.Component), _class.propTypes = {
  animateDelay: _propTypes2.default.number,
  animateDuration: _propTypes2.default.number,
  chartHeight: _propTypes2.default.number.isRequired, // Height in pixels
  chartWidth: _propTypes2.default.number
}, _class.defaultProps = {
  animateDelay: null,
  animateDuration: null,
  chartWidth: null
}, _temp);
exports.default = D3Component;