UNPKG

react-occult

Version:

Layered Information Visualization based on React and D3

226 lines (214 loc) 6.59 kB
import React from 'react'; const eventListenersGenerator = () => ({}); const drawAreaConnector = ({ x1, x2, y1, y2, sizeX1, sizeY1, sizeX2, sizeY2 }) => { return `M${x1},${y1}L${x2},${y2}L${x2 + sizeX2},${y2 + sizeY2}L${x1 + sizeX1},${y1 + sizeY1}Z`; }; const toConnectors = ({ type, data, renderMode, styleFn, classFn, projection, useCanvas, baseMarkProps, isOrdinalPoint = false }) => { const svgPipeline = []; const canvasPipeline = []; if (!type.type) { return { svgPipeline, canvasPipeline }; } const radarHash = new Map(); if (typeof type.type === 'function') { const connectionRule = type.type; const keys = Object.keys(data); keys.forEach((key, pieceArrayI) => { const pieceArray = data[key]; const nextColumn = data[keys[pieceArrayI + 1]]; if (nextColumn) { const matchArray = nextColumn.map((d, i) => connectionRule({ ...d.piece, ...d.piece.data }, i) ); pieceArray.forEach((piece, pieceI) => { const thisConnectionPiece = connectionRule( { ...piece.piece, ...piece.piece.data }, pieceI ); const targetMatch = connectionRule( { ...piece.piece, ...piece.piece.data }, pieceI ); const matchingPieceIndex = targetMatch !== undefined && targetMatch !== false && matchArray.indexOf(targetMatch); if ( thisConnectionPiece !== undefined && thisConnectionPiece !== null && matchingPieceIndex !== false && matchingPieceIndex !== -1 ) { const matchingPiece = nextColumn[matchingPieceIndex]; let markD; if (projection === 'radial' && isOrdinalPoint === true) { if (!radarHash.get(piece)) { radarHash.set(piece, [piece]); } const thisRadar = radarHash.get(piece); if (thisRadar) { thisRadar.push(matchingPiece); radarHash.set(matchingPiece, thisRadar); radarHash.delete(piece); } } else { const { xy } = piece; const { xy: mxy } = matchingPiece; const { x, y, height = 1, width = 1 } = xy; const { x: mx, y: my, height: mheight = 1, width: mwidth = 1 } = mxy; if (projection === 'vertical') { markD = drawAreaConnector({ x1: x + width, x2: mx, y1: y, y2: my, sizeX1: 0, sizeX2: 0, sizeY1: height, sizeY2: mheight }); } else if (projection === 'horizontal') { markD = drawAreaConnector({ x1: x, x2: mx, y1: y + height, y2: my, sizeX1: width, sizeX2: mwidth, sizeY1: 0, sizeY2: 0 }); } else if (projection === 'radial') { markD = drawAreaConnector({ x1: x, x2: mx, y1: y + height, y2: my, sizeX1: width, sizeX2: mwidth, sizeY1: 0, sizeY2: 0 }); } const renderValue = renderMode && renderMode(piece.piece, pieceI); const source = { ...piece.piece.data, ...piece.piece.data }; const target = { ...matchingPiece.piece, ...matchingPiece.piece.data }; const calculatedStyle = styleFn({ source, target }); const eventListeners = eventListenersGenerator( { source, target }, pieceI ); if (useCanvas === true) { const canvasConnector = { baseClass: 'xyframe-line', tx: 0, ty: 0, d: { source, target }, markProps: { d: markD, markType: 'path' }, styleFn: styleFn, renderFn: renderMode, classFn }; canvasPipeline.push(canvasConnector); } else { svgPipeline.push( <Mark {...baseMarkProps} {...eventListeners} renderMode={renderValue} markType="path" d={markD} className={classFn ? classFn(piece.piece.data, pieceI) : ''} key={`connector${piece.piece.renderKey}`} style={calculatedStyle} /> ); } } } }); } }); if (radarHash.size > 0) { for (const ring of radarHash.values()) { const ringPiece = { ...ring[0].piece, ...ring[0].piece.data }; const markD = `M${ring.map(d => `${d.xy.x},${d.xy.y}`).join('L')}Z`; if (useCanvas === true) { const canvasRadar = { baseClass: 'ordinal-radar', tx: 0, ty: 0, d: { source: ringPiece }, markProps: { d: markD, markType: 'path' }, styleFn: styleFn, renderFn: renderMode, classFn }; canvasPipeline.push(canvasRadar); } else { svgPipeline.push( <Mark {...baseMarkProps} renderMode={renderMode && renderMode(ringPiece)} markType="path" d={markD} className={classFn ? classFn(ringPiece) : ''} key={`ordinal-ring-${ringPiece.renderKey}`} style={styleFn({ source: ringPiece })} /> ); } } } } else if (type.type) { console.error( `Invalid connectorType - Must be a function that takes a data point and determines if it is connected to a data point in the next column` ); } return { svgPipeline, canvasPipeline }; }; export default toConnectors;