d3plus-shape
Version:
Fancy SVG shapes for visualizations
1,088 lines (944 loc) • 39.4 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); }
/**
@external BaseClass
@see https://github.com/d3plus/d3plus-common#BaseClass
*/
import { min } from "d3-array";
import { color } from "d3-color";
import { mouse, select as _select, selectAll } from "d3-selection";
import { transition } from "d3-transition";
import { accessor, assign, attrize, BaseClass, configPrep, constant, elem } from "d3plus-common";
import { colorContrast } from "d3plus-color";
import * as paths from "d3-shape";
import { strip, TextBox } from "d3plus-text";
import Image from "../Image";
import pointDistance from "../geom/pointDistance";
/**
@class Shape
@extends external:BaseClass
@desc An abstracted class for generating shapes.
*/
var Shape =
/*#__PURE__*/
function (_BaseClass) {
_inherits(Shape, _BaseClass);
/**
@memberof Shape
@desc Invoked when creating a new class instance, and sets any default parameters.
@private
*/
function Shape() {
var _this;
var tagName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "g";
_classCallCheck(this, Shape);
_this = _possibleConstructorReturn(this, _getPrototypeOf(Shape).call(this));
_this._activeOpacity = 0.25;
_this._activeStyle = {
"stroke": function stroke(d, i) {
var c = _this._fill(d, i);
if (["transparent", "none"].includes(c)) c = _this._stroke(d, i);
return color(c).darker(1);
},
"stroke-width": function strokeWidth(d, i) {
var s = _this._strokeWidth(d, i) || 1;
return s * 3;
}
};
_this._ariaLabel = constant("");
_this._backgroundImage = constant(false);
_this._backgroundImageClass = new Image();
_this._data = [];
_this._duration = 600;
_this._fill = constant("black");
_this._fillOpacity = constant(1);
_this._hoverOpacity = 0.5;
_this._hoverStyle = {
"stroke": function stroke(d, i) {
var c = _this._fill(d, i);
if (["transparent", "none"].includes(c)) c = _this._stroke(d, i);
return color(c).darker(0.5);
},
"stroke-width": function strokeWidth(d, i) {
var s = _this._strokeWidth(d, i) || 1;
return s * 2;
}
};
_this._id = function (d, i) {
return d.id !== void 0 ? d.id : i;
};
_this._label = constant(false);
_this._labelClass = new TextBox();
_this._labelConfig = {
fontColor: function fontColor(d, i) {
return colorContrast(_this._fill(d, i));
},
fontSize: 12,
padding: 5
};
_this._name = "Shape";
_this._opacity = constant(1);
_this._pointerEvents = constant("visiblePainted");
_this._role = constant("presentation");
_this._rotate = constant(0);
_this._rx = constant(0);
_this._ry = constant(0);
_this._scale = constant(1);
_this._shapeRendering = constant("geometricPrecision");
_this._stroke = function (d, i) {
return color(_this._fill(d, i)).darker(1);
};
_this._strokeDasharray = constant("0");
_this._strokeLinecap = constant("butt");
_this._strokeOpacity = constant(1);
_this._strokeWidth = constant(0);
_this._tagName = tagName;
_this._textAnchor = constant("start");
_this._vectorEffect = constant("non-scaling-stroke");
_this._verticalAlign = constant("top");
_this._x = accessor("x", 0);
_this._y = accessor("y", 0);
return _this;
}
/**
@memberof Shape
@desc Given a specific data point and index, returns the aesthetic properties of the shape.
@param {Object} *data point*
@param {Number} *index*
@private
*/
_createClass(Shape, [{
key: "_aes",
value: function _aes() {
return {};
}
/**
@memberof Shape
@desc Adds event listeners to each shape group or hit area.
@param {D3Selection} *update* The update cycle of the data binding.
@private
*/
}, {
key: "_applyEvents",
value: function _applyEvents(handler) {
var _this2 = this;
var events = Object.keys(this._on);
var _loop = function _loop(e) {
handler.on(events[e], function (d, i) {
if (!_this2._on[events[e]]) return;
if (d.i !== void 0) i = d.i;
if (d.nested && d.values) {
var cursor = mouse(_this2._select.node()),
values = d.values.map(function (d) {
return pointDistance(cursor, [_this2._x(d, i), _this2._y(d, i)]);
});
d = d.values[values.indexOf(min(values))];
}
_this2._on[events[e]].bind(_this2)(d, i);
});
};
for (var e = 0; e < events.length; e++) {
_loop(e);
}
}
/**
@memberof Shape
@desc Provides the updated styling to the given shape elements.
@param {HTMLElement} *elem*
@param {Object} *style*
@private
*/
}, {
key: "_updateStyle",
value: function _updateStyle(elem, style) {
var that = this;
if (elem.size() && elem.node().tagName === "g") elem = elem.selectAll("*");
/**
@desc Determines whether a shape is a nested collection of data points, and uses the appropriate data and index for the given function context.
@param {Object} *d* data point
@param {Number} *i* index
@private
*/
function styleLogic(d, i) {
return typeof this !== "function" ? this : d.nested && d.key && d.values ? this(d.values[0], that._data.indexOf(d.values[0])) : this(d, i);
}
var styleObject = {};
for (var key in style) {
if ({}.hasOwnProperty.call(style, key)) {
styleObject[key] = styleLogic.bind(style[key]);
}
}
elem.transition().duration(0).call(attrize, styleObject);
}
/**
@memberof Shape
@desc Provides the default styling to the shape elements.
@param {HTMLElement} *elem*
@private
*/
}, {
key: "_applyStyle",
value: function _applyStyle(elem) {
var that = this;
if (elem.size() && elem.node().tagName === "g") elem = elem.selectAll("*");
/**
@desc Determines whether a shape is a nested collection of data points, and uses the appropriate data and index for the given function context.
@param {Object} *d* data point
@param {Number} *i* index
@private
*/
function styleLogic(d, i) {
return typeof this !== "function" ? this : d.nested && d.key && d.values ? this(d.values[0], that._data.indexOf(d.values[0])) : this(d, i);
}
elem.attr("fill", styleLogic.bind(this._fill)).attr("fill-opacity", styleLogic.bind(this._fillOpacity)).attr("rx", styleLogic.bind(this._rx)).attr("ry", styleLogic.bind(this._ry)).attr("stroke", styleLogic.bind(this._stroke)).attr("stroke-dasharray", styleLogic.bind(this._strokeDasharray)).attr("stroke-linecap", styleLogic.bind(this._strokeLinecap)).attr("stroke-opacity", styleLogic.bind(this._strokeOpacity)).attr("stroke-width", styleLogic.bind(this._strokeWidth)).attr("vector-effect", styleLogic.bind(this._vectorEffect));
}
/**
@memberof Shape
@desc Calculates the transform for the group elements.
@param {HTMLElement} *elem*
@private
*/
}, {
key: "_applyTransform",
value: function _applyTransform(elem) {
var _this3 = this;
elem.attr("transform", function (d, i) {
return "\n translate(".concat(d.__d3plusShape__ ? d.translate ? d.translate : "".concat(_this3._x(d.data, d.i), ",").concat(_this3._y(d.data, d.i)) : "".concat(_this3._x(d, i), ",").concat(_this3._y(d, i)), ")\n scale(").concat(d.__d3plusShape__ ? d.scale || _this3._scale(d.data, d.i) : _this3._scale(d, i), ")\n rotate(").concat(d.__d3plusShape__ ? d.rotate ? d.rotate : _this3._rotate(d.data || d, d.i) : _this3._rotate(d.data || d, d.i), ")");
});
}
/**
@memberof Shape
@desc Checks for nested data and uses the appropriate variables for accessor functions.
@param {HTMLElement} *elem*
@private
*/
}, {
key: "_nestWrapper",
value: function _nestWrapper(method) {
return function (d, i) {
return method(d.__d3plusShape__ ? d.data : d, d.__d3plusShape__ ? d.i : i);
};
}
/**
@memberof Shape
@desc Modifies existing shapes to show active status.
@private
*/
}, {
key: "_renderActive",
value: function _renderActive() {
var that = this;
this._group.selectAll(".d3plus-Shape, .d3plus-Image, .d3plus-textBox").each(function (d, i) {
if (!d) d = {};
if (!d.parentNode) d.parentNode = this.parentNode;
var parent = d.parentNode;
if (_select(this).classed("d3plus-textBox")) d = d.data;
if (d.__d3plusShape__ || d.__d3plus__) {
while (d && (d.__d3plusShape__ || d.__d3plus__)) {
i = d.i;
d = d.data;
}
} else i = that._data.indexOf(d);
var group = !that._active || typeof that._active !== "function" || !that._active(d, i) ? parent : that._activeGroup.node();
if (group !== this.parentNode) {
group.appendChild(this);
if (this.className.baseVal.includes("d3plus-Shape")) {
if (parent === group) _select(this).call(that._applyStyle.bind(that));else _select(this).call(that._updateStyle.bind(that, _select(this), that._activeStyle));
}
}
}); // this._renderImage();
// this._renderLabels();
this._group.selectAll("g.d3plus-".concat(this._name, "-shape, g.d3plus-").concat(this._name, "-image, g.d3plus-").concat(this._name, "-text")).attr("opacity", this._hover ? this._hoverOpacity : this._active ? this._activeOpacity : 1);
}
/**
@memberof Shape
@desc Modifies existing shapes to show hover status.
@private
*/
}, {
key: "_renderHover",
value: function _renderHover() {
var that = this;
this._group.selectAll("g.d3plus-".concat(this._name, "-shape, g.d3plus-").concat(this._name, "-image, g.d3plus-").concat(this._name, "-text, g.d3plus-").concat(this._name, "-hover")).selectAll(".d3plus-Shape, .d3plus-Image, .d3plus-textBox").each(function (d, i) {
if (!d) d = {};
if (!d.parentNode) d.parentNode = this.parentNode;
var parent = d.parentNode;
if (_select(this).classed("d3plus-textBox")) d = d.data;
if (d.__d3plusShape__ || d.__d3plus__) {
while (d && (d.__d3plusShape__ || d.__d3plus__)) {
i = d.i;
d = d.data;
}
} else i = that._data.indexOf(d);
var group = !that._hover || typeof that._hover !== "function" || !that._hover(d, i) ? parent : that._hoverGroup.node();
if (group !== this.parentNode) group.appendChild(this);
if (this.className.baseVal.includes("d3plus-Shape")) {
if (parent === group) _select(this).call(that._applyStyle.bind(that));else _select(this).call(that._updateStyle.bind(that, _select(this), that._hoverStyle));
}
}); // this._renderImage();
// this._renderLabels();
this._group.selectAll("g.d3plus-".concat(this._name, "-shape, g.d3plus-").concat(this._name, "-image, g.d3plus-").concat(this._name, "-text")).attr("opacity", this._hover ? this._hoverOpacity : this._active ? this._activeOpacity : 1);
}
/**
@memberof Shape
@desc Adds background image to each shape group.
@private
*/
}, {
key: "_renderImage",
value: function _renderImage() {
var _this4 = this;
var imageData = [];
this._update.merge(this._enter).data().forEach(function (datum, i) {
var aes = _this4._aes(datum, i);
if (aes.r || aes.width && aes.height) {
var d = datum;
if (datum.nested && datum.key && datum.values) {
d = datum.values[0];
i = _this4._data.indexOf(d);
}
var height = aes.r ? aes.r * 2 : aes.height,
url = _this4._backgroundImage(d, i),
width = aes.r ? aes.r * 2 : aes.width;
if (url) {
var x = d.__d3plusShape__ ? d.translate ? d.translate[0] : _this4._x(d.data, d.i) : _this4._x(d, i),
y = d.__d3plusShape__ ? d.translate ? d.translate[1] : _this4._y(d.data, d.i) : _this4._y(d, i);
if (aes.x) x += aes.x;
if (aes.y) y += aes.y;
if (d.__d3plusShape__) {
d = d.data;
i = d.i;
}
imageData.push({
__d3plus__: true,
data: d,
height: height,
i: i,
id: _this4._id(d, i),
url: url,
width: width,
x: x + -width / 2,
y: y + -height / 2
});
}
}
});
this._backgroundImageClass.data(imageData).duration(this._duration).pointerEvents("none").select(elem("g.d3plus-".concat(this._name, "-image"), {
parent: this._group,
update: {
opacity: this._active ? this._activeOpacity : 1
}
}).node()).render();
}
/**
@memberof Shape
@desc Adds labels to each shape group.
@private
*/
}, {
key: "_renderLabels",
value: function _renderLabels() {
var _this5 = this;
var labelData = [];
this._update.merge(this._enter).data().forEach(function (datum, i) {
var d = datum;
if (datum.nested && datum.key && datum.values) {
d = datum.values[0];
i = _this5._data.indexOf(d);
}
var labels = _this5._label(d, i);
if (_this5._labelBounds && labels !== false && labels !== undefined && labels !== null) {
var bounds = _this5._labelBounds(d, i, _this5._aes(datum, i));
if (bounds) {
if (labels.constructor !== Array) labels = [labels];
var x = d.__d3plusShape__ ? d.translate ? d.translate[0] : _this5._x(d.data, d.i) : _this5._x(d, i),
y = d.__d3plusShape__ ? d.translate ? d.translate[1] : _this5._y(d.data, d.i) : _this5._y(d, i);
if (d.__d3plusShape__) {
d = d.data;
i = d.i;
}
for (var l = 0; l < labels.length; l++) {
var b = bounds.constructor === Array ? bounds[l] : Object.assign({}, bounds);
var rotate = _this5._rotate(d, i);
var r = d.labelConfig && d.labelConfig.rotate ? d.labelConfig.rotate : bounds.angle !== undefined ? bounds.angle : 0;
r += rotate;
var rotateAnchor = rotate !== 0 ? [b.x * -1 || 0, b.y * -1 || 0] : [b.width / 2, b.height / 2];
labelData.push({
__d3plus__: true,
data: d,
height: b.height,
l: l,
id: "".concat(_this5._id(d, i), "_").concat(l),
r: r,
rotateAnchor: rotateAnchor,
text: labels[l],
width: b.width,
x: x + b.x,
y: y + b.y
});
}
}
}
});
this._labelClass.data(labelData).duration(this._duration).pointerEvents("none").rotate(function (d) {
return d.__d3plus__ ? d.r : d.data.r;
}).rotateAnchor(function (d) {
return d.__d3plus__ ? d.rotateAnchor : d.data.rotateAnchor;
}).select(elem("g.d3plus-".concat(this._name, "-text"), {
parent: this._group,
update: {
opacity: this._active ? this._activeOpacity : 1
}
}).node()).config(configPrep.bind(this)(this._labelConfig)).render();
}
/**
@memberof Shape
@desc Renders the current Shape to the page. If a *callback* is specified, it will be called once the shapes are done drawing.
@param {Function} [*callback*]
@chainable
*/
}, {
key: "render",
value: function render(callback) {
var _this6 = 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());
}
this._transition = transition().duration(this._duration);
var data = this._data,
key = this._id;
if (this._dataFilter) {
data = this._dataFilter(data);
if (data.key) key = data.key;
}
if (this._sort) {
data = data.sort(function (a, b) {
while (a.__d3plusShape__ || a.__d3plus__) {
a = a.data;
}
while (b.__d3plusShape__ || b.__d3plus__) {
b = b.data;
}
return _this6._sort(a, b);
});
}
selectAll("g.d3plus-".concat(this._name, "-hover > *, g.d3plus-").concat(this._name, "-active > *")).each(function (d) {
if (d && d.parentNode) d.parentNode.appendChild(this);else this.parentNode.removeChild(this);
}); // Makes the update state of the group selection accessible.
this._group = elem("g.d3plus-".concat(this._name, "-group"), {
parent: this._select
});
var update = this._update = elem("g.d3plus-".concat(this._name, "-shape"), {
parent: this._group,
update: {
opacity: this._active ? this._activeOpacity : 1
}
}).selectAll(".d3plus-".concat(this._name)).data(data, key); // Orders and transforms the updating Shapes.
update.order();
if (this._duration) {
update.transition(this._transition).call(this._applyTransform.bind(this));
} else {
update.call(this._applyTransform.bind(this));
} // Makes the enter state of the group selection accessible.
var enter = this._enter = update.enter().append(this._tagName).attr("class", function (d, i) {
return "d3plus-Shape d3plus-".concat(_this6._name, " d3plus-id-").concat(strip(_this6._nestWrapper(_this6._id)(d, i)));
}).call(this._applyTransform.bind(this)).attr("aria-label", this._ariaLabel).attr("role", this._role).attr("opacity", this._nestWrapper(this._opacity));
var enterUpdate = enter.merge(update);
var enterUpdateRender = enterUpdate.attr("shape-rendering", this._nestWrapper(this._shapeRendering));
if (this._duration) {
enterUpdateRender = enterUpdateRender.attr("pointer-events", "none").transition(this._transition).transition().delay(100).attr("pointer-events", this._pointerEvents);
}
enterUpdateRender.attr("opacity", this._nestWrapper(this._opacity)); // Makes the exit state of the group selection accessible.
var exit = this._exit = update.exit();
if (this._duration) exit.transition().delay(this._duration).remove();else exit.remove();
this._renderImage();
this._renderLabels();
this._hoverGroup = elem("g.d3plus-".concat(this._name, "-hover"), {
parent: this._group
});
this._activeGroup = elem("g.d3plus-".concat(this._name, "-active"), {
parent: this._group
});
var hitAreas = this._group.selectAll(".d3plus-HitArea").data(this._hitArea ? data : [], key);
hitAreas.order().call(this._applyTransform.bind(this));
var isLine = this._name === "Line";
isLine && this._path.curve(paths["curve".concat(this._curve.charAt(0).toUpperCase()).concat(this._curve.slice(1))]).defined(this._defined).x(this._x).y(this._y);
var hitEnter = hitAreas.enter().append(isLine ? "path" : "rect").attr("class", function (d, i) {
return "d3plus-HitArea d3plus-id-".concat(strip(_this6._nestWrapper(_this6._id)(d, i)));
}).attr("fill", "black").attr("stroke", "black").attr("pointer-events", "painted").attr("opacity", 0).call(this._applyTransform.bind(this));
var that = this;
var hitUpdates = hitAreas.merge(hitEnter).each(function (d) {
var i = that._data.indexOf(d);
var h = that._hitArea(d, i, that._aes(d, i));
return h && !(that._name === "Line" && parseFloat(that._strokeWidth(d, i)) > 10) ? _select(this).call(attrize, h) : _select(this).remove();
});
hitAreas.exit().remove();
this._applyEvents(this._hitArea ? hitUpdates : enterUpdate);
setTimeout(function () {
if (_this6._active) _this6._renderActive();else if (_this6._hover) _this6._renderHover();
if (callback) callback();
}, this._duration + 100);
return this;
}
/**
@memberof Shape
@desc If *value* is specified, sets the highlight accessor to the specified function and returns the current class instance.
@param {Function} [*value*]
@chainable
*/
}, {
key: "active",
value: function active(_) {
if (!arguments.length || _ === undefined) return this._active;
this._active = _;
if (this._group) {
// this._renderImage();
// this._renderLabels();
this._renderActive();
}
return this;
}
/**
@memberof Shape
@desc When shapes are active, this is the opacity of any shape that is not active.
@param {Number} *value* = 0.25
@chainable
*/
}, {
key: "activeOpacity",
value: function activeOpacity(_) {
return arguments.length ? (this._activeOpacity = _, this) : this._activeOpacity;
}
/**
@memberof Shape
@desc The style to apply to active shapes.
@param {Object} *value*
@chainable
*/
}, {
key: "activeStyle",
value: function activeStyle(_) {
return arguments.length ? (this._activeStyle = assign({}, this._activeStyle, _), this) : this._activeStyle;
}
/**
@memberof Shape
@desc If *value* is specified, sets the aria-label attribute to the specified function or string and returns the current class instance.
@param {Function|String} *value*
@chainable
*/
}, {
key: "ariaLabel",
value: function ariaLabel(_) {
return _ !== undefined ? (this._ariaLabel = typeof _ === "function" ? _ : constant(_), this) : this._ariaLabel;
}
/**
@memberof Shape
@desc If *value* is specified, sets the background-image accessor to the specified function or string and returns the current class instance.
@param {Function|String} [*value* = false]
@chainable
*/
}, {
key: "backgroundImage",
value: function backgroundImage(_) {
return arguments.length ? (this._backgroundImage = typeof _ === "function" ? _ : constant(_), this) : this._backgroundImage;
}
/**
@memberof Shape
@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. A shape will be drawn for each object in the array.
@param {Array} [*data* = []]
@chainable
*/
}, {
key: "data",
value: function data(_) {
return arguments.length ? (this._data = _, this) : this._data;
}
/**
@memberof Shape
@desc If *ms* is specified, sets the animation duration to the specified number and returns the current class instance. If *ms* is not specified, returns the current animation duration.
@param {Number} [*ms* = 600]
@chainable
*/
}, {
key: "duration",
value: function duration(_) {
return arguments.length ? (this._duration = _, this) : this._duration;
}
/**
@memberof Shape
@desc If *value* is specified, sets the fill accessor to the specified function or string and returns the current class instance.
@param {Function|String} [*value* = "black"]
@chainable
*/
}, {
key: "fill",
value: function fill(_) {
return arguments.length ? (this._fill = typeof _ === "function" ? _ : constant(_), this) : this._fill;
}
/**
@memberof Shape
@desc Defines the "fill-opacity" attribute for the shapes.
@param {Function|Number} [*value* = 1]
@chainable
*/
}, {
key: "fillOpacity",
value: function fillOpacity(_) {
return arguments.length ? (this._fillOpacity = typeof _ === "function" ? _ : constant(_), this) : this._fillOpacity;
}
/**
@memberof Shape
@desc If *value* is specified, sets the highlight accessor to the specified function and returns the current class instance.
@param {Function} [*value*]
@chainable
*/
}, {
key: "hover",
value: function hover(_) {
if (!arguments.length || _ === void 0) return this._hover;
this._hover = _;
if (this._group) {
// this._renderImage();
// this._renderLabels();
this._renderHover();
}
return this;
}
/**
@memberof Shape
@desc The style to apply to hovered shapes.
@param {Object} *value*
@chainable
*/
}, {
key: "hoverStyle",
value: function hoverStyle(_) {
return arguments.length ? (this._hoverStyle = assign({}, this._hoverStyle, _), this) : this._hoverStyle;
}
/**
@memberof Shape
@desc If *value* is specified, sets the hover opacity to the specified function and returns the current class instance.
@param {Number} [*value* = 0.5]
@chainable
*/
}, {
key: "hoverOpacity",
value: function hoverOpacity(_) {
return arguments.length ? (this._hoverOpacity = _, this) : this._hoverOpacity;
}
/**
@memberof Shape
@desc If *bounds* is specified, sets the mouse hit area to the specified function and returns the current class instance. If *bounds* is not specified, returns the current mouse hit area accessor.
@param {Function} [*bounds*] The given function is passed the data point, index, and internally defined properties of the shape and should return an object containing the following values: `width`, `height`, `x`, `y`.
@chainable
@example
function(d, i, shape) {
return {
"width": shape.width,
"height": shape.height,
"x": -shape.width / 2,
"y": -shape.height / 2
};
}
*/
}, {
key: "hitArea",
value: function hitArea(_) {
return arguments.length ? (this._hitArea = typeof _ === "function" ? _ : constant(_), this) : this._hitArea;
}
/**
@memberof Shape
@desc If *value* is specified, sets the id accessor to the specified function and returns the current class instance.
@param {Function} [*value*]
@chainable
*/
}, {
key: "id",
value: function id(_) {
return arguments.length ? (this._id = _, this) : this._id;
}
/**
@memberof Shape
@desc If *value* is specified, sets the label accessor to the specified function or string and returns the current class instance.
@param {Function|String|Array} [*value*]
@chainable
*/
}, {
key: "label",
value: function label(_) {
return arguments.length ? (this._label = typeof _ === "function" ? _ : constant(_), this) : this._label;
}
/**
@memberof Shape
@desc If *bounds* is specified, sets the label bounds to the specified function and returns the current class instance. If *bounds* is not specified, returns the current inner bounds accessor.
@param {Function} [*bounds*] The given function is passed the data point, index, and internally defined properties of the shape and should return an object containing the following values: `width`, `height`, `x`, `y`. If an array is returned from the function, each value will be used in conjunction with each label.
@chainable
@example
function(d, i, shape) {
return {
"width": shape.width,
"height": shape.height,
"x": -shape.width / 2,
"y": -shape.height / 2
};
}
*/
}, {
key: "labelBounds",
value: function labelBounds(_) {
return arguments.length ? (this._labelBounds = typeof _ === "function" ? _ : constant(_), this) : this._labelBounds;
}
/**
@memberof Shape
@desc A pass-through to the config method of the TextBox class used to create a shape's labels.
@param {Object} [*value*]
@chainable
*/
}, {
key: "labelConfig",
value: function labelConfig(_) {
return arguments.length ? (this._labelConfig = assign(this._labelConfig, _), this) : this._labelConfig;
}
/**
@memberof Shape
@desc If *value* is specified, sets the opacity accessor to the specified function or number and returns the current class instance.
@param {Number} [*value* = 1]
@chainable
*/
}, {
key: "opacity",
value: function opacity(_) {
return arguments.length ? (this._opacity = typeof _ === "function" ? _ : constant(_), this) : this._opacity;
}
/**
@memberof Shape
@desc If *value* is specified, sets the pointerEvents accessor to the specified function or string and returns the current class instance.
@param {String} [*value*]
@chainable
*/
}, {
key: "pointerEvents",
value: function pointerEvents(_) {
return arguments.length ? (this._pointerEvents = typeof _ === "function" ? _ : constant(_), this) : this._pointerEvents;
}
/**
@memberof Shape
@desc If *value* is specified, sets the role attribute to the specified function or string and returns the current class instance.
@param {Function|String} *value*
@chainable
*/
}, {
key: "role",
value: function role(_) {
return _ !== undefined ? (this._role = typeof _ === "function" ? _ : constant(_), this) : this._role;
}
/**
@memberof Shape
@desc If *value* is specified, sets the rotate accessor to the specified function or number and returns the current class instance.
@param {Function|Number} [*value* = 0]
@chainable
*/
}, {
key: "rotate",
value: function rotate(_) {
return arguments.length ? (this._rotate = typeof _ === "function" ? _ : constant(_), this) : this._rotate;
}
/**
@memberof Shape
@desc Defines the "rx" attribute for the shapes.
@param {Function|Number} [*value* = 0]
@chainable
*/
}, {
key: "rx",
value: function rx(_) {
return arguments.length ? (this._rx = typeof _ === "function" ? _ : constant(_), this) : this._rx;
}
/**
@memberof Shape
@desc Defines the "rx" attribute for the shapes.
@param {Function|Number} [*value* = 0]
@chainable
*/
}, {
key: "ry",
value: function ry(_) {
return arguments.length ? (this._ry = typeof _ === "function" ? _ : constant(_), this) : this._ry;
}
/**
@memberof Shape
@desc If *value* is specified, sets the scale accessor to the specified function or string and returns the current class instance.
@param {Function|Number} [*value* = 1]
@chainable
*/
}, {
key: "scale",
value: function scale(_) {
return arguments.length ? (this._scale = typeof _ === "function" ? _ : constant(_), this) : this._scale;
}
/**
@memberof Shape
@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 Shape
@desc If *value* is specified, sets the shape-rendering accessor to the specified function or string and returns the current class instance.
@param {Function|String} [*value* = "geometricPrecision"]
@chainable
@example
function(d) {
return d.x;
}
*/
}, {
key: "shapeRendering",
value: function shapeRendering(_) {
return arguments.length ? (this._shapeRendering = typeof _ === "function" ? _ : constant(_), this) : this._shapeRendering;
}
/**
@memberof Shape
@desc If *value* is specified, sets the sort comparator to the specified function and returns the current class instance.
@param {false|Function} [*value* = []]
@chainable
*/
}, {
key: "sort",
value: function sort(_) {
return arguments.length ? (this._sort = _, this) : this._sort;
}
/**
@memberof Shape
@desc If *value* is specified, sets the stroke accessor to the specified function or string and returns the current class instance.
@param {Function|String} [*value* = "black"]
@chainable
*/
}, {
key: "stroke",
value: function stroke(_) {
return arguments.length ? (this._stroke = typeof _ === "function" ? _ : constant(_), this) : this._stroke;
}
/**
@memberof Shape
@desc Defines the "stroke-dasharray" attribute for the shapes.
@param {Function|String} [*value* = "1"]
@chainable
*/
}, {
key: "strokeDasharray",
value: function strokeDasharray(_) {
return arguments.length ? (this._strokeDasharray = typeof _ === "function" ? _ : constant(_), this) : this._strokeDasharray;
}
/**
@memberof Shape
@desc Defines the "stroke-linecap" attribute for the shapes. Accepted values are `"butt"`, `"round"`, and `"square"`.
@param {Function|String} [*value* = "butt"]
@chainable
*/
}, {
key: "strokeLinecap",
value: function strokeLinecap(_) {
return arguments.length ? (this._strokeLinecap = typeof _ === "function" ? _ : constant(_), this) : this._strokeLinecap;
}
/**
@memberof Shape
@desc Defines the "stroke-opacity" attribute for the shapes.
@param {Function|Number} [*value* = 1]
@chainable
*/
}, {
key: "strokeOpacity",
value: function strokeOpacity(_) {
return arguments.length ? (this._strokeOpacity = typeof _ === "function" ? _ : constant(_), this) : this._strokeOpacity;
}
/**
@memberof Shape
@desc If *value* is specified, sets the stroke-width accessor to the specified function or string and returns the current class instance.
@param {Function|Number} [*value* = 0]
@chainable
*/
}, {
key: "strokeWidth",
value: function strokeWidth(_) {
return arguments.length ? (this._strokeWidth = typeof _ === "function" ? _ : constant(_), this) : this._strokeWidth;
}
/**
@memberof Shape
@desc If *value* is specified, sets the text-anchor accessor to the specified function or string and returns the current class instance.
@param {Function|String|Array} [*value* = "start"]
@chainable
*/
}, {
key: "textAnchor",
value: function textAnchor(_) {
return arguments.length ? (this._textAnchor = typeof _ === "function" ? _ : constant(_), this) : this._textAnchor;
}
/**
@memberof Shape
@desc If *value* is specified, sets the vector-effect accessor to the specified function or string and returns the current class instance.
@param {Function|String} [*value* = "non-scaling-stroke"]
@chainable
*/
}, {
key: "vectorEffect",
value: function vectorEffect(_) {
return arguments.length ? (this._vectorEffect = typeof _ === "function" ? _ : constant(_), this) : this._vectorEffect;
}
/**
@memberof Shape
@desc If *value* is specified, sets the vertical alignment accessor to the specified function or string and returns the current class instance.
@param {Function|String|Array} [*value* = "start"]
@chainable
*/
}, {
key: "verticalAlign",
value: function verticalAlign(_) {
return arguments.length ? (this._verticalAlign = typeof _ === "function" ? _ : constant(_), this) : this._verticalAlign;
}
/**
@memberof Shape
@desc If *value* is specified, sets the x accessor 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 Shape
@desc If *value* is specified, sets the y accessor 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 Shape;
}(BaseClass);
export { Shape as default };