@patternfly/react-charts
Version:
This library provides a set of React chart components for use with the PatternFly reference implementation.
218 lines • 9.78 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getLegendTooltipVisibleText = exports.getLegendTooltipVisibleData = exports.getLegendTooltipSize = exports.getLegendTooltipDataProps = exports.getCursorTooltipPoniterOrientation = exports.getCursorTooltipCenterOffset = void 0;
const tslib_1 = require("tslib");
const chart_color_black_500_1 = tslib_1.__importDefault(require('@patternfly/react-tokens/dist/js/chart_color_black_500'));
const victory_core_1 = require("victory-core");
const ChartStyles_1 = require("../ChartTheme/ChartStyles");
const chart_legend_1 = require("./chart-legend");
const merge_1 = tslib_1.__importDefault(require("lodash/merge"));
/**
* When using a cursor container, the tooltip can be offset from the cursor point. If offsetCursorDimensionX is true,
* the tooltip will appear to the right the vertical cursor. If offsetCursorDimensionY is true, the tooltip will appear
* above the vertical cursor.
*
* @private Not intended as public API and subject to change
*/
const getCursorTooltipCenterOffset = ({ offsetCursorDimensionX = false, offsetCursorDimensionY = false, theme }) => {
const pointerLength = theme && theme.tooltip ? victory_core_1.Helpers.evaluateProp(theme.tooltip.pointerLength, undefined) : 10;
const offsetX = ({ center, flyoutWidth, width }) => {
const offset = flyoutWidth / 2 + pointerLength;
return width > center.x + flyoutWidth + pointerLength ? offset : -offset;
};
const offsetY = ({ center, flyoutHeight, width }) => {
const offset = flyoutHeight / 2 + pointerLength;
return width > center.y + flyoutHeight + pointerLength ? -offset : offset;
};
return {
x: offsetCursorDimensionX ? offsetX : 0,
y: offsetCursorDimensionY ? offsetY : 0
};
};
exports.getCursorTooltipCenterOffset = getCursorTooltipCenterOffset;
/**
* When using a cursor container, the tooltip pointer orientation can be adjusted as the cursor approaches the edge of
* the chart. If horizontal is true, the tooltip pointer will either be 'left' or 'right'. If horizontal is true, the
* tooltip pointer will either be 'top' or 'bottom'.
*
* @private Not intended as public API and subject to change
*/
const getCursorTooltipPoniterOrientation = ({ horizontal = true, theme }) => {
const pointerLength = theme && theme.tooltip ? victory_core_1.Helpers.evaluateProp(theme.tooltip.pointerLength, undefined) : 10;
const orientationX = ({ center, flyoutWidth, width }) => width > center.x + flyoutWidth + pointerLength ? 'left' : 'right';
const orientationY = ({ center, flyoutHeight, height }) => height > center.y + flyoutHeight + pointerLength ? 'top' : 'bottom';
return horizontal ? orientationX : orientationY;
};
exports.getCursorTooltipPoniterOrientation = getCursorTooltipPoniterOrientation;
/**
* Returns props associated with legend data
*
* @private Not intended as public API and subject to change
*/
const getLegendTooltipDataProps = (props) => (0, merge_1.default)({
borderPadding: 0,
gutter: 0,
orientation: 'vertical',
padding: 0,
rowGutter: 0,
style: {
labels: {
fill: ChartStyles_1.ChartLegendTooltipStyles.label.fill,
lineHeight: 0.275,
padding: 0
},
title: {
fill: ChartStyles_1.ChartLegendTooltipStyles.label.fill,
padding: 0
}
}
}, Object.assign({}, props));
exports.getLegendTooltipDataProps = getLegendTooltipDataProps;
/**
* Returns the legend height and width
*
* @private Not intended as public API and subject to change
*/
const getLegendTooltipSize = ({ legendData, legendOrientation = 'vertical', legendProps, minSpacing = 2, // Adjust min spacing, see https://issues.redhat.com/browse/COST-5648
text = '', theme }) => {
const textEvaluated = victory_core_1.Helpers.evaluateProp(text, undefined);
const _text = Array.isArray(textEvaluated) ? textEvaluated : [textEvaluated];
// Find max char lengths
let maxDataLength = 0;
let maxTextLength = 0;
_text.map((item, index) => {
if (typeof item === 'number') {
return;
}
if (item) {
if (item.length > maxTextLength) {
maxTextLength = item.length;
}
const hasData = legendData && legendData[index] && legendData[index].name !== undefined;
if (hasData) {
if (legendData[index].name.length > maxDataLength) {
maxDataLength = legendData[index].name.length;
}
}
}
});
// Set length to ensure minimum spacing between label and value
const maxLength = maxDataLength + maxTextLength + minSpacing;
// Get spacing to help align legend labels and text values
const spacer = 'x';
const getSpacing = (legendLabel, textLabel) => {
let spacing = '\u00A0';
if (maxLength === 0) {
return spacing;
}
const legendLabelChars = legendLabel ? legendLabel.length : 0;
const textLabelChars = textLabel ? textLabel.length : 0;
const maxChars = legendLabelChars + textLabelChars;
// Add spacer
while (spacing.length < maxLength - maxChars) {
spacing += spacer;
}
return spacing;
};
// Format all text (similar to below) to help determine overall width.
//
// {name: "Cats no data"}
// {name: "Dogs 1"}
// {name: "Birds 4"}
// {name: "Mice 3"}
const data = _text.map((label, index) => {
if (typeof label === 'number') {
return;
}
const hasData = legendData && legendData[index] && legendData[index].name !== undefined;
const spacing = hasData ? getSpacing(legendData[index].name, label) : '';
return {
name: `${hasData ? legendData[index].name : ''}${spacing}${label}`
};
});
// Replace whitespace with spacer char for consistency in width
const formattedData = data.map((val) => ({
name: val.name.replace(/ /g, spacer)
}));
// This should include both legend data and text
const widthDimensions = (0, chart_legend_1.getLegendDimensions)({
legendData: formattedData,
legendOrientation,
legendProps,
theme
});
// This should only use text. The row gutter changes when displaying all "no data" messages
const heightDimensions = (0, chart_legend_1.getLegendDimensions)({
legendData: _text.map((name) => ({ name })),
legendOrientation,
legendProps,
theme
});
return {
height: heightDimensions.height,
width: widthDimensions.width > 0 ? widthDimensions.width : 0
};
};
exports.getLegendTooltipSize = getLegendTooltipSize;
/**
* Returns visible legend data, while syncing color scale. If textAsLegendData is true, the text prop is used as
* legend data so y values can be passed individually to the label component
*
* @private Not intended as public API and subject to change
*/
const getLegendTooltipVisibleData = ({ activePoints, colorScale, legendData, patternScale, text, textAsLegendData = false, theme }) => {
const textEvaluated = victory_core_1.Helpers.evaluateProp(text, undefined);
const _text = Array.isArray(textEvaluated) ? textEvaluated : [textEvaluated];
const result = [];
// Sync data with interactive legends
if (legendData) {
let index = -1;
for (let i = 0; i < legendData.length; i++) {
const data = legendData[i];
const activePoint = activePoints ? activePoints.find((item) => item.childName === data.childName) : '';
if (!activePoint ||
(data.symbol && data.symbol.type === 'eyeSlash' && data.symbol.fill === chart_color_black_500_1.default.var)) {
continue; // Skip hidden data
}
if (index++ < _text.length - 1) {
const themeColor = theme && theme.legend && theme.legend.colorScale
? theme.legend.colorScale[i % theme.legend.colorScale.length]
: undefined;
const color = colorScale ? colorScale[i % colorScale.length] : themeColor; // Sync color scale
const pattern = patternScale ? patternScale[i % patternScale.length] : undefined;
result.push({
name: textAsLegendData ? _text[index] : data.name,
symbol: Object.assign({ fill: pattern ? pattern : color }, data.symbol)
});
}
}
}
return result;
};
exports.getLegendTooltipVisibleData = getLegendTooltipVisibleData;
/**
* Returns visible text for interactive legends
*
* @private Not intended as public API and subject to change
*/
const getLegendTooltipVisibleText = ({ activePoints, legendData, text }) => {
const textEvaluated = victory_core_1.Helpers.evaluateProp(text, undefined);
const _text = Array.isArray(textEvaluated) ? textEvaluated : [textEvaluated];
const result = [];
if (legendData) {
let index = -1;
for (const data of legendData) {
const activePoint = activePoints ? activePoints.find((item) => item.childName === data.childName) : '';
if (!activePoint ||
(data.symbol && data.symbol.type === 'eyeSlash' && data.symbol.fill === chart_color_black_500_1.default.var)) {
continue; // Skip hidden data
}
if (index++ < _text.length - 1) {
result.push(_text[index]);
}
}
}
return result;
};
exports.getLegendTooltipVisibleText = getLegendTooltipVisibleText;
//# sourceMappingURL=chart-tooltip.js.map