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 (3)
......@@ -448,7 +448,7 @@ export const CheckboxInput = ({ label, value, options, onChange, tooltip }: Chec
export const BooleanInput = ({ label, value, onChange, tooltip, info, size, required, className }: BooleanProps) => {
return (
<Tooltip>
<TooltipTrigger className={className + 'w-full flex justify-between'}>
<TooltipTrigger className={className + ' w-full flex justify-between'}>
{label && (
<label className="label p-0">
<span
......
......@@ -19,11 +19,7 @@ import { EntityPill } from '@graphpolaris/shared/lib/components/pills';
import { Handle, Position, useUpdateNodeInternals } from 'reactflow';
import { NodeAttribute, SchemaReactflowEntityNode, toHandleId } from '../../../model';
import { PillAttributes } from '../../pillattributes/PillAttributes';
import { DropdownTrigger, DropdownContainer, DropdownItemContainer, DropdownItem } from '@graphpolaris/shared/lib/components/dropdowns';
import { PopoverContext } from '@graphpolaris/shared/lib/components/layout/Popover';
import { useDispatch } from 'react-redux';
import { isEqual } from 'lodash-es';
import { getDataTypeIcon } from '@graphpolaris/shared/lib/components/DataTypeIcon';
import { uniqBy } from 'lodash-es';
/**
* Component to render an entity flow element
......@@ -43,6 +39,7 @@ export const QueryEntityPill = React.memo((node: SchemaReactflowEntityNode) => {
[graph],
);
const uniqueAttributes = useMemo(() => uniqBy(data.attributes, (attr) => attr.handleData.attributeName), [data.attributes]);
const unionType = useQuerybuilderUnionTypes()[node.id];
return (
......@@ -75,7 +72,7 @@ export const QueryEntityPill = React.memo((node: SchemaReactflowEntityNode) => {
{data?.attributes && (
<PillAttributes
node={node}
attributes={data.attributes}
attributes={uniqueAttributes}
attributeEdges={attributeEdges.map((edge) => edge?.attributes)}
unionType={unionType}
/>
......
......@@ -10,12 +10,14 @@ const getGraphStatistics = (graph: GraphQueryResultFromBackend): GraphStatistics
const density = n_nodes < 2 ? 0 : (n_edges * 2) / (n_nodes * (n_nodes - 1));
// general nodes and edges statistics
const metaData: GraphStatistics = {
topological: { density, self_loops: 0 },
nodes: { labels: [], count: n_nodes, types: {} },
edges: { labels: [], count: n_edges, types: {} },
};
// attributes based statistics
nodes.forEach((node) => {
const nodeType = getNodeLabel(node);
if (!metaData.nodes.labels.includes(nodeType)) {
......@@ -25,7 +27,6 @@ const getGraphStatistics = (graph: GraphQueryResultFromBackend): GraphStatistics
if (!metaData.nodes.types[nodeType]) {
metaData.nodes.types[nodeType] = { count: 0, attributes: {} };
}
metaData.nodes.types[nodeType].count++;
Object.entries(node.attributes).forEach(([attributeId, attributeValue]) => {
......@@ -34,7 +35,6 @@ const getGraphStatistics = (graph: GraphQueryResultFromBackend): GraphStatistics
if (!metaData.nodes.types[nodeType].attributes[attributeId]) {
metaData.nodes.types[nodeType].attributes[attributeId] = { attributeType, statistics: initializeStatistics(attributeType) };
}
updateStatistics(metaData.nodes.types[nodeType].attributes[attributeId], attributeValue);
});
});
......
......@@ -67,6 +67,7 @@ type CategoricalStats = {
uniqueItems: number;
values: string[];
mode: string;
count: number;
};
type TemporalStats = {
......@@ -77,6 +78,7 @@ type TemporalStats = {
type ArrayStats = {
length: number;
count: number;
};
type ObjectStats = {
......
......@@ -12,10 +12,11 @@ import type { ArrayStats, BooleanStats, CategoricalStats, NumericalStats, Tempor
describe('updateArrayStats', () => {
it('should update the length of the array', () => {
const stats: ArrayStats = { length: 0 };
const stats: ArrayStats = { length: 0, count: 0 };
const value = [1, 2, 3];
updateArrayStats(stats, value);
expect(stats.length).toBe(3);
expect(stats.count).toBe(1);
});
});
......@@ -37,7 +38,7 @@ describe('updateBooleanStats', () => {
describe('updateCategoricalStats', () => {
it('should update mode and unique items count', () => {
const stats: CategoricalStats = { uniqueItems: 0, values: [], mode: '' };
const stats: CategoricalStats = { uniqueItems: 0, values: [], mode: '', count: 0 };
updateCategoricalStats(stats, 'apple');
updateCategoricalStats(stats, 'banana');
updateCategoricalStats(stats, 'apple');
......@@ -45,6 +46,7 @@ describe('updateCategoricalStats', () => {
expect(stats.values).toEqual(['apple', 'banana', 'apple']);
expect(stats.uniqueItems).toBe(2);
expect(stats.mode).toBe('apple');
expect(stats.count).toBe(3);
});
});
......@@ -86,7 +88,7 @@ describe('updateObjectStats', () => {
describe('initializeStatistics', () => {
it('should initialize statistics for string type', () => {
const stats = initializeStatistics('string');
expect(stats).toEqual({ uniqueItems: 0, values: [], mode: '' });
expect(stats).toEqual({ uniqueItems: 0, values: [], mode: '', count: 0 });
});
it('should initialize statistics for boolean type', () => {
......@@ -96,7 +98,7 @@ describe('initializeStatistics', () => {
it('should initialize statistics for number type', () => {
const stats = initializeStatistics('number');
expect(stats).toEqual({ min: Infinity, max: -Infinity, average: 0 });
expect(stats).toEqual({ min: Infinity, max: -Infinity, average: 0, count: 0 });
});
it('should throw an error for an unknown type', () => {
......
......@@ -2,6 +2,7 @@ import { ArrayStats } from '../../statistics.types';
const updateArrayStats = (stats: ArrayStats, value: any[]) => {
stats.length = value.length;
stats.count++;
};
export { updateArrayStats };
......@@ -11,6 +11,7 @@ const updateCategoricalStats = (stats: CategoricalStats, value: string | boolean
frequencyMap[val] = (frequencyMap[val] || 0) + 1;
});
stats.mode = Object.keys(frequencyMap).reduce((a, b) => (frequencyMap[a] > frequencyMap[b] ? a : b));
stats.count++;
};
export { updateCategoricalStats };
......@@ -7,6 +7,7 @@ const initializeStatistics = <T extends AttributeType>(type: T): AttributeTypeSt
uniqueItems: 0,
values: [],
mode: '',
count: 0,
} as unknown as AttributeTypeStats<T>;
case 'boolean':
return {
......@@ -18,6 +19,7 @@ const initializeStatistics = <T extends AttributeType>(type: T): AttributeTypeSt
min: Infinity,
max: -Infinity,
average: 0,
count: 0,
} as unknown as AttributeTypeStats<T>;
case 'date':
case 'time':
......@@ -31,6 +33,7 @@ const initializeStatistics = <T extends AttributeType>(type: T): AttributeTypeSt
case 'array':
return {
length: 0,
count: 0,
} as unknown as AttributeTypeStats<T>;
case 'object':
return {
......
......@@ -1124,14 +1124,22 @@ const PaohSettings = ({ settings, graphMetadata, updateSettings }: Visualization
label="Row jump sensitivity"
value={settings.rowJumpAmount}
onChange={(val) => updateSettings({ rowJumpAmount: val })}
containerClassName="pt-2"
/>
<Input
type="number"
label="Column jump sensitivity"
value={settings.colJumpAmount}
onChange={(val) => updateSettings({ colJumpAmount: val })}
containerClassName="pt-2"
/>
<Input
type="boolean"
label="Merge Data"
value={settings.mergeData}
onChange={(val) => updateSettings({ mergeData: val })}
className="pt-2"
/>
<Input type="boolean" label="Merge Data" value={settings.mergeData} onChange={(val) => updateSettings({ mergeData: val })} />
</div>
</SettingsContainer>
);
......