You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

scalar.vue 63 kB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084
  1. <!--
  2. Copyright 2019-2021 Huawei Technologies Co., Ltd.All Rights Reserved.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. -->
  13. <template>
  14. <div class="cl-scalar-manage">
  15. <div class="scalar-bk">
  16. <div class="cl-title cl-scalar-title"
  17. v-show="originDataArr.length>0">
  18. <div class="cl-title-left">{{$t("scalar.titleText")}}
  19. <div class="path-message">
  20. <span>{{$t('symbols.leftbracket')}}</span>
  21. <span>{{$t('trainingDashboard.summaryDirPath')}}</span>
  22. <span>{{summaryPath}}</span>
  23. <span>{{$t('symbols.rightbracket')}}</span>
  24. </div>
  25. </div>
  26. <div class="cl-title-right">
  27. <ScalarButton class="scalar-btn"
  28. :right="scalarCompare"
  29. @compareClick='compareClick'
  30. :initOver="initOver"></ScalarButton>
  31. <div class="cl-close-btn"
  32. @click="jumpToTrainDashboard">
  33. <img src="@/assets/images/close-page.png">
  34. </div>
  35. </div>
  36. </div>
  37. <!--Operation area -->
  38. <div class="cl-eval-operate-content"
  39. v-show="!compare && originDataArr.length>0">
  40. <multiselectGroupComponents ref="multiselectGroupComponents"
  41. :checkListArr="tagOperateList"
  42. @selectedChange="tagSelectedChanged"></multiselectGroupComponents>
  43. </div>
  44. <!-- Slider -->
  45. <div class="cl-eval-slider-operate-content"
  46. v-show="!compare && originDataArr.length>0">
  47. <div class="xaxis-title">{{$t('scalar.xAxisTitle')}}</div>
  48. <el-radio-group v-model="curAxisName"
  49. fill="#00A5A7"
  50. text-color="#FFFFFF"
  51. size="small "
  52. @change="timeTypeChange">
  53. <el-radio-button :label="$t('scalar.step')"></el-radio-button>
  54. <el-radio-button :label="$t('scalar.relativeTime')"></el-radio-button>
  55. <el-radio-button :label="$t('scalar.absoluteTime')"></el-radio-button>
  56. </el-radio-group>
  57. <div class="xaxis-title">{{$t('scalar.smoothness')}}</div>
  58. <el-slider v-model="smoothValue"
  59. :step="0.01"
  60. :max="0.99"
  61. @input="updataInputValue"></el-slider>
  62. <el-input v-model="smoothValueNumber"
  63. class="w60"
  64. @input="smoothValueChange"
  65. @blur="smoothValueBlur"></el-input>
  66. </div>
  67. <!-- Content display -->
  68. <div class="cl-eval-show-data-content"
  69. ref="miDataShoeContent"
  70. v-show="!compare">
  71. <!-- No data -->
  72. <div class="image-noData"
  73. v-if="!originDataArr.length">
  74. <div>
  75. <img :src="require('@/assets/images/nodata.png')"
  76. alt="" />
  77. </div>
  78. <div v-if="initOver"
  79. class="noData-text">{{$t('public.noData')}}</div>
  80. <div v-else
  81. class="noData-text">{{$t("public.dataLoading")}}</div>
  82. </div>
  83. <!-- Data -->
  84. <div class="data-content"
  85. v-if="originDataArr.length">
  86. <div class="sample-content"
  87. v-for="sampleItem in originDataArr"
  88. :key="sampleItem.domId"
  89. :class="sampleItem.fullScreen?'char-full-screen':''"
  90. :id="'view'+sampleItem.domId"
  91. v-show="sampleItem.show">
  92. <!-- Charts -->
  93. <div class="chars-container">
  94. <div class="char-item-content"
  95. :id="sampleItem.domId"></div>
  96. </div>
  97. <div class="chartThreshold">
  98. <div class="chartThresholdLeft"
  99. :title="sampleItem.pieceStr">{{$t("scalar.currentThreshold")}}:{{sampleItem.pieceStr || "-"}}</div>
  100. <div class="chartThresholdRight">
  101. <span @click="setThreshold(sampleItem)"
  102. v-if="!thresholdLocal
  103. || !thresholdLocal[decodeTrainingJobId]
  104. || !thresholdLocal[decodeTrainingJobId][sampleItem.tagName]">
  105. {{$t("scalar.setThreshold")}}</span>
  106. <span v-else
  107. @click="delThreshold(sampleItem)">{{$t("scalar.deleteThreshold")}}</span>
  108. </div>
  109. </div>
  110. <!-- Tag name -->
  111. <div class="tag-name">{{sampleItem.tagName}}
  112. <el-tooltip v-if="sampleItem.invalidData"
  113. class="item"
  114. effect="dark"
  115. :content="$t('scalar.invalidData')"
  116. placement="top">
  117. <i class="el-icon-warning"></i>
  118. </el-tooltip>
  119. </div>
  120. </div>
  121. </div>
  122. <!-- page -->
  123. </div>
  124. <div class="pagination-content"
  125. v-if="!compare && originDataArr.length">
  126. <el-pagination @current-change="currentPageChange"
  127. :current-page="pageIndex + 1"
  128. :page-size="pageNum"
  129. layout="total, prev, pager, next, jumper"
  130. :total="curFilterSamples.length">
  131. </el-pagination>
  132. </div>
  133. <ScalarCompare :tagPropsList="tagPropsList"
  134. :initOver="initOver"
  135. :propsList="propsList"
  136. :compare="compare"
  137. v-show="compare"></ScalarCompare>
  138. </div>
  139. <el-dialog :title="$t('scalar.setThreshold')"
  140. :visible.sync="thresholdDialogVisible"
  141. :close-on-click-modal="false"
  142. @close="thresholdCancel"
  143. width="1000px">
  144. <div class="thresholdAll">
  145. <div class="thresholdItem fs16">{{$t('scalar.currentTag')}}:</div>
  146. <div class="thresholdItemWidth">
  147. <el-tooltip class="item"
  148. effect="dark"
  149. :content="currentTagName"
  150. placement="top">
  151. <span>{{currentTagName}}</span>
  152. </el-tooltip>
  153. </div>
  154. </div>
  155. <div class="thresholdAll">
  156. <div class="thresholdItem fs16">{{$t('scalar.filterCriteria')}}:</div>
  157. <div class="thresholdItem">
  158. <el-select v-model="thresholdValue[0].filterCondition"
  159. class="smallSelect">
  160. <el-option v-for="filterItem in filterOptions"
  161. :key="filterItem.value"
  162. :label="filterItem.label"
  163. :value="filterItem.value">
  164. </el-option>
  165. </el-select>
  166. </div>
  167. <div class="thresholdItem">
  168. <el-input v-model="thresholdValue[0].value"
  169. :placeholder="$t('scalar.placeHolderThreshold')"
  170. class="smallInput"
  171. clearable></el-input>
  172. </div>
  173. <div class="thresholdItem">
  174. <el-select v-model="thresholdRelational"
  175. :placeholder="$t('public.select')"
  176. @change="relationalChange"
  177. clearable
  178. class="smallSelectTwo">
  179. <el-option :label="$t('scalar.or')"
  180. :value="$t('scalar.or')">
  181. </el-option>
  182. <el-option :label="$t('scalar.and')"
  183. :value="$t('scalar.and')">
  184. </el-option>
  185. </el-select>
  186. </div>
  187. <div class="thresholdItem"
  188. v-show="thresholdRelational">
  189. <el-select v-model="thresholdValue[1].filterCondition"
  190. class="smallSelect">
  191. <el-option v-for="filterItem in filterOptions"
  192. :key="filterItem.value"
  193. :label="filterItem.label"
  194. :value="filterItem.value">
  195. </el-option>
  196. </el-select>
  197. </div>
  198. <div class="thresholdItem"
  199. v-show="thresholdRelational">
  200. <el-input v-model="thresholdValue[1].value"
  201. :placeholder="$t('scalar.placeHolderThreshold')"
  202. class="smallInput"
  203. clearable></el-input>
  204. </div>
  205. <div class="thresholdItem thresholdError">{{thresholdErrorMsg}}</div>
  206. </div>
  207. <div class="thresholdAll">
  208. <div class="thresholdItem fs16">{{$t('scalar.applyAllSelectTag')}}</div>
  209. <div class="thresholdItem">
  210. <el-switch v-model="thresholdSwitch"></el-switch>
  211. </div>
  212. </div>
  213. <span slot="footer"
  214. class="dialog-footer">
  215. <el-button @click="thresholdCancel"
  216. size="mini">{{$t('public.cancel')}}</el-button>
  217. <el-button type="primary"
  218. @click="thresholdCommit"
  219. size="mini">{{$t('public.sure')}}</el-button>
  220. </span>
  221. </el-dialog>
  222. <el-dialog :title="$t('scalar.info')"
  223. :visible.sync="delThresholdVisible"
  224. custom-class="delDialog"
  225. :close-on-click-modal="false"
  226. @close="delThresholdCancel"
  227. top="35vh"
  228. width="425px">
  229. <div class="delThresholdItem">
  230. <span class="delThresholdIcon el-icon-warning"></span>
  231. <span class="delThresholdInfo">{{$t('scalar.isDelete')}}</span>
  232. </div>
  233. <div class="delThresholdItem">
  234. <span class="delThresholdIcon">
  235. <el-switch v-model="delThresholdSwitch"></el-switch>
  236. </span>
  237. <span class="delThresholdInfo">{{$t('scalar.applyAllSelectTag')}}</span>
  238. </div>
  239. <span slot="footer"
  240. class="dialog-footer">
  241. <el-button @click="delThresholdCancel"
  242. size="mini">{{$t('public.cancel')}}</el-button>
  243. <el-button type="primary"
  244. @click="delThresholdCommit"
  245. size="mini">{{$t('public.sure')}}</el-button>
  246. </span>
  247. </el-dialog>
  248. </div>
  249. </template>
  250. <script>
  251. import ScalarButton from './scalar-button';
  252. import echarts from 'echarts';
  253. import RequestService from '../../services/request-service';
  254. import CommonProperty from '../../common/common-property';
  255. import ScalarCompare from './scalar-compare';
  256. import multiselectGroupComponents from '../../components/multiselect-group.vue';
  257. import autoUpdate from '../../mixins/auto-update.vue';
  258. import threshold from '../../mixins/threshold.vue';
  259. export default {
  260. mixins: [threshold, autoUpdate],
  261. data() {
  262. return {
  263. firstNum: 0, // First time
  264. isActive: 0, // Horizontal axis selected value
  265. initOver: false, // Indicates whether the initialization is complete
  266. charResizeTimer: null, // Delay after the window size is changed
  267. multiSelectedTagNames: {}, // Selected tag name
  268. curFilterSamples: [], // List of chart that meet the current filter criteria
  269. tagOperateList: [], // Array selected by tag
  270. tagPropsList: [], // Tag props
  271. propsList: [], // DataList props
  272. smoothValue: 0, // Initial smoothness of the slider
  273. smoothValueNumber: 0,
  274. smoothSliderValueTimer: null, // Smoothness slider timer
  275. DomIdIndex: 0, // DomId num
  276. originDataArr: [], // Original data
  277. oriDataDictionaries: {}, // Dictionary that contains all the current tags
  278. curPageArr: [], // Data of the current page
  279. pageIndex: 0, // Current page number
  280. pageNum: 6, // Number of records per page
  281. backendString: 'scalarBackend', // Background layer suffix
  282. curBenchX: 'stepData', // Front axle reference
  283. curAxisName: this.$t('scalar.step'), // Current chart tip
  284. axisBenchChangeTimer: null, // Horizontal axis reference switching timing
  285. yAxisScaleTimer: null, // yAxis scale timer
  286. compare: false, // Comparison Page
  287. scalarCompare: this.$t('scalar')['comparison'],
  288. trainingJobId: this.$route.query.train_id, // ID of the current training job
  289. summaryPath: this.$route.query.summaryPath,
  290. decodeTrainingJobId: '',
  291. };
  292. },
  293. destroyed() {
  294. // Remove the size of a window and change the listener
  295. window.removeEventListener('resize', this.resizeCallback);
  296. // Remove slider value change timing
  297. if (this.smoothSliderValueTimer) {
  298. clearTimeout(this.smoothSliderValueTimer);
  299. this.smoothSliderValueTimer = null;
  300. }
  301. // Remove Chart Calculation Delay
  302. if (this.charResizeTimer) {
  303. clearTimeout(this.charResizeTimer);
  304. this.charResizeTimer = null;
  305. }
  306. if (this.axisBenchChangeTimer) {
  307. clearTimeout(this.axisBenchChangeTimer);
  308. this.axisBenchChangeTimer = null;
  309. }
  310. if (this.yAxisScaleTimer) {
  311. clearTimeout(this.yAxisScaleTimer);
  312. this.yAxisScaleTimer = null;
  313. }
  314. },
  315. mounted() {
  316. if (!this.$route.query || !this.$route.query.train_id) {
  317. this.$message.error(this.$t('trainingDashboard.invalidId'));
  318. document.title = `${this.$t('scalar.titleText')}-MindInsight`;
  319. return;
  320. }
  321. document.title = `${decodeURIComponent(
  322. this.$route.query.train_id,
  323. )}-${this.$t('scalar.titleText')}-MindInsight`;
  324. // Adding a Listener
  325. window.addEventListener('resize', this.resizeCallback, false);
  326. // Dom ready
  327. this.$nextTick(() => {
  328. // Initializing Data
  329. this.getScalarsList();
  330. this.firstNum = 1;
  331. this.decodeTrainingJobId = decodeURIComponent(this.trainingJobId);
  332. this.getCache();
  333. // Auto refresh
  334. if (this.isTimeReload) {
  335. this.autoUpdateSamples();
  336. }
  337. });
  338. },
  339. methods: {
  340. /**
  341. * Obtain the tag and run list.
  342. */
  343. getScalarsList() {
  344. const params = {
  345. plugin_name: 'scalar',
  346. train_id: this.trainingJobId,
  347. };
  348. RequestService.getSingleTrainJob(params, false)
  349. .then((res) => {
  350. // Error
  351. if (
  352. !res ||
  353. !res.data ||
  354. !res.data.train_jobs ||
  355. !res.data.train_jobs.length
  356. ) {
  357. this.initOver = true;
  358. return;
  359. }
  360. const tempTagList = [];
  361. const dataList = [];
  362. const propsList = [];
  363. const data = res.data.train_jobs[0];
  364. const runNmeColor = CommonProperty.commonColorArr[0];
  365. data.tags.forEach((tagObj) => {
  366. if (!this.oriDataDictionaries[tagObj]) {
  367. this.oriDataDictionaries[tagObj] = true;
  368. // Add the tag list
  369. tempTagList.push({
  370. label: tagObj,
  371. checked: true,
  372. show: true,
  373. });
  374. const sampleIndex = dataList.length;
  375. // Adding chart data
  376. dataList.push({
  377. tagName: tagObj,
  378. runNames: data.name,
  379. colors: runNmeColor,
  380. show: false,
  381. updateFlag: false,
  382. dataRemove: false,
  383. fullScreen: false,
  384. sampleIndex: sampleIndex,
  385. domId: 'prDom' + this.DomIdIndex,
  386. charData: {
  387. oriData: [],
  388. charOption: {},
  389. },
  390. zoomData: [null, null],
  391. zoomDataTimer: null,
  392. charObj: null,
  393. invalidData: false,
  394. });
  395. propsList.push({
  396. tagName: tagObj,
  397. runNames: data.name,
  398. colors: '',
  399. });
  400. this.DomIdIndex++;
  401. }
  402. });
  403. this.tagOperateList = tempTagList;
  404. this.tagPropsList = JSON.parse(JSON.stringify(tempTagList));
  405. if (dataList.length === 1) {
  406. dataList[0].fullScreen = true;
  407. }
  408. this.originDataArr = dataList;
  409. this.propsList = propsList;
  410. this.initOver = true;
  411. this.$nextTick(() => {
  412. this.multiSelectedTagNames = this.$refs.multiselectGroupComponents.updateSelectedDic();
  413. // Obtains data on the current page
  414. this.updateTagInPage();
  415. this.resizeCallback();
  416. });
  417. }, this.requestErrorCallback)
  418. .catch((e) => {
  419. this.initOver = true;
  420. this.$message.error(this.$t('public.dataError'));
  421. });
  422. },
  423. /**
  424. * Obtains data on a specified page
  425. * @param {Boolen} noPageIndexChange // The page number does not change
  426. */
  427. getCurPageDataArr(noPageIndexChange) {
  428. if (!noPageIndexChange) {
  429. this.curPageArr.forEach((sampleItem) => {
  430. sampleItem.show = false;
  431. });
  432. }
  433. const startIndex = this.pageIndex * this.pageNum;
  434. const endIndex = startIndex + this.pageNum;
  435. const curPageArr = [];
  436. for (let i = startIndex; i < endIndex; i++) {
  437. const sampleItem = this.curFilterSamples[i];
  438. if (sampleItem) {
  439. sampleItem.updateFlag = true;
  440. sampleItem.show = true;
  441. curPageArr.push(sampleItem);
  442. }
  443. }
  444. this.curPageArr = curPageArr;
  445. this.updateCurPageSamples();
  446. },
  447. /**
  448. * Load the data on the current page
  449. */
  450. updateCurPageSamples() {
  451. this.curPageArr.forEach((sampleObject) => {
  452. const sampleIndex = sampleObject.sampleIndex;
  453. if (!sampleObject) {
  454. return;
  455. }
  456. sampleObject.updateFlag = true;
  457. const params = {
  458. train_id: this.trainingJobId,
  459. tag: sampleObject.tagName,
  460. };
  461. RequestService.getScalarsSample(params)
  462. .then((res) => {
  463. // Error
  464. if (!res || !res.data || !res.data.metadatas) {
  465. // Canceled
  466. if (res.toString() === 'false') {
  467. return;
  468. }
  469. if (sampleObject.charObj) {
  470. sampleObject.charObj.clear();
  471. sampleObject.onePoint = false;
  472. }
  473. return;
  474. }
  475. let hasInvalidData = false;
  476. if (sampleObject.charObj) {
  477. sampleObject.charObj.showLoading();
  478. }
  479. const resData = res.data;
  480. const tempObject = {
  481. valueData: {
  482. stepData: [],
  483. absData: [],
  484. relativeData: [],
  485. },
  486. logData: {
  487. stepData: [],
  488. absData: [],
  489. relativeData: [],
  490. },
  491. };
  492. let relativeTimeBench = 0;
  493. if (resData.metadatas.length) {
  494. relativeTimeBench = resData.metadatas[0].wall_time;
  495. }
  496. const mathData = [];
  497. // Initializing chart data
  498. resData.metadatas.forEach((metaData) => {
  499. if (metaData.value === null && !hasInvalidData) {
  500. hasInvalidData = true;
  501. }
  502. if (!isNaN(metaData.value) && metaData.value !== null) {
  503. mathData.push(metaData.value);
  504. }
  505. tempObject.valueData.stepData.push([
  506. metaData.step,
  507. metaData.value,
  508. ]);
  509. tempObject.valueData.absData.push([
  510. metaData.wall_time,
  511. metaData.value,
  512. ]);
  513. tempObject.valueData.relativeData.push([
  514. metaData.wall_time - relativeTimeBench,
  515. metaData.value,
  516. ]);
  517. // Values less than 0 have no logarithm
  518. // Set empty string and echart does not render
  519. const logValue = metaData.value > 0 ? metaData.value : '';
  520. tempObject.logData.stepData.push([metaData.step, logValue]);
  521. tempObject.logData.absData.push([metaData.wall_time, logValue]);
  522. tempObject.logData.relativeData.push([
  523. metaData.wall_time - relativeTimeBench,
  524. logValue,
  525. ]);
  526. });
  527. // Numerical range
  528. const filtersData = mathData.filter((item) => {
  529. // Values less than 0 have no logarithm
  530. return item > 0;
  531. });
  532. const maxData = Math.max(...filtersData);
  533. const minData = Math.min(...filtersData);
  534. sampleObject.max = maxData;
  535. if (maxData === minData) {
  536. sampleObject.isEqual = true;
  537. } else {
  538. sampleObject.isEqual = false;
  539. }
  540. sampleObject.charData.oriData[0] = tempObject;
  541. if (hasInvalidData) {
  542. this.$set(sampleObject, 'invalidData', true);
  543. } else {
  544. this.$set(sampleObject, 'invalidData', false);
  545. }
  546. sampleObject.charData.charOption = this.formateCharOption(
  547. sampleIndex,
  548. );
  549. const tempOption = sampleObject.charData.charOption;
  550. if (
  551. tempOption.series[0].data.length === 1 ||
  552. sampleObject.onePoint
  553. ) {
  554. tempOption.series[0].showSymbol = true;
  555. } else {
  556. tempOption.series[0].showSymbol = false;
  557. }
  558. this.$forceUpdate();
  559. this.$nextTick(() => {
  560. if (sampleObject.charObj) {
  561. sampleObject.charObj.hideLoading();
  562. }
  563. // Draw chart
  564. if (!this.compare) {
  565. this.updateOrCreateChar(sampleIndex, true);
  566. }
  567. });
  568. })
  569. .catch((e) => {
  570. if (sampleObject.charObj) {
  571. sampleObject.charObj.clear();
  572. }
  573. });
  574. });
  575. },
  576. /**
  577. * Formatting chart data
  578. * @param {Number} sampleIndex Chart subscript
  579. * @return {Object} Echar option
  580. */
  581. formateCharOption(sampleIndex) {
  582. const sampleObject = this.originDataArr[sampleIndex];
  583. if (!sampleObject) {
  584. return;
  585. }
  586. let returnFlag = false;
  587. const seriesData = [];
  588. const oriData = sampleObject.charData.oriData;
  589. const runName = sampleObject.runNames;
  590. const curBackName = runName + this.backendString;
  591. const dataObj = {
  592. name: runName,
  593. data: [],
  594. type: 'line',
  595. showSymbol: false,
  596. lineStyle: {
  597. color: sampleObject.colors,
  598. },
  599. markLine: [],
  600. };
  601. const dataObjBackend = {
  602. name: curBackName,
  603. data: [],
  604. type: 'line',
  605. smooth: 0,
  606. symbol: 'none',
  607. lineStyle: {
  608. color: sampleObject.colors,
  609. opacity: 0.2,
  610. },
  611. };
  612. const curOriData = oriData[0];
  613. if (curOriData) {
  614. if (sampleObject.log) {
  615. dataObj.data = this.formateSmoothData(
  616. curOriData.logData[this.curBenchX],
  617. );
  618. dataObjBackend.data = curOriData.logData[this.curBenchX];
  619. } else {
  620. dataObj.data = this.formateSmoothData(
  621. curOriData.valueData[this.curBenchX],
  622. );
  623. dataObjBackend.data = curOriData.valueData[this.curBenchX];
  624. }
  625. } else {
  626. returnFlag = true;
  627. }
  628. seriesData.push(dataObj, dataObjBackend);
  629. if (returnFlag) {
  630. return;
  631. }
  632. const that = this;
  633. const fullScreenFun = this.toggleFullScreen;
  634. const yAxisFun = this.yAxisScale;
  635. const tempOption = {
  636. legend: {
  637. show: false,
  638. },
  639. xAxis: {
  640. type: 'value',
  641. show: true,
  642. scale: true,
  643. nameGap: 30,
  644. minInterval: this.isActive === 0 ? 1 : 0,
  645. axisLine: {
  646. lineStyle: {
  647. color: '#E6EBF5',
  648. width: 2,
  649. },
  650. },
  651. axisLabel: {
  652. color: '#9EA4B3',
  653. interval: 0,
  654. rotate: that.isActive === 2 ? 0 : 90,
  655. formatter(value) {
  656. if (that.isActive === 2) {
  657. if (sampleObject.fullScreen) {
  658. const date = new Date(value * 1000);
  659. const dateTime = date.toTimeString().split(' ')[0];
  660. const dateYear = date.toDateString();
  661. return dateTime + '\n' + dateYear;
  662. } else {
  663. return '';
  664. }
  665. } else if (that.isActive === 1) {
  666. if (value < 1 && value.toString().length > 6) {
  667. return value.toFixed(3);
  668. } else if (value.toString().length > 6) {
  669. return value.toExponential(0);
  670. } else {
  671. return value;
  672. }
  673. } else {
  674. const symbol = Math.abs(value);
  675. if (symbol.toString().length > 6) {
  676. return value.toExponential(0);
  677. } else if (value >= 1000 || value <= -1000) {
  678. return parseFloat((value / 1000).toFixed(2)) + 'k';
  679. } else if (value > 0) {
  680. return value;
  681. } else {
  682. return parseFloat(value.toFixed(3));
  683. }
  684. }
  685. },
  686. },
  687. },
  688. yAxis: {
  689. type: sampleObject.log ? 'log' : 'value',
  690. scale: true,
  691. // Logbase for very small values,default 10
  692. logBase: sampleObject.max < 1 && sampleObject.isEqual ? 0.1 : 10,
  693. inverse:
  694. sampleObject.log && sampleObject.max < 1 && sampleObject.isEqual
  695. ? true
  696. : false,
  697. axisLine: {
  698. lineStyle: {
  699. color: '#E6EBF5',
  700. width: 2,
  701. },
  702. },
  703. axisLabel: {
  704. color: '#9EA4B3',
  705. formatter(value) {
  706. if (sampleObject.zoomDataTimer) {
  707. clearTimeout(sampleObject.zoomDataTimer);
  708. sampleObject.zoomDataTimer = setTimeout(() => {
  709. sampleObject.zoomDataTimer = null;
  710. }, 50);
  711. if (value < sampleObject.zoomData[0]) {
  712. sampleObject.zoomData[0] = value;
  713. } else if (sampleObject.zoomData[1] < value) {
  714. sampleObject.zoomData[1] = value;
  715. }
  716. } else {
  717. sampleObject.zoomData = [value, value];
  718. sampleObject.zoomDataTimer = setTimeout(() => {
  719. sampleObject.zoomDataTimer = null;
  720. }, 50);
  721. }
  722. const symbol = Math.abs(value);
  723. if (symbol.toString().length > 6) {
  724. return value.toExponential(4);
  725. } else if (value >= 1000 || value <= -1000) {
  726. return parseFloat((value / 1000).toFixed(2)) + 'k';
  727. } else if (value > 0) {
  728. return value;
  729. } else {
  730. return parseFloat(value.toFixed(3));
  731. }
  732. },
  733. },
  734. },
  735. grid: {
  736. left: 80,
  737. right: sampleObject.fullScreen ? 80 : 50,
  738. },
  739. animation: true,
  740. dataZoom: [
  741. {
  742. show: false,
  743. yAxisIndex: 0,
  744. filterMode: 'none',
  745. },
  746. ],
  747. tooltip: {
  748. trigger: 'axis',
  749. axisPointer: {
  750. type: 'line',
  751. },
  752. position: (point, params, dom, rect, size) => {
  753. const curDom = document.getElementById(sampleObject.domId);
  754. if (!curDom) {
  755. return {left: 0, bottom: '100%'};
  756. }
  757. if (sampleObject.fullScreen) {
  758. if (point[0] + size.contentSize[0] <= size.viewSize[0]) {
  759. return {left: point[0], bottom: '10%'};
  760. } else {
  761. return {right: size.viewSize[0] - point[0], bottom: '10%'};
  762. }
  763. } else {
  764. const parentNode = curDom.parentNode;
  765. if (!parentNode) {
  766. return {left: 0, bottom: '100%'};
  767. }
  768. if (parentNode.offsetLeft > size.contentSize[0]) {
  769. return {right: '100%', bottom: 0};
  770. } else {
  771. return {left: '100%', bottom: 0};
  772. }
  773. }
  774. },
  775. formatter(params) {
  776. const unit = 's';
  777. const strhead =
  778. `<table class="char-tip-table" class="borderspacing3"><tr><td></td>` +
  779. `<td>${that.$t('scalar.charTipHeadName')}</td>` +
  780. `<td>${that.$t('scalar.charSmoothedValue')}</td>` +
  781. `<td>${that.$t('scalar.charTipHeadValue')}</td>` +
  782. `<td>${that.$t('scalar.step')}</td>` +
  783. `<td>${that.$t('scalar.relativeTime')}</td>` +
  784. `<td>${that.$t('scalar.absoluteTime')}</td>` +
  785. `</tr>`;
  786. let strBody = '';
  787. const runArr = [];
  788. const detialArr = [];
  789. let curStep = null;
  790. let dataCount = 0;
  791. params.forEach((parma) => {
  792. if (parma.componentIndex % 2 === 0) {
  793. let addFlag = true;
  794. const curIndex = parseInt(parma.componentIndex / 2);
  795. let curSerieOriData;
  796. if (sampleObject.log) {
  797. curSerieOriData = oriData[curIndex].logData;
  798. } else {
  799. curSerieOriData = oriData[curIndex].valueData;
  800. }
  801. if (curStep === null) {
  802. curStep = curSerieOriData.stepData[parma.dataIndex][0];
  803. } else {
  804. if (
  805. curSerieOriData.stepData[parma.dataIndex][0] === curStep
  806. ) {
  807. const sameRunIndex = [];
  808. runArr.forEach((runName, index) => {
  809. if (parma.seriesName === runName) {
  810. sameRunIndex.push(index);
  811. }
  812. });
  813. if (sameRunIndex.length) {
  814. sameRunIndex.forEach((sameIndex) => {
  815. if (
  816. detialArr[sameIndex] &&
  817. detialArr[sameIndex].value ===
  818. curSerieOriData.stepData[parma.dataIndex][1] &&
  819. detialArr[sameIndex].wallTime ===
  820. curSerieOriData.absData[parma.dataIndex][0]
  821. ) {
  822. addFlag = false;
  823. }
  824. });
  825. }
  826. } else {
  827. addFlag = false;
  828. }
  829. }
  830. if (
  831. addFlag &&
  832. Math.ceil(parma.value[1] * 1000) / 1000 >=
  833. sampleObject.zoomData[0] &&
  834. Math.floor(parma.value[1] * 1000) / 1000 <=
  835. sampleObject.zoomData[1]
  836. ) {
  837. dataCount++;
  838. runArr.push(parma.seriesName);
  839. detialArr.push({
  840. value: curSerieOriData.stepData[parma.dataIndex][1],
  841. step: curSerieOriData.stepData[parma.dataIndex][0],
  842. wallTime: curSerieOriData.absData[parma.dataIndex][0],
  843. dataIndex: parma.dataIndex,
  844. });
  845. strBody +=
  846. `<tr><td style="border-radius:50%;width:15px;height:15px;vertical-align: middle;` +
  847. `margin-right: 5px;background-color:${
  848. parma.color === that.thresholdColor &&
  849. sampleObject.charData.charOption.visualMap
  850. ? that.thresholdColor
  851. : sampleObject.colors
  852. };` +
  853. `display:inline-block;"></td><td>${parma.seriesName}</td>` +
  854. `<td>${that.formateYaxisValue(parma.value[1])}</td>` +
  855. `<td>${that.formateYaxisValue(
  856. curSerieOriData.stepData[parma.dataIndex][1],
  857. )}</td>` +
  858. `<td>${curSerieOriData.stepData[parma.dataIndex][0]}</td>` +
  859. `<td>${curSerieOriData.relativeData[
  860. parma.dataIndex
  861. ][0].toFixed(3)}${unit}</td>` +
  862. `<td>${that.dealrelativeTime(
  863. new Date(
  864. curSerieOriData.absData[parma.dataIndex][0] * 1000,
  865. ).toString(),
  866. )}</td>` +
  867. `</tr>`;
  868. }
  869. }
  870. });
  871. if (dataCount) {
  872. return strhead + strBody + '</table>';
  873. }
  874. },
  875. },
  876. toolbox: {
  877. top: 20,
  878. emphasis: {
  879. iconStyle: {
  880. textPosition: 'top',
  881. textAlign: 'right',
  882. borderColor: '#00A5A7',
  883. },
  884. },
  885. // Toolbox
  886. feature: {
  887. // FullScreen
  888. myToolFullScreen: {
  889. show: true,
  890. title: this.$t('scalar.fullScreen'),
  891. iconStyle: {
  892. borderColor: sampleObject.fullScreen ? '#00A5A7' : '#6D7278',
  893. },
  894. icon: CommonProperty.fullScreenIcon,
  895. onclick() {
  896. fullScreenFun(sampleIndex);
  897. },
  898. },
  899. myTool2: {
  900. show: true,
  901. title:
  902. sampleObject.max <= 0
  903. ? this.$t('scalar.noLog')
  904. : this.$t('scalar.toggleYaxisScale'),
  905. iconStyle: {
  906. borderColor: sampleObject.log ? '#00A5A7' : '#6D7278',
  907. },
  908. icon:
  909. 'path://M0 150 c0 -18 7 -20 85 -20 78 0 85 2 85 20 0 18 -7 20 -85 20 -78 0 -85 -2 ' +
  910. '-85 -20z M0 95 c0 -12 16 -15 85 -15 69 0 85 3 85 15 0 12 -16 15 -85 15 -69 0 -85 ' +
  911. '-3 -85 -15z M0 50 c0 -6 35 -10 85 -10 50 0 85 4 85 10 0 6 -35 10 -85 10 -50 0 -85' +
  912. `-4 -85 -10z`,
  913. onclick(ExtendedClass, ExtensionAPI, toolName, event) {
  914. yAxisFun(sampleIndex);
  915. },
  916. },
  917. // Selection and rollback
  918. dataZoom: {
  919. textStyle: false,
  920. title: {
  921. zoom: this.$t('scalar.openOrCloseSelection'),
  922. back: this.$t('scalar.stepBack'),
  923. },
  924. show: true,
  925. },
  926. // Restore
  927. restore: {
  928. title: this.$t('scalar.restore'),
  929. },
  930. },
  931. },
  932. series: seriesData,
  933. };
  934. return tempOption;
  935. },
  936. /**
  937. * Updating or creating a specified chart
  938. * @param {Number} sampleIndex Chart subscript
  939. * @param {Boolean} isSetVisualMap IsSetVisualMap
  940. */
  941. updateOrCreateChar(sampleIndex, isSetVisualMap) {
  942. const sampleObject = this.originDataArr[sampleIndex];
  943. if (!sampleObject) {
  944. return;
  945. }
  946. if (sampleObject.charObj) {
  947. // Updating chart option
  948. if (sampleObject.updateFlag) {
  949. sampleObject.charObj.setOption(
  950. sampleObject.charData.charOption,
  951. sampleObject.dataRemove,
  952. );
  953. sampleObject.updateFlag = false;
  954. sampleObject.dataRemove = false;
  955. }
  956. } else {
  957. // Create chart
  958. sampleObject.charObj = echarts.init(
  959. document.getElementById(sampleObject.domId),
  960. null,
  961. );
  962. sampleObject.charObj.setOption(sampleObject.charData.charOption, true);
  963. this.setOnePoint(sampleObject);
  964. this.setRestore(sampleObject);
  965. }
  966. if (isSetVisualMap) {
  967. this.updateVisualMap(sampleObject);
  968. }
  969. },
  970. /**
  971. * Enabling/Disabling full screen
  972. * @param {Number} sampleIndex Chart subscript
  973. */
  974. toggleFullScreen(sampleIndex) {
  975. const sampleObject = this.originDataArr[sampleIndex];
  976. if (!sampleObject) {
  977. return;
  978. }
  979. // Background color of the refresh button
  980. sampleObject.fullScreen = !sampleObject.fullScreen;
  981. if (sampleObject.fullScreen) {
  982. sampleObject.charData.charOption.toolbox.feature.myToolFullScreen.iconStyle.borderColor =
  983. '#00A5A7';
  984. sampleObject.charData.charOption.grid.right = 80;
  985. } else {
  986. sampleObject.charData.charOption.toolbox.feature.myToolFullScreen.iconStyle.borderColor =
  987. '#6D7278';
  988. sampleObject.charData.charOption.grid.right = 50;
  989. }
  990. sampleObject.updateFlag = true;
  991. // Refresh icon display
  992. this.updateOrCreateChar(sampleIndex);
  993. setTimeout(() => {
  994. sampleObject.charObj.resize();
  995. document.getElementById('view' + sampleObject.domId).scrollIntoView();
  996. }, 0);
  997. },
  998. /**
  999. * Update chart by tag
  1000. * @param {Boolean} noPageDataNumChange No new data is added or deleted
  1001. */
  1002. updateTagInPage(noPageDataNumChange) {
  1003. const curFilterSamples = [];
  1004. // Obtains the chart subscript
  1005. this.originDataArr.forEach((sampleItem) => {
  1006. if (this.multiSelectedTagNames[sampleItem.tagName]) {
  1007. curFilterSamples.push(sampleItem);
  1008. }
  1009. });
  1010. this.curFilterSamples = curFilterSamples;
  1011. // Obtains data on the current page
  1012. this.getCurPageDataArr(noPageDataNumChange);
  1013. },
  1014. /**
  1015. *
  1016. * The time display type is changed
  1017. */
  1018. timeTypeChange(val) {
  1019. if (this.isTimeReload) {
  1020. this.autoUpdateSamples();
  1021. }
  1022. if (this.axisBenchChangeTimer) {
  1023. clearTimeout(this.axisBenchChangeTimer);
  1024. this.axisBenchChangeTimer = null;
  1025. }
  1026. this.axisBenchChangeTimer = setTimeout(() => {
  1027. switch (val) {
  1028. case this.$t('scalar.step'):
  1029. this.curBenchX = 'stepData';
  1030. this.curAxisName = this.$t('scalar.step');
  1031. this.isActive = 0;
  1032. break;
  1033. case this.$t('scalar.relativeTime'):
  1034. this.curBenchX = 'relativeData';
  1035. this.curAxisName = this.$t('scalar.relativeTime');
  1036. this.isActive = 1;
  1037. break;
  1038. case this.$t('scalar.absoluteTime'):
  1039. this.curBenchX = 'absData';
  1040. this.curAxisName = this.$t('scalar.absoluteTime');
  1041. this.isActive = 2;
  1042. break;
  1043. default:
  1044. this.curBenchX = 'stepData';
  1045. this.curAxisName = this.$t('scalar.step');
  1046. this.isActive = 0;
  1047. break;
  1048. }
  1049. // Update the horizontal benchmark of the default data
  1050. this.curPageArr.forEach((sampleObject) => {
  1051. if (sampleObject.charObj) {
  1052. sampleObject.charData.oriData.forEach((originData, index) => {
  1053. const seriesData = sampleObject.charData.charOption.series;
  1054. const oriIndexData = sampleObject.charData.oriData[index];
  1055. if (sampleObject.log) {
  1056. seriesData[index * 2].data = this.formateSmoothData(
  1057. oriIndexData.logData[this.curBenchX],
  1058. );
  1059. seriesData[index * 2 + 1].data =
  1060. oriIndexData.logData[this.curBenchX];
  1061. } else {
  1062. seriesData[index * 2].data = this.formateSmoothData(
  1063. oriIndexData.valueData[this.curBenchX],
  1064. );
  1065. seriesData[index * 2 + 1].data =
  1066. oriIndexData.valueData[this.curBenchX];
  1067. }
  1068. });
  1069. const optionxAxis = sampleObject.charData.charOption.xAxis;
  1070. const seriesData = sampleObject.charData.charOption.series[0];
  1071. optionxAxis.minInterval = this.isActive === 0 ? 1 : 0;
  1072. optionxAxis.axisLabel.rotate = this.isActive === 2 ? 0 : 90;
  1073. sampleObject.updateFlag = true;
  1074. sampleObject.charObj.clear();
  1075. if (seriesData.data.length === 1) {
  1076. seriesData.showSymbol = true;
  1077. sampleObject.onePoint = true;
  1078. } else {
  1079. seriesData.showSymbol = false;
  1080. sampleObject.onePoint = false;
  1081. }
  1082. this.updateOrCreateChar(sampleObject.sampleIndex, true);
  1083. }
  1084. });
  1085. }, 500);
  1086. },
  1087. /**
  1088. * Page number change event
  1089. * @param {Number} pageIndex (1~n)
  1090. */
  1091. currentPageChange(pageIndex) {
  1092. this.pageIndex = pageIndex - 1;
  1093. // Load the data on the current page
  1094. this.getCurPageDataArr();
  1095. },
  1096. /**
  1097. * The selected label is changed
  1098. * @param {Object} selectedItemDict Dictionary containing the selected tags
  1099. */
  1100. tagSelectedChanged(selectedItemDict) {
  1101. if (!selectedItemDict) {
  1102. return;
  1103. }
  1104. if (this.isTimeReload) {
  1105. this.autoUpdateSamples();
  1106. }
  1107. this.multiSelectedTagNames = selectedItemDict;
  1108. // Reset to the first page
  1109. this.pageIndex = 0;
  1110. this.updateTagInPage();
  1111. },
  1112. /**
  1113. *Window resize
  1114. */
  1115. resizeCallback() {
  1116. if (!this.compare) {
  1117. if (this.isTimeReload) {
  1118. this.autoUpdateSamples();
  1119. }
  1120. if (this.charResizeTimer) {
  1121. clearTimeout(this.charResizeTimer);
  1122. this.charResizeTimer = null;
  1123. }
  1124. this.charResizeTimer = setTimeout(() => {
  1125. this.curPageArr.forEach((sampleItem) => {
  1126. if (sampleItem.charObj) {
  1127. sampleItem.charObj.resize();
  1128. }
  1129. });
  1130. }, 500);
  1131. }
  1132. },
  1133. /**
  1134. * Clear data
  1135. */
  1136. clearAllData() {
  1137. this.multiSelectedTagNames = {};
  1138. this.curFilterSamples = [];
  1139. this.tagOperateList = [];
  1140. this.pageIndex = 0;
  1141. this.originDataArr = [];
  1142. this.oriDataDictionaries = {};
  1143. this.curPageArr = [];
  1144. this.tagPropsList = [];
  1145. this.propsList = [];
  1146. },
  1147. /**
  1148. * Error
  1149. * @param {Object} error Error object
  1150. */
  1151. requestErrorCallback(error) {
  1152. if (!this.initOver) {
  1153. this.initOver = true;
  1154. }
  1155. if (this.isReloading) {
  1156. this.$store.commit('setIsReload', false);
  1157. this.isReloading = false;
  1158. }
  1159. if (error.response && error.response.data) {
  1160. this.clearAllData();
  1161. } else {
  1162. if (
  1163. !(error.code === 'ECONNABORTED' && /^timeout/.test(error.message))
  1164. ) {
  1165. // Clear data
  1166. this.clearAllData();
  1167. }
  1168. }
  1169. },
  1170. /**
  1171. * Delete the data that does not exist
  1172. * @param {Object} oriData Original run and tag data
  1173. */
  1174. removeNonexistentData(oriData) {
  1175. if (!oriData) {
  1176. return false;
  1177. }
  1178. const newTagDictionaries = {}; // Index of the tag in the new data
  1179. let dataRemoveFlag = false;
  1180. oriData.tags.forEach((tagName) => {
  1181. newTagDictionaries[tagName] = true;
  1182. });
  1183. // Delete the tag that does not exist
  1184. const oldTagListLength = this.tagOperateList.length;
  1185. for (let i = oldTagListLength - 1; i >= 0; i--) {
  1186. if (!newTagDictionaries[this.tagOperateList[i].label]) {
  1187. dataRemoveFlag = true;
  1188. delete this.oriDataDictionaries[this.tagOperateList[i].label];
  1189. this.tagOperateList.splice(i, 1);
  1190. }
  1191. }
  1192. // Except the old data in the chart
  1193. const oldSampleLength = this.originDataArr.length;
  1194. for (let i = oldSampleLength - 1; i >= 0; i--) {
  1195. const oldSample = this.originDataArr[i];
  1196. if (!newTagDictionaries[oldSample.tagName]) {
  1197. dataRemoveFlag = true;
  1198. this.originDataArr.splice(i, 1);
  1199. }
  1200. }
  1201. return dataRemoveFlag;
  1202. },
  1203. /**
  1204. * Check and add new data
  1205. * @param {Object} oriData Original run and tag data
  1206. */
  1207. checkNewDataAndComplete(oriData) {
  1208. if (!oriData) {
  1209. return false;
  1210. }
  1211. let dataAddFlag = false;
  1212. const runColor = CommonProperty.commonColorArr[0];
  1213. oriData.tags.forEach((tagObj) => {
  1214. if (!this.oriDataDictionaries[tagObj]) {
  1215. this.oriDataDictionaries[tagObj] = true;
  1216. this.tagOperateList.push({
  1217. label: tagObj,
  1218. checked: true,
  1219. show: false,
  1220. });
  1221. const sampleIndex = this.originDataArr.length;
  1222. dataAddFlag = true;
  1223. this.originDataArr.push({
  1224. tagName: tagObj,
  1225. runNames: oriData.name,
  1226. colors: runColor,
  1227. show: false,
  1228. updateFlag: false,
  1229. dataRemove: false,
  1230. fullScreen: false,
  1231. sampleIndex: sampleIndex,
  1232. domId: 'prDom' + this.DomIdIndex,
  1233. charData: {
  1234. oriData: [],
  1235. charOption: {},
  1236. },
  1237. zoomData: [null, null],
  1238. zoomDataTimer: null,
  1239. charObj: null,
  1240. });
  1241. this.DomIdIndex++;
  1242. }
  1243. });
  1244. return dataAddFlag;
  1245. },
  1246. /**
  1247. * Update all data
  1248. * @param {Boolean} ignoreError Whether ignore error tip
  1249. */
  1250. updateAllData(ignoreError) {
  1251. const params = {
  1252. plugin_name: 'scalar',
  1253. train_id: this.trainingJobId,
  1254. };
  1255. RequestService.getSingleTrainJob(params, ignoreError)
  1256. .then((res) => {
  1257. if (this.isReloading) {
  1258. this.$store.commit('setIsReload', false);
  1259. this.isReloading = false;
  1260. }
  1261. // Fault tolerance processing
  1262. if (!res || !res.data) {
  1263. return;
  1264. } else if (!res.data.train_jobs || !res.data.train_jobs.length) {
  1265. this.clearAllData();
  1266. return;
  1267. }
  1268. const data = res.data.train_jobs[0];
  1269. // Delete the data that does not exist
  1270. const tagRemoveFlag = this.removeNonexistentData(data);
  1271. // Check whether new data exists and add it to the page
  1272. const tagAddFlag = this.checkNewDataAndComplete(data);
  1273. this.$nextTick(() => {
  1274. this.multiSelectedTagNames = this.$refs.multiselectGroupComponents.updateSelectedDic();
  1275. this.updateTagInPage(!tagRemoveFlag && !tagAddFlag);
  1276. this.resizeCallback();
  1277. });
  1278. const tempTagList = [];
  1279. const propsList = [];
  1280. // Initial chart data
  1281. data.tags.forEach((tagObj) => {
  1282. // Check whether the tag with the same name exists
  1283. tempTagList.push({
  1284. label: tagObj,
  1285. checked: true,
  1286. show: true,
  1287. });
  1288. // Add the tag list
  1289. propsList.push({
  1290. tagName: tagObj,
  1291. runNames: data.name,
  1292. colors: '',
  1293. });
  1294. });
  1295. this.tagPropsList = tempTagList;
  1296. this.propsList = propsList;
  1297. }, this.requestErrorCallback)
  1298. .catch((e) => {
  1299. this.$message.error(this.$t('public.dataError'));
  1300. });
  1301. },
  1302. /**
  1303. * Updata smoothness
  1304. * @param {String} value Slide value
  1305. */
  1306. updataInputValue(val) {
  1307. if (this.firstNum === 0) {
  1308. return;
  1309. }
  1310. this.smoothValueNumber = Number(val);
  1311. if (this.smoothSliderValueTimer) {
  1312. clearTimeout(this.smoothSliderValueTimer);
  1313. this.smoothSliderValueTimer = null;
  1314. }
  1315. this.smoothSliderValueTimer = setTimeout(() => {
  1316. // Change the smoothness
  1317. this.setCharLineSmooth();
  1318. }, 500);
  1319. },
  1320. smoothValueChange(val) {
  1321. if (!isNaN(val)) {
  1322. if (Number(val) === 0) {
  1323. this.smoothValue = 0;
  1324. }
  1325. if (Number(val) < 0) {
  1326. this.smoothValue = 0;
  1327. this.smoothValueNumber = 0;
  1328. }
  1329. if (Number(val) > 0) {
  1330. if (Number(val) > 0.99) {
  1331. this.smoothValue = 0.99;
  1332. this.smoothValueNumber = 0.99;
  1333. } else {
  1334. this.smoothValue = Number(val);
  1335. }
  1336. }
  1337. }
  1338. },
  1339. smoothValueBlur() {
  1340. this.smoothValueNumber = this.smoothValue;
  1341. },
  1342. /**
  1343. * Format absolute Time
  1344. * @param {String} time String
  1345. * @return {string} Str
  1346. */
  1347. dealrelativeTime(time) {
  1348. const arr = time.split(' ');
  1349. const str = arr[0] + ' ' + arr[1] + ' ' + arr[2] + ',' + ' ' + arr[4];
  1350. return str;
  1351. },
  1352. /**
  1353. * Setting the smoothness
  1354. */
  1355. setCharLineSmooth() {
  1356. if (this.curPageArr.length < 1) {
  1357. return;
  1358. }
  1359. if (this.isTimeReload) {
  1360. this.autoUpdateSamples();
  1361. }
  1362. // Update the smoothness of initialized data
  1363. this.curPageArr.forEach((sampleObject) => {
  1364. if (sampleObject.charObj) {
  1365. const log = sampleObject.log;
  1366. sampleObject.charData.charOption.series.forEach((serie, index) => {
  1367. if (index % 2 === 0) {
  1368. if (log) {
  1369. serie.data = this.formateSmoothData(
  1370. sampleObject.charData.oriData[index / 2].logData[
  1371. this.curBenchX
  1372. ],
  1373. );
  1374. } else {
  1375. serie.data = this.formateSmoothData(
  1376. sampleObject.charData.oriData[index / 2].valueData[
  1377. this.curBenchX
  1378. ],
  1379. );
  1380. }
  1381. }
  1382. });
  1383. sampleObject.updateFlag = true;
  1384. this.updateOrCreateChar(sampleObject.sampleIndex);
  1385. }
  1386. });
  1387. },
  1388. /**
  1389. * Format smooth data
  1390. * @param {Object} oriData
  1391. * @return {Object} Data
  1392. */
  1393. formateSmoothData(oriData) {
  1394. if (!oriData || oriData.length < 2) {
  1395. return oriData;
  1396. }
  1397. const data = JSON.parse(JSON.stringify(oriData));
  1398. const oriDataLength = oriData.length;
  1399. let last = 0;
  1400. const smoothValue = this.smoothValue;
  1401. let numAccun = 0;
  1402. const firstValue = data[0][1];
  1403. const isAllSame = data.every((curData) => {
  1404. return curData[1] === firstValue;
  1405. });
  1406. for (let i = 0; i < oriDataLength; i++) {
  1407. const curValue = data[i][1];
  1408. if (!isAllSame && Number.isFinite(curValue)) {
  1409. last = last * smoothValue + (1 - smoothValue) * curValue;
  1410. numAccun++;
  1411. let debiasWeight = 1;
  1412. if (smoothValue !== 1) {
  1413. debiasWeight = 1 - Math.pow(smoothValue, numAccun);
  1414. }
  1415. data[i][1] = last / debiasWeight;
  1416. }
  1417. }
  1418. return data;
  1419. },
  1420. /**
  1421. * Format the value of the Y axis
  1422. * @param {String} value number y
  1423. * @return {Number}
  1424. */
  1425. formateYaxisValue(value) {
  1426. if (!value) {
  1427. return value;
  1428. }
  1429. const symbol = Math.abs(value);
  1430. if (symbol.toString().length > 6) {
  1431. return value.toExponential(4);
  1432. } else if (value > 0) {
  1433. return value;
  1434. } else {
  1435. return parseFloat(value.toFixed(3));
  1436. }
  1437. },
  1438. /**
  1439. * YAxis Scale
  1440. * @param {Number} sampleIndex Number
  1441. */
  1442. yAxisScale(sampleIndex) {
  1443. if (this.isTimeReload) {
  1444. this.autoUpdateSamples();
  1445. }
  1446. if (this.yAxisScaleTimer) {
  1447. clearTimeout(this.yAxisScaleTimer);
  1448. this.yAxisScaleTimer = null;
  1449. }
  1450. const sampleObject = this.originDataArr[sampleIndex];
  1451. if (!sampleObject) {
  1452. return;
  1453. }
  1454. // There is no logarithm of 0 and negative numbers
  1455. if (sampleObject.max <= 0) {
  1456. return;
  1457. }
  1458. this.yAxisScaleTimer = setTimeout(() => {
  1459. const tempOption = sampleObject.charData.charOption;
  1460. const tempOriData = sampleObject.charData.oriData;
  1461. const log = !sampleObject.log;
  1462. if (log) {
  1463. tempOption.toolbox.feature.myTool2.iconStyle.borderColor = '#00A5A7';
  1464. tempOption.yAxis.type = 'log';
  1465. // Logarithmic axis scale ascending, maximum scale 1
  1466. if (sampleObject.max < 1 && sampleObject.isEqual) {
  1467. tempOption.yAxis.inverse = true;
  1468. }
  1469. } else {
  1470. tempOption.yAxis.type = 'value';
  1471. tempOption.toolbox.feature.myTool2.iconStyle.borderColor = '#666';
  1472. tempOption.yAxis.inverse = false;
  1473. }
  1474. tempOriData.forEach((originData, index) => {
  1475. if (log) {
  1476. tempOption.series[index * 2].data = this.formateSmoothData(
  1477. tempOriData[index].logData[this.curBenchX],
  1478. );
  1479. tempOption.series[index * 2 + 1].data =
  1480. tempOriData[index].logData[this.curBenchX];
  1481. } else {
  1482. tempOption.series[index * 2].data = this.formateSmoothData(
  1483. tempOriData[index].valueData[this.curBenchX],
  1484. );
  1485. tempOption.series[index * 2 + 1].data =
  1486. tempOriData[index].valueData[this.curBenchX];
  1487. }
  1488. });
  1489. sampleObject.log = log;
  1490. sampleObject.updateFlag = true;
  1491. sampleObject.charObj.clear();
  1492. const dataObj = tempOption.series[0];
  1493. // One point
  1494. if (dataObj.data.length === 1) {
  1495. tempOption.series[0].showSymbol = true;
  1496. sampleObject.onePoint = true;
  1497. } else {
  1498. tempOption.series[0].showSymbol = false;
  1499. sampleObject.onePoint = false;
  1500. }
  1501. if (
  1502. tempOption.visualMap &&
  1503. tempOption.visualMap['pieces'] &&
  1504. tempOption.visualMap['pieces'].length > 0
  1505. ) {
  1506. tempOption.visualMap = null;
  1507. tempOption.series[0].markLine = null;
  1508. sampleObject.charObj.setOption(tempOption, true);
  1509. this.updateVisualMap(sampleObject);
  1510. } else {
  1511. this.updateOrCreateChar(sampleIndex);
  1512. }
  1513. }, 500);
  1514. },
  1515. /**
  1516. * Scalar synthesis
  1517. */
  1518. compareClick() {
  1519. this.compare = !this.compare;
  1520. if (this.compare) {
  1521. this.scalarCompare = this.$t('scalar.compareCancel');
  1522. this.$bus.$emit('updateTag');
  1523. } else {
  1524. this.scalarCompare = this.$t('scalar.comparison');
  1525. this.curPageArr.forEach((sampleObject) => {
  1526. // Draw chart
  1527. if (!sampleObject.charObj) {
  1528. this.updateOrCreateChar(sampleObject.sampleIndex);
  1529. }
  1530. });
  1531. this.$nextTick(() => {
  1532. this.resizeCallback();
  1533. });
  1534. }
  1535. },
  1536. /**
  1537. * Jump back to train dashboard
  1538. */
  1539. jumpToTrainDashboard() {
  1540. this.$router.push({
  1541. path: '/train-manage/training-dashboard',
  1542. query: {
  1543. id: this.trainingJobId,
  1544. },
  1545. });
  1546. },
  1547. },
  1548. components: {
  1549. ScalarButton,
  1550. ScalarCompare,
  1551. multiselectGroupComponents,
  1552. },
  1553. };
  1554. </script>
  1555. <style lang="scss">
  1556. .cl-scalar-manage {
  1557. height: 100%;
  1558. .el-dialog {
  1559. border-radius: 4px;
  1560. }
  1561. .el-dialog__header {
  1562. padding: 15px 15px 10px;
  1563. font-size: 14px;
  1564. .el-dialog__title {
  1565. font-size: 14px;
  1566. }
  1567. }
  1568. .el-dialog__body {
  1569. padding: 10px 15px;
  1570. }
  1571. .el-dialog__footer {
  1572. padding: 5px 15px 10px;
  1573. }
  1574. .w60 {
  1575. width: 60px;
  1576. margin-left: 20px;
  1577. }
  1578. .w261 {
  1579. width: 261px;
  1580. }
  1581. .smallSelect {
  1582. width: 80px;
  1583. }
  1584. .smallSelectTwo {
  1585. width: 100px;
  1586. }
  1587. .smallInput {
  1588. width: 120px;
  1589. }
  1590. .scalar-btn {
  1591. height: 32px;
  1592. line-height: 32px;
  1593. padding: 0 20px;
  1594. color: #00a5a7;
  1595. border: 1px solid #00a5a7;
  1596. border-radius: 2px;
  1597. }
  1598. .borderspacing3 {
  1599. border-spacing: 3px;
  1600. }
  1601. .scalar-bk {
  1602. height: 100%;
  1603. background-color: #fff;
  1604. display: flex;
  1605. flex-direction: column;
  1606. .path-message {
  1607. display: inline-block;
  1608. line-height: 20px;
  1609. padding: 0px 4px 15px 4px;
  1610. font-weight: bold;
  1611. vertical-align: bottom;
  1612. }
  1613. .cl-scalar-title {
  1614. height: 56px;
  1615. line-height: 56px;
  1616. }
  1617. }
  1618. .select-all {
  1619. flex-shrink: 0;
  1620. cursor: pointer;
  1621. }
  1622. .cl-eval-operate-content {
  1623. width: 100%;
  1624. padding: 8px 32px 22px 32px;
  1625. background: #ffffff;
  1626. .tag-select-content {
  1627. display: flex;
  1628. align-items: center;
  1629. .title {
  1630. flex-shrink: 0;
  1631. }
  1632. .select-item-content {
  1633. display: flex;
  1634. height: 16px;
  1635. flex-wrap: wrap;
  1636. overflow: hidden;
  1637. text-overflow: ellipsis;
  1638. }
  1639. .run-select-content-open {
  1640. flex: 1;
  1641. text-align: right;
  1642. font-size: 14px;
  1643. color: #00a5a7;
  1644. cursor: pointer;
  1645. min-width: 60px;
  1646. }
  1647. }
  1648. .run-select-content-all {
  1649. max-height: 150px;
  1650. padding-left: 72px;
  1651. overflow-x: hidden;
  1652. display: flex;
  1653. flex-wrap: wrap;
  1654. .label-item {
  1655. line-height: 14px;
  1656. }
  1657. .select-item {
  1658. height: 25px;
  1659. margin-top: 25px;
  1660. }
  1661. }
  1662. .select-item {
  1663. margin-right: 20px;
  1664. flex-shrink: 0;
  1665. margin-bottom: 1px;
  1666. cursor: pointer;
  1667. .label-item {
  1668. width: 100px;
  1669. display: block;
  1670. text-overflow: ellipsis;
  1671. white-space: nowrap;
  1672. overflow: hidden;
  1673. text-align: left;
  1674. }
  1675. }
  1676. .multiCheckBox-border {
  1677. width: 16px;
  1678. height: 16px;
  1679. display: block;
  1680. margin-right: 20px;
  1681. cursor: pointer;
  1682. float: left;
  1683. }
  1684. .checkbox-checked {
  1685. background-image: url('../../assets/images/mult-select.png');
  1686. }
  1687. .checkbox-unchecked {
  1688. background-image: url('../../assets/images/mult-unselect.png');
  1689. }
  1690. .checkbox-disabled {
  1691. opacity: 0.2;
  1692. }
  1693. .label-item {
  1694. font-size: 14px;
  1695. line-height: 14px;
  1696. vertical-align: middle;
  1697. .el-tooltip {
  1698. text-overflow: ellipsis;
  1699. white-space: nowrap;
  1700. overflow: hidden;
  1701. text-align: left;
  1702. height: 16px;
  1703. }
  1704. span {
  1705. font-size: 14px;
  1706. line-height: 14px;
  1707. display: block;
  1708. }
  1709. }
  1710. }
  1711. .cl-eval-slider-operate-content {
  1712. background: #ffffff;
  1713. padding: 0 32px 21px 32px;
  1714. display: flex;
  1715. align-items: center;
  1716. border-bottom: 2px solid #e6ebf5;
  1717. .xaxis-title {
  1718. font-size: 14px;
  1719. line-height: 14px;
  1720. vertical-align: middle;
  1721. margin-right: 16px;
  1722. flex-shrink: 0;
  1723. }
  1724. .el-radio-group {
  1725. margin-right: 64px;
  1726. flex-shrink: 0;
  1727. }
  1728. .el-select {
  1729. width: 163px;
  1730. margin-right: 16px;
  1731. flex-shrink: 0;
  1732. }
  1733. .el-slider {
  1734. width: 400px;
  1735. flex-shrink: 0;
  1736. .el-input.el-input--small {
  1737. width: 60px;
  1738. }
  1739. .el-input-number .el-input__inner {
  1740. padding-left: 0px;
  1741. padding-right: 0px;
  1742. }
  1743. .el-input-number--small .el-input-number__increase {
  1744. display: none;
  1745. }
  1746. .el-input-number--small .el-input-number__decrease {
  1747. display: none;
  1748. }
  1749. }
  1750. }
  1751. .cl-eval-show-data-content {
  1752. background: #fff;
  1753. flex: 1;
  1754. overflow-y: auto;
  1755. display: flex;
  1756. flex-wrap: wrap;
  1757. padding-right: 10px;
  1758. .data-content {
  1759. display: flex;
  1760. height: 100%;
  1761. width: 100%;
  1762. flex-wrap: wrap;
  1763. min-height: 400px;
  1764. padding-left: 20px;
  1765. .sample-content {
  1766. width: 33.3%;
  1767. height: 400px;
  1768. display: flex;
  1769. flex-direction: column;
  1770. flex-shrink: 0;
  1771. padding-right: 20px;
  1772. margin-top: 20px;
  1773. }
  1774. .char-full-screen {
  1775. width: 100%;
  1776. height: 400px;
  1777. }
  1778. }
  1779. .chars-container {
  1780. flex: 1;
  1781. position: relative;
  1782. background-color: #edf0f5;
  1783. padding: 5px;
  1784. }
  1785. .chartThreshold {
  1786. height: 40px;
  1787. background-color: #edf0f5;
  1788. border-top: 1px solid #fff;
  1789. display: flex;
  1790. line-height: 40px;
  1791. .chartThresholdLeft {
  1792. flex: 1;
  1793. text-align: left;
  1794. padding-left: 5px;
  1795. font-size: 14px;
  1796. color: #6c7280;
  1797. white-space: nowrap;
  1798. overflow: hidden;
  1799. text-overflow: ellipsis;
  1800. }
  1801. .chartThresholdRight {
  1802. width: 120px;
  1803. text-align: right;
  1804. padding-right: 10px;
  1805. font-size: 12px;
  1806. color: #00a5a7;
  1807. flex-shrink: 0;
  1808. span {
  1809. cursor: pointer;
  1810. width: auto;
  1811. height: 39px;
  1812. display: inline-block;
  1813. }
  1814. }
  1815. }
  1816. .tag-name {
  1817. color: #333;
  1818. font-size: 16px;
  1819. overflow: hidden;
  1820. text-overflow: ellipsis;
  1821. font-weight: 600;
  1822. text-align: center;
  1823. margin-top: 10px;
  1824. i {
  1825. color: #e6a23c;
  1826. }
  1827. }
  1828. .char-item-content {
  1829. width: 100%;
  1830. height: 100%;
  1831. background-color: #fff;
  1832. }
  1833. .char-tip-table {
  1834. td {
  1835. padding-left: 5px;
  1836. padding-right: 5px;
  1837. text-overflow: ellipsis;
  1838. white-space: nowrap;
  1839. max-width: 150px;
  1840. overflow: hidden;
  1841. }
  1842. }
  1843. .image-noData {
  1844. width: 100%;
  1845. height: 100%;
  1846. display: flex;
  1847. justify-content: center;
  1848. align-items: center;
  1849. flex-direction: column;
  1850. }
  1851. .noData-text {
  1852. margin-top: 33px;
  1853. font-size: 18px;
  1854. }
  1855. }
  1856. .pagination-content {
  1857. text-align: right;
  1858. padding: 24px 32px;
  1859. }
  1860. .mr24 {
  1861. margin-right: 24px;
  1862. }
  1863. .select-disable {
  1864. -moz-user-select: none; /*Firefox*/
  1865. -webkit-user-select: none; /*Webkit*/
  1866. -ms-user-select: none; /*IE10*/
  1867. -khtml-user-select: none;
  1868. user-select: none;
  1869. }
  1870. .cl-close-btn {
  1871. width: 20px;
  1872. height: 20px;
  1873. vertical-align: -3px;
  1874. cursor: pointer;
  1875. display: inline-block;
  1876. line-height: 20px;
  1877. margin-left: 32px;
  1878. }
  1879. .thresholdAll {
  1880. display: flex;
  1881. line-height: 32px;
  1882. margin-bottom: 10px;
  1883. .thresholdItem {
  1884. margin-right: 10px;
  1885. }
  1886. .thresholdItemWidth {
  1887. width: 500px;
  1888. height: 32px;
  1889. margin-right: 10px;
  1890. overflow: hidden;
  1891. text-overflow: ellipsis;
  1892. }
  1893. }
  1894. .thresholdError {
  1895. color: #f56c6c;
  1896. text-align: center;
  1897. }
  1898. .fs16 {
  1899. font-size: 14px;
  1900. color: #6c7280;
  1901. width: 180px;
  1902. }
  1903. }
  1904. .tooltip-show-content {
  1905. max-width: 50%;
  1906. }
  1907. .cl-title-right {
  1908. padding-right: 20px;
  1909. }
  1910. .delDialog {
  1911. .delThresholdItem {
  1912. display: flex;
  1913. margin-bottom: 10px;
  1914. }
  1915. .delThresholdIcon {
  1916. color: #e6a23c;
  1917. font-size: 24px;
  1918. width: 40px;
  1919. margin-right: 10px;
  1920. }
  1921. .delThresholdInfo {
  1922. line-height: 24px;
  1923. height: 24px;
  1924. }
  1925. }
  1926. </style>