Skip to content

Commit

Permalink
Focus and tooltip placement around unsafe are
Browse files Browse the repository at this point in the history
  • Loading branch information
envex committed Feb 4, 2025
1 parent 1ba736d commit cceb658
Show file tree
Hide file tree
Showing 12 changed files with 221 additions and 513 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ export function getColorVisionEventAttrs({type, index, watch = true}: Props) {
[`${COLOR_VISION_EVENT.dataAttribute}-watch`]: watch,
[`${COLOR_VISION_EVENT.dataAttribute}-type`]: type,
[`${COLOR_VISION_EVENT.dataAttribute}-index`]: index,
['data-tooltip-type']: 'blah',
// ['data-tooltip-type']: 'blah',
};
}
42 changes: 21 additions & 21 deletions packages/polaris-viz/src/components/BarChart/stories/data.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,37 +12,37 @@ export const DEFAULT_DATA: DataSeries[] = [
{
name: 'Breakfast',
data: [
{key: 'Monday', value: 3},
{key: 'Tuesday', value: -7},
{key: 'Wednesday', value: -7},
{key: 'Thursday', value: -8},
{key: 'Friday', value: 45},
{key: 'Saturday', value: 0},
{key: 'Sunday', value: 0.1},
{key: 'Monday', value: 20},
{key: 'Tuesday', value: 20},
{key: 'Wednesday', value: 20},
{key: 'Thursday', value: 20},
{key: 'Friday', value: 20},
{key: 'Saturday', value: 20},
{key: 'Sunday', value: 20},
],
},
{
name: 'Lunch',
data: [
{key: 'Monday', value: 4},
{key: 'Tuesday', value: 0},
{key: 'Wednesday', value: -10},
{key: 'Thursday', value: 15},
{key: 'Friday', value: 8},
{key: 'Saturday', value: 45},
{key: 'Sunday', value: 0.1},
{key: 'Monday', value: 20},
{key: 'Tuesday', value: 20},
{key: 'Wednesday', value: 20},
{key: 'Thursday', value: 20},
{key: 'Friday', value: 20},
{key: 'Saturday', value: 20},
{key: 'Sunday', value: 20},
],
},
{
name: 'Dinner',
data: [
{key: 'Monday', value: 7},
{key: 'Tuesday', value: 0},
{key: 'Wednesday', value: -15},
{key: 'Thursday', value: -12},
{key: 'Friday', value: 45},
{key: 'Saturday', value: 5},
{key: 'Sunday', value: 0.1},
{key: 'Monday', value: 20},
{key: 'Tuesday', value: 20},
{key: 'Wednesday', value: 20},
{key: 'Thursday', value: 20},
{key: 'Friday', value: 20},
{key: 'Saturday', value: 20},
{key: 'Sunday', value: 20},
],
},
];
6 changes: 3 additions & 3 deletions packages/polaris-viz/src/components/ComboChart/Chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
checkAvailableAnnotations,
YAxisAnnotations,
} from '../Annotations';
import {TooltipWrapper} from '../TooltipWrapper';
// import {TooltipWrapper} from '../TooltipWrapper';
import type {
AnnotationLookupTable,
RenderLegendContent,
Expand Down Expand Up @@ -317,7 +317,7 @@ export function Chart({
)}
</ChartElements.Svg>

<TooltipWrapper
{/* <TooltipWrapper
bandwidth={labelWidth}
chartBounds={chartBounds}
chartType={InternalChartType.Bar}
Expand All @@ -330,7 +330,7 @@ export function Chart({
parentElement={svgRef}
xScale={barXScale}
yScale={barYScale}
/>
/> */}

{showLegend && (
<LegendContainer
Expand Down
17 changes: 9 additions & 8 deletions packages/polaris-viz/src/components/LineChart/Chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import type {
XAxisOptions,
YAxisOptions,
LineChartDataSeriesWithDefaults,
BoundingRect,
LabelFormatter,
} from '@shopify/polaris-viz-core';

Expand Down Expand Up @@ -297,20 +296,22 @@ export function Chart({
})}

{[...Array(longestSeriesLength + 1).keys()].map((_, index) => {
const x =
index * (drawableWidth / longestSeriesLength) -
drawableWidth / longestSeriesLength / 2;
const width = drawableWidth / longestSeriesLength;

return (
<rect
key={`${index}-tooltip-area`}
height={drawableHeight}
width={drawableWidth / longestSeriesLength}
x={
index * (drawableWidth / longestSeriesLength) -
drawableWidth / longestSeriesLength / 2
}
width={width}
x={x}
fill="rgba(255,0,0,0.2)"
data-tooltip-type="line"
data-tooltip-index={index}
data-tooltip-x={xScale(index)}
data-tooltip-y={yScale(index)}
data-tooltip-x={containerBounds.x + chartXPosition + x + width}
data-tooltip-y={containerBounds.y + chartYPosition}
/>
);
})}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type {ReactNode} from 'react';
import {useEffect, useRef, useState, useMemo, useCallback} from 'react';
import {useChartContext, InternalChartType} from '@shopify/polaris-viz-core';
import type {DataType} from '@shopify/polaris-viz-core';
import type {BoundingRect} from '@shopify/polaris-viz-core';
import {createPortal} from 'react-dom';

import {useRootContainer} from '../../hooks/useRootContainer';
Expand All @@ -17,32 +17,29 @@ const TOUCH_START_DELAY = 300;

interface BaseProps {
chartType: InternalChartType;
focusElementDataType: DataType;
getMarkup: (index: number | null) => ReactNode;
parentElement: SVGSVGElement | null;
onIndexChange?: (index: number | null) => void;
id?: string;
}

function TooltipWrapperRaw(props: BaseProps) {
const {chartType, focusElementDataType, id, onIndexChange, parentElement} =
props;
const {chartType, id, onIndexChange, parentElement} = props;
const {isTouchDevice, containerBounds} = useChartContext();
const [position, setPosition] = useState<TooltipPosition>({
x: containerBounds.x,
y: containerBounds.y,
activeIndex: -1,
unsafeArea: null,
});

const activeIndexRef = useRef<number | null>(null);
const touchStartTimer = useRef<number>(0);
const isLongTouch = useRef(false);

const focusElements = useMemo<NodeListOf<SVGPathElement> | undefined>(() => {
return parentElement?.querySelectorAll(
`[data-type="${focusElementDataType}"][aria-hidden="false"]`,
);
}, [focusElementDataType, parentElement]);
return parentElement?.querySelectorAll(`[data-tooltip-type]`);
}, [parentElement]);

useEffect(() => {
activeIndexRef.current = position.activeIndex;
Expand All @@ -54,54 +51,45 @@ function TooltipWrapperRaw(props: BaseProps) {

const getPosition = useCallback(
(event: MouseEvent | TouchEvent) => {
console.log('getPosition');

if (shouldBlockTooltipEvents(event)) {
return {
...position,
activeIndex: -1,
};
}

if (event == null || event.target == null) {
console.log('no event or target', event);
return position;
}

const target = event.target as HTMLElement;

if (target.dataset.tooltipType == null) {
console.log('no type', target);
return {
// x: 0,
// y: 0,
activeIndex: -1,
};
if (target.dataset.tooltipIndex == null) {
return position;
}

const activeIndex = target.dataset.tooltipIndex;

let x = Number(target.dataset.tooltipX);
let y = Number(target.dataset.tooltipY);
const {x, y, activeIndex, unsafeArea} = getDataFromElement(target);

if (alwaysUpdatePosition) {
const {x: eventX, y: eventY} = getXYFromEventType(event);

x = eventX;
y = eventY;
return {
...position,
x: eventX,
y: eventY,
activeIndex,
};
}

if (y == null || x == null) {
// console.log('no x or y', target);
return position;
}

// console.log('x or y', {x, y, activeIndex});

return {
x,
y,
activeIndex:
activeIndex == null ? position.activeIndex : Number(activeIndex),
activeIndex: activeIndex == null ? position.activeIndex : activeIndex,
unsafeArea,
};
},
[alwaysUpdatePosition, position],
Expand Down Expand Up @@ -169,16 +157,28 @@ function TooltipWrapperRaw(props: BaseProps) {

const onFocus = useCallback(
(event: FocusEvent) => {
// const target = event.currentTarget as SVGSVGElement;
// if (!target) {
// return;
// }
// const index = Number(target.dataset.index);
// const newPosition = getPosition({, eveindexntType: 'focus'});
// setPosition(newPosition);
// onIndexChange?.(newPosition.activeIndex);
const target = event.currentTarget as SVGSVGElement;

if (target == null) {
return;
}

const activeIndex = target.dataset.tooltipIndex;

const x = Number(target.dataset.tooltipX);
const y = Number(target.dataset.tooltipY);

const newActiveIndex = activeIndex == null ? -1 : Number(activeIndex);

setPosition((prevState) => ({
...prevState,
x,
y,
activeIndex: newActiveIndex,
}));
onIndexChange?.(newActiveIndex);
},
[getPosition, onIndexChange],
[onIndexChange],
);

const onFocusIn = useCallback(() => {
Expand All @@ -205,8 +205,6 @@ function TooltipWrapperRaw(props: BaseProps) {
);

useEffect(() => {
console.log('useEffect', parentElement);

if (!parentElement) {
return;
}
Expand Down Expand Up @@ -244,16 +242,13 @@ function TooltipWrapperRaw(props: BaseProps) {
};
}, [parentElement, onFocusIn]);

// if (position.activeIndex == null || position.activeIndex < 0) {
// return null;
// }

return (
<TooltipAnimatedContainer
activePointIndex={position.activeIndex}
chartType={chartType}
x={position.x}
y={position.y}
unsafeArea={position.unsafeArea}
id={id}
>
{props.getMarkup(position.activeIndex)}
Expand All @@ -275,3 +270,41 @@ function TooltipWithPortal(props: BaseProps) {
container,
);
}

function getDataFromElement(element: HTMLElement) {
const x = Number(element.dataset.tooltipX);
const y = Number(element.dataset.tooltipY);

const unsafeArea = getUnsafeAreaFromElement(element);
const activeIndex = element.dataset.tooltipIndex;

return {
x,
y,
activeIndex: activeIndex == null ? -1 : Number(activeIndex),
unsafeArea,
};
}

function getUnsafeAreaFromElement(element: HTMLElement): BoundingRect | null {
if (element.dataset.tooltipUnsafeArea == null) {
return null;
}

const unsafeArea = JSON.parse(element.dataset.tooltipUnsafeArea);

if (isUnsafeAreaValid(unsafeArea)) {
return unsafeArea;
}

return null;
}

function isUnsafeAreaValid(unsafeArea: unknown): boolean {
return (
Object.prototype.hasOwnProperty.call(unsafeArea, 'x') &&
Object.prototype.hasOwnProperty.call(unsafeArea, 'y') &&
Object.prototype.hasOwnProperty.call(unsafeArea, 'height') &&
Object.prototype.hasOwnProperty.call(unsafeArea, 'width')
);
}
Loading

0 comments on commit cceb658

Please sign in to comment.