@data-ui/xy-chart
Version:
A package of charts with standard x- and y- axes. https://williaster.github.io/data-ui
154 lines (148 loc) • 5.16 kB
JavaScript
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import React from 'react';
import PropTypes from 'prop-types';
import { extent } from 'd3-array';
import { color } from '@data-ui/theme';
import { Group } from '@vx/group';
import { Line } from '@vx/shape';
import { callOrValue, isDefined } from '../utils/chartUtils';
var GROUP_STYLE = {
pointerEvents: 'none'
};
var propTypes = {
fullHeight: PropTypes.bool,
fullWidth: PropTypes.bool,
circleSize: PropTypes.oneOfType([PropTypes.func, PropTypes.number]),
circleFill: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
circleStroke: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
circleStyles: PropTypes.oneOfType([PropTypes.func, PropTypes.objectOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string]))]),
lineStyles: PropTypes.objectOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string])),
showCircle: PropTypes.bool,
showMultipleCircles: PropTypes.bool,
showHorizontalLine: PropTypes.bool,
showVerticalLine: PropTypes.bool,
stroke: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
strokeDasharray: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
strokeWidth: PropTypes.oneOfType([PropTypes.func, PropTypes.number]),
// likely injected by parent
datum: PropTypes.object,
// eslint-disable-line react/forbid-prop-types
series: PropTypes.objectOf(PropTypes.object),
getScaledX: PropTypes.func,
getScaledY: PropTypes.func,
xScale: PropTypes.func,
yScale: PropTypes.func
};
var defaultProps = {
circleSize: 4,
circleFill: color.grays[7],
circleStroke: '#ffffff',
circleStyles: {
pointerEvents: 'none'
},
datum: {},
getScaledX: null,
getScaledY: null,
lineStyles: {
pointerEvents: 'none'
},
fullHeight: false,
fullWidth: false,
series: {},
showCircle: true,
showMultipleCircles: false,
showHorizontalLine: true,
showVerticalLine: true,
stroke: color.grays[6],
strokeDasharray: '5,2',
strokeWidth: 1,
xScale: null,
yScale: null
};
function CrossHair(_ref) {
var circleFill = _ref.circleFill,
circleSize = _ref.circleSize,
circleStroke = _ref.circleStroke,
circleStyles = _ref.circleStyles,
datum = _ref.datum,
getScaledX = _ref.getScaledX,
getScaledY = _ref.getScaledY,
fullHeight = _ref.fullHeight,
fullWidth = _ref.fullWidth,
lineStyles = _ref.lineStyles,
series = _ref.series,
showHorizontalLine = _ref.showHorizontalLine,
showCircle = _ref.showCircle,
showMultipleCircles = _ref.showMultipleCircles,
showVerticalLine = _ref.showVerticalLine,
stroke = _ref.stroke,
strokeDasharray = _ref.strokeDasharray,
strokeWidth = _ref.strokeWidth,
xScale = _ref.xScale,
yScale = _ref.yScale;
if (!xScale || !yScale || !getScaledX || !getScaledY) return null;
var _extent = extent(xScale.range()),
xMin = _extent[0],
xMax = _extent[1];
var _extent2 = extent(yScale.range()),
yMin = _extent2[0],
yMax = _extent2[1];
var circleData = showMultipleCircles && series && Object.keys(series).length > 0 ? Object.keys(series).map(function (seriesKey) {
return _extends({
seriesKey: seriesKey
}, series[seriesKey]);
}) : [datum];
var circlePositions = circleData.map(function (d) {
return {
x: getScaledX(d),
y: getScaledY(d)
};
});
return React.createElement(Group, {
style: GROUP_STYLE
}, showHorizontalLine && !showMultipleCircles && isDefined(circlePositions[0].y) && React.createElement(Line, {
from: {
x: xMin,
y: circlePositions[0].y
},
to: {
x: fullWidth ? xMax : circlePositions[0].x,
y: circlePositions[0].y
},
style: lineStyles,
stroke: stroke,
strokeDasharray: strokeDasharray,
strokeWidth: strokeWidth
}), showVerticalLine && isDefined(circlePositions[0].x) && React.createElement(Line, {
from: {
x: circlePositions[0].x,
y: yMax
},
to: {
x: circlePositions[0].x,
y: fullHeight ? yMin : circlePositions[0].y
},
style: lineStyles,
stroke: stroke,
strokeDasharray: strokeDasharray,
strokeWidth: strokeWidth
}), (showCircle || showMultipleCircles) && circleData.map(function (d, i) {
var _circlePositions$i = circlePositions[i],
x = _circlePositions$i.x,
y = _circlePositions$i.y;
return isDefined(x) && isDefined(y) && React.createElement("circle", {
key: "circle-" + (d.seriesKey || i),
cx: x,
cy: y,
r: callOrValue(circleSize, d, i),
fill: callOrValue(circleFill, d, i),
strokeWidth: 1,
stroke: callOrValue(circleStroke, d, i),
style: callOrValue(circleStyles, d, i)
});
}));
}
CrossHair.propTypes = propTypes;
CrossHair.defaultProps = defaultProps;
CrossHair.displayName = 'CrossHair';
export default CrossHair;