更改 SCADA 设备列表条目关键词;样式设置中新增彩虹色带;强制计算后清除计算范围内的缓存;

This commit is contained in:
JIANG
2025-10-31 15:24:23 +08:00
parent fe797c1bf3
commit b332a6437d
6 changed files with 331 additions and 29 deletions

View File

@@ -104,6 +104,40 @@ const GRADIENT_PALETTES = [
end: "rgba(148, 103, 189, 1)",
},
];
// 离散彩虹色系 - 提供高区分度的颜色
const RAINBOW_PALETTES = [
{
name: "正向彩虹",
colors: [
"rgba(255, 0, 0, 1)", // 红 #FF0000
"rgba(255, 127, 0, 1)", // 橙 #FF7F00
"rgba(255, 215, 0, 1)", // 金黄 #FFD700
"rgba(199, 224, 0, 1)", // 黄绿 #C7E000
"rgba(76, 175, 80, 1)", // 中绿 #4CAF50
"rgba(0, 158, 115, 1)", // 青绿/翡翠 #009E73
"rgba(0, 188, 212, 1)", // 青/青色 #00BCD4
"rgba(33, 150, 243, 1)", // 天蓝 #2196F3
"rgba(63, 81, 181, 1)", // 靛青 #3F51B5
"rgba(142, 68, 173, 1)", // 紫 #8E44AD
],
},
{
name: "反向彩虹",
colors: [
"rgba(142, 68, 173, 1)", // 紫 #8E44AD
"rgba(63, 81, 181, 1)", // 靛青 #3F51B5
"rgba(33, 150, 243, 1)", // 天蓝 #2196F3
"rgba(0, 188, 212, 1)", // 青/青色 #00BCD4
"rgba(0, 158, 115, 1)", // 青绿/翡翠 #009E73
"rgba(76, 175, 80, 1)", // 中绿 #4CAF50
"rgba(199, 224, 0, 1)", // 黄绿 #C7E000
"rgba(255, 215, 0, 1)", // 金黄 #FFD700
"rgba(255, 127, 0, 1)", // 橙 #FF7F00
"rgba(255, 0, 0, 1)", // 红 #FF0000
],
},
];
// 预设分类方法
const CLASSIFICATION_METHODS = [
{ name: "优雅分段", value: "pretty_breaks" },
@@ -164,6 +198,7 @@ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
// 颜色方案选择
const [singlePaletteIndex, setSinglePaletteIndex] = useState(0);
const [gradientPaletteIndex, setGradientPaletteIndex] = useState(0);
const [rainbowPaletteIndex, setRainbowPaletteIndex] = useState(0);
// 根据分段数生成相应数量的渐进颜色
const generateGradientColors = useCallback(
(segments: number): string[] => {
@@ -189,6 +224,29 @@ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
},
[gradientPaletteIndex, parseColor]
);
// 根据分段数生成彩虹色
const generateRainbowColors = useCallback(
(segments: number): string[] => {
const baseColors = RAINBOW_PALETTES[rainbowPaletteIndex].colors;
if (segments <= baseColors.length) {
// 如果分段数小于等于基础颜色数,均匀选取
const step = baseColors.length / segments;
return Array.from(
{ length: segments },
(_, i) => baseColors[Math.floor(i * step)]
);
} else {
// 如果分段数大于基础颜色数,重复使用
return Array.from(
{ length: segments },
(_, i) => baseColors[i % baseColors.length]
);
}
},
[rainbowPaletteIndex]
);
// 保存当前图层的样式状态
const saveLayerStyle = useCallback(
(layerId?: string, newLegendConfig?: LegendStyleConfig) => {
@@ -350,7 +408,9 @@ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
Array.from({ length: breaksLength }, () => {
return SINGLE_COLOR_PALETTES[singlePaletteIndex].color;
})
: generateGradientColors(breaksLength);
: styleConfig.colorType === "gradient"
? generateGradientColors(breaksLength)
: generateRainbowColors(breaksLength);
// 计算每个分段的线条粗细和点大小
const dimensions: number[] =
layerType === "linestring"
@@ -803,6 +863,73 @@ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
</FormControl>
);
}
if (styleConfig.colorType === "rainbow") {
return (
<FormControl
variant="standard"
fullWidth
margin="dense"
className="mt-3"
>
<InputLabel></InputLabel>
<Select
value={rainbowPaletteIndex}
onChange={(e) => setRainbowPaletteIndex(Number(e.target.value))}
>
{RAINBOW_PALETTES.map((p, idx) => {
// 根据当前分段数生成该方案的预览颜色
const baseColors = p.colors;
const segments = styleConfig.segments;
let previewColors: string[];
if (segments <= baseColors.length) {
const step = baseColors.length / segments;
previewColors = Array.from(
{ length: segments },
(_, i) => baseColors[Math.floor(i * step)]
);
} else {
previewColors = Array.from(
{ length: segments },
(_, i) => baseColors[i % baseColors.length]
);
}
return (
<MenuItem key={idx} value={idx}>
<Box
width="100%"
sx={{ display: "flex", alignItems: "center" }}
>
<Typography sx={{ marginRight: 1 }}>{p.name}</Typography>
<Box
sx={{
width: "60%",
height: 16,
borderRadius: 2,
display: "flex",
border: "1px solid #ccc",
overflow: "hidden",
}}
>
{previewColors.map((color, colorIdx) => (
<Box
key={colorIdx}
sx={{
flex: 1,
backgroundColor: color,
}}
/>
))}
</Box>
</Box>
</MenuItem>
);
})}
</Select>
</FormControl>
);
}
};
// 根据不同图层的类型和颜色分类方案显示不同的大小设置
const getSizeSetting = () => {
@@ -813,7 +940,9 @@ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
} else if (styleConfig.colorType === "gradient") {
const { start, end } = GRADIENT_PALETTES[gradientPaletteIndex];
colors = [start, end];
} else if (styleConfig.colorType === "categorical") {
} else if (styleConfig.colorType === "rainbow") {
const rainbowColors = RAINBOW_PALETTES[rainbowPaletteIndex].colors;
colors = [rainbowColors[0], rainbowColors[rainbowColors.length - 1]];
}
if (selectedRenderLayer?.get("type") === "point") {
@@ -1024,10 +1153,20 @@ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
}
onChange={(e) => {
const index = e.target.value as number;
setSelectedRenderLayer(
index >= 0 ? renderLayers[index] : undefined
);
setStyleConfig((prev) => ({ ...prev, property: "" }));
const newLayer = index >= 0 ? renderLayers[index] : undefined;
setSelectedRenderLayer(newLayer);
// 检查新图层是否有缓存的样式,没有才清空
if (newLayer) {
const layerId = newLayer.get("value");
const cachedStyleState = layerStyleStates.find(
(state) => state.layerId === layerId
);
// 只有在没有缓存时才清空属性
if (!cachedStyleState) {
setStyleConfig((prev) => ({ ...prev, property: "" }));
}
}
}}
>
{renderLayers.map((layer, index) => {
@@ -1102,13 +1241,13 @@ const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
onChange={(e) =>
setStyleConfig((prev) => ({
...prev,
colorType: e.target.value as "gradient" | "categorical",
colorType: e.target.value as "single" | "gradient" | "rainbow",
}))
}
>
<MenuItem value="single"></MenuItem>
<MenuItem value="gradient"></MenuItem>
{/* <MenuItem value="categorical">分类色</MenuItem> */}
<MenuItem value="rainbow"></MenuItem>
</Select>
{getColorSetting()}
</FormControl>