Skip to content

Commit

Permalink
Merge pull request #82 from williaster/chris--bugz
Browse files Browse the repository at this point in the history
[xy-chart] consider deltaX in findClosestDatums, fix tickLabelProps bug in <*Axis />
  • Loading branch information
williaster authored Dec 8, 2017
2 parents 2a72bc7 + 3a594de commit a2eae66
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 9 deletions.
1 change: 0 additions & 1 deletion packages/demo/examples/01-xy-chart/LineSeriesExample.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ class LineSeriesExample extends React.PureComponent {

eventTriggerRefs(triggers) {
this.triggers = triggers;
this.triggerTooltip();
}

triggerTooltip() {
Expand Down
6 changes: 4 additions & 2 deletions packages/xy-chart/src/axis/XAxis.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,11 @@ export default class XAxis extends React.PureComponent {
if (!scale || !innerHeight) return null;
const Axis = orientation === 'bottom' ? AxisBottom : AxisTop;

const tickLabelProps = passedTickLabelProps ||
(tickStyles.label && tickStyles.label[orientation])
let tickLabelProps = passedTickLabelProps;
if (!tickLabelProps) {
tickLabelProps = (tickStyles.label && tickStyles.label[orientation])
? () => tickStyles.label[orientation] : undefined;
}

return (
<Axis
Expand Down
6 changes: 4 additions & 2 deletions packages/xy-chart/src/axis/YAxis.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,11 @@ export default class YAxis extends React.PureComponent {

const Axis = orientation === 'left' ? AxisLeft : AxisRight;

const tickLabelProps = passedTickLabelProps ||
(tickStyles.label && tickStyles.label[orientation])
let tickLabelProps = passedTickLabelProps;
if (!tickLabelProps) {
tickLabelProps = (tickStyles.label && tickStyles.label[orientation])
? () => tickStyles.label[orientation] : undefined;
}

return (
<Axis
Expand Down
11 changes: 7 additions & 4 deletions packages/xy-chart/src/utils/findClosestDatums.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,22 @@ export default function findClosestDatums({
getX,
getY,
event,
maxXDistancePx = 25,
maxXDistancePx = 1000,
}) {
if (!event || !event.target || !event.target.ownerSVGElement) return null;
const series = {};

const gElement = event.target.ownerSVGElement.firstChild;
const { x: mouseX, y: mouseY } = localPoint(gElement, event);
let closestDatum;
let minDelta = Infinity;
let minDeltaX = Infinity;
let minDeltaY = Infinity;

// collect data from all series that have an x value near this point
Children.forEach(children, (Child, childIndex) => {
if (isSeries(componentName(Child)) && !Child.props.disableMouseEvents) {
const { data, seriesKey } = Child.props;

// @TODO data should be sorted, come up with a way to enforce+cache instead of relying on user
const datum = findClosestDatum({
data,
Expand All @@ -39,8 +41,9 @@ export default function findClosestDatums({
const key = seriesKey || childIndex; // fall back to child index
series[key] = datum;
const deltaY = Math.abs(yScale(getY(datum)) - mouseY);
closestDatum = deltaY < minDelta ? datum : closestDatum;
minDelta = Math.min(deltaY, minDelta);
closestDatum = deltaY < minDeltaY && deltaX <= minDeltaX ? datum : closestDatum;
minDeltaX = closestDatum === datum ? deltaX : minDeltaX;
minDeltaY = closestDatum === datum ? deltaY : minDeltaY;
}
}
});
Expand Down
67 changes: 67 additions & 0 deletions packages/xy-chart/test/axis/XAxis.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import { shallow } from 'enzyme';
import AxisBottom from '@vx/axis/build/axis/AxisBottom';
import AxisTop from '@vx/axis/build/axis/AxisTop';
import scaleLinear from '@vx/scale/build/scales/linear';
import { XYChart, XAxis, LineSeries } from '../../src/';

describe('<XAxis />', () => {
Expand Down Expand Up @@ -83,4 +84,70 @@ describe('<XAxis />', () => {
const tick = wrapper.render().find('.vx-axis-tick').first();
expect(tick.find('text').text()).toBe(tickFormat());
});

test('tickLabelProps should be passed tick value and indexif passed, and tickStyles.label[orientation] if not', () => {
const props = {
scale: scaleLinear({ range: [0, 100], domain: [0, 100] }),
innerHeight: 100,
};

const wrapper = shallow(
<XAxis
{...props}
tickLabelProps={(val, i) => ({
fill: i === 0 ? 'pink' : 'blue',
})}
/>,
);

const label0 = wrapper.find(AxisBottom)
.dive() // Axis
.dive() // Group
.find('.vx-axis-tick')
.first()
.dive()
.find('text');

const label1 = wrapper.find(AxisBottom)
.dive() // Axis
.dive() // Group
.find('.vx-axis-tick')
.last()
.dive()
.find('text');

expect(label0.prop('fill')).toBe('pink');
expect(label1.prop('fill')).toBe('blue');
});

test.only('tickStyles.label[orientation] should be used if tickLabelProps is not passed', () => {
const props = {
scale: scaleLinear({ range: [0, 100], domain: [0, 100] }),
innerHeight: 100,
};

const wrapper = shallow(
<XAxis
{...props}
tickLabelProps={null}
tickStyles={{
label: {
bottom: {
fill: 'skyblue',
},
},
}}
/>,
);

const label0 = wrapper.find(AxisBottom)
.dive() // Axis
.dive() // Group
.find('.vx-axis-tick')
.first()
.dive()
.find('text');

expect(label0.prop('fill')).toBe('skyblue');
});
});
67 changes: 67 additions & 0 deletions packages/xy-chart/test/axis/YAxis.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import { shallow } from 'enzyme';
import AxisLeft from '@vx/axis/build/axis/AxisLeft';
import AxisRight from '@vx/axis/build/axis/AxisRight';
import scaleLinear from '@vx/scale/build/scales/linear';
import { XYChart, YAxis, LineSeries } from '../../src/';

describe('<YAxis />', () => {
Expand Down Expand Up @@ -83,4 +84,70 @@ describe('<YAxis />', () => {
const tick = wrapper.render().find('.vx-axis-tick').first();
expect(tick.find('text').text()).toBe(tickFormat());
});

test('tickLabelProps should be passed tick value and indexif passed, and tickStyles.label[orientation] if not', () => {
const props = {
scale: scaleLinear({ range: [100, 0], domain: [0, 100] }),
innerWidth: 100,
};

const wrapper = shallow(
<YAxis
{...props}
tickLabelProps={(val, i) => ({
fill: i === 0 ? 'pink' : 'blue',
})}
/>,
);

const label0 = wrapper.find(AxisRight)
.dive() // Axis
.dive() // Group
.find('.vx-axis-tick')
.first()
.dive()
.find('text');

const label1 = wrapper.find(AxisRight)
.dive() // Axis
.dive() // Group
.find('.vx-axis-tick')
.last()
.dive()
.find('text');

expect(label0.prop('fill')).toBe('pink');
expect(label1.prop('fill')).toBe('blue');
});

test('tickStyles.label[orientation] should be used if tickLabelProps is not passed', () => {
const props = {
scale: scaleLinear({ range: [100, 0], domain: [0, 100] }),
innerWidth: 100,
};

const wrapper = shallow(
<YAxis
{...props}
tickLabelProps={null}
tickStyles={{
label: {
right: {
fill: 'skyblue',
},
},
}}
/>,
);

const label0 = wrapper.find(AxisRight)
.dive() // Axis
.dive() // Group
.find('.vx-axis-tick')
.first()
.dive()
.find('text');

expect(label0.prop('fill')).toBe('skyblue');
});
});

0 comments on commit a2eae66

Please sign in to comment.