Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • graphpolaris/frontend-v2
  • rijkheere/frontend-v-2-reordering-paoh
2 results
Show changes
Commits on Source (2)
Showing
with 714 additions and 612 deletions
import React from 'react';
import { StoryObj, Meta } from '@storybook/react';
import { Accordion, AccordionItem, AccordionHead, AccordionBody } from '.';
import { EntityPill, RelationPill } from '../pills';
export default {
title: 'Components/Accordion',
component: Accordion,
decorators: [(Story) => <div className="flex m-5">{Story()}</div>],
} as Meta<typeof Accordion>;
type Story = StoryObj<typeof Accordion>;
export const Default: Story = {
render: () => (
<div className="max-w-md mx-auto my-10">
<Accordion defaultOpenIndex={0} className="w-64">
<AccordionItem>
<AccordionHead>
<EntityPill title="PERSON" />
</AccordionHead>
<AccordionBody>This is the content of Section 1.</AccordionBody>
</AccordionItem>
<AccordionItem>
<AccordionHead>
<EntityPill title="INDICENT" />
</AccordionHead>
<AccordionBody>
<Accordion>
<AccordionItem>
<AccordionHead showArrow={false}>Location info</AccordionHead>
<AccordionBody>Location info settings</AccordionBody>
</AccordionItem>
<AccordionItem>
<AccordionHead showArrow={false}>Color and shape</AccordionHead>
<AccordionBody>Color and shape settings</AccordionBody>
</AccordionItem>
</Accordion>
</AccordionBody>
</AccordionItem>
<AccordionItem>
<AccordionHead>
<RelationPill title="PERSON_OF" />
</AccordionHead>
<AccordionBody>This is the content of Section 3.</AccordionBody>
</AccordionItem>
</Accordion>
</div>
),
};
import React, { useState, ReactElement } from 'react';
import { Button } from '../buttons';
type AccordionProps = {
children: React.ReactNode;
defaultOpenIndex?: number;
defaultOpenAll?: boolean;
className?: string;
};
export function Accordion({ children, defaultOpenIndex, defaultOpenAll = false, className = '' }: AccordionProps) {
const childrenArray = React.Children.toArray(children);
const [openIndexes, setOpenIndexes] = useState<number[]>(() => {
if (defaultOpenAll) {
return childrenArray.map((_, index) => index);
} else if (defaultOpenIndex !== undefined) {
return [defaultOpenIndex];
} else {
return [];
}
});
const toggleIndex = (index: number) => {
setOpenIndexes((currentIndexes) =>
currentIndexes.includes(index) ? currentIndexes.filter((i) => i !== index) : [...currentIndexes, index],
);
};
return (
<div className={`w-full ${className}`}>
{React.Children.map(children, (child, index) => {
if (React.isValidElement(child)) {
return React.cloneElement(child as ReactElement<AccordionItemProps>, {
isOpen: openIndexes.includes(index),
onToggle: () => toggleIndex(index),
});
}
return child;
})}
</div>
);
}
type AccordionItemProps = {
isOpen?: boolean;
onToggle?: () => void;
children: React.ReactNode;
className?: string;
};
export function AccordionItem({ isOpen = false, onToggle, children, className = '' }: AccordionItemProps) {
return (
<div className={`w-full ${className}`}>
{React.Children.map(children, (child) => {
if (React.isValidElement(child)) {
return React.cloneElement(child as ReactElement<AccordionHeadProps | AccordionBodyProps>, {
isOpen,
onToggle,
});
}
return child;
})}
</div>
);
}
type AccordionHeadProps = {
isOpen?: boolean;
onToggle?: () => void;
children: React.ReactNode;
showArrow?: boolean;
className?: string;
};
export function AccordionHead({ isOpen = false, onToggle, children, showArrow = true, className = '' }: AccordionHeadProps) {
return (
<div className={`cursor-pointer flex items-center w-full box-border ${className}`} onClick={onToggle}>
{showArrow && (
<Button
size="2xs"
iconComponent={!isOpen ? 'icon-[ic--baseline-arrow-right]' : 'icon-[ic--baseline-arrow-drop-down]'}
variant="ghost"
className="mr-1"
/>
)}
{children}
</div>
);
}
type AccordionBodyProps = {
isOpen?: boolean;
children: React.ReactNode;
className?: string;
};
export function AccordionBody({ isOpen = false, children, className = '' }: AccordionBodyProps) {
return (
<div
className={`overflow-hidden transition-max-height duration-300 ease-in-out w-full box-border ml-2 ${isOpen ? 'max-h-screen' : 'max-h-0'} ${className}`}
>
{isOpen && <div>{children}</div>}
</div>
);
}
import React, { useState } from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { ColorPicker } from '.';
const Component: Meta<typeof ColorPicker> = {
title: 'ColorManager/Legend/ColorPicker',
component: ColorPicker,
argTypes: { onChange: { action: 'changed' } },
decorators: [(Story) => <div className="w-52 m-5">{Story()}</div>],
};
export default Component;
type Story = StoryObj<typeof Component>;
export const ColorPickerStory: Story = (args: any) => {
const [value, setValue] = useState<[number, number, number]>([251, 150, 55]);
return <ColorPicker value={value} onChange={setValue} />;
};
ColorPickerStory.args = {};
import React from 'react';
import { TwitterPicker } from 'react-color';
import { useFloating, autoUpdate, offset, flip, shift, useInteractions, useClick, FloatingPortal } from '@floating-ui/react';
import { visualizationColors } from 'config';
import { Popover, PopoverTrigger, PopoverContent } from '@graphpolaris/shared/lib/components/layout/Popover';
type Props = {
value: any;
updateValue: (val: [number, number, number]) => void;
const hexToRgb = (hex: string): [number, number, number] => {
const r = parseInt(hex.slice(1, 3), 16);
const g = parseInt(hex.slice(3, 5), 16);
const b = parseInt(hex.slice(5, 7), 16);
return [r, g, b];
};
export default function ColorPicker({ value, updateValue }: Props) {
const [open, setOpen] = React.useState(false);
const { x, y, strategy, context, refs, floatingStyles } = useFloating({
placement: 'bottom',
open,
onOpenChange: setOpen,
whileElementsMounted: autoUpdate,
middleware: [offset(5), flip(), shift({ padding: 5 })],
});
const { getReferenceProps, getFloatingProps } = useInteractions([useClick(context)]);
type Props = {
value: [number, number, number];
onChange: (val: [number, number, number]) => void;
};
export function ColorPicker({ value, onChange }: Props) {
return (
<>
<div
className="p-1 inline-block cursor-pointer"
ref={refs.setReference}
{...getReferenceProps({
onClick: () => setOpen(!open),
})}
>
<div
className="w-5 h-5"
style={{
backgroundColor: `rgb(${value?.[0] ?? 0}, ${value?.[1] ?? 0}, ${value?.[2] ?? 0})`,
<div>
<Popover>
<PopoverTrigger
onClick={(e) => {
e.stopPropagation();
}}
/>
</div>
{open && (
<FloatingPortal>
>
<div className="w-4 h-4 rounded-sm" style={{ backgroundColor: `rgb(${value[0]}, ${value[1]}, ${value[2]})` }} />
</PopoverTrigger>
<PopoverContent>
<div
ref={refs.setFloating}
style={{
position: strategy,
top: y ?? 0,
left: x ?? 0,
...floatingStyles,
className="grid grid-cols-4 gap-2 p-2"
onClick={(e) => {
e.stopPropagation();
}}
className="z-10"
{...getFloatingProps()}
>
<TwitterPicker
triangle="top-right"
color={{ r: value[0], g: value[1], b: value[2] }}
onChangeComplete={(color) => {
const rgb = color.rgb;
const newValue: [number, number, number] = [rgb.r, rgb.g, rgb.b];
updateValue(newValue);
setOpen(false);
}}
/>
{visualizationColors.GPCat.colors[14].map((hexColor) => {
const [r, g, b] = hexToRgb(hexColor);
return (
<div
key={hexColor}
className="w-4 h-4 rounded-sm cursor-pointer"
style={{ backgroundColor: hexColor }}
onClick={(e) => {
e.stopPropagation();
onChange([r, g, b]);
}}
/>
);
})}
</div>
</FloatingPortal>
)}
</>
</PopoverContent>
</Popover>
</div>
);
}
import React, { useEffect } from 'react';
import ColorPicker from '@graphpolaris/shared/lib/components/colorComponents/colorPicker';
import { ColorPicker } from '@graphpolaris/shared/lib/components/colorComponents/colorPicker';
import { MapProps } from '../../mapvis';
import { Button, DropdownColorLegend, EntityPill, Input, RelationPill } from '@graphpolaris/shared/lib/components';
import { DropdownColorLegend, EntityPill, Input, RelationPill } from '@graphpolaris/shared/lib/components';
import { LayerSettingsComponentType } from '../../mapvis.types';
import { Accordion, AccordionBody, AccordionHead, AccordionItem } from '@graphpolaris/shared/lib/components/accordion';
const areaColoringStrategies = ['Node count', 'Edge count', 'Incoming edges', 'Outgoing edges', 'Connected edges', 'Attribute'];
......@@ -50,131 +51,108 @@ export function ChoroplethOptions({
}
}, [graphMetadata, layerType, settings, updateLayerSettings]);
const handleCollapseToggle = (type: string, itemType: 'nodes' | 'edges') => {
if (layerSettings) {
updateLayerSettings({
[itemType]: {
...layerSettings[itemType],
[type]: {
...layerSettings[itemType][type],
collapsed: !layerSettings[itemType][type]?.collapsed ?? true,
},
},
});
}
};
return (
layerSettings && (
<div>
<div className="mt-2">
<p className="text-bold">Area color</p>
<Input
inline
label="Based on"
type="dropdown"
value={layerSettings?.coloringStrategy}
options={areaColoringStrategies}
onChange={(val) => updateLayerSettings({ coloringStrategy: val as coloringStrategiesType })}
/>
<DropdownColorLegend value={settings?.colorScale} onChange={(val) => updateLayerSettings({ colorScale: val })} />
<Input
label="Opacity"
type="slider"
min={0}
max={1}
step={0.05}
unit="%"
value={layerSettings?.opacity ?? 0.8}
onChange={(val) => updateLayerSettings({ opacity: val as number })}
/>
</div>
{graphMetadata.nodes.labels.map((nodeType) => {
const nodeSettings = layerSettings?.nodes?.[nodeType] || {};
return (
<div className="mt-2" key={nodeType}>
<div className="flex items-center">
<Button
size="2xs"
iconComponent={nodeSettings.collapsed ? 'icon-[ic--baseline-arrow-right]' : 'icon-[ic--baseline-arrow-drop-down]'}
variant="ghost"
onClick={() => handleCollapseToggle(nodeType, 'nodes')}
/>
<div className="w-3/4 mr-6 cursor-pointer" onClick={() => handleCollapseToggle(nodeType, 'nodes')}>
<Accordion defaultOpenAll={true}>
<AccordionItem className="mt-2">
<AccordionHead className="flex items-center">
<span className="font-semibold">General</span>
</AccordionHead>
<AccordionBody>
<p className="text-bold">Area color</p>
<Input
inline
label="Based on"
type="dropdown"
value={layerSettings?.coloringStrategy}
options={areaColoringStrategies}
onChange={(val) => updateLayerSettings({ coloringStrategy: val as coloringStrategiesType })}
/>
<DropdownColorLegend value={settings?.colorScale} onChange={(val) => updateLayerSettings({ colorScale: val })} />
<Input
label="Opacity"
type="slider"
min={0}
max={1}
step={0.05}
unit="%"
value={layerSettings?.opacity ?? 0.8}
onChange={(val) => updateLayerSettings({ opacity: val as number })}
/>
</AccordionBody>
</AccordionItem>
{graphMetadata.nodes.labels.map((nodeType) => {
const nodeSettings = layerSettings?.nodes?.[nodeType] || {};
return (
<AccordionItem className="mt-2" key={nodeType}>
<AccordionHead className="flex items-center">
<EntityPill title={nodeType} />
</div>
</div>
{!nodeSettings.collapsed && (
<div>
<Input
inline
label="Latitude"
type="dropdown"
value={settings?.location[nodeType].lat}
options={[...spatialAttributes[nodeType]]}
disabled={spatialAttributes[nodeType].length < 1}
onChange={(val) => updateSpatialAttribute(nodeType, 'lat', val as string)}
/>
<Input
inline
label="Longitude"
type="dropdown"
value={settings?.location[nodeType].lon}
options={[...spatialAttributes[nodeType]]}
disabled={spatialAttributes[nodeType].length < 1}
onChange={(val) => updateSpatialAttribute(nodeType, 'lon', val as string)}
/>
</div>
)}
</div>
);
})}
</AccordionHead>
<AccordionBody>
<div>
<Input
inline
label="Latitude"
type="dropdown"
value={settings?.location[nodeType].lat}
options={[...spatialAttributes[nodeType]]}
disabled={spatialAttributes[nodeType].length < 1}
onChange={(val) => updateSpatialAttribute(nodeType, 'lat', val as string)}
/>
<Input
inline
label="Longitude"
type="dropdown"
value={settings?.location[nodeType].lon}
options={[...spatialAttributes[nodeType]]}
disabled={spatialAttributes[nodeType].length < 1}
onChange={(val) => updateSpatialAttribute(nodeType, 'lon', val as string)}
/>
</div>
</AccordionBody>
</AccordionItem>
);
})}
{graphMetadata.edges.labels.map((edgeType) => {
const edgeSettings = layerSettings?.edges?.[edgeType] || {};
{graphMetadata.edges.labels.map((edgeType) => {
const edgeSettings = layerSettings?.edges?.[edgeType] || {};
return (
<div key={edgeType} className="mt-2">
<div className="flex items-center">
<Button
size="2xs"
iconComponent={edgeSettings?.collapsed ? 'icon-[ic--baseline-arrow-right]' : 'icon-[ic--baseline-arrow-drop-down]'}
variant="ghost"
onClick={() => handleCollapseToggle(edgeType, 'edges')}
/>
<div className="w-3/4 mr-6 cursor-pointer" onClick={() => handleCollapseToggle(edgeType, 'edges')}>
return (
<AccordionItem key={edgeType} className="mt-2">
<AccordionHead className="flex items-center">
<RelationPill title={edgeType} />
</div>
</div>
{!edgeSettings.collapsed && (
<div>
<div className="flex justify-between">
<span className="font-bold">Color</span>
<ColorPicker
value={edgeSettings.color}
updateValue={(val) =>
updateLayerSettings({ edges: { ...settings.edges, [edgeType]: { ...edgeSettings, color: val } } })
}
</AccordionHead>
<AccordionBody>
<div>
<div className="flex justify-between">
<span className="font-bold">Color</span>
<ColorPicker
value={edgeSettings.color}
onChange={(val) =>
updateLayerSettings({ edges: { ...settings.edges, [edgeType]: { ...edgeSettings, color: val } } })
}
/>
</div>
<Input
label="Edges on hover"
type="boolean"
value={layerSettings?.enableBrushing}
onChange={(val) => {
updateLayerSettings({ enableBrushing: val as boolean });
}}
/>
</div>
<Input
label="Edges on hover"
type="boolean"
value={layerSettings?.enableBrushing}
onChange={(val) => {
updateLayerSettings({ enableBrushing: val as boolean });
}}
/>
</div>
)}
</div>
);
})}
</AccordionBody>
</AccordionItem>
);
})}
</Accordion>
</div>
)
);
......
import React, { useEffect } from 'react';
import { MapProps } from '../../mapvis';
import { Button, EntityPill, Input } from '@graphpolaris/shared/lib/components';
import { EntityPill, Input } from '@graphpolaris/shared/lib/components';
import { LayerSettingsComponentType } from '../../mapvis.types';
import { Accordion, AccordionBody, AccordionHead, AccordionItem } from '@graphpolaris/shared/lib/components/accordion';
export function HeatLayerOptions({
settings,
......@@ -38,84 +39,64 @@ export function HeatLayerOptions({
}
}, [graphMetadata, layerType, settings, updateLayerSettings]);
const handleCollapseToggle = (type: string, itemType: 'nodes' | 'edges') => {
if (layerSettings) {
updateLayerSettings({
[itemType]: {
...layerSettings[itemType],
[type]: {
...layerSettings[itemType][type],
collapsed: !layerSettings[itemType][type]?.collapsed ?? true,
},
},
});
}
};
return (
layerSettings && (
<div>
{graphMetadata.nodes.labels.map((nodeType) => {
const nodeSettings = layerSettings?.nodes?.[nodeType] || {};
<Accordion defaultOpenAll={true}>
{graphMetadata.nodes.labels.map((nodeType) => {
const nodeSettings = layerSettings?.nodes?.[nodeType] || {};
return (
<div className="mt-2" key={nodeType}>
<div className="flex items-center">
<Button
size="2xs"
iconComponent={nodeSettings.collapsed ? 'icon-[ic--baseline-arrow-right]' : 'icon-[ic--baseline-arrow-drop-down]'}
variant="ghost"
onClick={() => handleCollapseToggle(nodeType, 'nodes')}
/>
<div className="w-3/4 mr-6 cursor-pointer" onClick={() => handleCollapseToggle(nodeType, 'nodes')}>
return (
<AccordionItem className="mt-2" key={nodeType}>
<AccordionHead className="flex items-center">
<EntityPill title={nodeType} />
</div>
</div>
</AccordionHead>
{!nodeSettings.collapsed && (
<div>
<Input
label="Hidden"
type="boolean"
value={nodeSettings.hidden ?? false}
onChange={(val) => {
updateLayerSettings({ nodes: { ...layerSettings.nodes, [nodeType]: { ...nodeSettings, hidden: val } } });
}}
/>
<Input
inline
label="Latitude"
type="dropdown"
value={settings?.location[nodeType].lat}
options={[...spatialAttributes[nodeType]]}
disabled={spatialAttributes[nodeType].length < 1}
onChange={(val) => updateSpatialAttribute(nodeType, 'lat', val as string)}
/>
<Input
inline
label="Longitude"
type="dropdown"
value={settings?.location[nodeType].lon}
options={[...spatialAttributes[nodeType]]}
disabled={spatialAttributes[nodeType].length < 1}
onChange={(val) => updateSpatialAttribute(nodeType, 'lon', val as string)}
/>
<Input
label="Size"
type="slider"
min={0}
max={40}
step={1}
value={nodeSettings.size}
onChange={(val) => {
updateLayerSettings({ nodes: { ...layerSettings.nodes, [nodeType]: { ...nodeSettings, size: Number(val) } } });
}}
/>
</div>
)}
</div>
);
})}
<AccordionBody>
<div>
<Input
label="Hidden"
type="boolean"
value={nodeSettings.hidden ?? false}
onChange={(val) => {
updateLayerSettings({ nodes: { ...layerSettings.nodes, [nodeType]: { ...nodeSettings, hidden: val } } });
}}
/>
<Input
inline
label="Latitude"
type="dropdown"
value={settings?.location[nodeType].lat}
options={[...spatialAttributes[nodeType]]}
disabled={spatialAttributes[nodeType].length < 1}
onChange={(val) => updateSpatialAttribute(nodeType, 'lat', val as string)}
/>
<Input
inline
label="Longitude"
type="dropdown"
value={settings?.location[nodeType].lon}
options={[...spatialAttributes[nodeType]]}
disabled={spatialAttributes[nodeType].length < 1}
onChange={(val) => updateSpatialAttribute(nodeType, 'lon', val as string)}
/>
<Input
label="Size"
type="slider"
min={0}
max={40}
step={1}
value={nodeSettings.size}
onChange={(val) => {
updateLayerSettings({ nodes: { ...layerSettings.nodes, [nodeType]: { ...nodeSettings, size: Number(val) } } });
}}
/>
</div>
</AccordionBody>
</AccordionItem>
);
})}
</Accordion>
</div>
)
);
......
......@@ -31,21 +31,28 @@ export class NodeLinkLayer extends CompositeLayer<CompositeLayerType> {
// TODO: Remove any here
if (changeFlags.propsOrDataChanged) {
const colorScales: ColorScales = {};
Object.keys(props.settings[NodeLinkLayer.type].nodes).map((label) => {
const nodeSettings = props.settings[NodeLinkLayer.type].nodes[label];
const nodeDistribution = props.graphMetadata.nodes.types[label].attributes;
if (nodeSettings.colorByAttribute) {
if (nodeSettings.colorAttributeType === 'numerical') {
colorScales[label] = this.setNumericalColor(
nodeDistribution[nodeSettings?.colorAttribute]?.min,
nodeDistribution[nodeSettings?.colorAttribute]?.max,
nodeSettings.colorScale,
);
const nodesSettings = props.settings?.[NodeLinkLayer.type]?.nodes;
const nodesMetadata = props.graphMetadata?.nodes?.types;
if (nodesSettings && nodesMetadata) {
Object.keys(nodesSettings).forEach((label) => {
const nodeSettings = nodesSettings[label];
const nodeDistribution = nodesMetadata[label]?.attributes;
if (nodeSettings?.colorByAttribute && nodeDistribution) {
const colorAttribute = nodeSettings.colorAttribute;
const attributeData = nodeDistribution[colorAttribute];
if (nodeSettings.colorAttributeType === 'numerical' && attributeData) {
colorScales[label] = this.setNumericalColor(attributeData.min, attributeData.max, nodeSettings.colorScale);
}
}
}
});
});
}
this.setState({ colorScales });
}
return changeFlags.propsOrDataChanged || changeFlags.somethingChanged;
}
......
......@@ -10,7 +10,7 @@ import { Attribution, ActionBar, MapTooltip, MapSettings } from './components';
import { useSelectionLayer, useCoordinateLookup } from './hooks';
import { VisualizationTooltip } from '@graphpolaris/shared/lib/components/VisualizationTooltip';
import { Tooltip, TooltipContent, TooltipTrigger } from '@graphpolaris/shared/lib/components/tooltip';
import { isGeoJsonType } from './utils';
import { isGeoJsonType, rgbToHex } from './utils';
import { NodeType } from '../nodelinkvis/types';
export type MapProps = {
......@@ -270,7 +270,11 @@ export const MapVis = forwardRef((props: VisualizationPropTypes<MapProps>, refEx
? (node as SearchResultType)?.name
: 'N/A'
}
colorHeader="#FB9637"
colorHeader={rgbToHex(
props?.settings?.nodelink?.nodes?.[node.label]?.color?.[0] ?? 0,
props?.settings?.nodelink?.nodes?.[node.label]?.color?.[1] ?? 0,
props?.settings?.nodelink?.nodes?.[node.label]?.color?.[2] ?? 0,
)}
>
<MapTooltip type={node.selectedType} data={{ ...node }} key={node._id} />
</VisualizationTooltip>
......@@ -281,7 +285,9 @@ export const MapVis = forwardRef((props: VisualizationPropTypes<MapProps>, refEx
<Tooltip open={true} interactive={false} boundaryElement={ref} showArrow={true}>
<TooltipTrigger x={searchResult.x} y={searchResult.y} />
<TooltipContent>
<MapTooltip type="location" data={{ ...searchResult }} key={searchResult.name} />
<VisualizationTooltip name={searchResult.name} colorHeader="#FB9637">
<MapTooltip type="location" data={{ ...searchResult }} key={searchResult.name} />
</VisualizationTooltip>
</TooltipContent>
</Tooltip>
)}
......
......@@ -15,3 +15,8 @@ export function nodeColorRGB(num: number) {
export const isGeoJsonType = (data: NodeType | GeoJsonType | SearchResultType): data is GeoJsonType => {
return (data as GeoJsonType).properties !== undefined;
};
export const rgbToHex = (r: number, g: number, b: number): string => {
const toHex = (n: number) => n.toString(16).padStart(2, '0');
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
};
......@@ -15,6 +15,7 @@ import { Button } from '@graphpolaris/shared/lib/components/buttons';
import { EntityPill } from '@graphpolaris/shared/lib/components/pills/Pill';
import { cloneDeep } from 'lodash-es';
import { useImmer } from 'use-immer';
import { Accordion, AccordionBody, AccordionHead, AccordionItem } from '@graphpolaris/shared/lib/components/accordion';
import html2canvas from 'html2canvas';
export interface PaohVisHandle {
......@@ -1030,29 +1031,25 @@ const PaohSettings = ({ settings, graphMetadata, updateSettings }: Visualization
}
></Input>
</div>
<Button
variantType="secondary"
variant="ghost"
size="sm"
className="-pt-3 mt-1"
onClick={toggleCollapseAttrRows}
iconComponent={areCollapsedAttrRows ? 'icon-[ic--baseline-arrow-right]' : 'icon-[ic--baseline-arrow-drop-down]'}
>
attributes:{' '}
</Button>
{!areCollapsedAttrRows && (
<div className="">
<Input
type="checkbox"
value={settings.attributeRowShow}
options={rowNodeInformation.attributes}
onChange={(val: string[] | string) => {
const updatedVal = Array.isArray(val) ? val : [val];
updateSettings({ attributeRowShow: updatedVal });
}}
/>
</div>
)}
<Accordion>
<AccordionItem>
<AccordionHead>
<span className="font-semibold">attributes: </span>
</AccordionHead>
<AccordionBody>
<Input
type="checkbox"
value={settings.attributeRowShow}
options={rowNodeInformation.attributes}
onChange={(val: string[] | string) => {
const updatedVal = Array.isArray(val) ? val : [val];
updateSettings({ attributeRowShow: updatedVal });
}}
/>
</AccordionBody>
</AccordionItem>
</Accordion>
<div>
<span className="text-xs font-semibold">Node used in Column</span>
......@@ -1075,30 +1072,24 @@ const PaohSettings = ({ settings, graphMetadata, updateSettings }: Visualization
/>
</div>
<Button
variantType="secondary"
variant="ghost"
size="sm"
className="-pt-3 mt-1"
onClick={toggleCollapseAttrColumns}
iconComponent={areCollapsedAttrColumns ? 'icon-[ic--baseline-arrow-right]' : 'icon-[ic--baseline-arrow-drop-down]'}
>
attributes:{' '}
</Button>
{!areCollapsedAttrColumns && (
<div className="">
<Input
type="checkbox"
value={settings.attributeColumnShow}
options={columnsNodeInformation.attributes}
onChange={(val: string[] | string) => {
const updatedVal = Array.isArray(val) ? val : [val];
updateSettings({ attributeColumnShow: updatedVal });
}}
/>
</div>
)}
<Accordion>
<AccordionItem>
<AccordionHead>
<span className="font-semibold">attributes: </span>
</AccordionHead>
<AccordionBody>
<Input
type="checkbox"
value={settings.attributeColumnShow}
options={columnsNodeInformation.attributes}
onChange={(val: string[] | string) => {
const updatedVal = Array.isArray(val) ? val : [val];
updateSettings({ attributeColumnShow: updatedVal });
}}
/>
</AccordionBody>
</AccordionItem>
</Accordion>
<Input
type="slider"
......
......@@ -6,6 +6,7 @@ import { SettingsContainer } from '@graphpolaris/shared/lib/vis/components/confi
import { Button } from '@graphpolaris/shared/lib/components/buttons';
import { useSearchResultData } from '@graphpolaris/shared/lib/data-access';
import { EntityPill } from '@graphpolaris/shared/lib/components/pills/Pill';
import { Accordion, AccordionBody, AccordionHead, AccordionItem } from '@graphpolaris/shared/lib/components/accordion';
import html2canvas from 'html2canvas';
export interface TableVisHandle {
......@@ -148,11 +149,6 @@ const TableSettings = ({ settings, graphMetadata, updateSettings }: Visualizatio
}
}, [graphMetadata]);
const [areCollapsedAttr, setAreCollapsedAttr] = useState<boolean>(true);
const toggleCollapseAttr = () => {
setAreCollapsedAttr(!areCollapsedAttr);
};
const selectedNodeAttributes = useMemo(() => {
if (settings.displayEntity) {
const nodeType = graphMetadata.nodes.types[settings.displayEntity];
......@@ -214,20 +210,12 @@ const TableSettings = ({ settings, graphMetadata, updateSettings }: Visualizatio
onChange={(val) => updateSettings({ maxBarsCount: val })}
/>
</div>
<div className="flex flex-col items-start space-y-2">
<span className="text-sm">Attributes to display:</span>
<Button
className="w-full text-justify justify-start"
variantType="secondary"
variant="ghost"
size="sm"
onClick={toggleCollapseAttr}
iconComponent={areCollapsedAttr ? 'icon-[ic--baseline-arrow-right]' : 'icon-[ic--baseline-arrow-drop-down]'}
>
attributes:{' '}
</Button>
<div className="">
{!areCollapsedAttr && (
<Accordion>
<AccordionItem>
<AccordionHead>
<span className="text-sm">Attributes to display:</span>
</AccordionHead>
<AccordionBody>
<Input
type="checkbox"
value={settings.displayAttributes}
......@@ -237,9 +225,10 @@ const TableSettings = ({ settings, graphMetadata, updateSettings }: Visualizatio
updateSettings({ displayAttributes: updatedVal });
}}
/>
)}
</div>
</div>
test
</AccordionBody>
</AccordionItem>
</Accordion>
</div>
</SettingsContainer>
);
......
......@@ -54,7 +54,6 @@
"pixi-actions": "^1.1.10",
"pixi-viewport": "5.0.2",
"pixi.js": "^7.4.2",
"react-color": "^2.19.3",
"react-cookie": "^7.1.0",
"react-draggable": "^4.4.6",
"react-grid-layout": "^1.4.4",
......@@ -85,7 +84,6 @@
"@types/lodash-es": "^4.17.12",
"@types/node": "20.11.27",
"@types/react": "^18.2.65",
"@types/react-color": "^3.0.12",
"@types/react-dom": "^18.2.22",
"@types/react-window": "^1.8.8",
"@typescript-eslint/eslint-plugin": "~7.2.0",
......