bri-components 1.5.22 → 1.6.1

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.
Files changed (154) hide show
  1. package/README.md +83 -83
  2. package/lib/styles/bundle.css +12 -12
  3. package/lib/styles/font/fontello.svg +31 -31
  4. package/package.json +127 -125
  5. package/src/components/Error/Error403.vue +42 -42
  6. package/src/components/Error/Error404.vue +40 -40
  7. package/src/components/Error/Error500.vue +51 -51
  8. package/src/components/Error/error.less +162 -162
  9. package/src/components/Error/errorBack.vue +40 -40
  10. package/src/components/controls/DshControlInput.vue +195 -195
  11. package/src/components/controls/base/BriUpload/BriUpload.vue +435 -434
  12. package/src/components/controls/base/BriUpload/BriUploadImage.vue +430 -377
  13. package/src/components/controls/base/BriUpload/uploadList.vue +738 -727
  14. package/src/components/controls/base/BriUpload/uploadMixin.js +453 -446
  15. package/src/components/controls/base/DshCascader/DshCascader.vue +215 -215
  16. package/src/components/controls/base/DshCascader/components/cascaderModal.vue +366 -366
  17. package/src/components/controls/base/DshCascader/components/cascaderPicker.vue +416 -416
  18. package/src/components/controls/base/DshCascader/components/cascaderSimple.vue +141 -141
  19. package/src/components/controls/base/DshCascader/components/cascaderTree.vue +151 -151
  20. package/src/components/controls/base/DshCoordinates.vue +587 -585
  21. package/src/components/controls/base/DshDate/DshDate.vue +191 -191
  22. package/src/components/controls/base/DshDate/DshDaterange.vue +186 -186
  23. package/src/components/controls/base/DshDivider.vue +201 -201
  24. package/src/components/controls/base/DshEditor.vue +274 -274
  25. package/src/components/controls/base/DshInput/BriInputs.vue +166 -166
  26. package/src/components/controls/base/DshInput/DshInput.vue +260 -260
  27. package/src/components/controls/base/DshNumber/BriInputNumber/BriInputNumber.vue +435 -435
  28. package/src/components/controls/base/DshNumber/BriInputNumber/mixins/emitter.js +34 -34
  29. package/src/components/controls/base/DshNumber/BriInputNumber/mixins/form.js +14 -14
  30. package/src/components/controls/base/DshNumber/BriInputNumber/utils/assist.js +322 -322
  31. package/src/components/controls/base/DshNumber/DshNumber.vue +143 -143
  32. package/src/components/controls/base/DshNumber/DshNumberange.vue +109 -109
  33. package/src/components/controls/base/DshSelect/DshCheckbox.vue +168 -168
  34. package/src/components/controls/base/DshSelect/DshSelect.vue +180 -180
  35. package/src/components/controls/base/DshSelect/DshSelectAll.vue +269 -269
  36. package/src/components/controls/base/DshSwitch/DshSwitch.vue +115 -115
  37. package/src/components/controls/control.less +324 -324
  38. package/src/components/controls/controlMap.js +117 -117
  39. package/src/components/controls/extra/DshColor.vue +81 -81
  40. package/src/components/controls/extra/DshThemeColor.vue +100 -100
  41. package/src/components/controls/extra/DshThemeIcon.vue +122 -122
  42. package/src/components/controls/mixins/cascaderMixin.js +325 -325
  43. package/src/components/controls/mixins/cascaderPickerMixin.js +227 -227
  44. package/src/components/controls/mixins/cascaderTableMixin.js +130 -130
  45. package/src/components/controls/mixins/controlMixin.js +393 -393
  46. package/src/components/controls/mixins/dateMixin.js +149 -149
  47. package/src/components/controls/mixins/flatTableMixin.js +111 -111
  48. package/src/components/controls/mixins/numberMixin.js +112 -112
  49. package/src/components/controls/mixins/selectMixin.js +233 -233
  50. package/src/components/controls/mixins/switchMixin.js +87 -87
  51. package/src/components/controls/mixins/userAndDepartMixin.js +260 -260
  52. package/src/components/controls/senior/DshLabels.vue +333 -333
  53. package/src/components/controls/senior/DshPackage.vue +57 -57
  54. package/src/components/controls/senior/cascaderTable.vue +213 -213
  55. package/src/components/controls/senior/correlation.vue +135 -135
  56. package/src/components/controls/senior/flatTable.vue +138 -138
  57. package/src/components/controls/senior/selectDepartments.vue +397 -399
  58. package/src/components/controls/senior/selectUsers/departMenu.vue +296 -293
  59. package/src/components/controls/senior/selectUsers/selectUsers.vue +712 -712
  60. package/src/components/controls/special/DshBack.vue +42 -42
  61. package/src/components/controls/special/DshUndeveloped.vue +41 -41
  62. package/src/components/form/DshAdvSearch.vue +510 -510
  63. package/src/components/form/DshDefaultSearch.vue +260 -260
  64. package/src/components/form/DshForm.vue +494 -494
  65. package/src/components/form/searchMixin.js +376 -376
  66. package/src/components/list/BriCard.vue +95 -95
  67. package/src/components/list/BriTable.vue +205 -205
  68. package/src/components/list/BriTree.vue +529 -529
  69. package/src/components/list/BriTreeItem.vue +163 -163
  70. package/src/components/list/DshBox/DshBox.vue +219 -219
  71. package/src/components/list/DshBox/DshCard.vue +446 -446
  72. package/src/components/list/DshBox/DshCrossTable.vue +827 -827
  73. package/src/components/list/DshBox/DshList.vue +404 -404
  74. package/src/components/list/DshBox/DshPanel.vue +669 -669
  75. package/src/components/list/DshBox/DshSingleData.vue +119 -119
  76. package/src/components/list/DshBox/DshTable.vue +239 -239
  77. package/src/components/list/DshCascaderTable.vue +115 -115
  78. package/src/components/list/DshFlatTable.vue +334 -337
  79. package/src/components/list/DshPage.vue +194 -194
  80. package/src/components/list/DshTreeTable.vue +113 -113
  81. package/src/components/list/common/importModal.vue +243 -243
  82. package/src/components/list/common/quoteListModal.vue +206 -206
  83. package/src/components/list/mixins/DshCascaderTableMixin.js +278 -278
  84. package/src/components/list/mixins/DshFlatTableMixin.js +509 -509
  85. package/src/components/list/mixins/DshTreeTableMixin.js +286 -286
  86. package/src/components/list/mixins/tableBaseMixin.js +1653 -1653
  87. package/src/components/list/mixins/treeTableBaseMixin.js +145 -145
  88. package/src/components/other/BriAvatar.vue +166 -166
  89. package/src/components/other/BriCode.vue +125 -125
  90. package/src/components/other/BriCollapseTree.vue +207 -207
  91. package/src/components/other/BriGantt.vue +1087 -1087
  92. package/src/components/other/BriIframe.vue +116 -116
  93. package/src/components/other/BriLoading.vue +171 -171
  94. package/src/components/other/BriSvg.vue +27 -27
  95. package/src/components/other/DshColorPanel.vue +128 -128
  96. package/src/components/other/DshMenuNav.vue +188 -188
  97. package/src/components/other/DshVideoPlayer.vue +184 -0
  98. package/src/components/small/BriButton.vue +71 -71
  99. package/src/components/small/BriDrawer.vue +169 -169
  100. package/src/components/small/BriTooltip.vue +87 -87
  101. package/src/components/small/DshBtnModal.vue +68 -68
  102. package/src/components/small/DshButtons.vue +324 -324
  103. package/src/components/small/DshDropdown.vue +225 -225
  104. package/src/components/small/DshIcons.vue +59 -59
  105. package/src/components/small/DshListRender.js +21 -21
  106. package/src/components/small/DshModal.vue +160 -160
  107. package/src/components/small/DshSteps.vue +141 -141
  108. package/src/components/small/DshTabs.vue +598 -598
  109. package/src/components/small/DshTabsSet.vue +309 -309
  110. package/src/components/small/DshTags.vue +251 -251
  111. package/src/components/small/DshTitle.vue +50 -50
  112. package/src/components/small/render.js +20 -20
  113. package/src/components/unit/DshFormUnit.vue +398 -398
  114. package/src/components/unit/DshListUnit.vue +115 -115
  115. package/src/components/unit/unitMixin.js +86 -86
  116. package/src/data/index.js +4 -4
  117. package/src/index.js +287 -285
  118. package/src/styles/bundle.css +12 -12
  119. package/src/styles/components/BriButton.less +307 -307
  120. package/src/styles/components/BriTable.less +344 -344
  121. package/src/styles/components/DshModal.less +257 -257
  122. package/src/styles/components/index.less +3 -3
  123. package/src/styles/global/animate.less +11 -11
  124. package/src/styles/global/base.less +45 -45
  125. package/src/styles/global/box.less +186 -186
  126. package/src/styles/global/control.less +122 -122
  127. package/src/styles/global/flex.less +282 -282
  128. package/src/styles/global/global.less +8 -8
  129. package/src/styles/global/text.less +59 -59
  130. package/src/styles/global/variables.less +85 -85
  131. package/src/styles/iconfont/iconfont.css +254 -254
  132. package/src/styles/iconfont/iconfont.json +422 -422
  133. package/src/styles/iconfont/iconfont.svg +137 -137
  134. package/src/styles/index.less +26 -26
  135. package/src/styles/reset-easytable.less +21 -21
  136. package/src/styles/reset-iview-controls.less +145 -145
  137. package/src/styles/reset-iview-other.less +49 -49
  138. package/src/styles/reset-iview-variables.less +43 -43
  139. package/src/styles/reset.less +45 -45
  140. package/src/utils/index.js +3 -5
  141. package/lib/0.bri-components.min.js +0 -1
  142. package/lib/1.bri-components.min.js +0 -1
  143. package/lib/10.bri-components.min.js +0 -1
  144. package/lib/11.bri-components.min.js +0 -1
  145. package/lib/2.bri-components.min.js +0 -1
  146. package/lib/3.bri-components.min.js +0 -1
  147. package/lib/4.bri-components.min.js +0 -1
  148. package/lib/5.bri-components.min.js +0 -1
  149. package/lib/6.bri-components.min.js +0 -1
  150. package/lib/7.bri-components.min.js +0 -1
  151. package/lib/8.bri-components.min.js +0 -1
  152. package/lib/9.bri-components.min.js +0 -1
  153. package/lib/bri-components.min.js +0 -18
  154. package/src/utils/table.js +0 -175
@@ -1,1087 +1,1087 @@
1
- <template>
2
- <div class="briGantt">
3
- <div class="briGantt-top">
4
- <div class="bri-scrollbar0">
5
- <slot></slot>
6
- </div>
7
- <!-- 时间渲染 -->
8
- <div
9
- class="briGantt-timer"
10
- :style="{width: clientWidth + 'px'}"
11
- >
12
- <a
13
- class="briGantt-timer-icon briGantt-timer-icon-left"
14
- @click="preTime"
15
- >
16
- <Icon type="ios-arrow-back" />
17
- </a>
18
- <div class="briGantt-timer-bg"></div>
19
- <div
20
- class="bri-scrollbar0 briGantt-timer-main"
21
- ref="briGanttTimer"
22
- v-on:scroll="handleScroll($event, [{ ref: 'briGanttArea', direction: 'scrollLeft' }])"
23
- >
24
- <table
25
- :style="{tableLayout:'fixed', width: tableWidth}"
26
- class="briGantt-tableBox"
27
- >
28
- <thead class="briGantt-table-thead">
29
- <tr>
30
- <th
31
- class="briGantt-table-th"
32
- v-for="timeItem in simpleData"
33
- :key="timeItem.key"
34
- :colspan="timeItem.colspan"
35
- :style="{...timeItem.style}"
36
- >
37
- <Tooltip
38
- :content="timeItem.fullName"
39
- placement="top"
40
- :transfer="true"
41
- :transfer-class-name="`briGantt-transfer-tooltip-${themeName}`"
42
- >
43
- {{ timeItem.name }}
44
- </Tooltip>
45
- <div
46
- v-if="timeItem.now"
47
- class="briGantt-line-now"
48
- ></div>
49
- </th>
50
- </tr>
51
- </thead>
52
- </table>
53
- </div>
54
- <a
55
- class="briGantt-timer-icon briGantt-timer-icon-right"
56
- @click="nextTime"
57
- >
58
- <Icon type="ios-arrow-forward" />
59
- </a>
60
- </div>
61
- </div>
62
- <div class="briGantt-bottom">
63
- <div
64
- class="briGantt-bottom-title"
65
- v-if="title"
66
- >{{ title }}</div>
67
- <div class="briGantt-bottom-content">
68
- <!-- 数据映射 -->
69
- <div
70
- v-if="table"
71
- class="bri-scrollbar0 briGantt-tabledata"
72
- ref="briGanttColumn"
73
- v-on:scroll="handleScroll($event, [{ ref: 'briGanttArea', direction: 'scrollTop' }])"
74
- >
75
- <table class="briGantt-tableBox briGantt-table">
76
- <tbody>
77
- <tr
78
- class="briGantt-table-tr"
79
- v-for="(row, rowIndex) in table"
80
- :key="rowIndex"
81
- >
82
- <td
83
- class="briGantt-table-td"
84
- v-for="(col, colIndex) in row"
85
- :key="colIndex"
86
- :colspan="col.colspan"
87
- :rowspan="col.rowspan"
88
- :style="col.rowspan > 1 ? {background: '#fff',padding: '0 10px',fontWeight:500} : {padding: '0 10px'}"
89
- v-html="col.label"
90
- ></td>
91
- </tr>
92
- </tbody>
93
- </table>
94
- </div>
95
- <!-- 区域映射 -->
96
- <div
97
- class="briGantt-data bri-scrollbar"
98
- :class="`briGantt-data-${type}`"
99
- ref="briGanttArea"
100
- v-on:scroll="handleScroll($event, [{ ref: 'briGanttTimer', direction: 'scrollLeft' }, { ref:'briGanttColumn', direction:'scrollTop' }, { ref:'briGanttScrollbar', direction:'scrollLeft' }])"
101
- >
102
- <table
103
- :style="{tableLayout:'fixed', width: tableWidth}"
104
- class="briGantt-tableBox briGantt-table"
105
- border="0"
106
- cellspacing="0"
107
- cellpadding="0"
108
- >
109
- <tr v-if="computedData.length === 0">
110
- <td
111
- :colspan="timeData.length"
112
- class="briGantt-table-td"
113
- >暂无内容</td>
114
- </tr>
115
- <tbody v-if="type==='table'">
116
- <tr v-if="computedData.length === 0">
117
- <td
118
- :colspan="timeData.length"
119
- class="briGantt-table-td"
120
- >暂无内容</td>
121
- </tr>
122
- <tr
123
- class="briGantt-table-tr"
124
- v-for="(taskItem, taskIndex) in computedData"
125
- :key="taskIndex"
126
- style="border-left: none"
127
- >
128
- <td
129
- class="briGantt-table-td"
130
- v-for="(timeItem, timeIndex) in taskItem"
131
- :key="timeIndex"
132
- :colspan="timeItem.colspan"
133
- >
134
- <slot
135
- v-if="timeItem.isApply"
136
- name="table"
137
- v-bind:task="timeItem.task"
138
- v-bind:time="timeItem"
139
- >
140
- <div
141
- class="briGantt-table-td-main"
142
- :style="timeItem.style"
143
- ></div>
144
- </slot>
145
- <slot
146
- v-else
147
- name="tabletd"
148
- v-bind:preTime="taskItem[timeIndex-1]"
149
- v-bind:nextTime="taskItem[timeIndex+1]"
150
- v-bind:task="timeItem.task"
151
- v-bind:time="timeItem"
152
- ></slot>
153
- </td>
154
- </tr>
155
- </tbody>
156
- <tbody v-else-if="type==='chart'">
157
- <tr
158
- class="briGantt-chart-tr"
159
- v-for="(taskItem, taskIndex) in computedData"
160
- :key="taskIndex"
161
- >
162
- <td
163
- class="briGantt-chart-td"
164
- v-for="(timeItem, timeIndex) in taskItem"
165
- :key="timeIndex"
166
- :colspan="timeItem.colspan"
167
- >
168
- <div
169
- v-if="timeItem.isApply"
170
- class="briGantt-chart-td-main"
171
- >
172
- <slot
173
- name="chart"
174
- v-bind:task="timeItem.task"
175
- v-bind:chartItem="timeItem"
176
- >
177
- <Tooltip
178
- placement="right"
179
- transfer
180
- :transfer-class-name="`briGantt-transfer-tooltip-${themeName}`"
181
- style="width:100%"
182
- >
183
- <div
184
- class="briGantt-chart-td-main-center"
185
- :style="{
186
- background:$getColor(timeItem.style.background),
187
- minWidth: minTdWidth,
188
- border: `1px solid ${timeItem.style.background}`,
189
- padding: timeItem.task.progressField == 100 ? '' : '1px',
190
- cursor: canClick ? 'pointer' : ''
191
- }"
192
- @click="clickRow(timeItem)"
193
- >
194
- <slot
195
- name="chartCenter"
196
- v-bind:task="timeItem.task"
197
- v-bind:chartItem="timeItem"
198
- >
199
- <div
200
- class="ms-ellipsis"
201
- :style="{
202
- background:timeItem.style.background,
203
- width: `${timeItem.task.progressField}%`
204
- }"
205
- >
206
- {{ timeItem.task.label }}
207
- </div>
208
- </slot>
209
- </div>
210
- <div
211
- slot="content"
212
- class="briGantt-chart-td-main-center-tooltip"
213
- >
214
- <span
215
- class="briGantt-chart-td-main-center-tooltip-select"
216
- :style="{...timeItem.style}"
217
- >
218
- </span>
219
- {{timeItem.task.select}}
220
- <div>完成度:{{timeItem.task.progressField}}%</div>
221
- <div>{{ timeItem.task.label }}</div>
222
- </div>
223
- </Tooltip>
224
- </slot>
225
- </div>
226
- <slot
227
- v-else
228
- name="charttd"
229
- v-bind:task="timeItem.task"
230
- v-bind:time="timeItem"
231
- v-bind:preTime="taskItem[timeIndex-1]"
232
- v-bind:nextTime="taskItem[timeIndex+1]"
233
- >
234
- <div class="briGantt-chart-td-greyLine"></div>
235
- </slot>
236
- </td>
237
- </tr>
238
- </tbody>
239
- </table>
240
- </div>
241
- </div>
242
-
243
- <!-- 底部滚动条 -->
244
- <!-- <div class="briGantt-scroll">
245
- <div class="briGantt-scroll-main"
246
- ref="briGanttScrollbar"
247
- :style="{ width: clientWidth + 'px' }"
248
- v-on:scroll="handleScroll($event, [{ ref: 'briGanttTimer', direction: 'scrollLeft' }, { ref:'briGanttArea', direction:'scrollLeft' }, { ref:'briGanttBlue', direction:'scrollLeft' }])">
249
- <div :style="{width: tableWidth}"></div>
250
- </div>
251
- </div> -->
252
- </div>
253
- </div>
254
- </template>
255
- <script>
256
- function getDate (hours) {
257
- const currentDate = new Date();
258
- const currentYear = currentDate.getFullYear();
259
- const currentMonth = currentDate.getMonth();
260
- const currentDay = currentDate.getDate();
261
- const timeStamp = new Date(
262
- currentYear,
263
- currentMonth,
264
- currentDay,
265
- 0,
266
- 0,
267
- 0
268
- ).getTime();
269
- return new Date(timeStamp + hours * 60 * 60 * 1000).getTime();
270
- }
271
- function getMonth (N) {
272
- const currentDate = new Date();
273
- const currentYear = currentDate.getFullYear();
274
- const currentMonth = currentDate.getMonth();
275
- return new Date(currentYear, currentMonth + N, 1).getTime();
276
- }
277
- // 示例数据
278
- let tasks = [
279
- {
280
- id: 1,
281
- label: "Make some noise",
282
- user:
283
- '<a href="https://www.google.com/search?q=John+Doe" target="_blank" style="color:#0077c0;">John Doe</a>',
284
- start: getDate(-24 * 5),
285
- end: getDate(0),
286
- select: "紧急",
287
- duration: 15 * 24 * 60 * 60 * 1000,
288
- percent: 85,
289
- type: "project",
290
- style: {
291
- background: "orange",
292
- main: "rgba(109,174,242,1)"
293
- }
294
- // collapsed: true,
295
- },
296
- {
297
- id: 2,
298
- label: "With great power comes great responsibility",
299
- user:
300
- '<a href="https://www.google.com/search?q=Peter+Parker" target="_blank" style="color:#0077c0;">Peter Parker</a>',
301
- parentId: 1,
302
- start: getDate(-24 * 20),
303
- duration: 20 * 24 * 60 * 60 * 1000,
304
- percent: 50,
305
- select: "重要",
306
- type: "milestone",
307
- collapsed: true,
308
- style: {
309
- background: "red",
310
- main: "rgba(240,143,145,1)"
311
- }
312
- },
313
- {
314
- id: 3,
315
- label: "Courage is being scared to death, but saddling up anyway.",
316
- user:
317
- '<a href="https://www.google.com/search?q=John+Wayne" target="_blank" style="color:#0077c0;">John Wayne</a>',
318
- parentId: 2,
319
- select: "普通",
320
- start: getDate(-24 * 3),
321
- duration: 2 * 24 * 60 * 60 * 1000,
322
- percent: 100,
323
- type: "task",
324
- style: {
325
- background: "rgba(255,248,242,1)",
326
- main: "rgba(255,190,114,1)"
327
- }
328
- },
329
- {
330
- id: 4,
331
- label: "Put that toy AWAY!",
332
- user:
333
- '<a href="https://www.google.com/search?q=Clark+Kent" target="_blank" style="color:#0077c0;">Clark Kent</a>',
334
- start: getDate(-24 * 2),
335
- duration: 2 * 24 * 60 * 60 * 1000,
336
- select: "紧急",
337
- percent: 50,
338
- type: "task",
339
- dependentOn: [3],
340
- style: {
341
- background: "rgba(235,248,240,1)",
342
- main: "rgba(137,213,166,1)"
343
- }
344
- },
345
- {
346
- id: 5,
347
- label: "Put that toy AWAY!",
348
- select: "紧急",
349
- user:
350
- '<a href="https://www.google.com/search?q=Clark+Kent" target="_blank" style="color:#0077c0;">Clark Kent</a>',
351
- start: getDate(1 * 24),
352
- end: getDate(1 * 24),
353
- // duration: 1 * 24 * 60 * 60 * 1000,
354
- percent: 50,
355
- type: "task",
356
- dependentOn: [3],
357
- style: {
358
- background: "rgba(235,248,240,1)",
359
- main: "rgba(137,213,166,1)"
360
- }
361
- }
362
- ];
363
-
364
- export default {
365
- name: "briGantt",
366
- components: {},
367
- props: {
368
- simpleDataColor: {
369
- type: String,
370
- default: "#3DB8C5"
371
- },
372
-
373
- tasks: Array,
374
- options: {
375
- type: Object,
376
- default () {
377
- return {};
378
- }
379
- },
380
- value: {
381
- type: Object,
382
- default () {
383
- return {};
384
- }
385
- },
386
- propsObj: {
387
- type: Object,
388
- default () {
389
- return {};
390
- }
391
- },
392
- // 是否展示示例数据
393
- showEs: {
394
- type: Boolean,
395
- default: false
396
- },
397
- title: String,
398
- // 展示类型, 分图标和表格,默认表格
399
- type: {
400
- type: String,
401
- default: "table"
402
- },
403
- dimension: {
404
- type: String,
405
- default: "quarter"
406
- },
407
- showCloumns: {
408
- type: Boolean,
409
- default: true
410
- },
411
- table: Array,
412
- // 距离今天个数
413
- count: {
414
- type: Number,
415
- default: 5
416
- },
417
- // 展示日期间隔
418
- step: {
419
- type: Number,
420
- default: 1
421
- },
422
- canClick: {
423
- type: Boolean,
424
- default: false
425
- }
426
- },
427
- computed: {
428
- // 默认列表
429
- defaultTasks () {
430
- if (this.showEs) {
431
- return tasks;
432
- } else {
433
- return this.tasks || [];
434
- }
435
- },
436
- // 表格宽度
437
- tableWidth () {
438
- let timeDataWidth = this.simpleData.length * 50;
439
- let clientWidth = this.clientWidth;
440
- if (this.computedCountStep.stepKind === "month") {
441
- timeDataWidth = this.timeData.length * 3;
442
- }
443
- if (timeDataWidth < clientWidth) {
444
- return "100%";
445
- } else {
446
- return timeDataWidth + "px";
447
- }
448
- },
449
- minTdWidth () {
450
- let minWidth = 2;
451
- if (this.tableWidth.includes("px")) {
452
- minWidth = parseInt(this.tableWidth) / this.timeData.length;
453
- } else {
454
- minWidth = parseInt(this.clientWidth) / this.timeData.length;
455
- }
456
- minWidth > 20 && (minWidth = 2);
457
- return minWidth + "px";
458
- },
459
- // 间隔及时间,当前选择时间维度
460
- computedCountStep () {
461
- this.refreshStepCount();
462
- return this.dimensionObject[this.dimension] || { count: this.count, step: this.step };
463
- },
464
- // 任务数据
465
- taskData () {
466
- /**
467
- * task 默认数据
468
- */
469
- let tasks = this.defaultTasks;
470
- for (let task of tasks) {
471
- if (typeof task.x === "undefined") {
472
- task.x = 0;
473
- }
474
- if (typeof task.y === "undefined") {
475
- task.y = 0;
476
- }
477
- if (typeof task.width === "undefined") {
478
- task.width = 0;
479
- }
480
- if (typeof task.height === "undefined") {
481
- task.height = 0;
482
- }
483
- if (typeof task.mouseOver === "undefined") {
484
- task.mouseOver = false;
485
- }
486
- if (typeof task.collapsed === "undefined") {
487
- task.collapsed = false;
488
- }
489
- if (typeof task.dependentOn === "undefined") {
490
- task.dependentOn = [];
491
- }
492
- if (typeof task.parentId === "undefined") {
493
- task.parentId = null;
494
- }
495
- if (typeof task.style === "undefined") {
496
- task.style = {};
497
- }
498
- if (typeof task.children === "undefined") {
499
- task.children = [];
500
- }
501
- if (typeof task.allChildren === "undefined") {
502
- task.allChildren = [];
503
- }
504
- if (typeof task.parents === "undefined") {
505
- task.parents = [];
506
- }
507
- if (typeof task.parent === "undefined") {
508
- task.parent = null;
509
- }
510
- if (typeof task.startTime === "undefined") {
511
- task.startTime = new Date(task.start).valueOf();
512
- }
513
- if (typeof task.endTime === "undefined" && task.hasOwnProperty("end")) {
514
- task.endTime = new Date(task.end).valueOf();
515
- } else if (typeof task.endTime === "undefined" && task.hasOwnProperty("duration")) {
516
- task.endTime = task.startTime + task.duration - (1 * 24 * 60 * 60 * 1000);
517
- }
518
- if (typeof task.duration === "undefined" && task.hasOwnProperty("endTime")) {
519
- task.duration = task.endTime - task.startTime;
520
- }
521
- }
522
- return tasks;
523
- },
524
- // 时间数据
525
- simpleData () {
526
- // 小于今天
527
- let { count, step, stepKind } = this.computedCountStep;
528
- let data = [
529
- { key: getDate(0),
530
- endKey: getDate((step - 1) * 24 + 23.9999),
531
- name: "今天",
532
- colspan: 1,
533
- fullName: this.$dateFormat(getDate(0), "yyyy-MM-dd"),
534
- style: { color: this.simpleDataColor, fontWeight: 500 },
535
- now: true
536
- }
537
- ];
538
- let preCount = this.preCount * count + count;
539
- let nextCount = this.nextCount * count + count;
540
- for (let i = -step; i >= -(preCount * step); i -= step) {
541
- let key = stepKind === "month" ? getMonth(i) : getDate(i * 24);
542
- data.unshift({
543
- colspan: 1,
544
- key: key,
545
- endKey: getDate((i + step - 1) * 24 + 23.9999),
546
- name: this.getDayName(key, stepKind),
547
- fullName: this.$dateFormat(key, "yyyy-MM-dd"),
548
- style: this.$dateFormat(key, "d") == "1" && { fontWeight: 500 }
549
- });
550
- }
551
- // 大于今天
552
- for (let i = step; i <= nextCount * step; i += step) {
553
- let key = stepKind === "month" ? getMonth(i) : getDate(i * 24);
554
- data.push({
555
- colspan: 1,
556
- key: key,
557
- endKey: getDate((i + step - 1) * 24 + 23.9999),
558
- name: this.getDayName(key, stepKind),
559
- fullName: this.$dateFormat(key, "yyyy-MM-dd"),
560
- style: this.$dateFormat(key, "d") == "1" && { fontWeight: 500 }
561
- });
562
- }
563
- return data;
564
- },
565
- timeData () {
566
- let { count, step, stepKind } = this.computedCountStep;
567
- let data = [];
568
- let preCount = this.preCount * count + count;
569
- let nextCount = this.nextCount * count + count;
570
- let startTime = -(preCount * step); // 个数
571
- let endTime = nextCount * step;
572
- // 年度以月为分隔符
573
- if (stepKind === "month") {
574
- startTime = (getMonth(-preCount) - getMonth(0)) / 24 / 60 / 60 / 1000;
575
- endTime = (getMonth(nextCount) - getMonth(0)) / 24 / 60 / 60 / 1000;
576
- }
577
- for (let i = startTime; i <= endTime; i++) {
578
- let key = getDate(i * 24);
579
- data.push({
580
- now: this.$dateFormat(key, "yyyy-MM-dd") === this.$dateFormat(new Date(), "yyyy-MM-dd"),
581
- key: key,
582
- endKey: getDate(i * 24 + 23.9999),
583
- name: this.getDayName(key, stepKind),
584
- fullName: this.$dateFormat(key, "yyyy-MM-dd")
585
- });
586
- }
587
- return data;
588
- },
589
- // 任务时间结合数据
590
- computedData () {
591
- return this.taskData.map(taskItem => {
592
- let tr = [];
593
- this.timeData.forEach(timeItem => {
594
- let flag = this.filterTaskDate(taskItem, timeItem);
595
- if (flag) {
596
- let isEndStep = new Date(timeItem.endKey) > new Date(taskItem.endTime);
597
- if (tr[tr.length - 1] && tr[tr.length - 1].isApply) {
598
- tr[tr.length - 1].colspan++;
599
- // 判断是不是结束日期,当前节点日期startEnd endTime, endKey
600
- if (isEndStep) {
601
- tr[tr.length - 1].isEndStep = isEndStep;
602
- }
603
- } else {
604
- let defaultStyle = {
605
- background: "rgba(232,243,253,1)",
606
- border: "1px solid rgba(109,174,242,1)",
607
- main: "rgba(109,174,242,1)"
608
- };
609
- let obj = {
610
- colspan: 1,
611
- ...timeItem,
612
- style: taskItem.style || defaultStyle,
613
- task: taskItem,
614
- isApply: true
615
- };
616
- if (isEndStep) {
617
- obj.isEndStep = isEndStep;
618
- }
619
- tr.push(obj);
620
- }
621
-
622
- } else {
623
- let obj = {
624
- colspan: 1,
625
- ...timeItem,
626
- task: taskItem,
627
- isApply: false
628
- };
629
- tr.push(obj);
630
- }
631
- });
632
- return tr;
633
- });
634
- },
635
-
636
- theme () {
637
- return this.propsObj.theme || {};
638
- },
639
- themeName () {
640
- return this.theme.name;
641
- }
642
- },
643
- data () {
644
- return {
645
- // 当前客户端宽度
646
- clientWidth: 0,
647
- // 向下点了几次
648
- nextCount: 0,
649
- // 向上点了几次
650
- preCount: 0,
651
- // 时间维度
652
- dimensionObject: {
653
- doubleWeek: { name: "按周", count: 3, step: 1, stepKind: "day" },
654
- week: { name: "双周", count: 7, step: 1, stepKind: "day" },
655
- month: { name: "按月", count: 7, step: 2, stepKind: "day" },
656
- quarter: { name: "季度", count: 9, step: 5, stepKind: "day" },
657
- year: { name: "按年", count: 6, step: 1, stepKind: "month" }
658
- },
659
- nowOffsetLeft: 0
660
- };
661
- },
662
- created () {
663
- this.init();
664
- },
665
- mounted () {
666
- // 宽度调整
667
- window.onresize = this.refreshWidth;
668
- },
669
- destroyed () {
670
- window.onresize = null;
671
- },
672
- methods: {
673
- init () {
674
- // 赋初值
675
- setTimeout(() => {
676
- this.refreshWidth();
677
- });
678
- },
679
- // 比较时间
680
- filterTaskDate (taskItem, timeItem) {
681
- let flag = (new Date(taskItem.startTime) <= new Date(timeItem.endKey)) && (taskItem.endTime ? ((new Date(timeItem.key) <= new Date(taskItem.endTime))) : taskItem.endInfinite);
682
- return flag;
683
- },
684
- // 获得日期显示格式
685
- getDayName (key, stepKind) {
686
- let name = this.$dateFormat(key, "M月d日");
687
- if (name === "1日") {
688
- name = this.$dateFormat(key, "M月d日");
689
- }
690
- if (stepKind === "month") {
691
- name = this.$dateFormat(key, "M月");
692
- if (name === "1月") {
693
- name = `${this.$dateFormat(key, "yyyy年M月")}`;
694
- }
695
- }
696
- return name;
697
- },
698
- // 左右按钮重置
699
- refreshStepCount () {
700
- this.preCount = 0;
701
- this.nextCount = 0;
702
- },
703
- // 重新计算宽度
704
- refreshWidth () {
705
- this.clientWidth = this.$refs.briGanttArea ? this.$refs.briGanttArea.clientWidth : 0;
706
- },
707
- // 重新渲染
708
- refresh () {
709
-
710
- },
711
- // 绑定同步滚动
712
- handleScroll (el, scrollList) {
713
- scrollList.forEach(({ref, direction} = item) => {
714
- this.$refs[ref] && (this.$refs[ref][direction] = el.target[direction]);
715
- });
716
- },
717
- // 点击上一节点
718
- preTime () {
719
- let briGanttTimer = this.$refs.briGanttTimer;
720
- let timerWidth = briGanttTimer.clientWidth; // 盒子宽度
721
- let scrollLeft = briGanttTimer.scrollLeft; // 滚动距离
722
- if (scrollLeft === 0) {
723
- // 已经滑到尽头,加载时间数据
724
- this.preCount++;
725
- this.$nextTick(() => {
726
- this.slideTo(briGanttTimer, scrollLeft - timerWidth);
727
- });
728
- } else {
729
- this.slideTo(briGanttTimer, scrollLeft - timerWidth);
730
- }
731
- },
732
- // 点击下一节点
733
- nextTime () {
734
- let briGanttTimer = this.$refs.briGanttTimer;
735
- let timerWidth = briGanttTimer.clientWidth; // 盒子宽度
736
- let tableWidth = parseInt(this.tableWidth); // table 总宽度
737
- let scrollLeft = briGanttTimer.scrollLeft; // 滚动距离
738
- let distance = tableWidth - timerWidth; // 当前滚动条距离顶部的距离
739
- if (scrollLeft < distance) {
740
- // 未滑到尽头
741
- this.slideTo(briGanttTimer, scrollLeft + timerWidth);
742
- } else {
743
- // 已经滑到尽头,加载时间数据
744
- this.nextCount++;
745
- this.$nextTick(() => {
746
- this.slideTo(briGanttTimer, scrollLeft + timerWidth);
747
- });
748
- }
749
- },
750
- // 滚动到指定位置 增加滚动效果
751
- slideTo (ref, target) {
752
- let currScrollLeft = ref.scrollLeft; // 当前的距离
753
- let distance = target - currScrollLeft;
754
- let speed = distance / 10; // 每时刻速度
755
- let speedTarget = currScrollLeft + speed;
756
- let timer = setInterval(function () {
757
- if (distance > 0 ? (speedTarget > target) : (speedTarget < target)) {
758
- clearInterval(timer);
759
- } else {
760
- ref.scrollTo(speedTarget, 0);
761
- speedTarget += speed;
762
- }
763
- }, 10);
764
- },
765
- // 行点击
766
- clickRow (col) {
767
- this.canClick && this.$emit("clickRow", col.task, col);
768
- }
769
- }
770
- };
771
- </script>
772
-
773
- <style lang="less">
774
- .briGantt {
775
- width: 100%;
776
- height: 100%;
777
- color: #656565;
778
- font-size: @smallSize;
779
- line-height: 28px;
780
- position: relative;
781
- display: flex;
782
- overflow: auto;
783
- flex-direction: column;
784
-
785
- &-top {
786
- display: flex;
787
- height: 100%;
788
- width: 100%;
789
- justify-content: space-between;
790
- position: absolute;
791
- }
792
-
793
- &-bottom {
794
- width: 100%;
795
- overflow: auto;
796
- display: flex;
797
- flex-direction: column;
798
- margin-top: 38px;
799
- background: @white;
800
-
801
- &-title {
802
- text-align: center;
803
- border: 1px solid #EDEDED;
804
- border-bottom: none;
805
- line-height: 27px;
806
- // margin: 10px 14px 0 14px;
807
- }
808
-
809
- &-content {
810
- flex: 1;
811
- display: flex;
812
- overflow: auto;
813
- }
814
- }
815
-
816
- // 表格渲染
817
- &-tableBox {
818
- width: 100%;
819
- text-align: center;
820
- border-collapse: collapse;
821
- border-spacing: 0;
822
-
823
- td,
824
- th {
825
- word-break: break-all;
826
- word-wrap: break-word;
827
- min-width: 50px;
828
- height: 29px;
829
- text-align: center;
830
- // overflow: hidden;
831
- white-space: nowrap;
832
- text-overflow: ellipsis;
833
- max-width: 200px;
834
- }
835
-
836
- .briGantt-chart-td {
837
- height: 40px;
838
- }
839
-
840
- .briGantt-table-th-now {
841
- color: @themeColor;
842
- }
843
- }
844
-
845
- &-table {
846
- &-tr {
847
- border: 1px solid #EDEDED;
848
- }
849
-
850
- &-tr:nth-child(2n) {
851
- background: rgba(244, 246, 249, 0.5119);
852
- }
853
-
854
- &-th {
855
- background: #F4F8FF;
856
- font-weight: 400;
857
- color: rgba(101, 101, 101, 1);
858
- }
859
-
860
- &-td {
861
- border-right: 1px solid #EDEDED;
862
- font-weight: 400;
863
- color: rgba(111, 111, 111, 1);
864
-
865
- &-main {
866
- height: 28px;
867
- background: rgba(238, 238, 238, 0.5);
868
- border: 1px solid #f6f6f6;
869
- }
870
- }
871
-
872
- &-td:last-of-type {
873
- border: none;
874
- }
875
- }
876
-
877
- &-chart {
878
- &-td {
879
- overflow: visible;
880
-
881
- &-greyLine {
882
- border-top: 1px dashed #D5D5D5;
883
- }
884
-
885
- &-main {
886
- display: flex;
887
- width: 100%;
888
- height: 100%;
889
- align-items: center;
890
- justify-content: center;
891
-
892
- &-left,
893
- &-right {
894
- height: 100%;
895
- overflow: hidden;
896
- }
897
-
898
- &-right-auto {
899
- height: 100%;
900
- overflow: hidden;
901
- flex: 1;
902
- }
903
-
904
- &-center {
905
- height: 30px;
906
- border-radius: 4px;
907
- background: #f6f6f6;
908
- z-index: 1;
909
- min-width: 2px;
910
-
911
- .ms-ellipsis {
912
- border-radius: 4px;
913
- height: 100%;
914
- color: @white;
915
- text-align: left;
916
- padding-left: 10px;
917
- white-space: nowrap;
918
- text-overflow: ellipsis;
919
- overflow: hidden;
920
- }
921
-
922
- &-tooltip {
923
- white-space: normal;
924
-
925
- &-select {
926
- height: 5px;
927
- display: inline-block;
928
- vertical-align: middle;
929
- width: 5px;
930
- border-radius: 50%;
931
- }
932
- }
933
- }
934
-
935
- &-line {
936
- width: 100%;
937
- border-bottom: 1px solid #D5D5D5;
938
- font-weight: 400;
939
- color: rgba(74, 74, 74, 1);
940
- padding: 0 10px;
941
- transform: translateY(15px);
942
- text-align: left;
943
- height: 29px;
944
- font-size: @smallSize;
945
- white-space: nowrap;
946
- text-overflow: ellipsis;
947
- overflow: hidden;
948
-
949
- &-circle {
950
- display: block;
951
- width: 10px;
952
- height: 100%;
953
- min-width: 10px;
954
-
955
- .circle {
956
- display: block;
957
- width: 10px;
958
- height: 10px;
959
- border-radius: 50%;
960
- min-width: 10px;
961
- margin-top: 38px;
962
- background: #D5D5D5;
963
- }
964
- }
965
- }
966
-
967
- ;
968
- }
969
- }
970
- }
971
-
972
- // 蓝色虚线
973
- &-line-now {
974
- z-index: 9;
975
- text-align: center;
976
- background: transparent;
977
-
978
- &::before {
979
- content: "";
980
- border-left: 1px dashed @themeColor;
981
- position: absolute;
982
- top: 25px;
983
- bottom: 0px;
984
- z-index: 9;
985
- }
986
-
987
- &::after {
988
- content: "";
989
- width: 6px;
990
- height: 6px;
991
- border-radius: 6px;
992
- background: @themeColor;
993
- position: absolute;
994
- top: 25px;
995
- margin-left: -3px;
996
- }
997
- }
998
-
999
- // 时间轴
1000
- &-timer {
1001
- align-items: center;
1002
- position: relative;
1003
- float: right;
1004
- overflow: hidden;
1005
-
1006
- &-main {
1007
- overflow: auto;
1008
- flex: 1;
1009
- height: 100%;
1010
- position: relative;
1011
- }
1012
-
1013
- &-bg {
1014
- position: absolute;
1015
- background: #F4F8FF;
1016
- left: 0px;
1017
- right: 0px;
1018
- height: 28px;
1019
- border-radius: 28px;
1020
- }
1021
-
1022
- &-icon {
1023
- background: #F4F8FF;
1024
- color: #fff;
1025
- width: 28px;
1026
- height: 28px;
1027
- min-width: 28px;
1028
- display: flex;
1029
- align-items: center;
1030
- justify-content: center;
1031
- position: absolute;
1032
- z-index: 2;
1033
- top: 0px;
1034
- background: #F2F8FF;
1035
-
1036
- &:hover {
1037
- color: #fff;
1038
- }
1039
-
1040
- i {
1041
- display: block;
1042
- width: 16px;
1043
- height: 16px;
1044
- border-radius: 16px;
1045
- font-size: 13px;
1046
- background: @themeColor;
1047
- display: flex;
1048
- align-items: center;
1049
- justify-content: center;
1050
- }
1051
-
1052
- &-left {
1053
- left: -1px;
1054
- border-top-left-radius: 28px;
1055
- border-bottom-left-radius: 28px;
1056
- }
1057
-
1058
- &-right {
1059
- right: -1px;
1060
- border-top-right-radius: 28px;
1061
- border-bottom-right-radius: 28px;
1062
- }
1063
- }
1064
- }
1065
-
1066
- // 区域映射
1067
- &-data {
1068
- flex: 1;
1069
- overflow: auto;
1070
- position: relative;
1071
-
1072
- &-table {}
1073
-
1074
- &-chart {}
1075
-
1076
- &::-webkit-scrollbar {
1077
- height: 0px;
1078
- }
1079
- }
1080
-
1081
- // table 列表映射
1082
- &-tabledata {
1083
- overflow-y: auto;
1084
- border-right: none;
1085
- }
1086
- }
1087
- </style>
1
+ <template>
2
+ <div class="briGantt">
3
+ <div class="briGantt-top">
4
+ <div class="bri-scrollbar0">
5
+ <slot></slot>
6
+ </div>
7
+ <!-- 时间渲染 -->
8
+ <div
9
+ class="briGantt-timer"
10
+ :style="{width: clientWidth + 'px'}"
11
+ >
12
+ <a
13
+ class="briGantt-timer-icon briGantt-timer-icon-left"
14
+ @click="preTime"
15
+ >
16
+ <Icon type="ios-arrow-back" />
17
+ </a>
18
+ <div class="briGantt-timer-bg"></div>
19
+ <div
20
+ class="bri-scrollbar0 briGantt-timer-main"
21
+ ref="briGanttTimer"
22
+ v-on:scroll="handleScroll($event, [{ ref: 'briGanttArea', direction: 'scrollLeft' }])"
23
+ >
24
+ <table
25
+ :style="{tableLayout:'fixed', width: tableWidth}"
26
+ class="briGantt-tableBox"
27
+ >
28
+ <thead class="briGantt-table-thead">
29
+ <tr>
30
+ <th
31
+ class="briGantt-table-th"
32
+ v-for="timeItem in simpleData"
33
+ :key="timeItem.key"
34
+ :colspan="timeItem.colspan"
35
+ :style="{...timeItem.style}"
36
+ >
37
+ <Tooltip
38
+ :content="timeItem.fullName"
39
+ placement="top"
40
+ :transfer="true"
41
+ :transfer-class-name="`briGantt-transfer-tooltip-${themeName}`"
42
+ >
43
+ {{ timeItem.name }}
44
+ </Tooltip>
45
+ <div
46
+ v-if="timeItem.now"
47
+ class="briGantt-line-now"
48
+ ></div>
49
+ </th>
50
+ </tr>
51
+ </thead>
52
+ </table>
53
+ </div>
54
+ <a
55
+ class="briGantt-timer-icon briGantt-timer-icon-right"
56
+ @click="nextTime"
57
+ >
58
+ <Icon type="ios-arrow-forward" />
59
+ </a>
60
+ </div>
61
+ </div>
62
+ <div class="briGantt-bottom">
63
+ <div
64
+ class="briGantt-bottom-title"
65
+ v-if="title"
66
+ >{{ title }}</div>
67
+ <div class="briGantt-bottom-content">
68
+ <!-- 数据映射 -->
69
+ <div
70
+ v-if="table"
71
+ class="bri-scrollbar0 briGantt-tabledata"
72
+ ref="briGanttColumn"
73
+ v-on:scroll="handleScroll($event, [{ ref: 'briGanttArea', direction: 'scrollTop' }])"
74
+ >
75
+ <table class="briGantt-tableBox briGantt-table">
76
+ <tbody>
77
+ <tr
78
+ class="briGantt-table-tr"
79
+ v-for="(row, rowIndex) in table"
80
+ :key="rowIndex"
81
+ >
82
+ <td
83
+ class="briGantt-table-td"
84
+ v-for="(col, colIndex) in row"
85
+ :key="colIndex"
86
+ :colspan="col.colspan"
87
+ :rowspan="col.rowspan"
88
+ :style="col.rowspan > 1 ? {background: '#fff',padding: '0 10px',fontWeight:500} : {padding: '0 10px'}"
89
+ v-html="col.label"
90
+ ></td>
91
+ </tr>
92
+ </tbody>
93
+ </table>
94
+ </div>
95
+ <!-- 区域映射 -->
96
+ <div
97
+ class="briGantt-data bri-scrollbar"
98
+ :class="`briGantt-data-${type}`"
99
+ ref="briGanttArea"
100
+ v-on:scroll="handleScroll($event, [{ ref: 'briGanttTimer', direction: 'scrollLeft' }, { ref:'briGanttColumn', direction:'scrollTop' }, { ref:'briGanttScrollbar', direction:'scrollLeft' }])"
101
+ >
102
+ <table
103
+ :style="{tableLayout:'fixed', width: tableWidth}"
104
+ class="briGantt-tableBox briGantt-table"
105
+ border="0"
106
+ cellspacing="0"
107
+ cellpadding="0"
108
+ >
109
+ <tr v-if="computedData.length === 0">
110
+ <td
111
+ :colspan="timeData.length"
112
+ class="briGantt-table-td"
113
+ >暂无内容</td>
114
+ </tr>
115
+ <tbody v-if="type==='table'">
116
+ <tr v-if="computedData.length === 0">
117
+ <td
118
+ :colspan="timeData.length"
119
+ class="briGantt-table-td"
120
+ >暂无内容</td>
121
+ </tr>
122
+ <tr
123
+ class="briGantt-table-tr"
124
+ v-for="(taskItem, taskIndex) in computedData"
125
+ :key="taskIndex"
126
+ style="border-left: none"
127
+ >
128
+ <td
129
+ class="briGantt-table-td"
130
+ v-for="(timeItem, timeIndex) in taskItem"
131
+ :key="timeIndex"
132
+ :colspan="timeItem.colspan"
133
+ >
134
+ <slot
135
+ v-if="timeItem.isApply"
136
+ name="table"
137
+ v-bind:task="timeItem.task"
138
+ v-bind:time="timeItem"
139
+ >
140
+ <div
141
+ class="briGantt-table-td-main"
142
+ :style="timeItem.style"
143
+ ></div>
144
+ </slot>
145
+ <slot
146
+ v-else
147
+ name="tabletd"
148
+ v-bind:preTime="taskItem[timeIndex-1]"
149
+ v-bind:nextTime="taskItem[timeIndex+1]"
150
+ v-bind:task="timeItem.task"
151
+ v-bind:time="timeItem"
152
+ ></slot>
153
+ </td>
154
+ </tr>
155
+ </tbody>
156
+ <tbody v-else-if="type==='chart'">
157
+ <tr
158
+ class="briGantt-chart-tr"
159
+ v-for="(taskItem, taskIndex) in computedData"
160
+ :key="taskIndex"
161
+ >
162
+ <td
163
+ class="briGantt-chart-td"
164
+ v-for="(timeItem, timeIndex) in taskItem"
165
+ :key="timeIndex"
166
+ :colspan="timeItem.colspan"
167
+ >
168
+ <div
169
+ v-if="timeItem.isApply"
170
+ class="briGantt-chart-td-main"
171
+ >
172
+ <slot
173
+ name="chart"
174
+ v-bind:task="timeItem.task"
175
+ v-bind:chartItem="timeItem"
176
+ >
177
+ <Tooltip
178
+ placement="right"
179
+ transfer
180
+ :transfer-class-name="`briGantt-transfer-tooltip-${themeName}`"
181
+ style="width:100%"
182
+ >
183
+ <div
184
+ class="briGantt-chart-td-main-center"
185
+ :style="{
186
+ background:$getColor(timeItem.style.background),
187
+ minWidth: minTdWidth,
188
+ border: `1px solid ${timeItem.style.background}`,
189
+ padding: timeItem.task.progressField == 100 ? '' : '1px',
190
+ cursor: canClick ? 'pointer' : ''
191
+ }"
192
+ @click="clickRow(timeItem)"
193
+ >
194
+ <slot
195
+ name="chartCenter"
196
+ v-bind:task="timeItem.task"
197
+ v-bind:chartItem="timeItem"
198
+ >
199
+ <div
200
+ class="ms-ellipsis"
201
+ :style="{
202
+ background:timeItem.style.background,
203
+ width: `${timeItem.task.progressField}%`
204
+ }"
205
+ >
206
+ {{ timeItem.task.label }}
207
+ </div>
208
+ </slot>
209
+ </div>
210
+ <div
211
+ slot="content"
212
+ class="briGantt-chart-td-main-center-tooltip"
213
+ >
214
+ <span
215
+ class="briGantt-chart-td-main-center-tooltip-select"
216
+ :style="{...timeItem.style}"
217
+ >
218
+ </span>
219
+ {{timeItem.task.select}}
220
+ <div>完成度:{{timeItem.task.progressField}}%</div>
221
+ <div>{{ timeItem.task.label }}</div>
222
+ </div>
223
+ </Tooltip>
224
+ </slot>
225
+ </div>
226
+ <slot
227
+ v-else
228
+ name="charttd"
229
+ v-bind:task="timeItem.task"
230
+ v-bind:time="timeItem"
231
+ v-bind:preTime="taskItem[timeIndex-1]"
232
+ v-bind:nextTime="taskItem[timeIndex+1]"
233
+ >
234
+ <div class="briGantt-chart-td-greyLine"></div>
235
+ </slot>
236
+ </td>
237
+ </tr>
238
+ </tbody>
239
+ </table>
240
+ </div>
241
+ </div>
242
+
243
+ <!-- 底部滚动条 -->
244
+ <!-- <div class="briGantt-scroll">
245
+ <div class="briGantt-scroll-main"
246
+ ref="briGanttScrollbar"
247
+ :style="{ width: clientWidth + 'px' }"
248
+ v-on:scroll="handleScroll($event, [{ ref: 'briGanttTimer', direction: 'scrollLeft' }, { ref:'briGanttArea', direction:'scrollLeft' }, { ref:'briGanttBlue', direction:'scrollLeft' }])">
249
+ <div :style="{width: tableWidth}"></div>
250
+ </div>
251
+ </div> -->
252
+ </div>
253
+ </div>
254
+ </template>
255
+ <script>
256
+ function getDate (hours) {
257
+ const currentDate = new Date();
258
+ const currentYear = currentDate.getFullYear();
259
+ const currentMonth = currentDate.getMonth();
260
+ const currentDay = currentDate.getDate();
261
+ const timeStamp = new Date(
262
+ currentYear,
263
+ currentMonth,
264
+ currentDay,
265
+ 0,
266
+ 0,
267
+ 0
268
+ ).getTime();
269
+ return new Date(timeStamp + hours * 60 * 60 * 1000).getTime();
270
+ }
271
+ function getMonth (N) {
272
+ const currentDate = new Date();
273
+ const currentYear = currentDate.getFullYear();
274
+ const currentMonth = currentDate.getMonth();
275
+ return new Date(currentYear, currentMonth + N, 1).getTime();
276
+ }
277
+ // 示例数据
278
+ let tasks = [
279
+ {
280
+ id: 1,
281
+ label: "Make some noise",
282
+ user:
283
+ '<a href="https://www.google.com/search?q=John+Doe" target="_blank" style="color:#0077c0;">John Doe</a>',
284
+ start: getDate(-24 * 5),
285
+ end: getDate(0),
286
+ select: "紧急",
287
+ duration: 15 * 24 * 60 * 60 * 1000,
288
+ percent: 85,
289
+ type: "project",
290
+ style: {
291
+ background: "orange",
292
+ main: "rgba(109,174,242,1)"
293
+ }
294
+ // collapsed: true,
295
+ },
296
+ {
297
+ id: 2,
298
+ label: "With great power comes great responsibility",
299
+ user:
300
+ '<a href="https://www.google.com/search?q=Peter+Parker" target="_blank" style="color:#0077c0;">Peter Parker</a>',
301
+ parentId: 1,
302
+ start: getDate(-24 * 20),
303
+ duration: 20 * 24 * 60 * 60 * 1000,
304
+ percent: 50,
305
+ select: "重要",
306
+ type: "milestone",
307
+ collapsed: true,
308
+ style: {
309
+ background: "red",
310
+ main: "rgba(240,143,145,1)"
311
+ }
312
+ },
313
+ {
314
+ id: 3,
315
+ label: "Courage is being scared to death, but saddling up anyway.",
316
+ user:
317
+ '<a href="https://www.google.com/search?q=John+Wayne" target="_blank" style="color:#0077c0;">John Wayne</a>',
318
+ parentId: 2,
319
+ select: "普通",
320
+ start: getDate(-24 * 3),
321
+ duration: 2 * 24 * 60 * 60 * 1000,
322
+ percent: 100,
323
+ type: "task",
324
+ style: {
325
+ background: "rgba(255,248,242,1)",
326
+ main: "rgba(255,190,114,1)"
327
+ }
328
+ },
329
+ {
330
+ id: 4,
331
+ label: "Put that toy AWAY!",
332
+ user:
333
+ '<a href="https://www.google.com/search?q=Clark+Kent" target="_blank" style="color:#0077c0;">Clark Kent</a>',
334
+ start: getDate(-24 * 2),
335
+ duration: 2 * 24 * 60 * 60 * 1000,
336
+ select: "紧急",
337
+ percent: 50,
338
+ type: "task",
339
+ dependentOn: [3],
340
+ style: {
341
+ background: "rgba(235,248,240,1)",
342
+ main: "rgba(137,213,166,1)"
343
+ }
344
+ },
345
+ {
346
+ id: 5,
347
+ label: "Put that toy AWAY!",
348
+ select: "紧急",
349
+ user:
350
+ '<a href="https://www.google.com/search?q=Clark+Kent" target="_blank" style="color:#0077c0;">Clark Kent</a>',
351
+ start: getDate(1 * 24),
352
+ end: getDate(1 * 24),
353
+ // duration: 1 * 24 * 60 * 60 * 1000,
354
+ percent: 50,
355
+ type: "task",
356
+ dependentOn: [3],
357
+ style: {
358
+ background: "rgba(235,248,240,1)",
359
+ main: "rgba(137,213,166,1)"
360
+ }
361
+ }
362
+ ];
363
+
364
+ export default {
365
+ name: "briGantt",
366
+ components: {},
367
+ props: {
368
+ simpleDataColor: {
369
+ type: String,
370
+ default: "#3DB8C5"
371
+ },
372
+
373
+ tasks: Array,
374
+ options: {
375
+ type: Object,
376
+ default () {
377
+ return {};
378
+ }
379
+ },
380
+ value: {
381
+ type: Object,
382
+ default () {
383
+ return {};
384
+ }
385
+ },
386
+ propsObj: {
387
+ type: Object,
388
+ default () {
389
+ return {};
390
+ }
391
+ },
392
+ // 是否展示示例数据
393
+ showEs: {
394
+ type: Boolean,
395
+ default: false
396
+ },
397
+ title: String,
398
+ // 展示类型, 分图标和表格,默认表格
399
+ type: {
400
+ type: String,
401
+ default: "table"
402
+ },
403
+ dimension: {
404
+ type: String,
405
+ default: "quarter"
406
+ },
407
+ showCloumns: {
408
+ type: Boolean,
409
+ default: true
410
+ },
411
+ table: Array,
412
+ // 距离今天个数
413
+ count: {
414
+ type: Number,
415
+ default: 5
416
+ },
417
+ // 展示日期间隔
418
+ step: {
419
+ type: Number,
420
+ default: 1
421
+ },
422
+ canClick: {
423
+ type: Boolean,
424
+ default: false
425
+ }
426
+ },
427
+ computed: {
428
+ // 默认列表
429
+ defaultTasks () {
430
+ if (this.showEs) {
431
+ return tasks;
432
+ } else {
433
+ return this.tasks || [];
434
+ }
435
+ },
436
+ // 表格宽度
437
+ tableWidth () {
438
+ let timeDataWidth = this.simpleData.length * 50;
439
+ let clientWidth = this.clientWidth;
440
+ if (this.computedCountStep.stepKind === "month") {
441
+ timeDataWidth = this.timeData.length * 3;
442
+ }
443
+ if (timeDataWidth < clientWidth) {
444
+ return "100%";
445
+ } else {
446
+ return timeDataWidth + "px";
447
+ }
448
+ },
449
+ minTdWidth () {
450
+ let minWidth = 2;
451
+ if (this.tableWidth.includes("px")) {
452
+ minWidth = parseInt(this.tableWidth) / this.timeData.length;
453
+ } else {
454
+ minWidth = parseInt(this.clientWidth) / this.timeData.length;
455
+ }
456
+ minWidth > 20 && (minWidth = 2);
457
+ return minWidth + "px";
458
+ },
459
+ // 间隔及时间,当前选择时间维度
460
+ computedCountStep () {
461
+ this.refreshStepCount();
462
+ return this.dimensionObject[this.dimension] || { count: this.count, step: this.step };
463
+ },
464
+ // 任务数据
465
+ taskData () {
466
+ /**
467
+ * task 默认数据
468
+ */
469
+ let tasks = this.defaultTasks;
470
+ for (let task of tasks) {
471
+ if (typeof task.x === "undefined") {
472
+ task.x = 0;
473
+ }
474
+ if (typeof task.y === "undefined") {
475
+ task.y = 0;
476
+ }
477
+ if (typeof task.width === "undefined") {
478
+ task.width = 0;
479
+ }
480
+ if (typeof task.height === "undefined") {
481
+ task.height = 0;
482
+ }
483
+ if (typeof task.mouseOver === "undefined") {
484
+ task.mouseOver = false;
485
+ }
486
+ if (typeof task.collapsed === "undefined") {
487
+ task.collapsed = false;
488
+ }
489
+ if (typeof task.dependentOn === "undefined") {
490
+ task.dependentOn = [];
491
+ }
492
+ if (typeof task.parentId === "undefined") {
493
+ task.parentId = null;
494
+ }
495
+ if (typeof task.style === "undefined") {
496
+ task.style = {};
497
+ }
498
+ if (typeof task.children === "undefined") {
499
+ task.children = [];
500
+ }
501
+ if (typeof task.allChildren === "undefined") {
502
+ task.allChildren = [];
503
+ }
504
+ if (typeof task.parents === "undefined") {
505
+ task.parents = [];
506
+ }
507
+ if (typeof task.parent === "undefined") {
508
+ task.parent = null;
509
+ }
510
+ if (typeof task.startTime === "undefined") {
511
+ task.startTime = new Date(task.start).valueOf();
512
+ }
513
+ if (typeof task.endTime === "undefined" && task.hasOwnProperty("end")) {
514
+ task.endTime = new Date(task.end).valueOf();
515
+ } else if (typeof task.endTime === "undefined" && task.hasOwnProperty("duration")) {
516
+ task.endTime = task.startTime + task.duration - (1 * 24 * 60 * 60 * 1000);
517
+ }
518
+ if (typeof task.duration === "undefined" && task.hasOwnProperty("endTime")) {
519
+ task.duration = task.endTime - task.startTime;
520
+ }
521
+ }
522
+ return tasks;
523
+ },
524
+ // 时间数据
525
+ simpleData () {
526
+ // 小于今天
527
+ let { count, step, stepKind } = this.computedCountStep;
528
+ let data = [
529
+ { key: getDate(0),
530
+ endKey: getDate((step - 1) * 24 + 23.9999),
531
+ name: "今天",
532
+ colspan: 1,
533
+ fullName: this.$dateFormat(getDate(0), "yyyy-MM-dd"),
534
+ style: { color: this.simpleDataColor, fontWeight: 500 },
535
+ now: true
536
+ }
537
+ ];
538
+ let preCount = this.preCount * count + count;
539
+ let nextCount = this.nextCount * count + count;
540
+ for (let i = -step; i >= -(preCount * step); i -= step) {
541
+ let key = stepKind === "month" ? getMonth(i) : getDate(i * 24);
542
+ data.unshift({
543
+ colspan: 1,
544
+ key: key,
545
+ endKey: getDate((i + step - 1) * 24 + 23.9999),
546
+ name: this.getDayName(key, stepKind),
547
+ fullName: this.$dateFormat(key, "yyyy-MM-dd"),
548
+ style: this.$dateFormat(key, "d") == "1" && { fontWeight: 500 }
549
+ });
550
+ }
551
+ // 大于今天
552
+ for (let i = step; i <= nextCount * step; i += step) {
553
+ let key = stepKind === "month" ? getMonth(i) : getDate(i * 24);
554
+ data.push({
555
+ colspan: 1,
556
+ key: key,
557
+ endKey: getDate((i + step - 1) * 24 + 23.9999),
558
+ name: this.getDayName(key, stepKind),
559
+ fullName: this.$dateFormat(key, "yyyy-MM-dd"),
560
+ style: this.$dateFormat(key, "d") == "1" && { fontWeight: 500 }
561
+ });
562
+ }
563
+ return data;
564
+ },
565
+ timeData () {
566
+ let { count, step, stepKind } = this.computedCountStep;
567
+ let data = [];
568
+ let preCount = this.preCount * count + count;
569
+ let nextCount = this.nextCount * count + count;
570
+ let startTime = -(preCount * step); // 个数
571
+ let endTime = nextCount * step;
572
+ // 年度以月为分隔符
573
+ if (stepKind === "month") {
574
+ startTime = (getMonth(-preCount) - getMonth(0)) / 24 / 60 / 60 / 1000;
575
+ endTime = (getMonth(nextCount) - getMonth(0)) / 24 / 60 / 60 / 1000;
576
+ }
577
+ for (let i = startTime; i <= endTime; i++) {
578
+ let key = getDate(i * 24);
579
+ data.push({
580
+ now: this.$dateFormat(key, "yyyy-MM-dd") === this.$dateFormat(new Date(), "yyyy-MM-dd"),
581
+ key: key,
582
+ endKey: getDate(i * 24 + 23.9999),
583
+ name: this.getDayName(key, stepKind),
584
+ fullName: this.$dateFormat(key, "yyyy-MM-dd")
585
+ });
586
+ }
587
+ return data;
588
+ },
589
+ // 任务时间结合数据
590
+ computedData () {
591
+ return this.taskData.map(taskItem => {
592
+ let tr = [];
593
+ this.timeData.forEach(timeItem => {
594
+ let flag = this.filterTaskDate(taskItem, timeItem);
595
+ if (flag) {
596
+ let isEndStep = new Date(timeItem.endKey) > new Date(taskItem.endTime);
597
+ if (tr[tr.length - 1] && tr[tr.length - 1].isApply) {
598
+ tr[tr.length - 1].colspan++;
599
+ // 判断是不是结束日期,当前节点日期startEnd endTime, endKey
600
+ if (isEndStep) {
601
+ tr[tr.length - 1].isEndStep = isEndStep;
602
+ }
603
+ } else {
604
+ let defaultStyle = {
605
+ background: "rgba(232,243,253,1)",
606
+ border: "1px solid rgba(109,174,242,1)",
607
+ main: "rgba(109,174,242,1)"
608
+ };
609
+ let obj = {
610
+ colspan: 1,
611
+ ...timeItem,
612
+ style: taskItem.style || defaultStyle,
613
+ task: taskItem,
614
+ isApply: true
615
+ };
616
+ if (isEndStep) {
617
+ obj.isEndStep = isEndStep;
618
+ }
619
+ tr.push(obj);
620
+ }
621
+
622
+ } else {
623
+ let obj = {
624
+ colspan: 1,
625
+ ...timeItem,
626
+ task: taskItem,
627
+ isApply: false
628
+ };
629
+ tr.push(obj);
630
+ }
631
+ });
632
+ return tr;
633
+ });
634
+ },
635
+
636
+ theme () {
637
+ return this.propsObj.theme || {};
638
+ },
639
+ themeName () {
640
+ return this.theme.name;
641
+ }
642
+ },
643
+ data () {
644
+ return {
645
+ // 当前客户端宽度
646
+ clientWidth: 0,
647
+ // 向下点了几次
648
+ nextCount: 0,
649
+ // 向上点了几次
650
+ preCount: 0,
651
+ // 时间维度
652
+ dimensionObject: {
653
+ doubleWeek: { name: "按周", count: 3, step: 1, stepKind: "day" },
654
+ week: { name: "双周", count: 7, step: 1, stepKind: "day" },
655
+ month: { name: "按月", count: 7, step: 2, stepKind: "day" },
656
+ quarter: { name: "季度", count: 9, step: 5, stepKind: "day" },
657
+ year: { name: "按年", count: 6, step: 1, stepKind: "month" }
658
+ },
659
+ nowOffsetLeft: 0
660
+ };
661
+ },
662
+ created () {
663
+ this.init();
664
+ },
665
+ mounted () {
666
+ // 宽度调整
667
+ window.onresize = this.refreshWidth;
668
+ },
669
+ destroyed () {
670
+ window.onresize = null;
671
+ },
672
+ methods: {
673
+ init () {
674
+ // 赋初值
675
+ setTimeout(() => {
676
+ this.refreshWidth();
677
+ });
678
+ },
679
+ // 比较时间
680
+ filterTaskDate (taskItem, timeItem) {
681
+ let flag = (new Date(taskItem.startTime) <= new Date(timeItem.endKey)) && (taskItem.endTime ? ((new Date(timeItem.key) <= new Date(taskItem.endTime))) : taskItem.endInfinite);
682
+ return flag;
683
+ },
684
+ // 获得日期显示格式
685
+ getDayName (key, stepKind) {
686
+ let name = this.$dateFormat(key, "M月d日");
687
+ if (name === "1日") {
688
+ name = this.$dateFormat(key, "M月d日");
689
+ }
690
+ if (stepKind === "month") {
691
+ name = this.$dateFormat(key, "M月");
692
+ if (name === "1月") {
693
+ name = `${this.$dateFormat(key, "yyyy年M月")}`;
694
+ }
695
+ }
696
+ return name;
697
+ },
698
+ // 左右按钮重置
699
+ refreshStepCount () {
700
+ this.preCount = 0;
701
+ this.nextCount = 0;
702
+ },
703
+ // 重新计算宽度
704
+ refreshWidth () {
705
+ this.clientWidth = this.$refs.briGanttArea ? this.$refs.briGanttArea.clientWidth : 0;
706
+ },
707
+ // 重新渲染
708
+ refresh () {
709
+
710
+ },
711
+ // 绑定同步滚动
712
+ handleScroll (el, scrollList) {
713
+ scrollList.forEach(({ ref, direction } = item) => {
714
+ this.$refs[ref] && (this.$refs[ref][direction] = el.target[direction]);
715
+ });
716
+ },
717
+ // 点击上一节点
718
+ preTime () {
719
+ let briGanttTimer = this.$refs.briGanttTimer;
720
+ let timerWidth = briGanttTimer.clientWidth; // 盒子宽度
721
+ let scrollLeft = briGanttTimer.scrollLeft; // 滚动距离
722
+ if (scrollLeft === 0) {
723
+ // 已经滑到尽头,加载时间数据
724
+ this.preCount++;
725
+ this.$nextTick(() => {
726
+ this.slideTo(briGanttTimer, scrollLeft - timerWidth);
727
+ });
728
+ } else {
729
+ this.slideTo(briGanttTimer, scrollLeft - timerWidth);
730
+ }
731
+ },
732
+ // 点击下一节点
733
+ nextTime () {
734
+ let briGanttTimer = this.$refs.briGanttTimer;
735
+ let timerWidth = briGanttTimer.clientWidth; // 盒子宽度
736
+ let tableWidth = parseInt(this.tableWidth); // table 总宽度
737
+ let scrollLeft = briGanttTimer.scrollLeft; // 滚动距离
738
+ let distance = tableWidth - timerWidth; // 当前滚动条距离顶部的距离
739
+ if (scrollLeft < distance) {
740
+ // 未滑到尽头
741
+ this.slideTo(briGanttTimer, scrollLeft + timerWidth);
742
+ } else {
743
+ // 已经滑到尽头,加载时间数据
744
+ this.nextCount++;
745
+ this.$nextTick(() => {
746
+ this.slideTo(briGanttTimer, scrollLeft + timerWidth);
747
+ });
748
+ }
749
+ },
750
+ // 滚动到指定位置 增加滚动效果
751
+ slideTo (ref, target) {
752
+ let currScrollLeft = ref.scrollLeft; // 当前的距离
753
+ let distance = target - currScrollLeft;
754
+ let speed = distance / 10; // 每时刻速度
755
+ let speedTarget = currScrollLeft + speed;
756
+ let timer = setInterval(function () {
757
+ if (distance > 0 ? (speedTarget > target) : (speedTarget < target)) {
758
+ clearInterval(timer);
759
+ } else {
760
+ ref.scrollTo(speedTarget, 0);
761
+ speedTarget += speed;
762
+ }
763
+ }, 10);
764
+ },
765
+ // 行点击
766
+ clickRow (col) {
767
+ this.canClick && this.$emit("clickRow", col.task, col);
768
+ }
769
+ }
770
+ };
771
+ </script>
772
+
773
+ <style lang="less">
774
+ .briGantt {
775
+ width: 100%;
776
+ height: 100%;
777
+ color: #656565;
778
+ font-size: @smallSize;
779
+ line-height: 28px;
780
+ position: relative;
781
+ display: flex;
782
+ overflow: auto;
783
+ flex-direction: column;
784
+
785
+ &-top {
786
+ display: flex;
787
+ height: 100%;
788
+ width: 100%;
789
+ justify-content: space-between;
790
+ position: absolute;
791
+ }
792
+
793
+ &-bottom {
794
+ width: 100%;
795
+ overflow: auto;
796
+ display: flex;
797
+ flex-direction: column;
798
+ margin-top: 38px;
799
+ background: @white;
800
+
801
+ &-title {
802
+ text-align: center;
803
+ border: 1px solid #EDEDED;
804
+ border-bottom: none;
805
+ line-height: 27px;
806
+ // margin: 10px 14px 0 14px;
807
+ }
808
+
809
+ &-content {
810
+ flex: 1;
811
+ display: flex;
812
+ overflow: auto;
813
+ }
814
+ }
815
+
816
+ // 表格渲染
817
+ &-tableBox {
818
+ width: 100%;
819
+ text-align: center;
820
+ border-collapse: collapse;
821
+ border-spacing: 0;
822
+
823
+ td,
824
+ th {
825
+ word-break: break-all;
826
+ word-wrap: break-word;
827
+ min-width: 50px;
828
+ height: 29px;
829
+ text-align: center;
830
+ // overflow: hidden;
831
+ white-space: nowrap;
832
+ text-overflow: ellipsis;
833
+ max-width: 200px;
834
+ }
835
+
836
+ .briGantt-chart-td {
837
+ height: 40px;
838
+ }
839
+
840
+ .briGantt-table-th-now {
841
+ color: @themeColor;
842
+ }
843
+ }
844
+
845
+ &-table {
846
+ &-tr {
847
+ border: 1px solid #EDEDED;
848
+ }
849
+
850
+ &-tr:nth-child(2n) {
851
+ background: rgba(244, 246, 249, 0.5119);
852
+ }
853
+
854
+ &-th {
855
+ background: #F4F8FF;
856
+ font-weight: 400;
857
+ color: rgba(101, 101, 101, 1);
858
+ }
859
+
860
+ &-td {
861
+ border-right: 1px solid #EDEDED;
862
+ font-weight: 400;
863
+ color: rgba(111, 111, 111, 1);
864
+
865
+ &-main {
866
+ height: 28px;
867
+ background: rgba(238, 238, 238, 0.5);
868
+ border: 1px solid #f6f6f6;
869
+ }
870
+ }
871
+
872
+ &-td:last-of-type {
873
+ border: none;
874
+ }
875
+ }
876
+
877
+ &-chart {
878
+ &-td {
879
+ overflow: visible;
880
+
881
+ &-greyLine {
882
+ border-top: 1px dashed #D5D5D5;
883
+ }
884
+
885
+ &-main {
886
+ display: flex;
887
+ width: 100%;
888
+ height: 100%;
889
+ align-items: center;
890
+ justify-content: center;
891
+
892
+ &-left,
893
+ &-right {
894
+ height: 100%;
895
+ overflow: hidden;
896
+ }
897
+
898
+ &-right-auto {
899
+ height: 100%;
900
+ overflow: hidden;
901
+ flex: 1;
902
+ }
903
+
904
+ &-center {
905
+ height: 30px;
906
+ border-radius: 4px;
907
+ background: #f6f6f6;
908
+ z-index: 1;
909
+ min-width: 2px;
910
+
911
+ .ms-ellipsis {
912
+ border-radius: 4px;
913
+ height: 100%;
914
+ color: @white;
915
+ text-align: left;
916
+ padding-left: 10px;
917
+ white-space: nowrap;
918
+ text-overflow: ellipsis;
919
+ overflow: hidden;
920
+ }
921
+
922
+ &-tooltip {
923
+ white-space: normal;
924
+
925
+ &-select {
926
+ height: 5px;
927
+ display: inline-block;
928
+ vertical-align: middle;
929
+ width: 5px;
930
+ border-radius: 50%;
931
+ }
932
+ }
933
+ }
934
+
935
+ &-line {
936
+ width: 100%;
937
+ border-bottom: 1px solid #D5D5D5;
938
+ font-weight: 400;
939
+ color: rgba(74, 74, 74, 1);
940
+ padding: 0 10px;
941
+ transform: translateY(15px);
942
+ text-align: left;
943
+ height: 29px;
944
+ font-size: @smallSize;
945
+ white-space: nowrap;
946
+ text-overflow: ellipsis;
947
+ overflow: hidden;
948
+
949
+ &-circle {
950
+ display: block;
951
+ width: 10px;
952
+ height: 100%;
953
+ min-width: 10px;
954
+
955
+ .circle {
956
+ display: block;
957
+ width: 10px;
958
+ height: 10px;
959
+ border-radius: 50%;
960
+ min-width: 10px;
961
+ margin-top: 38px;
962
+ background: #D5D5D5;
963
+ }
964
+ }
965
+ }
966
+
967
+ ;
968
+ }
969
+ }
970
+ }
971
+
972
+ // 蓝色虚线
973
+ &-line-now {
974
+ z-index: 9;
975
+ text-align: center;
976
+ background: transparent;
977
+
978
+ &::before {
979
+ content: "";
980
+ border-left: 1px dashed @themeColor;
981
+ position: absolute;
982
+ top: 25px;
983
+ bottom: 0px;
984
+ z-index: 9;
985
+ }
986
+
987
+ &::after {
988
+ content: "";
989
+ width: 6px;
990
+ height: 6px;
991
+ border-radius: 6px;
992
+ background: @themeColor;
993
+ position: absolute;
994
+ top: 25px;
995
+ margin-left: -3px;
996
+ }
997
+ }
998
+
999
+ // 时间轴
1000
+ &-timer {
1001
+ align-items: center;
1002
+ position: relative;
1003
+ float: right;
1004
+ overflow: hidden;
1005
+
1006
+ &-main {
1007
+ overflow: auto;
1008
+ flex: 1;
1009
+ height: 100%;
1010
+ position: relative;
1011
+ }
1012
+
1013
+ &-bg {
1014
+ position: absolute;
1015
+ background: #F4F8FF;
1016
+ left: 0px;
1017
+ right: 0px;
1018
+ height: 28px;
1019
+ border-radius: 28px;
1020
+ }
1021
+
1022
+ &-icon {
1023
+ background: #F4F8FF;
1024
+ color: #fff;
1025
+ width: 28px;
1026
+ height: 28px;
1027
+ min-width: 28px;
1028
+ display: flex;
1029
+ align-items: center;
1030
+ justify-content: center;
1031
+ position: absolute;
1032
+ z-index: 2;
1033
+ top: 0px;
1034
+ background: #F2F8FF;
1035
+
1036
+ &:hover {
1037
+ color: #fff;
1038
+ }
1039
+
1040
+ i {
1041
+ display: block;
1042
+ width: 16px;
1043
+ height: 16px;
1044
+ border-radius: 16px;
1045
+ font-size: 13px;
1046
+ background: @themeColor;
1047
+ display: flex;
1048
+ align-items: center;
1049
+ justify-content: center;
1050
+ }
1051
+
1052
+ &-left {
1053
+ left: -1px;
1054
+ border-top-left-radius: 28px;
1055
+ border-bottom-left-radius: 28px;
1056
+ }
1057
+
1058
+ &-right {
1059
+ right: -1px;
1060
+ border-top-right-radius: 28px;
1061
+ border-bottom-right-radius: 28px;
1062
+ }
1063
+ }
1064
+ }
1065
+
1066
+ // 区域映射
1067
+ &-data {
1068
+ flex: 1;
1069
+ overflow: auto;
1070
+ position: relative;
1071
+
1072
+ &-table {}
1073
+
1074
+ &-chart {}
1075
+
1076
+ &::-webkit-scrollbar {
1077
+ height: 0px;
1078
+ }
1079
+ }
1080
+
1081
+ // table 列表映射
1082
+ &-tabledata {
1083
+ overflow-y: auto;
1084
+ border-right: none;
1085
+ }
1086
+ }
1087
+ </style>