UNPKG

cl-react-graph

Version:
143 lines (120 loc) 4.04 kB
import { axisBottom, axisLeft, AxisScale, } from 'd3-axis'; import attrs from './d3/attrs'; import { IAxes, IHistogramProps, } from './Histogram'; import { AnyScale } from './utils/scales'; import { TSelection } from './utils/svg'; // Grid lines in y axis function export const makeYGridLines = (y: AxisScale<any>, ticks: number = 5) => { return axisLeft(y) .ticks(ticks); }; // Grid lines in x axis function export const makeXGridLines = (x: any, ticks: number = 5) => { return axisBottom(x) .ticks(ticks); }; export const drawGrid = ( x: AxisScale<any>, y: AxisScale<any>, gridX: TSelection, gridY: TSelection, props: any, ticks: number, ) => { const { height, width, axis, grid, margin } = props; const axisWidth = axis.y.style['stroke-width']; const offset = { x: yAxisWidth(axis) + axisWidth, y: gridHeight(props), }; if (grid.x.visible) { // Add the X grid lines gridX.attr('transform', `translate(${offset.x}, ${offset.y})`) .transition() .call(makeXGridLines(x, grid?.x?.ticks ?? ticks) .tickSize(-height + xAxisHeight(props.axis) + (margin.top * 2)) .tickFormat(() => '')); attrs(gridX.selectAll('.tick line'), grid.x.style); attrs(gridX.selectAll('.domain'), { ...axis.y.style, stroke: 'transparent' }); } if (grid.y.visible) { // add the Y grid lines gridY.attr('transform', `translate(${offset.x}, 0)`) .transition() .call(makeYGridLines(y, grid?.y?.ticks ?? ticks) .tickSize(-width + (margin.left * 2) + yAxisWidth(axis)) .tickFormat(() => ''), ); attrs(gridY.selectAll('.tick line'), grid.y.style); // Hide the first horizontal grid line to show axis gridY.selectAll('.gridY .tick line').filter((d, i) => i === 0) .attr('display', 'none'); attrs(gridY.selectAll('.domain'), { ...axis.x.style, stroke: 'transparent' }); } }; interface IProps<T = IHistogramProps> { x: AnyScale; y: AnyScale; gridX: TSelection; gridY: TSelection; props: T; ticks: number; } export const drawHorizontalGrid: <T extends IHistogramProps>(props: IProps<T>) => void = (args) => { const { x, y, gridX, gridY, props, ticks } = args; const { height, width, axis, grid, margin } = props; const axisWidth = axis.y.style['stroke-width']; const offset = { x: yAxisWidth(axis), y: gridHeight(props) + margin.top, }; if (grid.x.visible) { // Add the X grid lines gridX.attr('transform', `translate(${offset.x}, ${offset.y})`) .transition() .call(makeXGridLines(x, grid?.x?.ticks ?? ticks) .tickSize(-height + xAxisHeight(props.axis) + (margin.top * 2)) .tickFormat(() => '')); attrs(gridX.selectAll('.tick line'), grid.x.style); attrs(gridX.selectAll('.domain'), { ...axis.y.style, stroke: 'transparent' }); } if (grid.y.visible) { // add the Y grid lines gridY.attr('transform', 'translate(' + (yAxisWidth(axis) + axisWidth) + ', 0)') .transition() .call(makeYGridLines(y, grid?.y?.ticks ?? ticks) .tickSize(-width + (margin.left * 2) + yAxisWidth(axis)) .tickFormat(() => ''), ); attrs(gridY.selectAll('.tick line'), grid.y.style); // Hide the first horizontal grid line to show axis gridY.selectAll('.gridY .tick line').filter((d, i) => i === 0) .attr('display', 'none'); attrs(gridY.selectAll('.domain'), { ...axis.x.style, stroke: 'transparent' }); } }; export const gridHeight = (props: any): number => { const { height, margin, axis } = props; return height - (margin.top * 2) - xAxisHeight(axis); }; export const yAxisWidth = (axis: IAxes) => { return axis.y.label === '' ? axis.y.width : axis.y.width + 30; }; export const xAxisHeight = (axis: IAxes) => { return axis.x.label === '' ? axis.x.height : axis.x.height + 30 + axis?.x?.margin ?? 0; }; export const gridWidth = (props: any): number => { const { axis, width, margin } = props; return width - (margin.left * 2) - yAxisWidth(axis); };