mirror of
https://github.com/PeWu/topola-viewer.git
synced 2026-05-26 23:26:15 +00:00
14
package-lock.json
generated
14
package-lock.json
generated
@@ -37,7 +37,7 @@
|
|||||||
"remark-rehype": "^10.0.0",
|
"remark-rehype": "^10.0.0",
|
||||||
"semantic-ui-css": "^2.4.1",
|
"semantic-ui-css": "^2.4.1",
|
||||||
"semantic-ui-react": "^2.0.3",
|
"semantic-ui-react": "^2.0.3",
|
||||||
"topola": "^3.5.2",
|
"topola": "^3.6.0",
|
||||||
"turbocommons-ts": "^3.8.0",
|
"turbocommons-ts": "^3.8.0",
|
||||||
"unified": "^10.1.0",
|
"unified": "^10.1.0",
|
||||||
"wikitree-js": "^0.1.0"
|
"wikitree-js": "^0.1.0"
|
||||||
@@ -22733,9 +22733,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/topola": {
|
"node_modules/topola": {
|
||||||
"version": "3.5.2",
|
"version": "3.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/topola/-/topola-3.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/topola/-/topola-3.6.0.tgz",
|
||||||
"integrity": "sha512-JTrWXP+8F+E1XdxEoruzwv+YPCgLoi6P+QUHCYXpl8NMcK2PbsV1YBXK3zvEtNQ2sjAPeDE/iknPz0Mxb+HBhg==",
|
"integrity": "sha512-5igi2Nc7HgwyFyh8aGnRjgLxtDhlZzTnnzX5DwBQUS38G52h9ywjyH+o6pPEm2EqFnbLpwObu2YcQ3WkwXJG7Q==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"array-flat-polyfill": "^1.0.1",
|
"array-flat-polyfill": "^1.0.1",
|
||||||
"d3-array": "^2.12.1",
|
"d3-array": "^2.12.1",
|
||||||
@@ -44053,9 +44053,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"topola": {
|
"topola": {
|
||||||
"version": "3.5.2",
|
"version": "3.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/topola/-/topola-3.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/topola/-/topola-3.6.0.tgz",
|
||||||
"integrity": "sha512-JTrWXP+8F+E1XdxEoruzwv+YPCgLoi6P+QUHCYXpl8NMcK2PbsV1YBXK3zvEtNQ2sjAPeDE/iknPz0Mxb+HBhg==",
|
"integrity": "sha512-5igi2Nc7HgwyFyh8aGnRjgLxtDhlZzTnnzX5DwBQUS38G52h9ywjyH+o6pPEm2EqFnbLpwObu2YcQ3WkwXJG7Q==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"array-flat-polyfill": "^1.0.1",
|
"array-flat-polyfill": "^1.0.1",
|
||||||
"d3-array": "^2.12.1",
|
"d3-array": "^2.12.1",
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
"remark-rehype": "^10.0.0",
|
"remark-rehype": "^10.0.0",
|
||||||
"semantic-ui-css": "^2.4.1",
|
"semantic-ui-css": "^2.4.1",
|
||||||
"semantic-ui-react": "^2.0.3",
|
"semantic-ui-react": "^2.0.3",
|
||||||
"topola": "^3.5.2",
|
"topola": "^3.6.0",
|
||||||
"turbocommons-ts": "^3.8.0",
|
"turbocommons-ts": "^3.8.0",
|
||||||
"unified": "^10.1.0",
|
"unified": "^10.1.0",
|
||||||
"wikitree-js": "^0.1.0"
|
"wikitree-js": "^0.1.0"
|
||||||
|
|||||||
10
src/app.tsx
10
src/app.tsx
@@ -32,6 +32,7 @@ import {
|
|||||||
configToArgs,
|
configToArgs,
|
||||||
DEFALUT_CONFIG,
|
DEFALUT_CONFIG,
|
||||||
Ids,
|
Ids,
|
||||||
|
Sex,
|
||||||
} from './config';
|
} from './config';
|
||||||
import {
|
import {
|
||||||
getSelection,
|
getSelection,
|
||||||
@@ -219,14 +220,16 @@ export function App() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleIds(config: Config, data: TopolaData | undefined) {
|
function toggleDetails(config: Config, data: TopolaData | undefined) {
|
||||||
if (data === undefined) {
|
if (data === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let shouldHideIds = config.id === Ids.HIDE;
|
let shouldHideIds = config.id === Ids.HIDE;
|
||||||
|
let shouldHideSex = config.sex === Sex.HIDE;
|
||||||
let indiMap = idToIndiMap(data.chartData);
|
let indiMap = idToIndiMap(data.chartData);
|
||||||
indiMap.forEach((indi) => {
|
indiMap.forEach((indi) => {
|
||||||
indi.hideId = shouldHideIds;
|
indi.hideId = shouldHideIds;
|
||||||
|
indi.hideSex = shouldHideSex;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,7 +341,7 @@ export function App() {
|
|||||||
const data = await loadData(args.sourceSpec, args.selection);
|
const data = await loadData(args.sourceSpec, args.selection);
|
||||||
// Set state with data.
|
// Set state with data.
|
||||||
setData(data);
|
setData(data);
|
||||||
toggleIds(args.config, data);
|
toggleDetails(args.config, data);
|
||||||
setShowSidePanel(args.showSidePanel);
|
setShowSidePanel(args.showSidePanel);
|
||||||
setState(AppState.SHOWING_CHART);
|
setState(AppState.SHOWING_CHART);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
@@ -482,7 +485,7 @@ export function App() {
|
|||||||
config={config}
|
config={config}
|
||||||
onChange={(config) => {
|
onChange={(config) => {
|
||||||
setConfig(config);
|
setConfig(config);
|
||||||
toggleIds(config, data);
|
toggleDetails(config, data);
|
||||||
updateUrl(configToArgs(config));
|
updateUrl(configToArgs(config));
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -507,6 +510,7 @@ export function App() {
|
|||||||
freezeAnimation={freezeAnimation}
|
freezeAnimation={freezeAnimation}
|
||||||
colors={config.color}
|
colors={config.color}
|
||||||
hideIds={config.id}
|
hideIds={config.id}
|
||||||
|
hideSex={config.sex}
|
||||||
/>
|
/>
|
||||||
{showSidePanel ? (
|
{showSidePanel ? (
|
||||||
<Media greaterThanOrEqual="large" className="sidePanel">
|
<Media greaterThanOrEqual="large" className="sidePanel">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {ChartColors, Ids} from './config';
|
import {ChartColors, Ids, Sex} from './config';
|
||||||
import {interpolateNumber} from 'd3-interpolate';
|
import {interpolateNumber} from 'd3-interpolate';
|
||||||
import {IntlShape, useIntl} from 'react-intl';
|
import {IntlShape, useIntl} from 'react-intl';
|
||||||
import {max, min} from 'd3-array';
|
import {max, min} from 'd3-array';
|
||||||
@@ -258,6 +258,7 @@ export interface ChartProps {
|
|||||||
freezeAnimation?: boolean;
|
freezeAnimation?: boolean;
|
||||||
colors?: ChartColors;
|
colors?: ChartColors;
|
||||||
hideIds?: Ids;
|
hideIds?: Ids;
|
||||||
|
hideSex?: Sex;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChartWrapper {
|
class ChartWrapper {
|
||||||
@@ -420,7 +421,8 @@ export function Chart(props: ChartProps) {
|
|||||||
const initialRender =
|
const initialRender =
|
||||||
props.chartType !== prevProps?.chartType ||
|
props.chartType !== prevProps?.chartType ||
|
||||||
props.colors !== prevProps?.colors ||
|
props.colors !== prevProps?.colors ||
|
||||||
props.hideIds !== prevProps?.hideIds;
|
props.hideIds !== prevProps?.hideIds ||
|
||||||
|
props.hideSex !== prevProps?.hideSex;
|
||||||
const resetPosition =
|
const resetPosition =
|
||||||
props.chartType !== prevProps?.chartType ||
|
props.chartType !== prevProps?.chartType ||
|
||||||
props.data !== prevProps.data ||
|
props.data !== prevProps.data ||
|
||||||
|
|||||||
@@ -13,14 +13,21 @@ export enum Ids {
|
|||||||
SHOW,
|
SHOW,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum Sex {
|
||||||
|
HIDE,
|
||||||
|
SHOW,
|
||||||
|
}
|
||||||
|
|
||||||
export interface Config {
|
export interface Config {
|
||||||
color: ChartColors;
|
color: ChartColors;
|
||||||
id: Ids;
|
id: Ids;
|
||||||
|
sex: Sex;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DEFALUT_CONFIG: Config = {
|
export const DEFALUT_CONFIG: Config = {
|
||||||
color: ChartColors.COLOR_BY_GENERATION,
|
color: ChartColors.COLOR_BY_GENERATION,
|
||||||
id: Ids.SHOW,
|
id: Ids.SHOW,
|
||||||
|
sex: Sex.SHOW,
|
||||||
};
|
};
|
||||||
|
|
||||||
const COLOR_ARG = new Map<string, ChartColors>([
|
const COLOR_ARG = new Map<string, ChartColors>([
|
||||||
@@ -38,6 +45,13 @@ const ID_ARG = new Map<string, Ids>([
|
|||||||
const ID_ARG_INVERSE = new Map<Ids, string>();
|
const ID_ARG_INVERSE = new Map<Ids, string>();
|
||||||
ID_ARG.forEach((v, k) => ID_ARG_INVERSE.set(v, k));
|
ID_ARG.forEach((v, k) => ID_ARG_INVERSE.set(v, k));
|
||||||
|
|
||||||
|
const SEX_ARG = new Map<string, Sex>([
|
||||||
|
['h', Sex.HIDE],
|
||||||
|
['s', Sex.SHOW],
|
||||||
|
]);
|
||||||
|
const SEX_ARG_INVERSE = new Map<Sex, string>();
|
||||||
|
SEX_ARG.forEach((v, k) => SEX_ARG_INVERSE.set(v, k));
|
||||||
|
|
||||||
export function argsToConfig(args: ParsedQuery<any>): Config {
|
export function argsToConfig(args: ParsedQuery<any>): Config {
|
||||||
const getParam = (name: string) => {
|
const getParam = (name: string) => {
|
||||||
const value = args[name];
|
const value = args[name];
|
||||||
@@ -47,6 +61,7 @@ export function argsToConfig(args: ParsedQuery<any>): Config {
|
|||||||
return {
|
return {
|
||||||
color: COLOR_ARG.get(getParam('c') ?? '') ?? DEFALUT_CONFIG.color,
|
color: COLOR_ARG.get(getParam('c') ?? '') ?? DEFALUT_CONFIG.color,
|
||||||
id: ID_ARG.get(getParam('i') ?? '') ?? DEFALUT_CONFIG.id,
|
id: ID_ARG.get(getParam('i') ?? '') ?? DEFALUT_CONFIG.id,
|
||||||
|
sex: SEX_ARG.get(getParam('s') ?? '') ?? DEFALUT_CONFIG.sex,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,6 +69,7 @@ export function configToArgs(config: Config): ParsedQuery<any> {
|
|||||||
return {
|
return {
|
||||||
c: COLOR_ARG_INVERSE.get(config.color),
|
c: COLOR_ARG_INVERSE.get(config.color),
|
||||||
i: ID_ARG_INVERSE.get(config.id),
|
i: ID_ARG_INVERSE.get(config.id),
|
||||||
|
s: SEX_ARG_INVERSE.get(config.sex),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,6 +184,49 @@ export function ConfigPanel(props: {
|
|||||||
</Form.Field>
|
</Form.Field>
|
||||||
</Item.Content>
|
</Item.Content>
|
||||||
</Item>
|
</Item>
|
||||||
|
<Item>
|
||||||
|
<Item.Content>
|
||||||
|
<Header sub>
|
||||||
|
<FormattedMessage id="config.sex" defaultMessage="Sex" />
|
||||||
|
</Header>
|
||||||
|
<Form.Field className="no-margin">
|
||||||
|
<Checkbox
|
||||||
|
radio
|
||||||
|
label={
|
||||||
|
<FormattedMessage
|
||||||
|
tagName="label"
|
||||||
|
id="config.sex.HIDE"
|
||||||
|
defaultMessage="hide"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
name="checkboxRadioGroup"
|
||||||
|
value="hide"
|
||||||
|
checked={props.config.sex === Sex.HIDE}
|
||||||
|
onClick={() =>
|
||||||
|
props.onChange({...props.config, sex: Sex.HIDE})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Form.Field>
|
||||||
|
<Form.Field className="no-margin">
|
||||||
|
<Checkbox
|
||||||
|
radio
|
||||||
|
label={
|
||||||
|
<FormattedMessage
|
||||||
|
tagName="label"
|
||||||
|
id="config.sex.SHOW"
|
||||||
|
defaultMessage="show"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
name="checkboxRadioGroup"
|
||||||
|
value="show"
|
||||||
|
checked={props.config.sex === Sex.SHOW}
|
||||||
|
onClick={() =>
|
||||||
|
props.onChange({...props.config, sex: Sex.SHOW})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Form.Field>
|
||||||
|
</Item.Content>
|
||||||
|
</Item>
|
||||||
</Item.Group>
|
</Item.Group>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user