UNPKG

lucid-ui

Version:

A UI component library from Xandr.

221 lines 10.7 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Axis = void 0; var lodash_1 = __importDefault(require("lodash")); var react_1 = __importDefault(require("react")); var prop_types_1 = __importDefault(require("prop-types")); var style_helpers_1 = require("../../util/style-helpers"); var chart_helpers_1 = require("../../util/chart-helpers"); var cx = style_helpers_1.lucidClassNames.bind('&-Axis'); var string = prop_types_1.default.string, array = prop_types_1.default.array, func = prop_types_1.default.func, number = prop_types_1.default.number, oneOf = prop_types_1.default.oneOf; var defaultProps = { innerTickSize: 6, outerTickSize: 6, tickPadding: 3, textOrientation: 'horizontal', orient: 'bottom', tickCount: null, }; var Axis = function (props) { var className = props.className, scale = props.scale, orient = props.orient, tickCount = props.tickCount, _a = props.ticks, ticks = _a === void 0 ? 'ticks' in scale ? scale.ticks(tickCount) : (0, chart_helpers_1.discreteTicks)(scale.domain(), tickCount) : _a, // ordinal scales don't have `ticks` but they do have `domains` innerTickSize = props.innerTickSize, outerTickSize = props.outerTickSize, _b = props.tickFormat, tickFormat = _b === void 0 ? 'tickFormat' in scale ? scale.tickFormat() : lodash_1.default.identity : _b, tickPadding = props.tickPadding, textOrientation = props.textOrientation, passThroughs = __rest(props, ["className", "scale", "orient", "tickCount", "ticks", "innerTickSize", "outerTickSize", "tickFormat", "tickPadding", "textOrientation"]); var tickSpacing = Math.max(innerTickSize, 0) + tickPadding; // Domain var range = scale.range(); var sign = orient === 'top' || orient === 'left' ? -1 : 1; var isH = orient === 'top' || orient === 'bottom'; // is horizontal var getOrientationProperties = function (orient, textOrientation) { var textAnchor, x, y, dy; var orientationSign = sign; var transform = textOrientation === 'vertical' ? 'rotate(-90)' : textOrientation === 'horizontal' ? '' : 'rotate(-30)'; switch (orient) { case 'bottom': if (textOrientation === 'vertical') { orientationSign = -orientationSign; } textAnchor = textOrientation === 'vertical' ? 'end' : textOrientation === 'diagonal' ? 'end' : 'middle'; x = textOrientation === 'vertical' ? orientationSign * tickSpacing : textOrientation === 'diagonal' ? -orientationSign * tickSpacing : 0; y = textOrientation === 'vertical' ? 0 : orientationSign * tickSpacing; dy = textOrientation === 'vertical' ? '.32em' : '.71em'; break; case 'top': if (textOrientation === 'vertical') { orientationSign = -orientationSign; } textAnchor = textOrientation === 'vertical' ? 'start' : textOrientation === 'diagonal' ? 'start' : 'middle'; x = textOrientation === 'vertical' || textOrientation === 'diagonal' ? -orientationSign * tickSpacing : 0; y = textOrientation === 'vertical' ? 0 : orientationSign * tickSpacing; dy = textOrientation === 'vertical' || textOrientation === 'diagonal' ? '.32em' : '0em'; break; case 'right': textAnchor = textOrientation === 'vertical' ? 'middle' : 'start'; x = textOrientation === 'vertical' ? 0 : orientationSign * tickSpacing; y = textOrientation === 'vertical' ? orientationSign * tickSpacing : textOrientation === 'horizontal' ? 0 : orientationSign * tickSpacing; dy = textOrientation === 'vertical' ? '.71em' : '.32em'; break; case 'left': textAnchor = textOrientation === 'vertical' ? 'middle' : 'end'; x = textOrientation === 'vertical' ? 0 : orientationSign * tickSpacing; y = textOrientation === 'vertical' || textOrientation === 'diagonal' ? orientationSign * tickSpacing : 0; dy = textOrientation === 'vertical' ? '0em' : textOrientation === 'horizontal' ? '.32em' : '.71em'; break; default: textAnchor = 'start'; x = 0; y = 0; dy = 'null'; } return { transform: transform, textAnchor: textAnchor, x: x, y: y, dy: dy, }; }; var orientationProperties = { vertical: getOrientationProperties(orient, 'vertical'), horizontal: getOrientationProperties(orient, 'horizontal'), diagonal: getOrientationProperties(orient, 'diagonal'), }; var orientationKey = textOrientation || 'horizontal'; // Only band scales have `bandwidth`, this conditional helps center the // ticks on the bands var scaleNormalized = 'bandwidth' in scale ? function (d) { return scale(d) + scale.bandwidth() / 2; } : scale; return (react_1.default.createElement("g", __assign({}, passThroughs, { className: cx(className, '&') }), isH ? (react_1.default.createElement("path", { className: cx('&-domain'), d: "M".concat(range[0], ",").concat(sign * outerTickSize, "V0H").concat(range[1], "V").concat(sign * outerTickSize) })) : (react_1.default.createElement("path", { className: cx('&-domain'), d: "M".concat(sign * outerTickSize, ",").concat(range[0], "H0V").concat(range[1], "H").concat(sign * outerTickSize) })), lodash_1.default.map(ticks, function (tick) { return (react_1.default.createElement("g", { key: tick, transform: "translate(".concat(isH ? scaleNormalized(tick) : 0, ", ").concat(isH ? 0 : scaleNormalized(tick), ")") }, react_1.default.createElement("line", { className: cx('&-tick'), x2: isH ? 0 : sign * innerTickSize, y2: isH ? sign * innerTickSize : 0 }), react_1.default.createElement("text", { className: cx('&-tick-text'), x: orientationProperties[orientationKey].x, y: orientationProperties[orientationKey].y, dy: orientationProperties[orientationKey].dy, style: { textAnchor: orientationProperties[orientationKey].textAnchor, }, transform: orientationProperties[orientationKey].transform }, tickFormat(tick)))); }))); }; exports.Axis = Axis; exports.Axis.defaultProps = defaultProps; exports.Axis.displayName = 'Axis'; exports.Axis.peek = { description: "`Axis` is used within an `svg`. An `Axis` is used to help render human-readable reference marks on charts. It can either be horizontal or vertical and really only needs a scale to be able to draw properly. This component is a very close sister to d3's svg axis and most of the logic was ported from there.", categories: ['visualizations', 'chart primitives'], }; exports.Axis.propTypes = { /** Appended to the component-specific class names set on the root element. */ className: string, /** Must be a d3 scale. Lucid exposes the \`lucid.d3Scale\` library for use here. */ scale: func.isRequired, /** Size of the ticks for each discrete tick mark. */ innerTickSize: number, /** Size of the tick marks found at the beginning and end of the axis. It's common to set this to \`0\` to remove them. */ outerTickSize: number, /** An optional function that can format ticks. Generally this shouldn't be needed since d3 has very good default formatters for most data. Signature: \`(tick) => {}\` */ tickFormat: func, /** If you need fine grained control over the axis ticks, you can pass them in this array. */ ticks: array, /** Determines the spacing between each tick and its text. */ tickPadding: number, /** Determines the orientation of the ticks. \`left\` and \`right\` will generate a vertical axis, whereas \`top\` and \`bottom\` will generate a horizontal axis. */ orient: oneOf(['top', 'bottom', 'left', 'right']), /** Control the number of ticks displayed. If the scale is time based or linear, this number acts a "hint" per the default behavior of D3. If it's an ordinal scale, this number is treated as an absolute number of ticks to display and is powered by our own utility function \`discreteTicks\`. */ tickCount: number, /** Determines the orientation of the tick text. This may override what the orient prop tries to determine. This defaults to \`horizontal\`. */ textOrientation: oneOf(['vertical', 'horizontal', 'diagonal']), }; exports.default = exports.Axis; //# sourceMappingURL=Axis.js.map