Skip to content
6 changes: 3 additions & 3 deletions src/components/side-panel/station-side-panel/more-section.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Box, Heading } from '@chakra-ui/react';
import { RmgButtonGroup, RmgFields, RmgFieldsField } from '@railmapgen/rmg-components';
import { useTranslation } from 'react-i18next';
import { FACILITIES, Facilities, RmgStyle, Services, TEMP } from '../../../constants/constants';
import { FACILITIES, Facilities, PanelTypeShmetro, RmgStyle, Services, TEMP } from '../../../constants/constants';
import { useRootDispatch, useRootSelector } from '../../../redux';
import {
updateStationCharacterSpacing,
Expand All @@ -20,7 +20,7 @@ export default function MoreSection() {
const dispatch = useRootDispatch();

const selectedStation = useRootSelector(state => state.app.selectedStation);
const { style, loop } = useRootSelector(state => state.param);
const { style, loop, info_panel_type } = useRootSelector(state => state.param);
const { services, facility, loop_pivot, one_line, int_padding, character_spacing, underConstruction } =
useRootSelector(state => state.param.stn_list[selectedStation]);

Expand Down Expand Up @@ -79,7 +79,7 @@ export default function MoreSection() {
label: t('StationSidePanel.more.oneLine'),
isChecked: one_line,
onChange: checked => dispatch(updateStationOneLine(selectedStation, checked)),
hidden: ![RmgStyle.SHMetro].includes(style),
hidden: !(style === RmgStyle.SHMetro && info_panel_type !== PanelTypeShmetro.sh2024),
minW: 'full',
oneLine: true,
},
Expand Down
1 change: 1 addition & 0 deletions src/constants/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ export enum PanelTypeGZMTR {
export enum PanelTypeShmetro {
sh = 'sh',
sh2020 = 'sh2020',
sh2024 = 'sh2024',
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/i18n/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@
"gz1421": "2017 style",
"gz7w": "2022 style",
"sh": "Default",
"sh2020": "2020 (Beta)",
"sh2020": "2020",
"sh2024": "2024 (Beta)",
"nameDisplay": "Display station names",
"alternatively": "Alternatively",
"onOneSide": "Same side",
Expand Down
3 changes: 2 additions & 1 deletion src/i18n/translations/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@
"gz1421": "2017風格",
"gz7w": "2022風格",
"sh": "デフォルト",
"sh2020": "2020風格(プレビュー版)",
"sh2020": "2020風格",
"sh2024": "2024風格(プレビュー版)",
"nameDisplay": "駅名表示",
"alternatively": "交互表示",
"onOneSide": "片側表示",
Expand Down
1 change: 1 addition & 0 deletions src/i18n/translations/ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
"gz7w": "2022년 모양",
"sh": "묵인",
"sh2020": "2020모양(사전 검토)",
"sh2024": "2024모양",
"nameDisplay": "역 명칭 보이기",
"alternatively": "교차 표시",
"onOneSide": "같은 쪽",
Expand Down
3 changes: 2 additions & 1 deletion src/i18n/translations/zh-Hans.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@
"gz1421": "2017样式",
"gz7w": "2022样式",
"sh": "默认",
"sh2020": "2020样式(预览版)",
"sh2020": "2020样式",
"sh2024": "2024样式(预览版)",
"nameDisplay": "显示车站名称",
"alternatively": "交错显示",
"onOneSide": "同一侧",
Expand Down
3 changes: 2 additions & 1 deletion src/i18n/translations/zh-Hant.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@
"gz1421": "2017樣式",
"gz7w": "2022樣式",
"sh": "預設",
"sh2020": "2020樣式(預覽版)",
"sh2020": "2020樣式",
"sh2024": "2024樣式(預覽版)",
"nameDisplay": "顯示車站名稱",
"alternatively": "交錯顯示",
"onOneSide": "同一側",
Expand Down
93 changes: 88 additions & 5 deletions src/svgs/shmetro/indoor/indoor-shmetro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { memo, useMemo } from 'react';
import { adjacencyList, criticalPathMethod, getStnState, getXShareMTR } from '../../methods/share';
import StationSHMetro from './station-shmetro';
import { StationsSHMetro } from '../../methods/mtr';
import { CanvasType, Services, StationDict } from '../../../constants/constants';
import { CanvasType, PanelTypeShmetro, Services, StationDict } from '../../../constants/constants';
import { useRootSelector } from '../../../redux';
import LoopSHMetro from '../loop/loop-shmetro';
import SvgWrapper from '../../svg-wrapper';
Expand All @@ -11,7 +11,13 @@ const CANVAS_TYPE = CanvasType.Indoor;

export default function IndoorWrapperSHMetro() {
const { canvasScale } = useRootSelector(state => state.app);
const { svgWidth: svgWidths, svg_height: svgHeight, theme, loop } = useRootSelector(store => store.param);
const {
svgWidth: svgWidths,
svg_height: svgHeight,
theme,
loop,
info_panel_type,
} = useRootSelector(store => store.param);

const svgWidth = svgWidths[CANVAS_TYPE];

Expand All @@ -25,12 +31,12 @@ export default function IndoorWrapperSHMetro() {
>
<DefsSHMetro />
{loop ? <LoopSHMetro bank_angle={false} canvas={CanvasType.Indoor} /> : <IndoorSHMetro />}
<InfoElements />
{info_panel_type !== PanelTypeShmetro.sh2024 ? <InfoElements /> : <InfoElements2024 />}
</SvgWrapper>
);
}

export const DefsSHMetro = memo(function DefsSHMetro() {
const DefsSHMetro = memo(function DefsSHMetro() {
return (
<defs>
<circle id="stn_indoor_sh" fill="var(--rmg-white)" strokeWidth={5} r={8} transform="scale(1.5)" />
Expand Down Expand Up @@ -61,6 +67,32 @@ export const DefsSHMetro = memo(function DefsSHMetro() {
<circle cy="-12" fill="var(--rmg-white)" strokeWidth={5} r={8} transform="scale(1.5)" />
<circle cy="12" fill="var(--rmg-white)" strokeWidth={5} r={8} transform="scale(1.5)" />
</g>

<rect id="stn_sh_2024" stroke="none" height={24} width={12} x={-6} y={-18} />
<path
id="stn_sh_2024_int"
fill="var(--rmg-white)"
strokeWidth={2}
d="M -5,-12 a 5,5 0 1 1 10,0 V0 a 5,5 0 1 1 -10,0 Z"
/>
<g id="stn_sh_2024_int_osysi" filter='url("#station-border")'>
<circle cy="-14" r="4" fill="var(--rmg-white)" strokeWidth={2} />
<path fill="var(--rmg-white)" strokeWidth={2} d="M -4,-4 a 4,4 0 1 1 8,0 V0 a 4,4 0 1 1 -8,0 Z" />
</g>
<g id="stn_sh_2024_osysi2">
<circle cy="-12" r="5.5" stroke="var(--rmg-white)" strokeWidth={2} />
<circle cy="0" r="5.5" stroke="var(--rmg-white)" strokeWidth={2} />
<circle cy="-12" r="5" fill="var(--rmg-white)" strokeWidth={2} />
<circle cy="0" r="5" fill="var(--rmg-white)" strokeWidth={2} />
</g>
<g id="stn_sh_2024_osysi3">
<circle cy="-15" r="3.5" stroke="var(--rmg-white)" strokeWidth={2} />
<circle cy="-7" r="3.5" stroke="var(--rmg-white)" strokeWidth={2} />
<circle cy="1" r="3.5" stroke="var(--rmg-white)" strokeWidth={2} />
<circle cy="-15" r="3" fill="var(--rmg-white)" strokeWidth={2} />
<circle cy="-7" r="3" fill="var(--rmg-white)" strokeWidth={2} />
<circle cy="1" r="3" fill="var(--rmg-white)" strokeWidth={2} />
</g>
</defs>
);
});
Expand Down Expand Up @@ -89,7 +121,7 @@ const IndoorSHMetro = () => {
const realCP = criticalPathMethod(criticalPath.nodes[1], criticalPath.nodes.slice(-2)[0], adjMat);

const xShares = useMemo(() => {
console.log('computing x shares');
console.debug('computing x shares');
return Object.keys(param.stn_list).reduce(
(acc, cur) => ({ ...acc, [cur]: getXShareMTR(cur, adjMat, branches) }),
{} as { [stnId: string]: number }
Expand Down Expand Up @@ -142,10 +174,16 @@ const IndoorSHMetro = () => {
0
);

const lineBadgeDX = Math.min(
...Object.entries(xs)
.filter(([k]) => !['linestart', 'lineend'].includes(k))
.map(([, v]) => v)
);
return (
<g id="main" transform={`translate(0,${param.svg_height / 2})`}>
<Lines paths={linePaths} services={servicesPresent} />
<StationGroup xs={xs} ys={ys} services={servicesPresent} />
{param.info_panel_type === PanelTypeShmetro.sh2024 && <LineBadge dx={lineBadgeDX} />}
</g>
);
};
Expand Down Expand Up @@ -286,6 +324,51 @@ const InfoElements = memo(() => {

InfoElements.displayName = 'InfoElements';

const InfoElements2024 = () => {
const {
svg_height,
svgWidth: { indoor: svg_width },
} = useRootSelector(store => store.param);

return (
<g transform={`translate(${svg_width},${svg_height - 20})`}>
<text textAnchor="end" fontSize="14" className="rmg-name__zh" dx="-670">
友情提示:请留意您需要换乘线路的首末班时间,以免耽误您的出行,末班车进站前三分钟停售该末班车车票。
</text>
<text textAnchor="end" fontSize="10" className="rmg-name__en" dx="-30">
Please pay attention to the interchange schedule if you want to transfer to other lines. Stop selling
tickets 3 minutes before the last train services.
</text>
</g>
);
};

const LineBadge = (props: { dx: number }) => {
const { dx } = props;
const { line_name, theme } = useRootSelector(store => store.param);
const num = line_name[0].match(/^(\d+)号线$/)?.[1] ?? '';
const width = num.length > 1 ? 26.4 : 21.6;
const textDX = num.length > 1 ? 0 : 4;
const letterSpacing = num.length > 1 ? -1.5 : 0;
const padding = 15;
return (
<g transform={`translate(${dx - width - padding},0)`}>
<rect height={24} width={width} y={-18} fill={theme[2]} />
<text
x={textDX}
y={-6}
className="rmg-name__zh"
fill={theme[3]}
dominantBaseline="central"
letterSpacing={letterSpacing}
fontSize="24"
>
{num}
</text>
</g>
);
};

/* Some unused functions to split branches from the main line.
* Note the branches here has a slightly different meaning.
* It refers to all the line sections that have a parallel line
Expand Down
Loading