Skip to content

Commit

Permalink
feat: use GeoStylerContext composition for Rules and RuleTable (#2142)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: This removes the properties `showAmountColumn` and
`showDuplicatesColumn` from <RuleTable> and thereby also from <Style>. Please
use GeoStylerContext.composition.Rule.amount.visibility and
GeoStylerContext.composition.Rule.duplicate.visibility instead.
  • Loading branch information
jansule committed May 10, 2023
1 parent 94f13e6 commit ad98b61
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 92 deletions.
172 changes: 136 additions & 36 deletions src/Component/RuleTable/RuleTable.example.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,52 +31,152 @@
This demonstrates the use of `RuleTable`.

```jsx
import * as React from 'react';
import React, { useState } from 'react';
import { RuleTable } from 'geostyler';

class RuleTableExample extends React.Component {
constructor(props) {
super(props);

this.state = {
style: {
"name": "Demo Style",
"rules": [
function RuleTableExample() {
const [style, setStyle] = useState({
name: "Demo Style",
rules: [
{
name: "Rule 1",
symbolizers: [
{
"name": "Rule 1",
"symbolizers": [
{
"kind": "Mark",
"wellKnownName": "circle"
}
]
kind: "Mark",
wellKnownName: "circle"
}
]
}
};
]
});

const onRulesChange = (rules) => {
const newStyle = JSON.parse(JSON.stringify(style));
newStyle.rules = rules;
setStyle(newStyle);
};

return (
<RuleTable
rules={style.rules}
onRulesChange={onRulesChange}
/>
);
}

<RuleTableExample />
```

This demonstrates the use of `RuleTable` with `GeoStylerContext`.

this.onRulesChange = this.onRulesChange.bind(this);
}
```jsx
import React, { useState } from 'react';
import { Switch } from 'antd';
import { GeoStylerContext, RuleTable } from 'geostyler';

function RuleTableExample() {
const [myContext, setMyContext] = useState({
composition: {
Rule: {
name: {
visibility: true
},
filter: {
visibility: true
},
minScale: {
visibility: true
},
maxScale: {
visibility: true
},
amount: {
visibility: true
},
duplicate: {
visibility: true
}
}
}
});
const [style, setStyle] = useState({
name: "Demo Style",
rules: [
{
name: "Rule 1",
symbolizers: [
{
kind: "Mark",
wellKnownName: "circle"
}
]
}
]
});

onRulesChange(rules) {
const style = JSON.parse(JSON.stringify(this.state.style));
style.rules = rules;
this.setState({style});
}
const onRulesChange = (rules) => {
const newStyle = JSON.parse(JSON.stringify(style));
newStyle.rules = rules;
setStyle(newStyle);
};

render() {
const {
style
} = this.state;
const rules = style.rules;
const onVisibilityChange = (visibility, prop) => {
setMyContext(oldContext => {
const newContext = {...oldContext};
newContext.composition.Rule[prop].visibility = visibility;
return newContext;
});
};

return (
<RuleTable
rules={rules}
onRulesChange={this.onRulesChange}
/>
);
}
return (
<div>
<div style={{display: 'flex', flexWrap: 'wrap', gap: '15px'}}>
<Switch
checked={myContext.composition.Rule.name.visibility}
onChange={visibility => {onVisibilityChange(visibility, 'name')}}
checkedChildren="Name"
unCheckedChildren="Name"
/>
<Switch
checked={myContext.composition.Rule.filter.visibility}
onChange={visibility => {onVisibilityChange(visibility, 'filter')}}
checkedChildren="Filter"
unCheckedChildren="Filter"
/>
<Switch
checked={myContext.composition.Rule.minScale.visibility}
onChange={visibility => {onVisibilityChange(visibility, 'minScale')}}
checkedChildren="Min. Scale"
unCheckedChildren="Min. Scale"
/>
<Switch
checked={myContext.composition.Rule.maxScale.visibility}
onChange={visibility => {onVisibilityChange(visibility, 'maxScale')}}
checkedChildren="Max. Scale"
unCheckedChildren="Max. Scale"
/>
<Switch
checked={myContext.composition.Rule.amount.visibility}
onChange={visibility => {onVisibilityChange(visibility, 'amount')}}
checkedChildren="Amount"
unCheckedChildren="Amount"
/>
<Switch
checked={myContext.composition.Rule.duplicate.visibility}
onChange={visibility => {onVisibilityChange(visibility, 'duplicate')}}
checkedChildren="Duplicate"
unCheckedChildren="Duplicate"
/>
</div>
<hr/>
<GeoStylerContext.Provider value={myContext}>
<RuleTable
rules={style.rules}
onRulesChange={onRulesChange}
/>
</GeoStylerContext.Provider>
</div>
);
}

<RuleTableExample />
Expand Down
92 changes: 55 additions & 37 deletions src/Component/RuleTable/RuleTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ import RuleReorderButtons from './RuleReorderButtons/RuleReorderButtons';
import { BgColorsOutlined, BlockOutlined, EditOutlined } from '@ant-design/icons';
import type GeoStylerLocale from '../../locale/locale';
import Renderer from '../Renderer/Renderer/Renderer';
import { useGeoStylerComposition } from '../../context/GeoStylerContext/GeoStylerContext';

// i18n
export interface RuleTableLocale {
Expand Down Expand Up @@ -101,10 +102,6 @@ interface RuleTableDefaultProps extends Partial<TableProps<RuleRecord>> {
locale: GeoStylerLocale['RuleTable'];
/** The renderer to use */
rendererType: 'SLD' | 'OpenLayers';
/** Display the number of features that match a rule */
showAmountColumn: boolean;
/** Display the number of features that match more than one rule */
showDuplicatesColumn: boolean;
}

// non default props
Expand Down Expand Up @@ -136,21 +133,25 @@ export interface RuleTableProps extends Partial<RuleTableDefaultProps> {
const COMPONENTNAME = 'RuleTable';

// export class RuleTable extends React.Component<RuleTableProps, RuleTableState> {
export const RuleTable: React.FC<RuleTableProps> = ({
locale = en_US.RuleTable,
rendererType = 'OpenLayers',
showAmountColumn = true,
showDuplicatesColumn = true,
data: dataProp,
rules: rulesProp,
onRulesChange,
filterUiProps,
iconLibraries,
colorRamps,
sldRendererProps,
oLRendererProps,
...restProps
}) => {
export const RuleTable: React.FC<RuleTableProps> = (props) => {

const composition = useGeoStylerComposition('Rule', {});

const composed = {...props, ...composition};

const {
locale = en_US.RuleTable,
rendererType = 'OpenLayers',
data: dataProp,
rules: rulesProp,
onRulesChange,
filterUiProps,
iconLibraries,
colorRamps,
sldRendererProps,
oLRendererProps,
...restProps
} = composed;

const [ruleEditIndex, setRuleEditIndex] = useState<number>();
const [symbolizerEditorVisible, setSymbolizerEditorVisible] = useState<boolean>();
Expand Down Expand Up @@ -405,32 +406,49 @@ export const RuleTable: React.FC<RuleTableProps> = ({
</Tooltip>),
dataIndex: 'symbolizers',
render: symbolizerRenderer
}, {
title: locale.nameColumnTitle,
dataIndex: 'name',
render: nameRenderer
}, {
title: locale.filterColumnTitle,
dataIndex: 'filter',
render: filterRenderer
}, {
title: locale.minScaleColumnTitle,
dataIndex: 'minScale',
render: minScaleRenderer
}, {
title: locale.maxScaleColumnTitle,
dataIndex: 'maxScale',
render: maxScaleRenderer
}];

if (showAmountColumn) {
if (!(composition.name?.visibility === false)) {
columns.push({
title: locale.nameColumnTitle,
dataIndex: 'name',
render: nameRenderer
});
}

if (!(composition.filter?.visibility === false)) {
columns.push({
title: locale.filterColumnTitle,
dataIndex: 'filter',
render: filterRenderer
});
}

if (!(composition.minScale?.visibility === false)) {
columns.push({
title: locale.minScaleColumnTitle,
dataIndex: 'minScale',
render: minScaleRenderer
});
}

if (!(composition.maxScale?.visibility === false)) {
columns.push({
title: locale.maxScaleColumnTitle,
dataIndex: 'maxScale',
render: maxScaleRenderer
});
}

if (!(composition.amount?.visibility === false)) {
columns.push({
title: (<Tooltip title={locale.amountColumnTitle}>Σ</Tooltip>),
dataIndex: 'amount',
render: amountRenderer
});
}
if (showDuplicatesColumn) {

if (!(composition.duplicate?.visibility === false)) {
columns.push({
title: (
<Tooltip title={locale.duplicatesColumnTitle}>
Expand Down
28 changes: 18 additions & 10 deletions src/Component/Rules/Rules.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import en_US from '../../locale/en_US';
import { useDragDropSensors } from '../../hook/UseDragDropSensors';
import { SortableItem } from '../SortableItem/SortableItem';
import { RemovableItem } from '../RemovableItem/RemovableItem';
import { useGeoStylerComposition } from '../../context/GeoStylerContext/GeoStylerContext';

// default props
interface RulesDefaultProps {
Expand Down Expand Up @@ -82,16 +83,23 @@ export interface RulesProps extends Partial<RulesDefaultProps> {
onEditRuleClick?: (ruleId: number) => void;
}

export const Rules: React.FC<RulesProps> = ({
locale = en_US.Rules,
data,
rules,
onRulesChange,
onClassificationClick,
onEditSelectionClick,
onEditRuleClick,
enableClassification = true
}) => {
export const Rules: React.FC<RulesProps> = (props) => {

const composition = useGeoStylerComposition('Rule', {});

const composed = {...props, ...composition};

const {
locale = en_US.Rules,
data,
rules,
onRulesChange,
onClassificationClick,
onEditSelectionClick,
onEditRuleClick,
enableClassification = true
} = composed;

const [multiEditActive, setMultiEditActive] = useState<boolean>(false);
const [selectedRules, setSelectedRules] = useState<number[]>([]);
const toggleMultiEdit = () => {
Expand Down
9 changes: 0 additions & 9 deletions src/Component/Style/Style.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,6 @@ export interface StyleProps extends Partial<StyleDefaultProps> {
sldRendererProps?: SLDRendererAdditonalProps;
/** List of supported icons ordered as library */
iconLibraries?: IconLibrary[];
/** Display the number of features that match a rule */
showAmountColumn?: boolean;
/** Display the number of features that match more than one rule */
showDuplicatesColumn?: boolean;
/** Object containing the predefined color ramps */
colorRamps?: {
[name: string]: string[];
};
Expand Down Expand Up @@ -152,8 +147,6 @@ export const Style: React.FC<StyleProps> = ({
ruleRendererType,
sldRendererProps,
iconLibraries,
showAmountColumn,
showDuplicatesColumn,
colorRamps,
useBrewerColorRamps,
colorSpaces,
Expand Down Expand Up @@ -513,8 +506,6 @@ export const Style: React.FC<StyleProps> = ({
data={data}
footer={createFooter}
iconLibraries={iconLibraries}
showAmountColumn={showAmountColumn}
showDuplicatesColumn={showDuplicatesColumn}
colorRamps={colorRamps}
{...ruleTableProps}
/>
Expand Down
3 changes: 3 additions & 0 deletions src/context/GeoStylerContext/GeoStylerContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ export type CompositionContext = {
minScale?: {
visibility?: boolean;
};
filter?: {
visibility?: boolean;
};
name?: {
visibility?: boolean;
};
Expand Down

0 comments on commit ad98b61

Please sign in to comment.