UNPKG

d3plus-shape

Version:

Fancy SVG shapes for visualizations

309 lines (265 loc) 11.2 kB
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } import { select as _select } from "d3-selection"; import { accessor, assign, BaseClass, configPrep, constant, elem } from "d3plus-common"; import { nest } from "d3-collection"; import Circle from "./Circle"; import Line from "./Line"; import Rect from "./Rect"; var shapes = { Circle: Circle, Rect: Rect }; /** @class Whisker @extends BaseClass @desc Creates SVG whisker based on an array of data. */ var Whisker = /*#__PURE__*/ function (_BaseClass) { _inherits(Whisker, _BaseClass); /** @memberof Whisker @desc Invoked when creating a new class instance, and overrides any default parameters inherited from BaseClass. @private */ function Whisker() { var _this; _classCallCheck(this, Whisker); _this = _possibleConstructorReturn(this, _getPrototypeOf(Whisker).call(this)); _this._endpoint = accessor("endpoint", "Rect"); _this._endpointConfig = { Circle: { r: accessor("r", 5) } }; _this._length = accessor("length", 25); _this._lineConfig = {}; _this._orient = accessor("orient", "top"); _this._x = accessor("x", 0); _this._y = accessor("y", 0); return _this; } /** @memberof Whisker @desc Draws the whisker. @param {Function} [*callback*] @chainable */ _createClass(Whisker, [{ key: "render", value: function render(callback) { var _this2 = this; if (this._select === void 0) { this.select(_select("body").append("svg").style("width", "".concat(window.innerWidth, "px")).style("height", "".concat(window.innerHeight, "px")).style("display", "block").node()); } var lineData = []; this._data.forEach(function (d, i) { var orient = _this2._orient(d, i); var x = _this2._x(d, i); var y = _this2._y(d, i); var endpointX = x; if (orient === "left") endpointX -= _this2._length(d, i);else if (orient === "right") endpointX += _this2._length(d, i); var endpointY = y; if (orient === "top") endpointY -= _this2._length(d, i);else if (orient === "bottom") endpointY += _this2._length(d, i); lineData.push({ __d3plus__: true, data: d, i: i, id: i, x: x, y: y }); lineData.push({ __d3plus__: true, data: d, i: i, id: i, x: endpointX, y: endpointY }); }); // Draw whisker line. this._line = new Line().data(lineData).select(elem("g.d3plus-Whisker", { parent: this._select }).node()).config(configPrep.bind(this)(this._lineConfig, "shape")).render(callback); var whiskerData = this._data.map(function (d, i) { var dataObj = {}; dataObj.__d3plus__ = true; dataObj.data = d; dataObj.i = i; dataObj.endpoint = _this2._endpoint(d, i); dataObj.length = _this2._length(d, i); dataObj.orient = _this2._orient(d, i); var endpointX = _this2._x(d, i); if (dataObj.orient === "left") endpointX -= dataObj.length;else if (dataObj.orient === "right") endpointX += dataObj.length; var endpointY = _this2._y(d, i); if (dataObj.orient === "top") endpointY -= dataObj.length;else if (dataObj.orient === "bottom") endpointY += dataObj.length; dataObj.x = endpointX; dataObj.y = endpointY; return dataObj; }); // Draw whisker endpoint. this._whiskerEndpoint = []; nest().key(function (d) { return d.endpoint; }).entries(whiskerData).forEach(function (shapeData) { var shapeName = shapeData.key; _this2._whiskerEndpoint.push(new shapes[shapeName]().data(shapeData.values).select(elem("g.d3plus-Whisker-Endpoint-".concat(shapeName), { parent: _this2._select }).node()).config({ height: function height(d) { return d.orient === "top" || d.orient === "bottom" ? 5 : 20; }, width: function width(d) { return d.orient === "top" || d.orient === "bottom" ? 20 : 5; } }).config(configPrep.bind(_this2)(_this2._endpointConfig, "shape", shapeName)).render()); }); return this; } /** @memberof Whisker @desc Sets the highlight accessor to the Shape class's active function. @param {Function} [*value*] @chainable */ }, { key: "active", value: function active(_) { if (this._line) this._line.active(_); if (this._whiskerEndpoint) this._whiskerEndpoint.forEach(function (endPoint) { return endPoint.active(_); }); } /** @memberof Whisker @desc If *data* is specified, sets the data array to the specified array and returns the current class instance. If *data* is not specified, returns the current data array. @param {Array} [*data* = []] @chainable */ }, { key: "data", value: function data(_) { return arguments.length ? (this._data = _, this) : this._data; } /** @memberof Whisker @desc If *value* is specified, sets the endpoint accessor to the specified function or string and returns the current class instance. @param {Function|String} @chainable */ }, { key: "endpoint", value: function endpoint(_) { return arguments.length ? (this._endpoint = typeof _ === "function" ? _ : constant(_), this) : this._endpoint; } /** @memberof Whisker @desc If *value* is specified, sets the config method for each endpoint and returns the current class instance. @param {Object} [*value*] @chainable */ }, { key: "endpointConfig", value: function endpointConfig(_) { return arguments.length ? (this._endpointConfig = assign(this._endpointConfig, _), this) : this._endpointConfig; } /** @memberof Whisker @desc Sets the highlight accessor to the Shape class's hover function. @param {Function} [*value*] @chainable */ }, { key: "hover", value: function hover(_) { if (this._line) this._line.hover(_); if (this._whiskerEndpoint) this._whiskerEndpoint.forEach(function (endPoint) { return endPoint.hover(_); }); } /** @memberof Whisker @desc If *value* is specified, sets the length accessor for whisker and returns the current class instance. @param {Function|Number} [*value*] @chainable */ }, { key: "length", value: function length(_) { return arguments.length ? (this._length = typeof _ === "function" ? _ : constant(_), this) : this._length; } /** @memberof Whisker @desc If *value* is specified, sets the config method for line shape and returns the current class instance. @param {Object} [*value*] @chainable */ }, { key: "lineConfig", value: function lineConfig(_) { return arguments.length ? (this._lineConfig = assign(this._lineConfig, _), this) : this._lineConfig; } /** @memberof Whisker @desc If *value* is specified, sets the orientation to the specified value. If *value* is not specified, returns the current orientation. @param {Function|String} [*value* = "top"] Accepts "top", "right", "bottom" or "left" @chainable */ }, { key: "orient", value: function orient(_) { return arguments.length ? (this._orient = typeof _ === "function" ? _ : constant(_), this) : this._orient; } /** @memberof Whisker @desc If *selector* is specified, sets the SVG container element to the specified d3 selector or DOM element and returns the current class instance. If *selector* is not specified, returns the current SVG container element. @param {String|HTMLElement} [*selector* = d3.select("body").append("svg")] @chainable */ }, { key: "select", value: function select(_) { return arguments.length ? (this._select = _select(_), this) : this._select; } /** @memberof Whisker @desc If *value* is specified, sets the x axis to the specified function or number and returns the current class instance. @param {Function|Number} [*value*] @chainable @example function(d) { return d.x; } */ }, { key: "x", value: function x(_) { return arguments.length ? (this._x = typeof _ === "function" ? _ : constant(_), this) : this._x; } /** @memberof Whisker @desc If *value* is specified, sets the y axis to the specified function or number and returns the current class instance. @param {Function|Number} [*value*] @chainable @example function(d) { return d.y; } */ }, { key: "y", value: function y(_) { return arguments.length ? (this._y = typeof _ === "function" ? _ : constant(_), this) : this._y; } }]); return Whisker; }(BaseClass); export { Whisker as default };