victory-native
Version:
A charting library for React Native with a focus on performance and customization.
130 lines (129 loc) • 6.49 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.YAxis = exports.YAxisDefaults = void 0;
const react_1 = __importDefault(require("react"));
const react_native_skia_1 = require("@shopify/react-native-skia");
const boundsToClip_1 = require("../../utils/boundsToClip");
const getAxisTitleLayout_1 = require("../utils/getAxisTitleLayout");
const getAxisLabelLayout_1 = require("../utils/getAxisLabelLayout");
var axisDefaults_1 = require("../utils/axisDefaults");
Object.defineProperty(exports, "YAxisDefaults", { enumerable: true, get: function () { return axisDefaults_1.YAxisDefaults; } });
const YAxis = ({ xScale, yScale, yTicksNormalized, axisSide, labelPosition, labelOffset, labelColor, lineWidth, lineColor, font, title, labelRenderer, formatYLabel = (label) => String(label), linePathEffect, chartBounds, orientation, }) => {
var _a;
const [x1 = 0, x2 = 0] = xScale.domain();
const [_ = 0, y2 = 0] = yScale.domain();
const fontSize = (_a = font === null || font === void 0 ? void 0 : font.getSize()) !== null && _a !== void 0 ? _a : 0;
const yTickLabels = yTicksNormalized.map((tick, index) => {
const contentY = String(formatYLabel(tick));
const labelLayout = (0, getAxisLabelLayout_1.getAxisLabelLayout)({
axis: "y",
orientation,
value: tick,
text: contentY,
index,
font,
labelRenderer,
});
return {
tick,
labelLayout,
};
});
const maxYLabelWidth = Math.max(0, ...yTickLabels.map(({ labelLayout }) => labelLayout.width));
const labelOutset = labelPosition === "outset" && yTickLabels.length > 0 && maxYLabelWidth > 0
? maxYLabelWidth + labelOffset
: 0;
const titleLayout = (0, getAxisTitleLayout_1.getAxisTitleLayout)({ title, font });
const titleFont = titleLayout.font;
const titleBaselineY = (0, getAxisTitleLayout_1.getRotatedYAxisTitleBaselineY)(titleLayout);
const titleX = axisSide === "left"
? chartBounds.left - labelOutset - titleLayout.offset
: chartBounds.right + labelOutset + titleLayout.offset;
const titleCenterY = (() => {
if (titleLayout.position === "start") {
return chartBounds.top + titleLayout.width / 2;
}
if (titleLayout.position === "end") {
return chartBounds.bottom - titleLayout.width / 2;
}
return chartBounds.top + (chartBounds.bottom - chartBounds.top) / 2;
})();
const titleNodes = titleLayout.hasContent && titleFont
? titleLayout.lines.map((line, index) => {
var _a;
return (<react_native_skia_1.Text key={`y-axis-title-line-${index}`} color={(_a = titleLayout.color) !== null && _a !== void 0 ? _a : labelColor} text={line} font={titleFont} y={titleBaselineY + index * titleLayout.lineHeight} x={-titleLayout.width / 2}/>);
})
: null;
const yAxisNodes = yTickLabels.map(({ tick, labelLayout }) => {
const labelWidth = labelLayout.width;
const labelY = yScale(tick) +
fontSize / 3 -
Math.max(0, labelLayout.height - fontSize) / 2;
const labelX = (() => {
// left, outset
if (axisSide === "left" && labelPosition === "outset") {
return chartBounds.left - (labelWidth + labelOffset);
}
// left, inset
if (axisSide === "left" && labelPosition === "inset") {
return chartBounds.left + labelOffset;
}
// right, outset
if (axisSide === "right" && labelPosition === "outset") {
return chartBounds.right + labelOffset;
}
// right, inset
return chartBounds.right - (labelWidth + labelOffset);
})();
const labelTopY = yScale(tick) - labelLayout.height / 2;
const lastLabelY = labelY + (labelLayout.lines.length - 1) * labelLayout.lineHeight;
const canFitLabelContent = labelY > fontSize && lastLabelY < yScale(y2);
const canFitCustomLabel = labelTopY >= chartBounds.top &&
labelTopY + labelLayout.height <= chartBounds.bottom;
return (<react_1.default.Fragment key={`y-tick-${tick}`}>
{lineWidth > 0 ? (<react_native_skia_1.Group clip={(0, boundsToClip_1.boundsToClip)(chartBounds)}>
<react_native_skia_1.Line p1={(0, react_native_skia_1.vec)(xScale(x1), yScale(tick))} p2={(0, react_native_skia_1.vec)(xScale(x2), yScale(tick))} color={lineColor} strokeWidth={lineWidth}>
{linePathEffect ? linePathEffect : null}
</react_native_skia_1.Line>
</react_native_skia_1.Group>) : null}
{labelRenderer
? labelWidth > 0 && labelLayout.height > 0
? labelRenderer.render({
axis: "y",
orientation,
value: labelLayout.value,
text: labelLayout.text,
index: labelLayout.index,
x: labelX,
y: labelTopY,
width: labelLayout.width,
height: labelLayout.height,
fontSize: labelLayout.fontSize,
lineHeight: labelLayout.lineHeight,
color: labelColor,
canFitContent: canFitCustomLabel,
chartBounds,
})
: null
: font
? canFitLabelContent && (<>
{labelLayout.lines.map((line, index) => (<react_native_skia_1.Text key={`y-tick-${tick}-label-line-${index}`} color={labelColor} text={line} font={font} y={labelY + index * labelLayout.lineHeight} x={labelX}/>))}
</>)
: null}
</react_1.default.Fragment>);
});
return (<>
{yAxisNodes}
{titleNodes ? (<react_native_skia_1.Group transform={[
{ translateX: titleX },
{ translateY: titleCenterY },
{ rotate: axisSide === "right" ? Math.PI / 2 : -Math.PI / 2 },
]}>
{titleNodes}
</react_native_skia_1.Group>) : null}
</>);
};
exports.YAxis = YAxis;