import * as React from 'react'; import { css } from '@emotion/css'; import { Box, Center, Group, ScrollArea, Stack } from '@mantine/core'; import * as d3v7 from 'd3v7'; import uniqueId from 'lodash/uniqueId'; import { useAsync } from '../../hooks/useAsync'; import { i18n } from '../../i18n'; import { EScatterSelectSettings, ICommonVisProps } from '../interfaces'; import { BrushOptionButtons } from '../sidebar'; import { Hexplot } from './Hexplot'; import { IHexbinConfig } from './interfaces'; import { getHexData } from './utils'; import { LegendItem } from '../general/LegendItem'; import { WarningMessage } from '../general/WarningMessage'; import { assignColorToNullValues } from '../general/utils'; function Legend({ categories, filteredCategories, colorScale, onClick, }: { categories: string[]; filteredCategories: string[]; colorScale: d3v7.ScaleOrdinal; onClick: (string) => void; }) { return ( div { display: flex !important; flex-direction: column !important; } `} > {categories.map((c) => { return onClick(c)} filtered={filteredCategories.includes(c)} />; })} ); } export function HexbinVis({ config, columns, dimensions, setConfig, selectionCallback = () => null, selectedMap = {}, showDragModeOptions = true, uniquePlotId, showDownloadScreenshot, }: ICommonVisProps) { const id = React.useMemo(() => uniquePlotId || uniqueId('HexbinVis'), [uniquePlotId]); const { width, height } = dimensions; const { value: allColumns, status: colsStatus } = useAsync(getHexData, [columns, config.numColumnsSelected, config.color]); const [filteredCategories, setFilteredCategories] = React.useState([]); const currentColorColumn = React.useMemo(() => { if (config.color && allColumns?.colorColVals) { return { allValues: allColumns.colorColVals.resolvedValues, filteredValues: allColumns.colorColVals.resolvedValues.filter((val) => !filteredCategories.includes(`${val.val}` as string)), // need to have a string, even if it's 'undefined' or 'null' }; } return null; }, [allColumns?.colorColVals, config.color, filteredCategories]); const colorScale = React.useMemo(() => { if (!currentColorColumn?.allValues) { return null; } const colorOptions = currentColorColumn.allValues.map((val) => { return String(val.val); // need to have a string, even if it's 'undefined' or 'null' }); return d3v7 .scaleOrdinal< string, string >(allColumns.colorColVals.color ? Object.values(allColumns.colorColVals.color) : assignColorToNullValues(Array.from(new Set(colorOptions)), [...d3v7.schemeCategory10])) .domain(allColumns.colorColVals.color ? Object.keys(allColumns.colorColVals.color) : Array.from(new Set(colorOptions))); }, [currentColorColumn, allColumns]); return (
{showDragModeOptions || showDownloadScreenshot ? (
{showDragModeOptions ? ( setConfig({ ...config, dragMode })} options={[EScatterSelectSettings.RECTANGLE, EScatterSelectSettings.PAN]} dragMode={config.dragMode} /> ) : null} {/* TODO: the download is broken right now because we are rendering an SVG, which is not supported {showDownloadScreenshot && config.numColumnsSelected.length >= 2 ? : null} */}
) : null} {currentColorColumn ? (
{ return null; // TODO: activate legend interactions later on by removing this line // filteredCategories.includes(s) // ? setFilteredCategories(filteredCategories.filter((f) => f !== s)) // : setFilteredCategories([...filteredCategories, s]); }} />
) : null} 2 ? { gridTemplateColumns: 'repeat(3, minmax(0, 1fr))', gridTemplateRows: 'repeat(3, minmax(0, 1fr))', gap: '1rem 1rem' } : { gridTemplateColumns: 'repeat(1, minmax(0, 1fr))', gridTemplateRows: 'repeat(1, minmax(0, 1fr))', gap: '1rem 1rem' }), }} > {config.numColumnsSelected.length < 2 ? ( {i18n.t('visyn:vis.missingColumn.hexbinError')} ) : null} {config.numColumnsSelected.length === 2 && allColumns?.numColVals.length === config.numColumnsSelected.length && colsStatus === 'success' ? ( ) : null} {config.numColumnsSelected.length > 2 && allColumns?.numColVals.length === config.numColumnsSelected.length && colsStatus === 'success' ? config.numColumnsSelected.map((xCol) => { return config.numColumnsSelected.map((yCol) => { if (xCol.id !== yCol.id) { return ( col.info.id === yCol.id), allColumns.numColVals.find((col) => col.info.id === xCol.id), ], colorColVals: allColumns.colorColVals, }} colorScale={colorScale} /> ); } return
; }); }) : null}
); }