Make it possible to navigate charts with the keyboard (https://github.com/woocommerce/woocommerce-admin/pull/399)
* Hide tooltip when mouse leaves chart bars * Allow focus on chart lines/bars and show tooltip * Extract position calculation to a function * Make columns focusable instead of individual points in line charts
This commit is contained in:
parent
b5b84fe72c
commit
5669eb4b1a
|
@ -13,7 +13,7 @@ import {
|
||||||
scaleLinear as d3ScaleLinear,
|
scaleLinear as d3ScaleLinear,
|
||||||
scaleTime as d3ScaleTime,
|
scaleTime as d3ScaleTime,
|
||||||
} from 'd3-scale';
|
} from 'd3-scale';
|
||||||
import { mouse as d3Mouse, select as d3Select } from 'd3-selection';
|
import { event as d3Event, mouse as d3Mouse, select as d3Select } from 'd3-selection';
|
||||||
import { line as d3Line } from 'd3-shape';
|
import { line as d3Line } from 'd3-shape';
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
@ -297,9 +297,9 @@ export const drawAxis = ( node, params ) => {
|
||||||
.remove();
|
.remove();
|
||||||
};
|
};
|
||||||
|
|
||||||
const showTooltip = ( node, params, d ) => {
|
const showTooltip = ( node, params, d, position ) => {
|
||||||
const chartCoords = node.node().getBoundingClientRect();
|
const chartCoords = node.node().getBoundingClientRect();
|
||||||
let [ xPosition, yPosition ] = d3Mouse( node.node() );
|
let [ xPosition, yPosition ] = position ? position : d3Mouse( node.node() );
|
||||||
xPosition = xPosition > chartCoords.width - 340 ? xPosition - 340 : xPosition + 100;
|
xPosition = xPosition > chartCoords.width - 340 ? xPosition - 340 : xPosition + 100;
|
||||||
yPosition = yPosition > chartCoords.height - 150 ? yPosition - 200 : yPosition + 20;
|
yPosition = yPosition > chartCoords.height - 150 ? yPosition - 200 : yPosition + 20;
|
||||||
const keys = params.orderedKeys.filter( row => row.visible ).map(
|
const keys = params.orderedKeys.filter( row => row.visible ).map(
|
||||||
|
@ -327,25 +327,25 @@ const showTooltip = ( node, params, d ) => {
|
||||||
` );
|
` );
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMouseOverBarChart = ( d, i, nodes, node, data, params ) => {
|
const handleMouseOverBarChart = ( d, i, nodes, node, data, params, position ) => {
|
||||||
d3Select( nodes[ i ].parentNode )
|
d3Select( nodes[ i ].parentNode )
|
||||||
.select( '.barfocus' )
|
.select( '.barfocus' )
|
||||||
.attr( 'opacity', '0.1' );
|
.attr( 'opacity', '0.1' );
|
||||||
showTooltip( node, params, d );
|
showTooltip( node, params, d, position );
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMouseOutBarChart = ( d, i, nodes, params ) => {
|
const handleMouseOutBarChart = ( d, i, nodes, params ) => {
|
||||||
d3Select( nodes[ i ].parentNode )
|
d3Select( nodes[ i ].parentNode )
|
||||||
.select( '.barfocus' )
|
.select( '.barfocus' )
|
||||||
.attr( 'opacity', '0' );
|
.attr( 'opacity', '0' );
|
||||||
params.tooltip.style( 'display', 'flex' );
|
params.tooltip.style( 'display', 'none' );
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMouseOverLineChart = ( d, i, nodes, node, data, params ) => {
|
const handleMouseOverLineChart = ( d, i, nodes, node, data, params, position ) => {
|
||||||
d3Select( nodes[ i ].parentNode )
|
d3Select( nodes[ i ].parentNode )
|
||||||
.select( '.focus-grid' )
|
.select( '.focus-grid' )
|
||||||
.attr( 'opacity', '1' );
|
.attr( 'opacity', '1' );
|
||||||
showTooltip( node, params, data.find( e => e.date === d.date ) );
|
showTooltip( node, params, data.find( e => e.date === d.date ), position );
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMouseOutLineChart = ( d, i, nodes, params ) => {
|
const handleMouseOutLineChart = ( d, i, nodes, params ) => {
|
||||||
|
@ -355,6 +355,12 @@ const handleMouseOutLineChart = ( d, i, nodes, params ) => {
|
||||||
params.tooltip.style( 'display', 'none' );
|
params.tooltip.style( 'display', 'none' );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const calculatePositionInChart = ( element, chart ) => {
|
||||||
|
const elementCoords = element.getBoundingClientRect();
|
||||||
|
const chartCoords = chart.getBoundingClientRect();
|
||||||
|
return [ elementCoords.x - chartCoords.x, elementCoords.y - chartCoords.y ];
|
||||||
|
};
|
||||||
|
|
||||||
export const drawLines = ( node, data, params ) => {
|
export const drawLines = ( node, data, params ) => {
|
||||||
const series = node
|
const series = node
|
||||||
.append( 'g' )
|
.append( 'g' )
|
||||||
|
@ -424,10 +430,15 @@ export const drawLines = ( node, data, params ) => {
|
||||||
.attr( 'width', d => d.width )
|
.attr( 'width', d => d.width )
|
||||||
.attr( 'height', params.height )
|
.attr( 'height', params.height )
|
||||||
.attr( 'opacity', 0 )
|
.attr( 'opacity', 0 )
|
||||||
|
.attr( 'tabindex', '0' )
|
||||||
.on( 'mouseover', ( d, i, nodes ) =>
|
.on( 'mouseover', ( d, i, nodes ) =>
|
||||||
handleMouseOverLineChart( d, i, nodes, node, data, params )
|
handleMouseOverLineChart( d, i, nodes, node, data, params )
|
||||||
)
|
)
|
||||||
.on( 'mouseout', ( d, i, nodes ) => handleMouseOutLineChart( d, i, nodes, params ) );
|
.on( 'focus', ( d, i, nodes ) => {
|
||||||
|
const position = calculatePositionInChart( d3Event.target, node.node() );
|
||||||
|
handleMouseOverLineChart( d, i, nodes, node, data, params, position );
|
||||||
|
} )
|
||||||
|
.on( 'mouseout blur', ( d, i, nodes ) => handleMouseOutLineChart( d, i, nodes, params ) );
|
||||||
};
|
};
|
||||||
|
|
||||||
export const drawBars = ( node, data, params ) => {
|
export const drawBars = ( node, data, params ) => {
|
||||||
|
@ -485,8 +496,13 @@ export const drawBars = ( node, data, params ) => {
|
||||||
.attr( 'width', params.xGroupScale.range()[ 1 ] )
|
.attr( 'width', params.xGroupScale.range()[ 1 ] )
|
||||||
.attr( 'height', params.height )
|
.attr( 'height', params.height )
|
||||||
.attr( 'opacity', '0' )
|
.attr( 'opacity', '0' )
|
||||||
|
.attr( 'tabindex', '0' )
|
||||||
.on( 'mouseover', ( d, i, nodes ) =>
|
.on( 'mouseover', ( d, i, nodes ) =>
|
||||||
handleMouseOverBarChart( d, i, nodes, node, data, params )
|
handleMouseOverBarChart( d, i, nodes, node, data, params )
|
||||||
)
|
)
|
||||||
.on( 'mouseout', ( d, i, nodes ) => handleMouseOutBarChart( d, i, nodes, params ) );
|
.on( 'focus', ( d, i, nodes ) => {
|
||||||
|
const position = calculatePositionInChart( d3Event.target, node.node() );
|
||||||
|
handleMouseOverBarChart( d, i, nodes, node, data, params, position );
|
||||||
|
} )
|
||||||
|
.on( 'mouseout blur', ( d, i, nodes ) => handleMouseOutBarChart( d, i, nodes, params ) );
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue