lambo-design-bi 0.0.258 → 0.0.262

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,9 +18,6 @@
18
18
 
19
19
  </LamboPageContainer>
20
20
  </template>
21
-
22
-
23
-
24
21
  <script>
25
22
  import LamboPageContainer from '@lambo-design/page-container'
26
23
  import BiSearchForm from '../search/search-form.vue'
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "lambo-design-bi",
3
- "version": "0.0.258",
3
+ "version": "0.0.262",
4
4
  "description": "Vue2 BI 数据可视化组件库",
5
5
  "main": "index.js",
6
+ "scripts": {
7
+ "publish": "pnpm publish --access public --no-git-checks",
8
+ "release": "npm version patch --no-git-tag-version && npm publish --access public"
9
+ },
6
10
  "author": "finch",
7
11
  "license": "ISC",
8
12
  "publishConfig": {
@@ -44,6 +48,5 @@
44
48
  "eslint": "^7.32.0",
45
49
  "eslint-plugin-vue": "^8.0.3",
46
50
  "vue-template-compiler": "^2.7.16"
47
- },
48
- "scripts": {}
49
- }
51
+ }
52
+ }
@@ -116,6 +116,40 @@ function getLevelOption() {
116
116
  ];
117
117
  }
118
118
 
119
+ /**
120
+ * 坐标轴区间 nice 化(气泡图 type=46 用)
121
+ *
122
+ * 对按 10% padding 算出的 min/max 按 nice 步长向外取整,
123
+ * 让 ECharts 刻度线落在整数/半数等友好数值上,
124
+ * 同时消除浮点误差(如 2 - 1.1 = 0.8999... 会被规整掉)。
125
+ *
126
+ * 算法:
127
+ * 1. 步长 = 跨度/5 规格化后, 向上命中候选 {1,1.5,2,2.5,3,4,5,6,8,10} × 10^n
128
+ * 2. min 向下、max 向上对齐到步长的整数倍
129
+ *
130
+ * @param {number} min 原始下边界(已含 padding)
131
+ * @param {number} max 原始上边界(已含 padding)
132
+ * @returns {Array<number>|null} [niceMin, niceMax], 输入非法(如非数值数据)返回 null
133
+ */
134
+ function niceAxisRange(min, max) {
135
+ if (!isFinite(min) || !isFinite(max)) return null
136
+ const span = max - min
137
+ if (span <= 0) return [min, max]
138
+ // 1) 按 5 段分割求 nice 步长
139
+ const rawStep = span / 5
140
+ const exp10 = Math.pow(10, Math.floor(Math.log10(rawStep)))
141
+ const f = rawStep / exp10
142
+ const candidates = [1, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10]
143
+ const step = (candidates.find(c => c >= f - 1e-9) || 10) * exp10
144
+ // 2) 边界对齐到步长整数倍(带容差防浮点), toPrecision 清理乘积小数尾巴
145
+ const align = function (value, isCeil) {
146
+ const k = value / step
147
+ const r = isCeil ? Math.ceil(k - 1e-6) : Math.floor(k + 1e-6)
148
+ return Number((r * step).toPrecision(12))
149
+ }
150
+ return [align(min, false), align(max, true)]
151
+ }
152
+
119
153
  /**
120
154
  * type:
121
155
  * (charts类型:
@@ -2901,6 +2935,17 @@ export function getECharts(type, dataX, dataY, dataDim, dataZ) {
2901
2935
  })
2902
2936
  }
2903
2937
 
2938
+ // X/Y 轴区间: 数据范围 ±10% padding(避免气泡贴边被裁)后, 再按 nice 步长向外取整
2939
+ // 使刻度落在 0/3/6/9 这类友好数值上, 并消除浮点误差(2 - 1.1 = 0.8999...)
2940
+ const xPadding = (xArr.length > 0) ? (Math.max(...xArr) - Math.min(...xArr)) * 0.10 : 0
2941
+ const xRange = (xArr.length > 0
2942
+ ? niceAxisRange(Math.min(...xArr) - xPadding, Math.max(...xArr) + xPadding)
2943
+ : null) || [0, 100]
2944
+ const yPadding = (yArr.length > 0) ? (Math.max(...yArr) - Math.min(...yArr)) * 0.10 : 0
2945
+ const yRange = (yArr.length > 0
2946
+ ? niceAxisRange(Math.min(...yArr) - yPadding, Math.max(...yArr) + yPadding)
2947
+ : null) || [0, 100]
2948
+
2904
2949
  opt = {
2905
2950
  backgroundColor: '#fff',
2906
2951
  tooltip: {
@@ -2951,9 +2996,9 @@ export function getECharts(type, dataX, dataY, dataDim, dataZ) {
2951
2996
  fontSize: 11
2952
2997
  },
2953
2998
  // 留出气泡最大半径(25px)对应的坐标值, 避免最低/最高点贴边被裁
2954
- // 按数据范围反推: (max-min) * 10% 留作 padding
2955
- min: xArr.length > 0 ? Math.min(...xArr) - (Math.max(...xArr) - Math.min(...xArr)) * 0.10 : 0,
2956
- max: xArr.length > 0 ? Math.max(...xArr) + (Math.max(...xArr) - Math.min(...xArr)) * 0.10 : 100,
2999
+ // (max-min) * 10% 作 padding 后按 nice 步长取整, 详见上方 xRange
3000
+ min: xRange[0],
3001
+ max: xRange[1],
2957
3002
  splitLine: {
2958
3003
  show: true,
2959
3004
  lineStyle: {
@@ -2979,8 +3024,8 @@ export function getECharts(type, dataX, dataY, dataDim, dataZ) {
2979
3024
  color: '#666',
2980
3025
  fontSize: 11
2981
3026
  },
2982
- min: yArr.length > 0 ? Math.min(...yArr) - (Math.max(...yArr) - Math.min(...yArr)) * 0.10 : 0,
2983
- max: yArr.length > 0 ? Math.max(...yArr) + (Math.max(...yArr) - Math.min(...yArr)) * 0.10 : 100,
3027
+ min: yRange[0],
3028
+ max: yRange[1],
2984
3029
  splitLine: {
2985
3030
  show: true,
2986
3031
  lineStyle: {
@@ -310,7 +310,9 @@ export default {
310
310
  extractHeadings(xml, headingStyleSet) {
311
311
  const styleSet = headingStyleSet || {};
312
312
  const headings = [];
313
- const blocks = xml.match(/<w:p[ >][\s\S]*?<\/w:p>/g) || [];
313
+ // 剔除表格块:表格单元格内的 <w:p> 不参与标题识别,避免表格数字被误判为目录项
314
+ const bodyNoTbl = xml.replace(/<w:tbl>[\s\S]*?<\/w:tbl>/g, "");
315
+ const blocks = bodyNoTbl.match(/<w:p[ >][\s\S]*?<\/w:p>/g) || [];
314
316
  blocks.forEach(block => {
315
317
  const texts = block.match(/<w:t[^>]*>([\s\S]*?)<\/w:t>/g) || [];
316
318
  const text = texts
@@ -14,7 +14,7 @@
14
14
  </el-button>
15
15
  </div>
16
16
  <div class="select-list">
17
- <el-option v-for="(item, index) in data" :key="index" :label="item.V" :value="item.K" />
17
+ <el-option v-for="(item, index) in data" :key="index" :label="item[actualVKey]" :value="item[actualKKey]" />
18
18
  </div>
19
19
  </el-select>
20
20
  </div>
@@ -40,6 +40,26 @@ export default {
40
40
  width: {
41
41
  type: String,
42
42
  default: "250px"
43
+ },
44
+ // 选项值对应的字段名
45
+ kKey: {
46
+ type: String,
47
+ default: "K"
48
+ },
49
+ // 选项标签对应的字段名
50
+ vKey: {
51
+ type: String,
52
+ default: "V"
53
+ }
54
+ },
55
+ computed: {
56
+ // 实际使用的值字段名,未传入或非有效字符串时回退为 K
57
+ actualKKey() {
58
+ return typeof this.kKey === "string" && this.kKey ? this.kKey : "K"
59
+ },
60
+ // 实际使用的标签字段名,未传入或非有效字符串时回退为 V
61
+ actualVKey() {
62
+ return typeof this.vKey === "string" && this.vKey ? this.vKey : "V"
43
63
  }
44
64
  },
45
65
  data() {
@@ -83,7 +103,7 @@ export default {
83
103
  return
84
104
  }
85
105
 
86
- const allValues = this.data.map(item => item.K)
106
+ const allValues = this.data.map(item => item[this.actualKKey])
87
107
  this.internalValue = [...allValues]
88
108
  this.$emit('change', allValues)
89
109
  this.$emit('select-all', allValues) // 可选:触发全选事件
@@ -95,7 +115,7 @@ export default {
95
115
  return
96
116
  }
97
117
 
98
- const allValues = this.data.map(item => item.K)
118
+ const allValues = this.data.map(item => item[this.actualKKey])
99
119
  const currentValues = this.internalValue
100
120
 
101
121
  // 找出当前未选中的项目
@@ -103,7 +123,7 @@ export default {
103
123
 
104
124
  this.internalValue = [...reversedValues]
105
125
  this.$emit('change', reversedValues)
106
- this.$emit('reverse-select', reversedValues) // 可选:触发反选事件
126
+ this.$emit('reverse-select', reversedValues)
107
127
  },
108
128
 
109
129
  // select变化时触发