/** * @upsetjs/react * https://github.com/upsetjs/upsetjs * * Copyright (c) 2021 Samuel Gratzl */ import type { ISetCombination } from '@upsetjs/model'; import React, { PropsWithChildren, ReactElement } from 'react'; import type { UpSetDataInfo } from '../derive/deriveDataDependent'; import type { UpSetSizeInfo } from '../derive/deriveSizeDependent'; import type { UpSetStyleInfo } from '../derive/deriveStyleDependent'; import type { UpSetSelection } from './interfaces'; import UpSetDot from './UpSetDot'; import { addonPositionGenerator, mergeColor } from './utils'; import { clsx } from '../utils'; import { OVERFLOW_PADDING_FACTOR } from '../defaults'; export function computeOverflowValues(value: number, max: number, scale: (v: number) => number) { const scaled = [scale(value)]; for (let i = 0; i < OVERFLOW_PADDING_FACTOR.length && value > max; i++) { value -= max; scaled.push(scale(value)); } return scaled; } export type CombinationChartProps = PropsWithChildren<{ d: ISetCombination; size: UpSetSizeInfo; style: UpSetStyleInfo; data: UpSetDataInfo; className?: string; h: UpSetSelection; }>; const CombinationChart = /*!#__PURE__*/ React.memo(function CombinationChart({ d, h, className, data, size, style, children, }: CombinationChartProps) { const yValues = computeOverflowValues(d.cardinality, data.cs.max, data.cs.y); const genPosition = addonPositionGenerator(size.cs.h + size.sets.h, size.cs.addonPadding); return ( {style.tooltips && ( {d.name}: {data.cs.format(d.cardinality)} )} {size.cs.h > 0 && ( <> {yValues.map((y, i) => { const offset = i > 0 ? Math.floor(data.cs.bandWidth * OVERFLOW_PADDING_FACTOR[i - 1]) : 0; return ( ); })} {data.cs.format(d.cardinality)} )} {d.name} {data.sets.v.map((s, i) => { if (data.cs.has(d, s)) { // only not return null; } return ( ); })} {d.sets.size > 1 && ( data.cs.has(d, p))!)! + data.sets.cy - (data.r - 1)} x2={data.cs.cx} y2={data.sets.y(data.sets.rv.find((p) => data.cs.has(d, p))!)! + data.sets.cy + (data.r - 1)} style={d.color ? { stroke: d.color } : undefined} className={`upsetLine-${data.id}`} /> )} {data.sets.v.map((s, i) => { if (!data.cs.has(d, s)) { // only has return null; } return ( ); })} {size.cs.addons.map((addon) => ( {addon.render({ set: d, width: data.cs.bandWidth, height: addon.size, theme: style.theme })} ))} {children} ); }); export default CombinationChart as (props: CombinationChartProps) => ReactElement;