UNPKG

lucid-ui

Version:

A UI component library from AppNexus.

114 lines (113 loc) 3.75 kB
import _ from 'lodash'; import * as d3Array from 'd3-array'; import ReactDOM from 'react-dom'; const getGroup = (selection, className) => { const xAxisGroup = selection.select(`.${className}`); if (xAxisGroup.empty()) { return selection.append('g').classed(className, true); } return xAxisGroup; }; const getGroups = (selection, className, dataset) => { const selectionGroup = selection.selectAll(`.${className}`); if (selectionGroup.empty()) { const xAxisGroup = selectionGroup.data(dataset).order(); return xAxisGroup .enter() .append('g') .classed(className, true); } return selectionGroup; }; const getTickObj = (selection) => { let data = selection.selectAll('.innerDiv'); if (data.empty()) { data = selection .selectAll('foreignObject') .append('xhtml:div') .attr('tabindex', 0) .style('position', 'fixed') .style('transform', 'translate(0px, -50px)') .classed('innerDiv', true); } return data; }; const getTickRender = (selection, containerWidth) => { const tickRender = selection.selectAll('.tickRender'); if (!tickRender.empty()) { tickRender.remove(); } return selection .append('xhtml:div') .style('width', `${containerWidth}px`) .attr('id', (d) => d) .classed('tickRender', true); }; const getLines = (selection, xScale, tickSize) => { const lines = selection.selectAll('line'); if (lines.empty()) { return selection .append('line') .attr('x1', 0) .attr('x2', 0) .attr('y1', 0) .attr('y2', -tickSize || 5); } return lines; }; const getForeignObject = (selection) => { const fO = selection.selectAll('foreignObject'); if (fO.empty()) { return selection .append('foreignObject') .style('overflow', 'visible') .style('display', 'flex') .attr('x', 0) .attr('y', 0) .attr('height', 1) .attr('width', 1); } return fO; }; const lucidXAxis = (selection, { xScale, tickSize, xAxisRenderProp, dataIsCentered, data, }) => { const range = xScale.range(); const domain = xScale.domain(); const rMin = Number(d3Array.min(range)) || 0; const rMax = Number(d3Array.max(range)) || 0; const domainLength = dataIsCentered ? domain.length - 1 : domain.length; const axisGroup = getGroup(selection, 'axis'); axisGroup .append('line') .attr('stroke', 'black') .attr('x1', rMin) .attr('x2', rMax) .attr('y1', 0) .attr('y2', 0); axisGroup .append('line') .attr('stroke', 'black') .attr('x1', rMin) .attr('x2', rMax) .attr('y1', -tickSize) .attr('y2', -tickSize); const xLines = getGroups(axisGroup, 'xLines', domain); const xLine = xLines.attr('transform', (d) => `translate( ${xScale(d)}, 0)`); getLines(xLine, xScale, tickSize); getForeignObject(xLine); if (!xAxisRenderProp) { xLine.append('text').text((d) => d); } else { const tickObj = getTickObj(xLine); const tickRender = getTickRender(tickObj, (rMax - rMin) / domainLength); tickRender.html((xValue, num, node) => { if (xValue !== '' && !_.isNil(xValue)) { const subData = _.find(data, { x: xValue }) || { y: 0, ref: undefined }; ReactDOM.render(xAxisRenderProp({ x: xValue, y: subData.y, ref: subData.ref }), node[0]); } else return xValue; }); } }; export { lucidXAxis, getGroup };