d3plus-shape
Version:
Fancy SVG shapes for visualizations
309 lines (265 loc) • 11.2 kB
JavaScript
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 };