victory-axis
Version:
Axis Component for Victory
176 lines (172 loc) • 7.35 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.VictoryAxis = void 0;
var _react = _interopRequireDefault(require("react"));
var _isEmpty = _interopRequireDefault(require("lodash/isEmpty"));
var _victoryCore = require("victory-core");
var _helperMethods = require("./helper-methods");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const fallbackProps = {
width: 450,
height: 300,
padding: 50
};
const options = {
components: [{
name: "axis",
index: 0
}, {
name: "axisLabel",
index: 0
}, {
name: "grid"
}, {
name: "parent",
index: "parent"
}, {
name: "ticks"
}, {
name: "tickLabels"
}]
};
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
class VictoryAxisBase extends _react.default.Component {
static animationWhitelist = ["style", "domain", "range", "tickCount", "tickValues", "offsetX", "offsetY", "padding", "width", "height"];
static displayName = "VictoryAxis";
static role = "axis";
static defaultTransitions = {
onExit: {
duration: 500
},
onEnter: {
duration: 500
}
};
static defaultProps = {
axisComponent: /*#__PURE__*/_react.default.createElement(_victoryCore.LineSegment, null),
axisLabelComponent: /*#__PURE__*/_react.default.createElement(_victoryCore.VictoryLabel, null),
tickLabelComponent: /*#__PURE__*/_react.default.createElement(_victoryCore.VictoryLabel, null),
tickComponent: /*#__PURE__*/_react.default.createElement(_victoryCore.LineSegment, null),
gridComponent: /*#__PURE__*/_react.default.createElement(_victoryCore.LineSegment, null),
standalone: true,
theme: _victoryCore.VictoryTheme.grayscale,
containerComponent: /*#__PURE__*/_react.default.createElement(_victoryCore.VictoryContainer, null),
groupComponent: /*#__PURE__*/_react.default.createElement("g", {
role: "presentation"
}),
fixLabelOverlap: false
};
static getDomain = _victoryCore.Axis.getDomain;
static getAxis = _victoryCore.Axis.getAxis;
static getStyles(props) {
return (0, _helperMethods.getStyles)(props);
}
static getBaseProps(props) {
return (0, _helperMethods.getBaseProps)(props, fallbackProps);
}
static expectedComponents = ["axisComponent", "axisLabelComponent", "groupComponent", "containerComponent", "tickComponent", "tickLabelComponent", "gridComponent"];
renderLine(props) {
const {
axisComponent
} = props;
const axisProps = this.getComponentProps(axisComponent, "axis", 0);
return /*#__PURE__*/_react.default.cloneElement(axisComponent, axisProps);
}
renderLabel(props) {
const {
axisLabelComponent,
label
} = props;
if (!label) {
return null;
}
const axisLabelProps = this.getComponentProps(axisLabelComponent, "axisLabel", 0);
return /*#__PURE__*/_react.default.cloneElement(axisLabelComponent, axisLabelProps);
}
renderGridAndTicks(props) {
const {
tickComponent,
tickLabelComponent,
gridComponent,
name
} = props;
const shouldRender = componentProps => {
const {
style = {},
events = {}
} = componentProps;
const visible = style.stroke !== "transparent" && style.stroke !== "none" && style.strokeWidth !== 0;
return visible || !(0, _isEmpty.default)(events);
};
return this.dataKeys.map((key, index) => {
const tickProps = this.getComponentProps(tickComponent, "ticks", index);
const BaseTickComponent = /*#__PURE__*/_react.default.cloneElement(tickComponent, tickProps);
const TickComponent = shouldRender(BaseTickComponent.props) ? BaseTickComponent : undefined;
const gridProps = this.getComponentProps(gridComponent, "grid", index);
const BaseGridComponent = /*#__PURE__*/_react.default.cloneElement(gridComponent, gridProps);
const GridComponent = shouldRender(BaseGridComponent.props) ? BaseGridComponent : undefined;
const tickLabelProps = this.getComponentProps(tickLabelComponent, "tickLabels", index);
const TickLabel = /*#__PURE__*/_react.default.cloneElement(tickLabelComponent, tickLabelProps);
const children = [GridComponent, TickComponent, TickLabel].filter(Boolean);
return /*#__PURE__*/_react.default.cloneElement(props.groupComponent, {
key: `${name}-tick-group-${key}`
}, children);
});
}
fixLabelOverlap(gridAndTicks, props) {
const isVertical = _victoryCore.Axis.isVertical(props);
const size = isVertical ? props.height : props.width;
const isVictoryLabel = child => child.type && child.type.role === "label";
const labels = gridAndTicks.map(gridAndTick => gridAndTick.props.children).reduce((accumulator, childArr) => accumulator.concat(childArr), []).filter(isVictoryLabel).map(child => child.props);
const paddingToObject = padding => typeof padding === "object" ? Object.assign({}, {
top: 0,
right: 0,
bottom: 0,
left: 0
}, padding) : {
top: padding,
right: padding,
bottom: padding,
left: padding
};
const labelsSumSize = labels.reduce((sum, label) => {
const padding = paddingToObject(label.style.padding);
const labelSize = _victoryCore.TextSize.approximateTextSize(label.text, {
angle: label.angle,
fontSize: label.style.fontSize,
letterSpacing: label.style.letterSpacing,
fontFamily: label.style.fontFamily
});
return sum + (isVertical ? labelSize.height + padding.top + padding.bottom : labelSize.width + padding.right + padding.left);
}, 0);
const availiableLabelCount = Math.floor(size * gridAndTicks.length / labelsSumSize);
const divider = Math.ceil(gridAndTicks.length / availiableLabelCount) || 1;
const getLabelCoord = gridAndTick => gridAndTick.props.children.filter(isVictoryLabel).reduce((prev, child) => (isVertical ? child.props.y : child.props.x) || 0, 0);
const sorted = gridAndTicks.sort((a, b) => isVertical ? getLabelCoord(b) - getLabelCoord(a) // ordinary axis has top-bottom orientation
: getLabelCoord(a) - getLabelCoord(b) // ordinary axis has left-right orientation
);
return sorted.filter((gridAndTick, index) => index % divider === 0);
}
// Overridden in native versions
shouldAnimate() {
return !!this.props.animate;
}
render() {
const {
animationWhitelist
} = VictoryAxis;
const props = _victoryCore.Axis.modifyProps(this.props, fallbackProps);
const userProps = _victoryCore.UserProps.getSafeUserProps(this.props);
if (this.shouldAnimate()) {
return this.animateComponent(props, animationWhitelist);
}
const gridAndTicks = this.renderGridAndTicks(props);
const modifiedGridAndTicks = props.fixLabelOverlap ? this.fixLabelOverlap(gridAndTicks, props) : gridAndTicks;
const children = [this.renderLine(props), this.renderLabel(props), ...modifiedGridAndTicks];
const container = /*#__PURE__*/_react.default.cloneElement(props.containerComponent, userProps);
return props.standalone ? this.renderContainer(container, children) : /*#__PURE__*/_react.default.cloneElement(props.groupComponent, userProps, children);
}
}
const VictoryAxis = exports.VictoryAxis = (0, _victoryCore.addEvents)(VictoryAxisBase, options);