update at 2026-01-28 16:45:27
This commit is contained in:
327
public/demo.json
327
public/demo.json
@@ -39,14 +39,38 @@
|
|||||||
"startAngle": 0,
|
"startAngle": 0,
|
||||||
"colorRef": "水",
|
"colorRef": "水",
|
||||||
"sectors": [
|
"sectors": [
|
||||||
{ "content": "乾", "innerFill": 1 },
|
{
|
||||||
{ "content": "兑", "innerFill": 0 },
|
"content": "乾",
|
||||||
{ "content": "离", "innerFill": 1 },
|
"innerFill": 1
|
||||||
{ "content": "震", "innerFill": 0 },
|
},
|
||||||
{ "content": "巽", "innerFill": 1 },
|
{
|
||||||
{ "content": "坎", "innerFill": 0 },
|
"content": "兑",
|
||||||
{ "content": "艮", "innerFill": 1 },
|
"innerFill": 0
|
||||||
{ "content": "坤", "innerFill": 0 }
|
},
|
||||||
|
{
|
||||||
|
"content": "离",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "震",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "巽",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "坎",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "艮",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "坤",
|
||||||
|
"innerFill": 0
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -58,18 +82,58 @@
|
|||||||
"num": 3,
|
"num": 3,
|
||||||
"interval": 1,
|
"interval": 1,
|
||||||
"sectors": [
|
"sectors": [
|
||||||
{ "content": "子", "colorRef": "水", "innerFill": 1 },
|
{
|
||||||
{ "content": "丑" },
|
"content": "子",
|
||||||
{ "content": "寅", "colorRef": "木", "innerFill": 0 },
|
"colorRef": "水",
|
||||||
{ "content": "卯", "colorRef": "木", "innerFill": 1 },
|
"innerFill": 1
|
||||||
{ "content": "辰" },
|
},
|
||||||
{ "content": "巳", "colorRef": "火", "innerFill": 1 },
|
{
|
||||||
{ "content": "午", "colorRef": "火", "innerFill": 0 },
|
"content": "丑"
|
||||||
{ "content": "未", "innerFill": 1 },
|
},
|
||||||
{ "content": "申", "colorRef": "金", "innerFill": 0 },
|
{
|
||||||
{ "content": "酉", "colorRef": "金", "innerFill": 1 },
|
"content": "寅",
|
||||||
{ "content": "戌" },
|
"colorRef": "木",
|
||||||
{ "content": "亥", "innerFill": 0 }
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "卯",
|
||||||
|
"colorRef": "木",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "辰"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "巳",
|
||||||
|
"colorRef": "火",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "午",
|
||||||
|
"colorRef": "火",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "未",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "申",
|
||||||
|
"colorRef": "金",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "酉",
|
||||||
|
"colorRef": "金",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "戌"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "亥",
|
||||||
|
"innerFill": 0
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -78,30 +142,88 @@
|
|||||||
"rOuter": 240,
|
"rOuter": 240,
|
||||||
"startAngle": 0,
|
"startAngle": 0,
|
||||||
"sectors": [
|
"sectors": [
|
||||||
{ "content": "甲乙|子|丙丁", "colorRef": "木", "innerFill": 1 },
|
{
|
||||||
{ "content": "丑" },
|
"content": "甲乙|子|丙丁",
|
||||||
{ "content": "戊己|寅|庚辛", "colorRef": "土", "innerFill": 0 },
|
"colorRef": "木",
|
||||||
{ "content": "卯" },
|
"innerFill": 1
|
||||||
{ "content": "壬癸|辰|甲乙", "innerFill": 1 },
|
},
|
||||||
{ "content": "巳" },
|
{
|
||||||
{ "content": "丙丁|午|戊己", "colorRef": "火", "innerFill": 0 },
|
"content": "丑"
|
||||||
{ "content": "未" },
|
},
|
||||||
{ "content": "庚辛|申|壬癸", "colorRef": "金", "innerFill": 1 },
|
{
|
||||||
{ "content": "酉" },
|
"content": "戊己|寅|庚辛",
|
||||||
{ "content": "甲乙|戌|丙丁", "innerFill": 0 },
|
"colorRef": "土",
|
||||||
{ "content": "亥" },
|
"innerFill": 0
|
||||||
{ "content": "戊己|子|庚辛" },
|
},
|
||||||
{ "content": "丑" },
|
{
|
||||||
{ "content": "壬癸|寅|甲乙" },
|
"content": "卯"
|
||||||
{ "content": "卯" },
|
},
|
||||||
{ "content": "丙丁|辰|戊己" },
|
{
|
||||||
{ "content": "巳" },
|
"content": "壬癸|辰|甲乙",
|
||||||
{ "content": "庚辛|午|壬癸" },
|
"innerFill": 1
|
||||||
{ "content": "未" },
|
},
|
||||||
{ "content": "甲乙|申|丙丁" },
|
{
|
||||||
{ "content": "酉" },
|
"content": "巳"
|
||||||
{ "content": "戊己|戌|庚辛" },
|
},
|
||||||
{ "content": "亥" }
|
{
|
||||||
|
"content": "丙丁|午|戊己",
|
||||||
|
"colorRef": "火",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "未"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "庚辛|申|壬癸",
|
||||||
|
"colorRef": "金",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "酉"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "甲乙|戌|丙丁",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "亥"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "戊己|子|庚辛"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "丑"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "壬癸|寅|甲乙"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "卯"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "丙丁|辰|戊己"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "巳"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "庚辛|午|壬癸"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "未"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "甲乙|申|丙丁"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "酉"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "戊己|戌|庚辛"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "亥"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -110,22 +232,81 @@
|
|||||||
"rOuter": 270,
|
"rOuter": 270,
|
||||||
"startAngle": 0,
|
"startAngle": 0,
|
||||||
"sectors": [
|
"sectors": [
|
||||||
{ "content": "甲乙|丙丁|戊己|庚辛", "colorRef": "木", "innerFill": 1 },
|
{
|
||||||
{ "content": "壬癸|甲乙|丙丁|戊己", "colorRef": "土", "innerFill": 0 },
|
"content": "甲乙|丙丁|戊己|庚辛",
|
||||||
{ "content": "庚辛|壬癸|甲乙|丙丁", "innerFill": 1 },
|
"colorRef": "木",
|
||||||
{ "content": "戊己|庚辛|壬癸|甲乙", "colorRef": "火", "innerFill": 0 },
|
"innerFill": 1
|
||||||
{ "content": "丙丁|戊己|庚辛|壬癸", "colorRef": "金", "innerFill": 1 },
|
},
|
||||||
{ "content": "子丑|寅卯|辰巳|午未", "innerFill": 0 },
|
{
|
||||||
{ "content": "申酉|戌亥|子丑|寅卯", "colorRef": "木", "innerFill": 1 },
|
"content": "壬癸|甲乙|丙丁|戊己",
|
||||||
{ "content": "辰巳|午未|申酉|戌亥", "colorRef": "水", "innerFill": 0 },
|
"colorRef": "土",
|
||||||
{ "content": "甲乙|丙丁|戊己|庚辛", "innerFill": 1 },
|
"innerFill": 0
|
||||||
{ "content": "壬癸|甲乙|丙丁|戊己", "colorRef": "土", "innerFill": 0 },
|
},
|
||||||
{ "content": "庚辛|壬癸|甲乙|丙丁", "colorRef": "木", "innerFill": 1 },
|
{
|
||||||
{ "content": "戊己|庚辛|壬癸|甲乙", "innerFill": 0 },
|
"content": "庚辛|壬癸|甲乙|丙丁",
|
||||||
{ "content": "丙丁|戊己|庚辛|壬癸", "colorRef": "火", "innerFill": 1 },
|
"innerFill": 1
|
||||||
{ "content": "子丑|寅卯|辰巳|午未", "colorRef": "金", "innerFill": 0 },
|
},
|
||||||
{ "content": "申酉|戌亥|子丑|寅卯", "innerFill": 1 },
|
{
|
||||||
{ "content": "辰巳|午未|申酉|戌亥", "colorRef": "水", "innerFill": 0 }
|
"content": "戊己|庚辛|壬癸|甲乙",
|
||||||
|
"colorRef": "火",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "丙丁|戊己|庚辛|壬癸",
|
||||||
|
"colorRef": "金",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "子丑|寅卯|辰巳|午未",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "申酉|戌亥|子丑|寅卯",
|
||||||
|
"colorRef": "木",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "辰巳|午未|申酉|戌亥",
|
||||||
|
"colorRef": "水",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "甲乙|丙丁|戊己|庚辛",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "壬癸|甲乙|丙丁|戊己",
|
||||||
|
"colorRef": "土",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "庚辛|壬癸|甲乙|丙丁",
|
||||||
|
"colorRef": "木",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "戊己|庚辛|壬癸|甲乙",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "丙丁|戊己|庚辛|壬癸",
|
||||||
|
"colorRef": "火",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "子丑|寅卯|辰巳|午未",
|
||||||
|
"colorRef": "金",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "申酉|戌亥|子丑|寅卯",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "辰巳|午未|申酉|戌亥",
|
||||||
|
"colorRef": "水",
|
||||||
|
"innerFill": 0
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -141,20 +322,18 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "degreeRing",
|
"type": "degreeRing",
|
||||||
"degreeRing": {
|
"rInner": 350,
|
||||||
"rInner": 350,
|
"rOuter": 380,
|
||||||
"rOuter": 380,
|
"showDegree": 1,
|
||||||
"showDegree": 1,
|
"mode": "both",
|
||||||
"mode": "both",
|
"opacity": 1,
|
||||||
"opacity": 1,
|
"tickLength": 6,
|
||||||
"tickLength": 6,
|
"tickLengthStep": 2,
|
||||||
"tickLengthStep": 2,
|
"majorTick": 10,
|
||||||
"majorTick": 10,
|
"minorTick": 5,
|
||||||
"minorTick": 5,
|
"microTick": 1,
|
||||||
"microTick": 1,
|
"tickColor": "#000000",
|
||||||
"tickColor": "#000000",
|
"ringColor": "#000000"
|
||||||
"ringColor": "#000000"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "demo2",
|
"name": "demo2",
|
||||||
"description": "luopan demo2 config with named color palettes",
|
"description": "luopan demo2 config with named color palettes",
|
||||||
"background": "#000000",
|
"background": "#000000",
|
||||||
"strokeWidth": 1,
|
"strokeWidth": 1,
|
||||||
"strokeOpacity": 1,
|
"strokeOpacity": 1,
|
||||||
"strokeColor": "白",
|
"strokeColor": "白",
|
||||||
"insetDistance": 1,
|
"insetDistance": 1,
|
||||||
"outerRadius": 500,
|
"outerRadius": 500,
|
||||||
"themeRef": "五行弱",
|
"themeRef": "五行弱",
|
||||||
"layers": [
|
"layers": [
|
||||||
{
|
{
|
||||||
@@ -18,21 +18,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"divisions": 2,
|
"divisions": 2,
|
||||||
"rInner": 60,
|
"rInner": 60,
|
||||||
"rOuter": 90,
|
"rOuter": 90,
|
||||||
"startAngle": 0,
|
"startAngle": 0,
|
||||||
|
|
||||||
"sectors": [
|
"sectors": [
|
||||||
{
|
{
|
||||||
"content": "阴",
|
"content": "阴",
|
||||||
"colorRef": "黑",
|
"colorRef": "黑",
|
||||||
"innerFill": 1
|
"innerFill": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"content": "阳",
|
"content": "阳",
|
||||||
"colorRef": "白",
|
"colorRef": "白",
|
||||||
"innerFill": 0
|
"innerFill": 0
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -42,14 +41,38 @@
|
|||||||
"rOuter": 160,
|
"rOuter": 160,
|
||||||
"startAngle": 0,
|
"startAngle": 0,
|
||||||
"sectors": [
|
"sectors": [
|
||||||
{ "content": "乾", "innerFill": 1 },
|
{
|
||||||
{ "content": "兑", "innerFill": 0 },
|
"content": "乾",
|
||||||
{ "content": "离", "innerFill": 1 },
|
"innerFill": 1
|
||||||
{ "content": "震", "innerFill": 0 },
|
},
|
||||||
{ "content": "巽", "innerFill": 1 },
|
{
|
||||||
{ "content": "坎", "innerFill": 0 },
|
"content": "兑",
|
||||||
{ "content": "艮", "innerFill": 1 },
|
"innerFill": 0
|
||||||
{ "content": "坤", "innerFill": 0 }
|
},
|
||||||
|
{
|
||||||
|
"content": "离",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "震",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "巽",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "坎",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "艮",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "坤",
|
||||||
|
"innerFill": 0
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -62,18 +85,58 @@
|
|||||||
"num": 3,
|
"num": 3,
|
||||||
"interval": 1,
|
"interval": 1,
|
||||||
"sectors": [
|
"sectors": [
|
||||||
{ "content": "子", "colorRef": "水", "innerFill": 1 },
|
{
|
||||||
{ "content": "丑" },
|
"content": "子",
|
||||||
{ "content": "寅", "colorRef": "木", "innerFill": 0 },
|
"colorRef": "水",
|
||||||
{ "content": "卯", "colorRef": "木", "innerFill": 1 },
|
"innerFill": 1
|
||||||
{ "content": "辰" },
|
},
|
||||||
{ "content": "巳", "colorRef": "火", "innerFill": 1 },
|
{
|
||||||
{ "content": "午", "colorRef": "火", "innerFill": 0 },
|
"content": "丑"
|
||||||
{ "content": "未", "innerFill": 1 },
|
},
|
||||||
{ "content": "申", "colorRef": "金", "innerFill": 0 },
|
{
|
||||||
{ "content": "酉", "colorRef": "金", "innerFill": 1 },
|
"content": "寅",
|
||||||
{ "content": "戌" },
|
"colorRef": "木",
|
||||||
{ "content": "亥", "innerFill": 0 }
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "卯",
|
||||||
|
"colorRef": "木",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "辰"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "巳",
|
||||||
|
"colorRef": "火",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "午",
|
||||||
|
"colorRef": "火",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "未",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "申",
|
||||||
|
"colorRef": "金",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "酉",
|
||||||
|
"colorRef": "金",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "戌"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "亥",
|
||||||
|
"innerFill": 0
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -82,30 +145,88 @@
|
|||||||
"rOuter": 240,
|
"rOuter": 240,
|
||||||
"startAngle": 0,
|
"startAngle": 0,
|
||||||
"sectors": [
|
"sectors": [
|
||||||
{ "content": "甲乙|子|丙丁", "colorRef": "木", "innerFill": 1 },
|
{
|
||||||
{ "content": "丑" },
|
"content": "甲乙|子|丙丁",
|
||||||
{ "content": "戊己|寅|庚辛", "colorRef": "土", "innerFill": 0 },
|
"colorRef": "木",
|
||||||
{ "content": "卯" },
|
"innerFill": 1
|
||||||
{ "content": "壬癸|辰|甲乙", "innerFill": 1 },
|
},
|
||||||
{ "content": "巳" },
|
{
|
||||||
{ "content": "丙丁|午|戊己", "colorRef": "火", "innerFill": 0 },
|
"content": "丑"
|
||||||
{ "content": "未" },
|
},
|
||||||
{ "content": "庚辛|申|壬癸", "colorRef": "金", "innerFill": 1 },
|
{
|
||||||
{ "content": "酉" },
|
"content": "戊己|寅|庚辛",
|
||||||
{ "content": "甲乙|戌|丙丁", "innerFill": 0 },
|
"colorRef": "土",
|
||||||
{ "content": "亥" },
|
"innerFill": 0
|
||||||
{ "content": "戊己|子|庚辛" },
|
},
|
||||||
{ "content": "丑" },
|
{
|
||||||
{ "content": "壬癸|寅|甲乙" },
|
"content": "卯"
|
||||||
{ "content": "卯" },
|
},
|
||||||
{ "content": "丙丁|辰|戊己" },
|
{
|
||||||
{ "content": "巳" },
|
"content": "壬癸|辰|甲乙",
|
||||||
{ "content": "庚辛|午|壬癸" },
|
"innerFill": 1
|
||||||
{ "content": "未" },
|
},
|
||||||
{ "content": "甲乙|申|丙丁" },
|
{
|
||||||
{ "content": "酉" },
|
"content": "巳"
|
||||||
{ "content": "戊己|戌|庚辛" },
|
},
|
||||||
{ "content": "亥" }
|
{
|
||||||
|
"content": "丙丁|午|戊己",
|
||||||
|
"colorRef": "火",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "未"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "庚辛|申|壬癸",
|
||||||
|
"colorRef": "金",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "酉"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "甲乙|戌|丙丁",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "亥"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "戊己|子|庚辛"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "丑"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "壬癸|寅|甲乙"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "卯"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "丙丁|辰|戊己"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "巳"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "庚辛|午|壬癸"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "未"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "甲乙|申|丙丁"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "酉"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "戊己|戌|庚辛"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "亥"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -114,22 +235,81 @@
|
|||||||
"rOuter": 270,
|
"rOuter": 270,
|
||||||
"startAngle": 0,
|
"startAngle": 0,
|
||||||
"sectors": [
|
"sectors": [
|
||||||
{ "content": "甲乙|丙丁|戊己|庚辛", "colorRef": "木", "innerFill": 1 },
|
{
|
||||||
{ "content": "壬癸|甲乙|丙丁|戊己", "colorRef": "土", "innerFill": 0 },
|
"content": "甲乙|丙丁|戊己|庚辛",
|
||||||
{ "content": "庚辛|壬癸|甲乙|丙丁", "innerFill": 1 },
|
"colorRef": "木",
|
||||||
{ "content": "戊己|庚辛|壬癸|甲乙", "colorRef": "火", "innerFill": 0 },
|
"innerFill": 1
|
||||||
{ "content": "丙丁|戊己|庚辛|壬癸", "colorRef": "金", "innerFill": 1 },
|
},
|
||||||
{ "content": "子丑|寅卯|辰巳|午未", "innerFill": 0 },
|
{
|
||||||
{ "content": "申酉|戌亥|子丑|寅卯", "colorRef": "木", "innerFill": 1 },
|
"content": "壬癸|甲乙|丙丁|戊己",
|
||||||
{ "content": "辰巳|午未|申酉|戌亥", "colorRef": "水", "innerFill": 0 },
|
"colorRef": "土",
|
||||||
{ "content": "甲乙|丙丁|戊己|庚辛", "innerFill": 1 },
|
"innerFill": 0
|
||||||
{ "content": "壬癸|甲乙|丙丁|戊己", "colorRef": "土", "innerFill": 0 },
|
},
|
||||||
{ "content": "庚辛|壬癸|甲乙|丙丁", "colorRef": "木", "innerFill": 1 },
|
{
|
||||||
{ "content": "戊己|庚辛|壬癸|甲乙", "innerFill": 0 },
|
"content": "庚辛|壬癸|甲乙|丙丁",
|
||||||
{ "content": "丙丁|戊己|庚辛|壬癸", "colorRef": "火", "innerFill": 1 },
|
"innerFill": 1
|
||||||
{ "content": "子丑|寅卯|辰巳|午未", "colorRef": "金", "innerFill": 0 },
|
},
|
||||||
{ "content": "申酉|戌亥|子丑|寅卯", "innerFill": 1 },
|
{
|
||||||
{ "content": "辰巳|午未|申酉|戌亥", "colorRef": "水", "innerFill": 0 }
|
"content": "戊己|庚辛|壬癸|甲乙",
|
||||||
|
"colorRef": "火",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "丙丁|戊己|庚辛|壬癸",
|
||||||
|
"colorRef": "金",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "子丑|寅卯|辰巳|午未",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "申酉|戌亥|子丑|寅卯",
|
||||||
|
"colorRef": "木",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "辰巳|午未|申酉|戌亥",
|
||||||
|
"colorRef": "水",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "甲乙|丙丁|戊己|庚辛",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "壬癸|甲乙|丙丁|戊己",
|
||||||
|
"colorRef": "土",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "庚辛|壬癸|甲乙|丙丁",
|
||||||
|
"colorRef": "木",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "戊己|庚辛|壬癸|甲乙",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "丙丁|戊己|庚辛|壬癸",
|
||||||
|
"colorRef": "火",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "子丑|寅卯|辰巳|午未",
|
||||||
|
"colorRef": "金",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "申酉|戌亥|子丑|寅卯",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "辰巳|午未|申酉|戌亥",
|
||||||
|
"colorRef": "水",
|
||||||
|
"innerFill": 0
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -145,19 +325,17 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "degreeRing",
|
"type": "degreeRing",
|
||||||
"degreeRing": {
|
"rInner": 450,
|
||||||
"rInner": 450,
|
"rOuter": 500,
|
||||||
"rOuter": 500,
|
"showDegree": 1,
|
||||||
"showDegree": 1,
|
"mode": "both",
|
||||||
"mode": "both",
|
"opacity": 0.3,
|
||||||
"opacity": 0.3,
|
"tickLength": 6,
|
||||||
"tickLength": 6,
|
"majorTick": 10,
|
||||||
"majorTick": 10,
|
"minorTick": 5,
|
||||||
"minorTick": 5,
|
"microTick": 1,
|
||||||
"microTick": 1,
|
"tickColor": "#ffffff",
|
||||||
"tickColor": "#ffffff",
|
"ringColor": "#ffffff"
|
||||||
"ringColor": "#ffffff"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,14 +39,38 @@
|
|||||||
"startAngle": 0,
|
"startAngle": 0,
|
||||||
"colorRef": "水",
|
"colorRef": "水",
|
||||||
"sectors": [
|
"sectors": [
|
||||||
{ "content": "乾", "innerFill": 1 },
|
{
|
||||||
{ "content": "兑", "innerFill": 0 },
|
"content": "乾",
|
||||||
{ "content": "离", "innerFill": 1 },
|
"innerFill": 1
|
||||||
{ "content": "震", "innerFill": 0 },
|
},
|
||||||
{ "content": "巽", "innerFill": 1 },
|
{
|
||||||
{ "content": "坎", "innerFill": 0 },
|
"content": "兑",
|
||||||
{ "content": "艮", "innerFill": 1 },
|
"innerFill": 0
|
||||||
{ "content": "坤", "innerFill": 0 }
|
},
|
||||||
|
{
|
||||||
|
"content": "离",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "震",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "巽",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "坎",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "艮",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "坤",
|
||||||
|
"innerFill": 0
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -58,18 +82,58 @@
|
|||||||
"num": 3,
|
"num": 3,
|
||||||
"interval": 1,
|
"interval": 1,
|
||||||
"sectors": [
|
"sectors": [
|
||||||
{ "content": "子", "colorRef": "水", "innerFill": 1 },
|
{
|
||||||
{ "content": "丑" },
|
"content": "子",
|
||||||
{ "content": "寅", "colorRef": "木", "innerFill": 0 },
|
"colorRef": "水",
|
||||||
{ "content": "卯", "colorRef": "木", "innerFill": 1 },
|
"innerFill": 1
|
||||||
{ "content": "辰" },
|
},
|
||||||
{ "content": "巳", "colorRef": "火", "innerFill": 1 },
|
{
|
||||||
{ "content": "午", "colorRef": "火", "innerFill": 0 },
|
"content": "丑"
|
||||||
{ "content": "未", "innerFill": 1 },
|
},
|
||||||
{ "content": "申", "colorRef": "金", "innerFill": 0 },
|
{
|
||||||
{ "content": "酉", "colorRef": "金", "innerFill": 1 },
|
"content": "寅",
|
||||||
{ "content": "戌" },
|
"colorRef": "木",
|
||||||
{ "content": "亥", "innerFill": 0 }
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "卯",
|
||||||
|
"colorRef": "木",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "辰"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "巳",
|
||||||
|
"colorRef": "火",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "午",
|
||||||
|
"colorRef": "火",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "未",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "申",
|
||||||
|
"colorRef": "金",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "酉",
|
||||||
|
"colorRef": "金",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "戌"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "亥",
|
||||||
|
"innerFill": 0
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -78,30 +142,88 @@
|
|||||||
"rOuter": 240,
|
"rOuter": 240,
|
||||||
"startAngle": 0,
|
"startAngle": 0,
|
||||||
"sectors": [
|
"sectors": [
|
||||||
{ "content": "甲乙|子|丙丁", "colorRef": "木", "innerFill": 1 },
|
{
|
||||||
{ "content": "丑" },
|
"content": "甲乙|子|丙丁",
|
||||||
{ "content": "戊己|寅|庚辛", "colorRef": "土", "innerFill": 0 },
|
"colorRef": "木",
|
||||||
{ "content": "卯" },
|
"innerFill": 1
|
||||||
{ "content": "壬癸|辰|甲乙", "innerFill": 1 },
|
},
|
||||||
{ "content": "巳" },
|
{
|
||||||
{ "content": "丙丁|午|戊己", "colorRef": "火", "innerFill": 0 },
|
"content": "丑"
|
||||||
{ "content": "未" },
|
},
|
||||||
{ "content": "庚辛|申|壬癸", "colorRef": "金", "innerFill": 1 },
|
{
|
||||||
{ "content": "酉" },
|
"content": "戊己|寅|庚辛",
|
||||||
{ "content": "甲乙|戌|丙丁", "innerFill": 0 },
|
"colorRef": "土",
|
||||||
{ "content": "亥" },
|
"innerFill": 0
|
||||||
{ "content": "戊己|子|庚辛" },
|
},
|
||||||
{ "content": "丑" },
|
{
|
||||||
{ "content": "壬癸|寅|甲乙" },
|
"content": "卯"
|
||||||
{ "content": "卯" },
|
},
|
||||||
{ "content": "丙丁|辰|戊己" },
|
{
|
||||||
{ "content": "巳" },
|
"content": "壬癸|辰|甲乙",
|
||||||
{ "content": "庚辛|午|壬癸" },
|
"innerFill": 1
|
||||||
{ "content": "未" },
|
},
|
||||||
{ "content": "甲乙|申|丙丁" },
|
{
|
||||||
{ "content": "酉" },
|
"content": "巳"
|
||||||
{ "content": "戊己|戌|庚辛" },
|
},
|
||||||
{ "content": "亥" }
|
{
|
||||||
|
"content": "丙丁|午|戊己",
|
||||||
|
"colorRef": "火",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "未"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "庚辛|申|壬癸",
|
||||||
|
"colorRef": "金",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "酉"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "甲乙|戌|丙丁",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "亥"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "戊己|子|庚辛"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "丑"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "壬癸|寅|甲乙"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "卯"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "丙丁|辰|戊己"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "巳"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "庚辛|午|壬癸"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "未"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "甲乙|申|丙丁"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "酉"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "戊己|戌|庚辛"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "亥"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -110,22 +232,81 @@
|
|||||||
"rOuter": 270,
|
"rOuter": 270,
|
||||||
"startAngle": 0,
|
"startAngle": 0,
|
||||||
"sectors": [
|
"sectors": [
|
||||||
{ "content": "甲乙|丙丁|戊己|庚辛", "colorRef": "木", "innerFill": 1 },
|
{
|
||||||
{ "content": "壬癸|甲乙|丙丁|戊己", "colorRef": "土", "innerFill": 0 },
|
"content": "甲乙|丙丁|戊己|庚辛",
|
||||||
{ "content": "庚辛|壬癸|甲乙|丙丁", "innerFill": 1 },
|
"colorRef": "木",
|
||||||
{ "content": "戊己|庚辛|壬癸|甲乙", "colorRef": "火", "innerFill": 0 },
|
"innerFill": 1
|
||||||
{ "content": "丙丁|戊己|庚辛|壬癸", "colorRef": "金", "innerFill": 1 },
|
},
|
||||||
{ "content": "子丑|寅卯|辰巳|午未", "innerFill": 0 },
|
{
|
||||||
{ "content": "申酉|戌亥|子丑|寅卯", "colorRef": "木", "innerFill": 1 },
|
"content": "壬癸|甲乙|丙丁|戊己",
|
||||||
{ "content": "辰巳|午未|申酉|戌亥", "colorRef": "水", "innerFill": 0 },
|
"colorRef": "土",
|
||||||
{ "content": "甲乙|丙丁|戊己|庚辛", "innerFill": 1 },
|
"innerFill": 0
|
||||||
{ "content": "壬癸|甲乙|丙丁|戊己", "colorRef": "土", "innerFill": 0 },
|
},
|
||||||
{ "content": "庚辛|壬癸|甲乙|丙丁", "colorRef": "木", "innerFill": 1 },
|
{
|
||||||
{ "content": "戊己|庚辛|壬癸|甲乙", "innerFill": 0 },
|
"content": "庚辛|壬癸|甲乙|丙丁",
|
||||||
{ "content": "丙丁|戊己|庚辛|壬癸", "colorRef": "火", "innerFill": 1 },
|
"innerFill": 1
|
||||||
{ "content": "子丑|寅卯|辰巳|午未", "colorRef": "金", "innerFill": 0 },
|
},
|
||||||
{ "content": "申酉|戌亥|子丑|寅卯", "innerFill": 1 },
|
{
|
||||||
{ "content": "辰巳|午未|申酉|戌亥", "colorRef": "水", "innerFill": 0 }
|
"content": "戊己|庚辛|壬癸|甲乙",
|
||||||
|
"colorRef": "火",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "丙丁|戊己|庚辛|壬癸",
|
||||||
|
"colorRef": "金",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "子丑|寅卯|辰巳|午未",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "申酉|戌亥|子丑|寅卯",
|
||||||
|
"colorRef": "木",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "辰巳|午未|申酉|戌亥",
|
||||||
|
"colorRef": "水",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "甲乙|丙丁|戊己|庚辛",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "壬癸|甲乙|丙丁|戊己",
|
||||||
|
"colorRef": "土",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "庚辛|壬癸|甲乙|丙丁",
|
||||||
|
"colorRef": "木",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "戊己|庚辛|壬癸|甲乙",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "丙丁|戊己|庚辛|壬癸",
|
||||||
|
"colorRef": "火",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "子丑|寅卯|辰巳|午未",
|
||||||
|
"colorRef": "金",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "申酉|戌亥|子丑|寅卯",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "辰巳|午未|申酉|戌亥",
|
||||||
|
"colorRef": "水",
|
||||||
|
"innerFill": 0
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -141,20 +322,18 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "degreeRing",
|
"type": "degreeRing",
|
||||||
"degreeRing": {
|
"rInner": 350,
|
||||||
"rInner": 350,
|
"rOuter": 380,
|
||||||
"rOuter": 380,
|
"showDegree": 1,
|
||||||
"showDegree": 1,
|
"mode": "both",
|
||||||
"mode": "both",
|
"opacity": 1,
|
||||||
"opacity": 1,
|
"tickLength": 6,
|
||||||
"tickLength": 6,
|
"tickLengthStep": 2,
|
||||||
"tickLengthStep": 2,
|
"majorTick": 10,
|
||||||
"majorTick": 10,
|
"minorTick": 5,
|
||||||
"minorTick": 5,
|
"microTick": 1,
|
||||||
"microTick": 1,
|
"tickColor": "#000000",
|
||||||
"tickColor": "#000000",
|
"ringColor": "#000000"
|
||||||
"ringColor": "#000000"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
4540
public/fengshui.json
4540
public/fengshui.json
File diff suppressed because one or more lines are too long
3766
public/fengshui10.json
Normal file
3766
public/fengshui10.json
Normal file
File diff suppressed because it is too large
Load Diff
3768
public/fengshui2.json
Normal file
3768
public/fengshui2.json
Normal file
File diff suppressed because it is too large
Load Diff
3768
public/fengshui3.json
Normal file
3768
public/fengshui3.json
Normal file
File diff suppressed because it is too large
Load Diff
3768
public/fengshui4.json
Normal file
3768
public/fengshui4.json
Normal file
File diff suppressed because it is too large
Load Diff
3768
public/fengshui5.json
Normal file
3768
public/fengshui5.json
Normal file
File diff suppressed because it is too large
Load Diff
3768
public/fengshui6.json
Normal file
3768
public/fengshui6.json
Normal file
File diff suppressed because it is too large
Load Diff
3768
public/fengshui7.json
Normal file
3768
public/fengshui7.json
Normal file
File diff suppressed because it is too large
Load Diff
3768
public/fengshui8.json
Normal file
3768
public/fengshui8.json
Normal file
File diff suppressed because it is too large
Load Diff
3768
public/fengshui9.json
Normal file
3768
public/fengshui9.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -20,6 +20,42 @@
|
|||||||
{
|
{
|
||||||
"name": "fengshui",
|
"name": "fengshui",
|
||||||
"path": "/fengshui.json"
|
"path": "/fengshui.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fengshui2",
|
||||||
|
"path": "/fengshui2.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fengshui3",
|
||||||
|
"path": "/fengshui3.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fengshui4",
|
||||||
|
"path": "/fengshui4.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fengshui5",
|
||||||
|
"path": "/fengshui5.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fengshui6",
|
||||||
|
"path": "/fengshui6.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fengshui7",
|
||||||
|
"path": "/fengshui7.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fengshui8",
|
||||||
|
"path": "/fengshui8.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fengshui9",
|
||||||
|
"path": "/fengshui9.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fengshui10",
|
||||||
|
"path": "/fengshui10.json"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,14 +38,46 @@
|
|||||||
"rOuter": 160,
|
"rOuter": 160,
|
||||||
"startAngle": 0,
|
"startAngle": 0,
|
||||||
"sectors": [
|
"sectors": [
|
||||||
{ "content": "乾", "colorRef": "火", "innerFill": 1 },
|
{
|
||||||
{ "content": "兑", "colorRef": "冷", "innerFill": 0 },
|
"content": "乾",
|
||||||
{ "content": "离", "colorRef": "火", "innerFill": 1 },
|
"colorRef": "火",
|
||||||
{ "content": "震", "colorRef": "木", "innerFill": 0 },
|
"innerFill": 1
|
||||||
{ "content": "巽", "colorRef": "木", "innerFill": 1 },
|
},
|
||||||
{ "content": "坎", "colorRef": "冷", "innerFill": 0 },
|
{
|
||||||
{ "content": "艮", "colorRef": "强", "innerFill": 1 },
|
"content": "兑",
|
||||||
{ "content": "坤", "colorRef": "土", "innerFill": 0 }
|
"colorRef": "冷",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "离",
|
||||||
|
"colorRef": "火",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "震",
|
||||||
|
"colorRef": "木",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "巽",
|
||||||
|
"colorRef": "木",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "坎",
|
||||||
|
"colorRef": "冷",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "艮",
|
||||||
|
"colorRef": "强",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "坤",
|
||||||
|
"colorRef": "土",
|
||||||
|
"innerFill": 0
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -57,18 +89,58 @@
|
|||||||
"num": 3,
|
"num": 3,
|
||||||
"interval": 1,
|
"interval": 1,
|
||||||
"sectors": [
|
"sectors": [
|
||||||
{ "content": "子", "colorRef": "水", "innerFill": 1 },
|
{
|
||||||
{ "content": "丑" },
|
"content": "子",
|
||||||
{ "content": "寅", "colorRef": "木", "innerFill": 0 },
|
"colorRef": "水",
|
||||||
{ "content": "卯", "colorRef": "木", "innerFill": 1 },
|
"innerFill": 1
|
||||||
{ "content": "辰" },
|
},
|
||||||
{ "content": "巳", "colorRef": "火", "innerFill": 1 },
|
{
|
||||||
{ "content": "午", "colorRef": "火", "innerFill": 0 },
|
"content": "丑"
|
||||||
{ "content": "未", "innerFill": 1 },
|
},
|
||||||
{ "content": "申", "colorRef": "金", "innerFill": 0 },
|
{
|
||||||
{ "content": "酉", "colorRef": "金", "innerFill": 1 },
|
"content": "寅",
|
||||||
{ "content": "戌" },
|
"colorRef": "木",
|
||||||
{ "content": "亥", "innerFill": 0 }
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "卯",
|
||||||
|
"colorRef": "木",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "辰"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "巳",
|
||||||
|
"colorRef": "火",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "午",
|
||||||
|
"colorRef": "火",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "未",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "申",
|
||||||
|
"colorRef": "金",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "酉",
|
||||||
|
"colorRef": "金",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "戌"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "亥",
|
||||||
|
"innerFill": 0
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -80,30 +152,88 @@
|
|||||||
"num": 2,
|
"num": 2,
|
||||||
"interval": 1,
|
"interval": 1,
|
||||||
"sectors": [
|
"sectors": [
|
||||||
{ "content": "甲乙|子|丙丁", "colorRef": "木", "innerFill": 1 },
|
{
|
||||||
{ "content": "丑" },
|
"content": "甲乙|子|丙丁",
|
||||||
{ "content": "戊己|寅|庚辛", "colorRef": "土", "innerFill": 0 },
|
"colorRef": "木",
|
||||||
{ "content": "卯" },
|
"innerFill": 1
|
||||||
{ "content": "壬癸|辰|甲乙", "innerFill": 1 },
|
},
|
||||||
{ "content": "巳" },
|
{
|
||||||
{ "content": "丙丁|午|戊己", "colorRef": "火", "innerFill": 0 },
|
"content": "丑"
|
||||||
{ "content": "未" },
|
},
|
||||||
{ "content": "庚辛|申|壬癸", "colorRef": "金", "innerFill": 1 },
|
{
|
||||||
{ "content": "酉" },
|
"content": "戊己|寅|庚辛",
|
||||||
{ "content": "甲乙|戌|丙丁", "innerFill": 0 },
|
"colorRef": "土",
|
||||||
{ "content": "亥" },
|
"innerFill": 0
|
||||||
{ "content": "戊己|子|庚辛" },
|
},
|
||||||
{ "content": "丑" },
|
{
|
||||||
{ "content": "壬癸|寅|甲乙" },
|
"content": "卯"
|
||||||
{ "content": "卯" },
|
},
|
||||||
{ "content": "丙丁|辰|戊己" },
|
{
|
||||||
{ "content": "巳" },
|
"content": "壬癸|辰|甲乙",
|
||||||
{ "content": "庚辛|午|壬癸" },
|
"innerFill": 1
|
||||||
{ "content": "未" },
|
},
|
||||||
{ "content": "甲乙|申|丙丁" },
|
{
|
||||||
{ "content": "酉" },
|
"content": "巳"
|
||||||
{ "content": "戊己|戌|庚辛" },
|
},
|
||||||
{ "content": "亥" }
|
{
|
||||||
|
"content": "丙丁|午|戊己",
|
||||||
|
"colorRef": "火",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "未"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "庚辛|申|壬癸",
|
||||||
|
"colorRef": "金",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "酉"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "甲乙|戌|丙丁",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "亥"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "戊己|子|庚辛"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "丑"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "壬癸|寅|甲乙"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "卯"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "丙丁|辰|戊己"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "巳"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "庚辛|午|壬癸"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "未"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "甲乙|申|丙丁"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "酉"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "戊己|戌|庚辛"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "亥"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -112,22 +242,81 @@
|
|||||||
"rOuter": 270,
|
"rOuter": 270,
|
||||||
"startAngle": 0,
|
"startAngle": 0,
|
||||||
"sectors": [
|
"sectors": [
|
||||||
{ "content": "甲乙|丙丁|戊己|庚辛", "colorRef": "木", "innerFill": 1 },
|
{
|
||||||
{ "content": "壬癸|甲乙|丙丁|戊己", "colorRef": "土", "innerFill": 0 },
|
"content": "甲乙|丙丁|戊己|庚辛",
|
||||||
{ "content": "庚辛|壬癸|甲乙|丙丁", "innerFill": 1 },
|
"colorRef": "木",
|
||||||
{ "content": "戊己|庚辛|壬癸|甲乙", "colorRef": "火", "innerFill": 0 },
|
"innerFill": 1
|
||||||
{ "content": "丙丁|戊己|庚辛|壬癸", "colorRef": "金", "innerFill": 1 },
|
},
|
||||||
{ "content": "子丑|寅卯|辰巳|午未", "innerFill": 0 },
|
{
|
||||||
{ "content": "申酉|戌亥|子丑|寅卯", "colorRef": "木", "innerFill": 1 },
|
"content": "壬癸|甲乙|丙丁|戊己",
|
||||||
{ "content": "辰巳|午未|申酉|戌亥", "colorRef": "水", "innerFill": 0 },
|
"colorRef": "土",
|
||||||
{ "content": "甲乙|丙丁|戊己|庚辛", "innerFill": 1 },
|
"innerFill": 0
|
||||||
{ "content": "壬癸|甲乙|丙丁|戊己", "colorRef": "土", "innerFill": 0 },
|
},
|
||||||
{ "content": "庚辛|壬癸|甲乙|丙丁", "colorRef": "木", "innerFill": 1 },
|
{
|
||||||
{ "content": "戊己|庚辛|壬癸|甲乙", "innerFill": 0 },
|
"content": "庚辛|壬癸|甲乙|丙丁",
|
||||||
{ "content": "丙丁|戊己|庚辛|壬癸", "colorRef": "火", "innerFill": 1 },
|
"innerFill": 1
|
||||||
{ "content": "子丑|寅卯|辰巳|午未", "colorRef": "金", "innerFill": 0 },
|
},
|
||||||
{ "content": "申酉|戌亥|子丑|寅卯", "innerFill": 1 },
|
{
|
||||||
{ "content": "辰巳|午未|申酉|戌亥", "colorRef": "水", "innerFill": 0 }
|
"content": "戊己|庚辛|壬癸|甲乙",
|
||||||
|
"colorRef": "火",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "丙丁|戊己|庚辛|壬癸",
|
||||||
|
"colorRef": "金",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "子丑|寅卯|辰巳|午未",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "申酉|戌亥|子丑|寅卯",
|
||||||
|
"colorRef": "木",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "辰巳|午未|申酉|戌亥",
|
||||||
|
"colorRef": "水",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "甲乙|丙丁|戊己|庚辛",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "壬癸|甲乙|丙丁|戊己",
|
||||||
|
"colorRef": "土",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "庚辛|壬癸|甲乙|丙丁",
|
||||||
|
"colorRef": "木",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "戊己|庚辛|壬癸|甲乙",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "丙丁|戊己|庚辛|壬癸",
|
||||||
|
"colorRef": "火",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "子丑|寅卯|辰巳|午未",
|
||||||
|
"colorRef": "金",
|
||||||
|
"innerFill": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "申酉|戌亥|子丑|寅卯",
|
||||||
|
"innerFill": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"content": "辰巳|午未|申酉|戌亥",
|
||||||
|
"colorRef": "水",
|
||||||
|
"innerFill": 0
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -143,20 +332,18 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "degreeRing",
|
"type": "degreeRing",
|
||||||
"degreeRing": {
|
"rInner": 350,
|
||||||
"rInner": 350,
|
"rOuter": 380,
|
||||||
"rOuter": 380,
|
"showDegree": 1,
|
||||||
"showDegree": 1,
|
"mode": "both",
|
||||||
"mode": "both",
|
"opacity": 1,
|
||||||
"opacity": 1,
|
"tickLength": 6,
|
||||||
"tickLength": 6,
|
"tickLengthStep": 2,
|
||||||
"tickLengthStep": 2,
|
"majorTick": 10,
|
||||||
"majorTick": 10,
|
"minorTick": 5,
|
||||||
"minorTick": 5,
|
"microTick": 1,
|
||||||
"microTick": 1,
|
"tickColor": "#000000",
|
||||||
"tickColor": "#000000",
|
"ringColor": "#000000"
|
||||||
"ringColor": "#000000"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,20 @@
|
|||||||
# 罗盘项目重构方案
|
# 罗盘项目重构方案
|
||||||
|
|
||||||
|
## 0. 重构方案提要(先看这一段)
|
||||||
|
|
||||||
|
**目标:** 从“硬编码示例”升级到“配置驱动”的罗盘渲染系统,并为大罗盘性能优化留出清晰路径。
|
||||||
|
**策略:** 先重构数据解析与渲染结构,再完善主题/多文本/刻度/中心图标,最后补齐测试与性能。
|
||||||
|
**落地路径:**
|
||||||
|
1) 解析层与类型统一(配置校验、主题、层级半径推导)。
|
||||||
|
2) 扇区构建器与颜色引擎(含规律填色、groupSplit)。
|
||||||
|
3) UI 适配(Luopan.vue、useLuopan 重构)。
|
||||||
|
4) 测试与性能优化(含大罗盘拖拽优化计划 10.4)。
|
||||||
|
|
||||||
|
**预期产出:**
|
||||||
|
- 新增/替换若干模块(configParser / colorResolver / sectorBuilder / degreeRing / centerIcon)。
|
||||||
|
- `public/*.json` 配置即可新增罗盘,无需改代码。
|
||||||
|
- 统一主题与颜色规则,支持复杂布局与 SVG 图标。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 一、项目现状分析
|
## 一、项目现状分析
|
||||||
@@ -103,6 +118,22 @@
|
|||||||
- 新增 `public/themes.json`
|
- 新增 `public/themes.json`
|
||||||
- 更新 `demo.json.conf` 说明
|
- 更新 `demo.json.conf` 说明
|
||||||
|
|
||||||
|
### 1.5 layerHeight 参数规则(新增)
|
||||||
|
|
||||||
|
**目标:** 支持在 layer 中以 `layerHeight` 定义厚度,并可自动推导 `rInner` / `rOuter`。
|
||||||
|
|
||||||
|
**规则:**
|
||||||
|
1. 若 layer 同时指定 `rInner` 和 `rOuter`,则忽略 `layerHeight`。
|
||||||
|
2. 若 layer 仅指定 `layerHeight`,且没有 `rInner` / `rOuter`:
|
||||||
|
- 使用上一层的 `rOuter` 作为当前 `rInner`
|
||||||
|
- 当前 `rOuter = 上一层 rOuter + layerHeight`
|
||||||
|
3. 若 layer 未提供任何半径信息(`rInner` / `rOuter` / `layerHeight`),则视为配置错误(或按实现约定抛错/警告)。
|
||||||
|
|
||||||
|
**实现改动点:**
|
||||||
|
1. `types.ts`:为 sector layer 增加可选字段 `layerHeight?: number`
|
||||||
|
2. `configParser.ts`:新增“层半径归一化”步骤,按层顺序推导半径
|
||||||
|
3. 文档/示例:补充 `layerHeight` 的说明与示例用法
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 二、整体架构设计
|
## 二、整体架构设计
|
||||||
|
|||||||
503
src/Luopan.vue
503
src/Luopan.vue
@@ -42,6 +42,7 @@
|
|||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
class="svg-container"
|
class="svg-container"
|
||||||
|
:class="{ 'is-dragging': isDragging }"
|
||||||
@wheel.prevent="handleWheel"
|
@wheel.prevent="handleWheel"
|
||||||
@mousedown="handleMouseDown"
|
@mousedown="handleMouseDown"
|
||||||
@mousemove="handleMouseMove"
|
@mousemove="handleMouseMove"
|
||||||
@@ -53,252 +54,258 @@
|
|||||||
:height="size"
|
:height="size"
|
||||||
:viewBox="`${viewBoxMin} ${viewBoxMin} ${viewBoxSize} ${viewBoxSize}`"
|
:viewBox="`${viewBoxMin} ${viewBoxMin} ${viewBoxSize} ${viewBoxSize}`"
|
||||||
class="svg"
|
class="svg"
|
||||||
:style="{
|
|
||||||
transform: `scale(${scale}) translate(${panX}px, ${panY}px)`,
|
|
||||||
cursor: isDragging ? 'grabbing' : 'grab'
|
|
||||||
}"
|
|
||||||
>
|
>
|
||||||
<!-- 背景 -->
|
<g ref="viewport" class="viewport">
|
||||||
<circle
|
<!-- 背景 -->
|
||||||
:r="outerMost || viewBoxSize / 2"
|
<circle
|
||||||
:fill="config?.background || '#ffffff'"
|
:r="outerMost || viewBoxSize / 2"
|
||||||
/>
|
:fill="config?.background || '#ffffff'"
|
||||||
|
|
||||||
<g v-memo="[sectors]">
|
|
||||||
<!-- 扇区 -->
|
|
||||||
<g>
|
|
||||||
<path
|
|
||||||
v-for="s in sectors"
|
|
||||||
:key="s.key"
|
|
||||||
:d="s.path"
|
|
||||||
:fill="s.fill"
|
|
||||||
/>
|
/>
|
||||||
</g>
|
|
||||||
|
|
||||||
<!-- 内部填色区域 -->
|
<g v-memo="[sectors]">
|
||||||
<g>
|
<!-- 扇区 -->
|
||||||
<template v-for="s in sectors" :key="s.key + '-inner'">
|
<g>
|
||||||
<path
|
<path
|
||||||
v-if="s.innerFillPath"
|
v-for="s in sectors"
|
||||||
:d="s.innerFillPath"
|
:key="s.key"
|
||||||
:fill="s.innerFillColor"
|
:d="s.path"
|
||||||
fill-opacity="1"
|
:fill="s.fill"
|
||||||
stroke="none"
|
/>
|
||||||
/>
|
</g>
|
||||||
</template>
|
|
||||||
</g>
|
|
||||||
|
|
||||||
<!-- 定义文字路径 -->
|
<!-- 内部填色区域 -->
|
||||||
<defs>
|
<g>
|
||||||
<path
|
<template v-for="s in sectors" :key="s.key + '-inner'">
|
||||||
v-for="s in sectors"
|
<path
|
||||||
:key="s.textPathId"
|
v-if="s.innerFillPath"
|
||||||
:id="s.textPathId"
|
:d="s.innerFillPath"
|
||||||
:d="s.textPath"
|
:fill="s.innerFillColor"
|
||||||
fill="none"
|
fill-opacity="1"
|
||||||
/>
|
stroke="none"
|
||||||
<template v-for="s in sectors" :key="s.key + '-units'">
|
/>
|
||||||
<path
|
</template>
|
||||||
v-for="unit in s.textUnits || []"
|
</g>
|
||||||
:key="unit.textPathId"
|
|
||||||
:id="unit.textPathId"
|
<!-- 定义文字路径 -->
|
||||||
:d="unit.textPath"
|
<defs>
|
||||||
|
<path
|
||||||
|
v-for="s in sectors"
|
||||||
|
:key="s.textPathId"
|
||||||
|
:id="s.textPathId"
|
||||||
|
:d="s.textPath"
|
||||||
|
fill="none"
|
||||||
|
/>
|
||||||
|
<template v-for="s in sectors" :key="s.key + '-units'">
|
||||||
|
<path
|
||||||
|
v-for="unit in s.textUnits || []"
|
||||||
|
:key="unit.textPathId"
|
||||||
|
:id="unit.textPathId"
|
||||||
|
:d="unit.textPath"
|
||||||
|
fill="none"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<!-- 文字标签(沿圆弧排列) -->
|
||||||
|
<g>
|
||||||
|
<template v-for="s in sectors" :key="s.key + '-text'">
|
||||||
|
<template v-if="s.textUnits">
|
||||||
|
<g v-for="unit in s.textUnits || []" :key="unit.textPathId">
|
||||||
|
<text
|
||||||
|
v-if="!unit.isSvg"
|
||||||
|
:font-size="unit.fontSize"
|
||||||
|
:fill="s.textColor"
|
||||||
|
:writing-mode="unit.isVertical ? 'tb' : undefined"
|
||||||
|
:glyph-orientation-vertical="unit.isVertical ? '0' : undefined"
|
||||||
|
:text-anchor="unit.isVertical ? 'middle' : undefined"
|
||||||
|
style="user-select: none"
|
||||||
|
>
|
||||||
|
<textPath
|
||||||
|
:href="'#' + unit.textPathId"
|
||||||
|
startOffset="50%"
|
||||||
|
text-anchor="middle"
|
||||||
|
dominant-baseline="central"
|
||||||
|
>
|
||||||
|
{{ unit.content }}
|
||||||
|
</textPath>
|
||||||
|
</text>
|
||||||
|
<image
|
||||||
|
v-else
|
||||||
|
:href="unit.svgPath"
|
||||||
|
:x="getUnitSvgBox(s, unit).x"
|
||||||
|
:y="getUnitSvgBox(s, unit).y"
|
||||||
|
:width="getUnitSvgBox(s, unit).size"
|
||||||
|
:height="getUnitSvgBox(s, unit).size"
|
||||||
|
:opacity="s.textColor ? 1 : 1"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<text
|
||||||
|
v-if="!s.isSvgContent"
|
||||||
|
:font-size="s.fontSize"
|
||||||
|
:fill="s.textColor"
|
||||||
|
:writing-mode="s.isVertical ? 'tb' : undefined"
|
||||||
|
:glyph-orientation-vertical="s.isVertical ? '0' : undefined"
|
||||||
|
:text-anchor="s.isVertical ? 'middle' : undefined"
|
||||||
|
style="user-select: none"
|
||||||
|
>
|
||||||
|
<textPath
|
||||||
|
:href="'#' + s.textPathId"
|
||||||
|
startOffset="50%"
|
||||||
|
text-anchor="middle"
|
||||||
|
dominant-baseline="central"
|
||||||
|
>
|
||||||
|
{{ s.label }}
|
||||||
|
</textPath>
|
||||||
|
</text>
|
||||||
|
<image
|
||||||
|
v-else
|
||||||
|
:href="s.svgPath"
|
||||||
|
:x="getSectorSvgBox(s).x"
|
||||||
|
:y="getSectorSvgBox(s).y"
|
||||||
|
:width="getSectorSvgBox(s).size"
|
||||||
|
:height="getSectorSvgBox(s).size"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- 扇区边界线 -->
|
||||||
|
<g
|
||||||
|
v-memo="[sectors, boundaryRings, strokeColor, strokeOpacity, strokeWidth]"
|
||||||
|
:stroke="strokeColor"
|
||||||
|
:stroke-opacity="strokeOpacity"
|
||||||
|
:stroke-width="strokeWidth"
|
||||||
|
>
|
||||||
|
<circle
|
||||||
|
v-for="r in boundaryRings"
|
||||||
|
:key="'ring-outline-' + r"
|
||||||
|
:r="r"
|
||||||
fill="none"
|
fill="none"
|
||||||
/>
|
/>
|
||||||
</template>
|
<template v-for="s in sectors" :key="'split-' + s.key">
|
||||||
</defs>
|
<line
|
||||||
|
v-if="s.groupSplitVisible !== false"
|
||||||
<!-- 文字标签(沿圆弧排列) -->
|
:x1="toXY(s.aStart, s.rInner).x"
|
||||||
<g>
|
:y1="toXY(s.aStart, s.rInner).y"
|
||||||
<template v-for="s in sectors" :key="s.key + '-text'">
|
:x2="toXY(s.aStart, s.rOuter).x"
|
||||||
<template v-if="s.textUnits">
|
:y2="toXY(s.aStart, s.rOuter).y"
|
||||||
<g v-for="unit in s.textUnits || []" :key="unit.textPathId">
|
|
||||||
<text
|
|
||||||
v-if="!unit.isSvg"
|
|
||||||
:font-size="unit.fontSize"
|
|
||||||
:fill="s.textColor"
|
|
||||||
:writing-mode="unit.isVertical ? 'tb' : undefined"
|
|
||||||
:glyph-orientation-vertical="unit.isVertical ? '0' : undefined"
|
|
||||||
:text-anchor="unit.isVertical ? 'middle' : undefined"
|
|
||||||
style="user-select: none"
|
|
||||||
>
|
|
||||||
<textPath
|
|
||||||
:href="'#' + unit.textPathId"
|
|
||||||
startOffset="50%"
|
|
||||||
text-anchor="middle"
|
|
||||||
dominant-baseline="central"
|
|
||||||
>
|
|
||||||
{{ unit.content }}
|
|
||||||
</textPath>
|
|
||||||
</text>
|
|
||||||
<image
|
|
||||||
v-else
|
|
||||||
:href="unit.svgPath"
|
|
||||||
:x="getUnitSvgBox(s, unit).x"
|
|
||||||
:y="getUnitSvgBox(s, unit).y"
|
|
||||||
:width="getUnitSvgBox(s, unit).size"
|
|
||||||
:height="getUnitSvgBox(s, unit).size"
|
|
||||||
:opacity="s.textColor ? 1 : 1"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
<text
|
|
||||||
v-if="!s.isSvgContent"
|
|
||||||
:font-size="s.fontSize"
|
|
||||||
:fill="s.textColor"
|
|
||||||
:writing-mode="s.isVertical ? 'tb' : undefined"
|
|
||||||
:glyph-orientation-vertical="s.isVertical ? '0' : undefined"
|
|
||||||
:text-anchor="s.isVertical ? 'middle' : undefined"
|
|
||||||
style="user-select: none"
|
|
||||||
>
|
|
||||||
<textPath
|
|
||||||
:href="'#' + s.textPathId"
|
|
||||||
startOffset="50%"
|
|
||||||
text-anchor="middle"
|
|
||||||
dominant-baseline="central"
|
|
||||||
>
|
|
||||||
{{ s.label }}
|
|
||||||
</textPath>
|
|
||||||
</text>
|
|
||||||
<image
|
|
||||||
v-else
|
|
||||||
:href="s.svgPath"
|
|
||||||
:x="getSectorSvgBox(s).x"
|
|
||||||
:y="getSectorSvgBox(s).y"
|
|
||||||
:width="getSectorSvgBox(s).size"
|
|
||||||
:height="getSectorSvgBox(s).size"
|
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
</g>
|
||||||
|
|
||||||
</template>
|
<!-- 形心点(仅辅助线开启时显示) -->
|
||||||
|
<g v-if="showGuides" v-memo="[sectors]">
|
||||||
|
<circle
|
||||||
|
v-for="s in sectors"
|
||||||
|
:key="s.key + '-center'"
|
||||||
|
:cx="s.cx"
|
||||||
|
:cy="s.cy"
|
||||||
|
r="2.2"
|
||||||
|
fill="#ef4444"
|
||||||
|
opacity="0.8"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- 辅助线:圆环、分度线 -->
|
||||||
|
<g v-if="showGuides" v-memo="[rings, anglesDeg, outerMost]" stroke="#111827" stroke-opacity="0.18">
|
||||||
|
<!-- 圆环 -->
|
||||||
|
<circle
|
||||||
|
v-for="r in rings"
|
||||||
|
:key="'ring-' + r"
|
||||||
|
:r="r"
|
||||||
|
fill="none"
|
||||||
|
:stroke-width="SECTOR_STROKE_WIDTH"
|
||||||
|
/>
|
||||||
|
<!-- 径向线 -->
|
||||||
|
<line
|
||||||
|
v-for="a in anglesDeg"
|
||||||
|
:key="'ang-' + a"
|
||||||
|
:x1="0"
|
||||||
|
:y1="0"
|
||||||
|
:x2="toXY(a, outerMost).x"
|
||||||
|
:y2="toXY(a, outerMost).y"
|
||||||
|
:stroke-width="SECTOR_STROKE_WIDTH"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- 刻度环 -->
|
||||||
|
<g v-if="degreeRing" v-memo="[degreeRing]">
|
||||||
|
<defs>
|
||||||
|
<path
|
||||||
|
v-for="label in degreeRing.labels || []"
|
||||||
|
:key="label.textPathId"
|
||||||
|
:id="label.textPathId"
|
||||||
|
:d="label.textPath"
|
||||||
|
fill="none"
|
||||||
|
/>
|
||||||
|
</defs>
|
||||||
|
<circle
|
||||||
|
v-if="degreeRing.background"
|
||||||
|
:r="(degreeRing.ring.rInner + degreeRing.ring.rOuter) / 2"
|
||||||
|
fill="none"
|
||||||
|
:stroke="degreeRing.background.color"
|
||||||
|
:stroke-opacity="degreeRing.background.opacity"
|
||||||
|
:stroke-width="degreeRing.ring.rOuter - degreeRing.ring.rInner"
|
||||||
|
/>
|
||||||
|
<circle
|
||||||
|
:r="degreeRing.ring.rOuter"
|
||||||
|
fill="none"
|
||||||
|
:stroke="degreeRing.ring.color"
|
||||||
|
:stroke-opacity="degreeRing.ring.opacity"
|
||||||
|
:stroke-width="SECTOR_STROKE_WIDTH"
|
||||||
|
/>
|
||||||
|
<circle
|
||||||
|
:r="degreeRing.ring.rInner"
|
||||||
|
fill="none"
|
||||||
|
:stroke="degreeRing.ring.color"
|
||||||
|
:stroke-opacity="degreeRing.ring.opacity"
|
||||||
|
:stroke-width="SECTOR_STROKE_WIDTH"
|
||||||
|
/>
|
||||||
|
<line
|
||||||
|
v-for="tick in degreeRing.ticks"
|
||||||
|
:key="'tick-' + tick.angle + '-' + tick.startR + '-' + tick.endR"
|
||||||
|
:x1="tick.x1"
|
||||||
|
:y1="tick.y1"
|
||||||
|
:x2="tick.x2"
|
||||||
|
:y2="tick.y2"
|
||||||
|
:stroke="degreeRing.tickColor"
|
||||||
|
:stroke-width="SECTOR_STROKE_WIDTH"
|
||||||
|
/>
|
||||||
|
<text
|
||||||
|
v-for="label in degreeRing.labels || []"
|
||||||
|
:key="'degree-' + label.angle"
|
||||||
|
:fill="degreeRing.tickColor"
|
||||||
|
:font-size="label.fontSize"
|
||||||
|
style="user-select: none"
|
||||||
|
>
|
||||||
|
<textPath
|
||||||
|
:href="'#' + label.textPathId"
|
||||||
|
startOffset="50%"
|
||||||
|
text-anchor="middle"
|
||||||
|
dominant-baseline="central"
|
||||||
|
>
|
||||||
|
{{ label.text }}
|
||||||
|
</textPath>
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- 中心图标 -->
|
||||||
|
<g v-if="centerIcon" v-memo="[centerIcon]">
|
||||||
|
<image
|
||||||
|
:href="centerIcon.svgPath"
|
||||||
|
:width="centerIcon.rIcon * 2"
|
||||||
|
:height="centerIcon.rIcon * 2"
|
||||||
|
:x="-centerIcon.rIcon"
|
||||||
|
:y="-centerIcon.rIcon"
|
||||||
|
:opacity="centerIcon.opacity"
|
||||||
|
:transform="`rotate(${centerIcon.rotation})`"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
|
||||||
|
|
||||||
<!-- 扇区边界线 -->
|
|
||||||
<g
|
|
||||||
v-memo="[sectors, boundaryRings, strokeColor, strokeOpacity, strokeWidth]"
|
|
||||||
:stroke="strokeColor"
|
|
||||||
:stroke-opacity="strokeOpacity"
|
|
||||||
:stroke-width="strokeWidth"
|
|
||||||
>
|
|
||||||
<circle
|
|
||||||
v-for="r in boundaryRings"
|
|
||||||
:key="'ring-outline-' + r"
|
|
||||||
:r="r"
|
|
||||||
fill="none"
|
|
||||||
/>
|
|
||||||
<template v-for="s in sectors" :key="'split-' + s.key">
|
|
||||||
<line
|
|
||||||
v-if="s.groupSplitVisible !== false"
|
|
||||||
:x1="toXY(s.aStart, s.rInner).x"
|
|
||||||
:y1="toXY(s.aStart, s.rInner).y"
|
|
||||||
:x2="toXY(s.aStart, s.rOuter).x"
|
|
||||||
:y2="toXY(s.aStart, s.rOuter).y"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</g>
|
|
||||||
|
|
||||||
<!-- 形心点(仅辅助线开启时显示) -->
|
|
||||||
<g v-if="showGuides" v-memo="[sectors]">
|
|
||||||
<circle
|
|
||||||
v-for="s in sectors"
|
|
||||||
:key="s.key + '-center'"
|
|
||||||
:cx="s.cx"
|
|
||||||
:cy="s.cy"
|
|
||||||
r="2.2"
|
|
||||||
fill="#ef4444"
|
|
||||||
opacity="0.8"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
|
|
||||||
<!-- 辅助线:圆环、分度线 -->
|
|
||||||
<g v-if="showGuides" v-memo="[rings, anglesDeg, outerMost]" stroke="#111827" stroke-opacity="0.18">
|
|
||||||
<!-- 圆环 -->
|
|
||||||
<circle
|
|
||||||
v-for="r in rings"
|
|
||||||
:key="'ring-' + r"
|
|
||||||
:r="r"
|
|
||||||
fill="none"
|
|
||||||
:stroke-width="SECTOR_STROKE_WIDTH"
|
|
||||||
/>
|
|
||||||
<!-- 径向线 -->
|
|
||||||
<line
|
|
||||||
v-for="a in anglesDeg"
|
|
||||||
:key="'ang-' + a"
|
|
||||||
:x1="0"
|
|
||||||
:y1="0"
|
|
||||||
:x2="toXY(a, outerMost).x"
|
|
||||||
:y2="toXY(a, outerMost).y"
|
|
||||||
:stroke-width="SECTOR_STROKE_WIDTH"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
|
|
||||||
<!-- 刻度环 -->
|
|
||||||
<g v-if="degreeRing" v-memo="[degreeRing]">
|
|
||||||
<defs>
|
|
||||||
<path
|
|
||||||
v-for="label in degreeRing.labels || []"
|
|
||||||
:key="label.textPathId"
|
|
||||||
:id="label.textPathId"
|
|
||||||
:d="label.textPath"
|
|
||||||
fill="none"
|
|
||||||
/>
|
|
||||||
</defs>
|
|
||||||
<circle
|
|
||||||
:r="degreeRing.ring.rOuter"
|
|
||||||
fill="none"
|
|
||||||
:stroke="degreeRing.ring.color"
|
|
||||||
:stroke-opacity="degreeRing.ring.opacity"
|
|
||||||
:stroke-width="SECTOR_STROKE_WIDTH"
|
|
||||||
/>
|
|
||||||
<circle
|
|
||||||
:r="degreeRing.ring.rInner"
|
|
||||||
fill="none"
|
|
||||||
:stroke="degreeRing.ring.color"
|
|
||||||
:stroke-opacity="degreeRing.ring.opacity"
|
|
||||||
:stroke-width="SECTOR_STROKE_WIDTH"
|
|
||||||
/>
|
|
||||||
<line
|
|
||||||
v-for="tick in degreeRing.ticks"
|
|
||||||
:key="'tick-' + tick.angle + '-' + tick.startR + '-' + tick.endR"
|
|
||||||
:x1="tick.x1"
|
|
||||||
:y1="tick.y1"
|
|
||||||
:x2="tick.x2"
|
|
||||||
:y2="tick.y2"
|
|
||||||
:stroke="degreeRing.tickColor"
|
|
||||||
:stroke-width="SECTOR_STROKE_WIDTH"
|
|
||||||
/>
|
|
||||||
<text
|
|
||||||
v-for="label in degreeRing.labels || []"
|
|
||||||
:key="'degree-' + label.angle"
|
|
||||||
:fill="degreeRing.tickColor"
|
|
||||||
:font-size="label.fontSize"
|
|
||||||
style="user-select: none"
|
|
||||||
>
|
|
||||||
<textPath
|
|
||||||
:href="'#' + label.textPathId"
|
|
||||||
startOffset="50%"
|
|
||||||
text-anchor="middle"
|
|
||||||
dominant-baseline="central"
|
|
||||||
>
|
|
||||||
{{ label.text }}
|
|
||||||
</textPath>
|
|
||||||
</text>
|
|
||||||
</g>
|
|
||||||
|
|
||||||
<!-- 中心图标 -->
|
|
||||||
<g v-if="centerIcon" v-memo="[centerIcon]">
|
|
||||||
<image
|
|
||||||
:href="centerIcon.svgPath"
|
|
||||||
:width="centerIcon.rIcon * 2"
|
|
||||||
:height="centerIcon.rIcon * 2"
|
|
||||||
:x="-centerIcon.rIcon"
|
|
||||||
:y="-centerIcon.rIcon"
|
|
||||||
:opacity="centerIcon.opacity"
|
|
||||||
:transform="`rotate(${centerIcon.rotation})`"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -341,6 +348,7 @@ const textRadialPosition = ref<TextRadialPosition>(DEFAULT_TEXT_RADIAL_POSITION)
|
|||||||
const scale = ref(1);
|
const scale = ref(1);
|
||||||
const panX = ref(0);
|
const panX = ref(0);
|
||||||
const panY = ref(0);
|
const panY = ref(0);
|
||||||
|
const viewport = ref<SVGGElement | null>(null);
|
||||||
let nextScale = scale.value;
|
let nextScale = scale.value;
|
||||||
let nextPanX = panX.value;
|
let nextPanX = panX.value;
|
||||||
let nextPanY = panY.value;
|
let nextPanY = panY.value;
|
||||||
@@ -421,6 +429,9 @@ const loadConfigList = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onMounted(loadConfigList);
|
onMounted(loadConfigList);
|
||||||
|
onMounted(() => {
|
||||||
|
applyViewportTransform(scale.value, panX.value, panY.value);
|
||||||
|
});
|
||||||
|
|
||||||
watch(selectedConfigPath, (value, previous) => {
|
watch(selectedConfigPath, (value, previous) => {
|
||||||
if (value === previous) return;
|
if (value === previous) return;
|
||||||
@@ -472,6 +483,14 @@ const boundaryRings = computed(() => {
|
|||||||
return Array.from(set);
|
return Array.from(set);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const applyViewportTransform = (scaleValue: number, panXValue: number, panYValue: number) => {
|
||||||
|
if (!viewport.value) return;
|
||||||
|
viewport.value.setAttribute(
|
||||||
|
'transform',
|
||||||
|
`scale(${scaleValue}) translate(${panXValue}, ${panYValue})`
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
// 使用 `rAF` 合并缩放/拖拽更新,减少渲染频率
|
// 使用 `rAF` 合并缩放/拖拽更新,减少渲染频率
|
||||||
const scheduleTransform = () => {
|
const scheduleTransform = () => {
|
||||||
if (rafId !== null) return;
|
if (rafId !== null) return;
|
||||||
@@ -484,6 +503,7 @@ const scheduleTransform = () => {
|
|||||||
scale.value = nextScale;
|
scale.value = nextScale;
|
||||||
panX.value = nextPanX;
|
panX.value = nextPanX;
|
||||||
panY.value = nextPanY;
|
panY.value = nextPanY;
|
||||||
|
applyViewportTransform(nextScale, nextPanX, nextPanY);
|
||||||
rafId = null;
|
rafId = null;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -638,6 +658,12 @@ button.active {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
contain: paint;
|
||||||
|
cursor: grab;
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-container.is-dragging {
|
||||||
|
cursor: grabbing;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status {
|
.status {
|
||||||
@@ -650,10 +676,13 @@ button.active {
|
|||||||
|
|
||||||
.svg {
|
.svg {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
transition: transform 0.1s ease-out;
|
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.viewport {
|
||||||
|
will-change: transform;
|
||||||
|
}
|
||||||
|
|
||||||
.note {
|
.note {
|
||||||
color: #6b7280;
|
color: #6b7280;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ import type {
|
|||||||
ThemesConfig,
|
ThemesConfig,
|
||||||
TextRadialPosition,
|
TextRadialPosition,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import { polarToXY } from '../utils';
|
import { getTextColorForBackground, polarToXY } from '../utils';
|
||||||
import { parseConfig } from '../configParser';
|
import { normalizeLayerRadii, parseConfig } from '../configParser';
|
||||||
import { ColorResolver } from '../colorResolver';
|
import { ColorResolver } from '../colorResolver';
|
||||||
import { SectorBuilder } from '../sectorBuilder';
|
import { SectorBuilder } from '../sectorBuilder';
|
||||||
import { buildDegreeRing } from '../degreeRing';
|
import { buildDegreeRing } from '../degreeRing';
|
||||||
@@ -39,6 +39,29 @@ const resolveThemeColor = (
|
|||||||
return theme.colorPalettes[value] ?? fallback;
|
return theme.colorPalettes[value] ?? fallback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const resolveDegreeRingColor = (
|
||||||
|
value: string | undefined,
|
||||||
|
theme: ThemeConfig,
|
||||||
|
background: string
|
||||||
|
) => {
|
||||||
|
if (typeof value === 'string' && value.trim().length > 0) {
|
||||||
|
return resolveThemeColor(theme, value, value);
|
||||||
|
}
|
||||||
|
const contrast = getTextColorForBackground(background);
|
||||||
|
return contrast === '#ffffff' ? '#ffffff' : '#000000';
|
||||||
|
};
|
||||||
|
|
||||||
|
const resolveDegreeRingBackground = (
|
||||||
|
value: string | undefined,
|
||||||
|
theme: ThemeConfig,
|
||||||
|
fallback: string
|
||||||
|
) => {
|
||||||
|
if (typeof value === 'string' && value.trim().length > 0) {
|
||||||
|
return resolveThemeColor(theme, value, fallback);
|
||||||
|
}
|
||||||
|
return fallback;
|
||||||
|
};
|
||||||
|
|
||||||
const findDegreeRingLayer = (layers: LayerConfig[]) =>
|
const findDegreeRingLayer = (layers: LayerConfig[]) =>
|
||||||
layers.find((layer) => layer.type === 'degreeRing');
|
layers.find((layer) => layer.type === 'degreeRing');
|
||||||
|
|
||||||
@@ -158,39 +181,45 @@ export function useLuopan(
|
|||||||
error.value = null;
|
error.value = null;
|
||||||
|
|
||||||
let configObj: LuopanConfigInput;
|
let configObj: LuopanConfigInput;
|
||||||
|
let normalizedLayers: LuopanConfig['layers'];
|
||||||
const configInput = configSource.value;
|
const configInput = configSource.value;
|
||||||
if (typeof configInput === 'string') {
|
if (typeof configInput === 'string') {
|
||||||
const jsonText = await fetch(configInput).then((res) => res.text());
|
const jsonText = await fetch(configInput).then((res) => res.text());
|
||||||
configObj = parseConfig(jsonText);
|
configObj = parseConfig(jsonText);
|
||||||
|
// parseConfig 已完成层归一化,避免重复处理
|
||||||
|
normalizedLayers = configObj.layers;
|
||||||
} else {
|
} else {
|
||||||
configObj = configInput;
|
configObj = configInput;
|
||||||
|
normalizedLayers = normalizeLayerRadii(configObj.layers);
|
||||||
}
|
}
|
||||||
|
|
||||||
const resolvedTheme = await resolveTheme(configObj);
|
const normalizedConfig = { ...configObj, layers: normalizedLayers };
|
||||||
|
|
||||||
|
const resolvedTheme = await resolveTheme(normalizedConfig);
|
||||||
const resolvedBackground = resolveThemeColor(
|
const resolvedBackground = resolveThemeColor(
|
||||||
resolvedTheme,
|
resolvedTheme,
|
||||||
configObj.background,
|
normalizedConfig.background,
|
||||||
'#000000'
|
'#000000'
|
||||||
);
|
);
|
||||||
const resolvedStrokeColor = resolveThemeColor(
|
const resolvedStrokeColor = resolveThemeColor(
|
||||||
resolvedTheme,
|
resolvedTheme,
|
||||||
configObj.strokeColor,
|
normalizedConfig.strokeColor,
|
||||||
'#1f2937'
|
'#1f2937'
|
||||||
);
|
);
|
||||||
|
|
||||||
const resolvedConfig: LuopanConfig = {
|
const resolvedConfig: LuopanConfig = {
|
||||||
...configObj,
|
...normalizedConfig,
|
||||||
theme: resolvedTheme,
|
theme: resolvedTheme,
|
||||||
background: resolvedBackground,
|
background: resolvedBackground,
|
||||||
strokeColor: resolvedStrokeColor,
|
strokeColor: resolvedStrokeColor,
|
||||||
strokeWidth: typeof configObj.strokeWidth === 'number'
|
strokeWidth: typeof normalizedConfig.strokeWidth === 'number'
|
||||||
? configObj.strokeWidth
|
? normalizedConfig.strokeWidth
|
||||||
: undefined,
|
: undefined,
|
||||||
strokeOpacity: typeof configObj.strokeOpacity === 'number'
|
strokeOpacity: typeof normalizedConfig.strokeOpacity === 'number'
|
||||||
? configObj.strokeOpacity
|
? normalizedConfig.strokeOpacity
|
||||||
: undefined,
|
: undefined,
|
||||||
insetDistance: typeof configObj.insetDistance === 'number'
|
insetDistance: typeof normalizedConfig.insetDistance === 'number'
|
||||||
? configObj.insetDistance
|
? normalizedConfig.insetDistance
|
||||||
: undefined,
|
: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -198,15 +227,52 @@ export function useLuopan(
|
|||||||
sectors.value = buildSectors(resolvedConfig);
|
sectors.value = buildSectors(resolvedConfig);
|
||||||
|
|
||||||
const degreeRingLayer = findDegreeRingLayer(resolvedConfig.layers);
|
const degreeRingLayer = findDegreeRingLayer(resolvedConfig.layers);
|
||||||
degreeRing.value = degreeRingLayer
|
if (degreeRingLayer) {
|
||||||
? buildDegreeRing(degreeRingLayer.degreeRing)
|
const ringBackground = resolveDegreeRingBackground(
|
||||||
: null;
|
degreeRingLayer.degreeRing.colorRef,
|
||||||
|
resolvedConfig.theme,
|
||||||
|
resolvedConfig.background
|
||||||
|
);
|
||||||
|
const hasBackgroundRef =
|
||||||
|
typeof degreeRingLayer.degreeRing.colorRef === 'string' &&
|
||||||
|
degreeRingLayer.degreeRing.colorRef.trim().length > 0;
|
||||||
|
const tickColor = resolveDegreeRingColor(
|
||||||
|
degreeRingLayer.degreeRing.tickColor,
|
||||||
|
resolvedConfig.theme,
|
||||||
|
ringBackground
|
||||||
|
);
|
||||||
|
const ringColor = resolveDegreeRingColor(
|
||||||
|
degreeRingLayer.degreeRing.ringColor,
|
||||||
|
resolvedConfig.theme,
|
||||||
|
ringBackground
|
||||||
|
);
|
||||||
|
const ringData = buildDegreeRing({
|
||||||
|
...degreeRingLayer.degreeRing,
|
||||||
|
tickColor,
|
||||||
|
ringColor,
|
||||||
|
});
|
||||||
|
degreeRing.value = {
|
||||||
|
...ringData,
|
||||||
|
background: hasBackgroundRef
|
||||||
|
? {
|
||||||
|
color: ringBackground,
|
||||||
|
opacity: degreeRingLayer.degreeRing.opacity,
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
degreeRing.value = null;
|
||||||
|
}
|
||||||
|
|
||||||
const centerIconLayer = findCenterIconLayer(resolvedConfig.layers);
|
const centerIconLayer = findCenterIconLayer(resolvedConfig.layers);
|
||||||
centerIcon.value = centerIconLayer
|
centerIcon.value = centerIconLayer
|
||||||
? await loadCenterIcon(centerIconLayer.centerIcon)
|
? await loadCenterIcon(centerIconLayer.centerIcon)
|
||||||
: null;
|
: null;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
console.error('加载罗盘配置失败', {
|
||||||
|
source: typeof configSource.value === 'string' ? configSource.value : 'inline config',
|
||||||
|
error: err,
|
||||||
|
});
|
||||||
error.value = err as Error;
|
error.value = err as Error;
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
|||||||
@@ -1,4 +1,13 @@
|
|||||||
import type { LuopanConfigInput, ThemeConfig } from './types';
|
import type {
|
||||||
|
DegreeRingLayerConfig,
|
||||||
|
DegreeRingLayerConfigInput,
|
||||||
|
LayerConfig,
|
||||||
|
LayerConfigInput,
|
||||||
|
LuopanConfigInput,
|
||||||
|
SectorLayerConfig,
|
||||||
|
SectorLayerConfigInput,
|
||||||
|
ThemeConfig,
|
||||||
|
} from './types';
|
||||||
|
|
||||||
const isObject = (value: unknown): value is Record<string, unknown> =>
|
const isObject = (value: unknown): value is Record<string, unknown> =>
|
||||||
typeof value === 'object' && value !== null && !Array.isArray(value);
|
typeof value === 'object' && value !== null && !Array.isArray(value);
|
||||||
@@ -9,6 +18,9 @@ const assertCondition = (condition: boolean, message: string): void => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isFiniteNumber = (value: unknown): value is number =>
|
||||||
|
typeof value === 'number' && Number.isFinite(value);
|
||||||
|
|
||||||
export const stripJsonComments = (input: string): string => {
|
export const stripJsonComments = (input: string): string => {
|
||||||
let output = '';
|
let output = '';
|
||||||
let inString = false;
|
let inString = false;
|
||||||
@@ -53,6 +65,175 @@ const normalizeTheme = (theme: Record<string, unknown>): ThemeConfig => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const normalizeSectorLayer = (
|
||||||
|
layer: SectorLayerConfigInput,
|
||||||
|
index: number,
|
||||||
|
lastOuter: number | null
|
||||||
|
): { layer: SectorLayerConfig; nextOuter: number } => {
|
||||||
|
const rInnerRaw = layer.rInner;
|
||||||
|
const rOuterRaw = layer.rOuter;
|
||||||
|
const layerHeightRaw = layer.layerHeight;
|
||||||
|
|
||||||
|
const hasRInner = rInnerRaw !== undefined;
|
||||||
|
const hasROuter = rOuterRaw !== undefined;
|
||||||
|
|
||||||
|
if (hasRInner && !isFiniteNumber(rInnerRaw)) {
|
||||||
|
throw new Error(`layers[${index}].rInner 必须为数字`);
|
||||||
|
}
|
||||||
|
if (hasROuter && !isFiniteNumber(rOuterRaw)) {
|
||||||
|
throw new Error(`layers[${index}].rOuter 必须为数字`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasRInner || hasROuter) {
|
||||||
|
assertCondition(
|
||||||
|
hasRInner && hasROuter,
|
||||||
|
`layers[${index}] 必须同时提供 rInner 与 rOuter`
|
||||||
|
);
|
||||||
|
const rInner = rInnerRaw as number;
|
||||||
|
const rOuter = rOuterRaw as number;
|
||||||
|
assertCondition(rOuter > rInner, `layers[${index}] rOuter 必须大于 rInner`);
|
||||||
|
return {
|
||||||
|
layer: { ...layer, rInner, rOuter },
|
||||||
|
nextOuter: rOuter,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layerHeightRaw === undefined) {
|
||||||
|
throw new Error(`layers[${index}] 缺少 rInner/rOuter 或 layerHeight`);
|
||||||
|
}
|
||||||
|
if (!isFiniteNumber(layerHeightRaw)) {
|
||||||
|
throw new Error(`layers[${index}].layerHeight 必须为数字`);
|
||||||
|
}
|
||||||
|
assertCondition(
|
||||||
|
layerHeightRaw > 0,
|
||||||
|
`layers[${index}].layerHeight 必须大于 0`
|
||||||
|
);
|
||||||
|
assertCondition(
|
||||||
|
lastOuter !== null,
|
||||||
|
`layers[${index}] 使用 layerHeight 时必须有上一层 rOuter`
|
||||||
|
);
|
||||||
|
|
||||||
|
const rInner = lastOuter as number;
|
||||||
|
const rOuter = rInner + layerHeightRaw;
|
||||||
|
return {
|
||||||
|
layer: { ...layer, rInner, rOuter },
|
||||||
|
nextOuter: rOuter,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const normalizeDegreeRingLayer = (
|
||||||
|
layer: DegreeRingLayerConfigInput,
|
||||||
|
index: number,
|
||||||
|
lastOuter: number | null
|
||||||
|
): { layer: DegreeRingLayerConfig; nextOuter: number } => {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(layer, 'degreeRing')) {
|
||||||
|
const keys = Object.keys(layer).join(', ');
|
||||||
|
console.error('检测到废弃的 degreeRing 嵌套配置', {
|
||||||
|
index,
|
||||||
|
keys,
|
||||||
|
layer,
|
||||||
|
});
|
||||||
|
throw new Error(
|
||||||
|
`layers[${index}].degreeRing 已废弃,请改为扁平写法(keys: ${keys})`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const { type: _type, layerHeight: layerHeightRaw, ...degreeRing } = layer;
|
||||||
|
|
||||||
|
const rInnerRaw = degreeRing.rInner;
|
||||||
|
const rOuterRaw = degreeRing.rOuter;
|
||||||
|
|
||||||
|
const hasRInner = rInnerRaw !== undefined;
|
||||||
|
const hasROuter = rOuterRaw !== undefined;
|
||||||
|
|
||||||
|
if (hasRInner && !isFiniteNumber(rInnerRaw)) {
|
||||||
|
throw new Error(`layers[${index}].rInner 必须为数字`);
|
||||||
|
}
|
||||||
|
if (hasROuter && !isFiniteNumber(rOuterRaw)) {
|
||||||
|
throw new Error(`layers[${index}].rOuter 必须为数字`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasRInner || hasROuter) {
|
||||||
|
assertCondition(
|
||||||
|
hasRInner && hasROuter,
|
||||||
|
`layers[${index}] 必须同时提供 rInner 与 rOuter`
|
||||||
|
);
|
||||||
|
const rInner = rInnerRaw as number;
|
||||||
|
const rOuter = rOuterRaw as number;
|
||||||
|
assertCondition(
|
||||||
|
rOuter > rInner,
|
||||||
|
`layers[${index}].rOuter 必须大于 rInner`
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
layer: {
|
||||||
|
type: 'degreeRing',
|
||||||
|
layerHeight: layerHeightRaw,
|
||||||
|
degreeRing: { ...degreeRing, rInner, rOuter },
|
||||||
|
},
|
||||||
|
nextOuter: rOuter,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layerHeightRaw === undefined) {
|
||||||
|
throw new Error(`layers[${index}] 缺少 rInner/rOuter 或 layerHeight`);
|
||||||
|
}
|
||||||
|
if (!isFiniteNumber(layerHeightRaw)) {
|
||||||
|
throw new Error(`layers[${index}].layerHeight 必须为数字`);
|
||||||
|
}
|
||||||
|
assertCondition(
|
||||||
|
layerHeightRaw > 0,
|
||||||
|
`layers[${index}].layerHeight 必须大于 0`
|
||||||
|
);
|
||||||
|
assertCondition(
|
||||||
|
lastOuter !== null,
|
||||||
|
`layers[${index}] 使用 layerHeight 时必须有上一层 rOuter`
|
||||||
|
);
|
||||||
|
|
||||||
|
const rInner = lastOuter as number;
|
||||||
|
const rOuter = rInner + layerHeightRaw;
|
||||||
|
return {
|
||||||
|
layer: {
|
||||||
|
type: 'degreeRing',
|
||||||
|
layerHeight: layerHeightRaw,
|
||||||
|
degreeRing: { ...degreeRing, rInner, rOuter },
|
||||||
|
},
|
||||||
|
nextOuter: rOuter,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const normalizeLayerRadii = (layers: LayerConfigInput[]): LayerConfig[] => {
|
||||||
|
const normalized: LayerConfig[] = [];
|
||||||
|
let lastOuter: number | null = null;
|
||||||
|
|
||||||
|
layers.forEach((layer, index) => {
|
||||||
|
assertCondition(isObject(layer), `layers[${index}] 必须为对象`);
|
||||||
|
const type = (layer as Record<string, unknown>).type;
|
||||||
|
if (type === 'centerIcon') {
|
||||||
|
normalized.push(layer as LayerConfig);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (type === 'degreeRing') {
|
||||||
|
const { layer: degreeRingLayer, nextOuter } = normalizeDegreeRingLayer(
|
||||||
|
layer as DegreeRingLayerConfigInput,
|
||||||
|
index,
|
||||||
|
lastOuter
|
||||||
|
);
|
||||||
|
normalized.push(degreeRingLayer);
|
||||||
|
lastOuter = nextOuter;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { layer: sectorLayer, nextOuter } = normalizeSectorLayer(
|
||||||
|
layer as SectorLayerConfigInput,
|
||||||
|
index,
|
||||||
|
lastOuter
|
||||||
|
);
|
||||||
|
normalized.push(sectorLayer);
|
||||||
|
lastOuter = nextOuter;
|
||||||
|
});
|
||||||
|
|
||||||
|
return normalized;
|
||||||
|
};
|
||||||
|
|
||||||
export const parseConfig = (jsonText: string): LuopanConfigInput => {
|
export const parseConfig = (jsonText: string): LuopanConfigInput => {
|
||||||
const cleanText = stripJsonComments(jsonText);
|
const cleanText = stripJsonComments(jsonText);
|
||||||
let parsed: unknown;
|
let parsed: unknown;
|
||||||
@@ -73,6 +254,7 @@ export const parseConfig = (jsonText: string): LuopanConfigInput => {
|
|||||||
assertCondition(isObject(config.theme), 'theme 必须为对象');
|
assertCondition(isObject(config.theme), 'theme 必须为对象');
|
||||||
}
|
}
|
||||||
assertCondition(Array.isArray(config.layers), 'layers 为必填数组');
|
assertCondition(Array.isArray(config.layers), 'layers 为必填数组');
|
||||||
|
const normalizedLayers = normalizeLayerRadii(config.layers as LayerConfigInput[]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: config.name,
|
name: config.name,
|
||||||
@@ -85,6 +267,6 @@ export const parseConfig = (jsonText: string): LuopanConfigInput => {
|
|||||||
outerRadius: typeof config.outerRadius === 'number' ? config.outerRadius : undefined,
|
outerRadius: typeof config.outerRadius === 'number' ? config.outerRadius : undefined,
|
||||||
themeRef: typeof config.themeRef === 'string' ? config.themeRef : undefined,
|
themeRef: typeof config.themeRef === 'string' ? config.themeRef : undefined,
|
||||||
theme: isObject(config.theme) ? normalizeTheme(config.theme) : undefined,
|
theme: isObject(config.theme) ? normalizeTheme(config.theme) : undefined,
|
||||||
layers: config.layers as LuopanConfigInput['layers'],
|
layers: normalizedLayers,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ export function buildDegreeRing(config: DegreeRingConfig): DegreeRingData {
|
|||||||
const ticks: TickMark[] = [];
|
const ticks: TickMark[] = [];
|
||||||
const { rInner, rOuter, mode } = config;
|
const { rInner, rOuter, mode } = config;
|
||||||
const labelFontSize = 8;
|
const labelFontSize = 8;
|
||||||
|
const tickColor = config.tickColor ?? '#000000';
|
||||||
|
const ringColor = config.ringColor ?? tickColor;
|
||||||
|
|
||||||
const majorTick = Math.max(1, config.majorTick);
|
const majorTick = Math.max(1, config.majorTick);
|
||||||
const minorTick = Math.max(1, config.minorTick);
|
const minorTick = Math.max(1, config.minorTick);
|
||||||
@@ -125,11 +127,11 @@ export function buildDegreeRing(config: DegreeRingConfig): DegreeRingData {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
ticks,
|
ticks,
|
||||||
tickColor: config.tickColor,
|
tickColor,
|
||||||
ring: {
|
ring: {
|
||||||
rInner,
|
rInner,
|
||||||
rOuter,
|
rOuter,
|
||||||
color: config.ringColor,
|
color: ringColor,
|
||||||
opacity: config.opacity,
|
opacity: config.opacity,
|
||||||
},
|
},
|
||||||
labels: labels.length > 0 ? labels : undefined,
|
labels: labels.length > 0 ? labels : undefined,
|
||||||
|
|||||||
@@ -62,10 +62,6 @@ export class SectorBuilder {
|
|||||||
|
|
||||||
// 颜色优先级:扇区 > 规律填色 > 背景
|
// 颜色优先级:扇区 > 规律填色 > 背景
|
||||||
const fillColor = this.colorResolver.resolveSectorColor(layerColorMap, sectorConfig, i);
|
const fillColor = this.colorResolver.resolveSectorColor(layerColorMap, sectorConfig, i);
|
||||||
const layerColor = layer.colorRef ? this.colorResolver.resolveColor(layer.colorRef) : undefined;
|
|
||||||
const sectorColor = sectorConfig?.colorRef
|
|
||||||
? this.colorResolver.resolveColor(sectorConfig.colorRef)
|
|
||||||
: undefined;
|
|
||||||
// 扇区的 `innerFill` 优先级高于层级的 `innerFill`。
|
// 扇区的 `innerFill` 优先级高于层级的 `innerFill`。
|
||||||
const innerFill = (sectorConfig?.innerFill ?? layer.innerFill ?? 0) === 1;
|
const innerFill = (sectorConfig?.innerFill ?? layer.innerFill ?? 0) === 1;
|
||||||
const innerFillPath = innerFill
|
const innerFillPath = innerFill
|
||||||
@@ -80,10 +76,10 @@ export class SectorBuilder {
|
|||||||
const normalizedInnerFillPath =
|
const normalizedInnerFillPath =
|
||||||
innerFillPath && innerFillPath.length > 0 ? innerFillPath : undefined;
|
innerFillPath && innerFillPath.length > 0 ? innerFillPath : undefined;
|
||||||
const hasInnerFillPath = Boolean(normalizedInnerFillPath);
|
const hasInnerFillPath = Boolean(normalizedInnerFillPath);
|
||||||
// `innerFill` 开启时:外圈保持白色,仅填充内缩块。
|
// `innerFill` 开启时:外圈保持白色,内缩块仍按规律填色。
|
||||||
const baseFillColor = hasInnerFillPath ? '#ffffff' : fillColor;
|
const baseFillColor = hasInnerFillPath ? '#ffffff' : fillColor;
|
||||||
const innerFillColor = hasInnerFillPath ? sectorColor ?? layerColor ?? fillColor : undefined;
|
const innerFillColor = hasInnerFillPath ? fillColor : undefined;
|
||||||
const textBaseColor = hasInnerFillPath ? innerFillColor ?? fillColor : fillColor;
|
const textBaseColor = fillColor;
|
||||||
const textColor = getTextColorForBackground(textBaseColor);
|
const textColor = getTextColorForBackground(textBaseColor);
|
||||||
|
|
||||||
const sectorKey = `L${layerIndex}-P${i}`;
|
const sectorKey = `L${layerIndex}-P${i}`;
|
||||||
|
|||||||
50
src/types.ts
50
src/types.ts
@@ -22,7 +22,7 @@ export interface Example {
|
|||||||
/**
|
/**
|
||||||
* JSON 配置根对象
|
* JSON 配置根对象
|
||||||
*/
|
*/
|
||||||
export interface LuopanConfigBase {
|
export interface LuopanConfigBase<TLayer = LayerConfig> {
|
||||||
name: string;
|
name: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
background: string;
|
background: string;
|
||||||
@@ -33,15 +33,13 @@ export interface LuopanConfigBase {
|
|||||||
outerRadius?: number;
|
outerRadius?: number;
|
||||||
themeRef?: string;
|
themeRef?: string;
|
||||||
theme?: ThemeConfig;
|
theme?: ThemeConfig;
|
||||||
layers: LayerConfig[];
|
layers: TLayer[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LuopanConfig extends LuopanConfigBase {
|
export interface LuopanConfig extends LuopanConfigBase<LayerConfig> {
|
||||||
theme: ThemeConfig;
|
theme: ThemeConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type LuopanConfigInput = LuopanConfigBase;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 主题配置
|
* 主题配置
|
||||||
*/
|
*/
|
||||||
@@ -84,8 +82,15 @@ export interface DegreeRingConfig {
|
|||||||
majorTick: number;
|
majorTick: number;
|
||||||
minorTick: number;
|
minorTick: number;
|
||||||
microTick: number;
|
microTick: number;
|
||||||
tickColor: string;
|
tickColor?: string;
|
||||||
ringColor: string;
|
ringColor?: string;
|
||||||
|
colorRef?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DegreeRingConfigInput
|
||||||
|
extends Omit<DegreeRingConfig, 'rInner' | 'rOuter'> {
|
||||||
|
rInner?: number;
|
||||||
|
rOuter?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -99,11 +104,9 @@ export type LayerConfig =
|
|||||||
/**
|
/**
|
||||||
* 普通扇区层配置
|
* 普通扇区层配置
|
||||||
*/
|
*/
|
||||||
export interface SectorLayerConfig {
|
interface SectorLayerBase {
|
||||||
type?: 'sectors';
|
type?: 'sectors';
|
||||||
divisions: number;
|
divisions: number;
|
||||||
rInner: number;
|
|
||||||
rOuter: number;
|
|
||||||
startAngle?: number;
|
startAngle?: number;
|
||||||
colorRef?: string;
|
colorRef?: string;
|
||||||
innerFill?: 0 | 1;
|
innerFill?: 0 | 1;
|
||||||
@@ -115,6 +118,25 @@ export interface SectorLayerConfig {
|
|||||||
sectors?: SectorConfig[];
|
sectors?: SectorConfig[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SectorLayerConfig extends SectorLayerBase {
|
||||||
|
rInner: number;
|
||||||
|
rOuter: number;
|
||||||
|
layerHeight?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SectorLayerConfigInput extends SectorLayerBase {
|
||||||
|
rInner?: number;
|
||||||
|
rOuter?: number;
|
||||||
|
layerHeight?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LayerConfigInput =
|
||||||
|
| SectorLayerConfigInput
|
||||||
|
| CenterIconLayerConfig
|
||||||
|
| DegreeRingLayerConfigInput;
|
||||||
|
|
||||||
|
export type LuopanConfigInput = LuopanConfigBase<LayerConfigInput>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 中心图标层配置
|
* 中心图标层配置
|
||||||
*/
|
*/
|
||||||
@@ -129,6 +151,13 @@ export interface CenterIconLayerConfig {
|
|||||||
export interface DegreeRingLayerConfig {
|
export interface DegreeRingLayerConfig {
|
||||||
type: 'degreeRing';
|
type: 'degreeRing';
|
||||||
degreeRing: DegreeRingConfig;
|
degreeRing: DegreeRingConfig;
|
||||||
|
layerHeight?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 扁平化输入:刻度环字段直接挂在层上。
|
||||||
|
export interface DegreeRingLayerConfigInput extends DegreeRingConfigInput {
|
||||||
|
type: 'degreeRing';
|
||||||
|
layerHeight?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -190,6 +219,7 @@ export interface DegreeRingData {
|
|||||||
ticks: TickMark[];
|
ticks: TickMark[];
|
||||||
tickColor: string;
|
tickColor: string;
|
||||||
ring: { rInner: number; rOuter: number; color: string; opacity: number };
|
ring: { rInner: number; rOuter: number; color: string; opacity: number };
|
||||||
|
background?: { color: string; opacity: number };
|
||||||
labels?: DegreeLabel[];
|
labels?: DegreeLabel[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,11 @@
|
|||||||
import { describe, it, expect } from 'vitest';
|
import { describe, it, expect } from 'vitest';
|
||||||
import { mount } from '@vue/test-utils';
|
import { mount } from '@vue/test-utils';
|
||||||
import Luopan from '../src/Luopan.vue';
|
import Luopan from '../src/Luopan.vue';
|
||||||
import type { LuopanConfig } from '../src/types';
|
import type { LuopanConfigInput } from '../src/types';
|
||||||
|
|
||||||
const flushPromises = () => new Promise((resolve) => setTimeout(resolve, 0));
|
const flushPromises = () => new Promise((resolve) => setTimeout(resolve, 0));
|
||||||
|
|
||||||
const baseConfig: LuopanConfig = {
|
const baseConfig: LuopanConfigInput = {
|
||||||
name: '测试配置',
|
name: '测试配置',
|
||||||
background: '#000000',
|
background: '#000000',
|
||||||
theme: {
|
theme: {
|
||||||
@@ -26,20 +26,18 @@ const baseConfig: LuopanConfig = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'degreeRing',
|
type: 'degreeRing',
|
||||||
degreeRing: {
|
rInner: 90,
|
||||||
rInner: 90,
|
rOuter: 100,
|
||||||
rOuter: 100,
|
showDegree: 1,
|
||||||
showDegree: 1,
|
mode: 'both',
|
||||||
mode: 'both',
|
opacity: 0.3,
|
||||||
opacity: 0.3,
|
tickLength: 6,
|
||||||
tickLength: 6,
|
tickLengthStep: 1,
|
||||||
tickLengthStep: 1,
|
majorTick: 10,
|
||||||
majorTick: 10,
|
minorTick: 5,
|
||||||
minorTick: 5,
|
microTick: 1,
|
||||||
microTick: 1,
|
tickColor: '#ffffff',
|
||||||
tickColor: '#ffffff',
|
ringColor: '#ffffff',
|
||||||
ringColor: '#ffffff',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'centerIcon',
|
type: 'centerIcon',
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
import { describe, it, expect } from 'vitest';
|
import { describe, it, expect } from 'vitest';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { useLuopan } from '../src/composables/useLuopan';
|
import { useLuopan } from '../src/composables/useLuopan';
|
||||||
import type { LuopanConfig, TextRadialPosition } from '../src/types';
|
import type { LuopanConfigInput, TextRadialPosition } from '../src/types';
|
||||||
|
|
||||||
const createMockConfig = (): LuopanConfig => ({
|
const createMockConfig = (): LuopanConfigInput => ({
|
||||||
name: '测试配置',
|
name: '测试配置',
|
||||||
background: '#000000',
|
background: '#000000',
|
||||||
theme: {
|
theme: {
|
||||||
|
|||||||
Reference in New Issue
Block a user