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.

model-traceback.vue 78 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
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276
  1. <!--
  2. Copyright 2020 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-model-traceback">
  15. <div class="traceback-tab">
  16. <div class="traceback-tab-item item-active">{{$t("summaryManage.modelTraceback")}}</div>
  17. <div class="traceback-tab-item"
  18. @click="jumpToDataTraceback()">{{$t("summaryManage.dataTraceback")}}</div>
  19. </div>
  20. <div id="model-traceback-con">
  21. <div v-if="loading"
  22. class="no-data-page">
  23. <div class="no-data-img">
  24. <img :src="require('@/assets/images/nodata.png')"
  25. alt="" />
  26. <p class="no-data-text">{{$t("public.dataLoading")}}</p>
  27. </div>
  28. </div>
  29. <div class="cl-model-left"
  30. :class="{collapse:collapse}"
  31. v-show="!loading && !errorData">
  32. <div class="left-chart-container"
  33. v-show="!collapse && !errorData">
  34. <div class="left-title">
  35. <div class="title-style">{{$t('modelTraceback.optimizationObject')}}</div>
  36. <div class="pie-select-style">
  37. <el-select v-model="targetValue"
  38. class="left-select"
  39. @change="targetSelectChange()">
  40. <el-option v-for="item in targetOptions"
  41. :key="item.value"
  42. :label="item.label"
  43. :value="item.value">
  44. </el-option>
  45. </el-select>
  46. </div>
  47. </div>
  48. <!-- pie chart -->
  49. <div class="pie-module-container">
  50. <div class="title-container">
  51. <div class="pie-title">{{$t('modelTraceback.targetDistribution')}}</div>
  52. </div>
  53. <div id="pie-chart"></div>
  54. </div>
  55. <!-- bar -->
  56. <div class="bar-module-container">
  57. <div class="bar-title-container">
  58. <div class="bar-title"> {{$t('modelTraceback.parameterImportance')}}</div>
  59. <div class="inline-block-set bar-select">
  60. <!-- Parameter importance drop-down box -->
  61. <el-select v-model="selectedBarArray"
  62. multiple
  63. collapse-tags
  64. @change="selectedBarNameListChange"
  65. :placeholder="$t('public.select')"
  66. @focus="selectinputFocus('left')">
  67. <div class="select-input-button">
  68. <div class="select-inner-input">
  69. <el-input v-model="barKeyWord"
  70. @input="myfilter('left')"
  71. :placeholder="$t('public.search')"
  72. ref="barKeyInput"></el-input>
  73. </div>
  74. <button type="text"
  75. @click="barAllSelect"
  76. class="select-all-button"
  77. :class="[selectedAllBar ? 'checked-color' : 'button-text',
  78. (baseOptions.length > searchOptions.length)||!canSelected.length ? 'btn-disabled' : '']"
  79. :disabled="(baseOptions.length > searchOptions.length)||!canSelected.length">
  80. {{$t('public.selectAll')}}
  81. </button>
  82. <button type="text"
  83. @click="barDeselectAll"
  84. class="deselect-all-button"
  85. :class="[!selectedAllBar ? 'checked-color' : 'button-text',
  86. (baseOptions.length > searchOptions.length)||!canSelected.length ? 'btn-disabled' : '']"
  87. :disabled="(baseOptions.length > searchOptions.length)||!canSelected.length">
  88. {{$t('public.deselectAll')}}
  89. </button>
  90. </div>
  91. <el-option-group v-for="group in barNameList"
  92. :key="group.label"
  93. :label="group.label">
  94. <el-option v-for="item in group.options"
  95. :key="item.value"
  96. :label="item.label"
  97. :value="item.value"
  98. :disabled="item.disabled||item.unselected"
  99. :title="item.message ? item.message : item.disabled ?
  100. $t('modelTraceback.mustExist') : ''">
  101. </el-option>
  102. </el-option-group>
  103. <div slot="empty">
  104. <div class="select-input-button empty-container">
  105. <div class="select-inner-input">
  106. <el-input v-model="barKeyWord"
  107. @input="myfilter('left')"
  108. :placeholder="$t('public.search')"
  109. ref="barKeyEmptyInput"></el-input>
  110. </div>
  111. <button type="text"
  112. class="select-all-button"
  113. disabled>
  114. {{$t('public.selectAll')}}
  115. </button>
  116. <button type="text"
  117. class="deselect-all-button"
  118. disabled>
  119. {{$t('public.deselectAll')}}
  120. </button>
  121. <div class="search-no-data">{{$t('public.emptyData')}}</div>
  122. </div>
  123. </div>
  124. </el-select>
  125. </div>
  126. </div>
  127. <div id="bar-chart"></div>
  128. </div>
  129. <!-- scatter -->
  130. <div class="scatter-container">
  131. <div class="scatter-title-container">
  132. <div>
  133. {{$t('modelTraceback.optimizationTitle')}}
  134. <el-tooltip class="item"
  135. effect="light"
  136. placement="top">
  137. <div slot="content"
  138. class="tooltip-container">
  139. {{$t('modelTraceback.targetTips')}}
  140. </div>
  141. <i class="el-icon-info"></i>
  142. </el-tooltip>
  143. </div>
  144. <div class="right-view">
  145. <div class="view-big"
  146. @click="viewLargeImage"
  147. :disabled="viewBigBtnDisabled"
  148. :class="[viewBigBtnDisabled ? 'btn-disabled' : '']"
  149. :title="$t('modelTraceback.viewBigImage')">
  150. </div>
  151. </div>
  152. </div>
  153. <div class="left-scatters-container">
  154. <Scatter ref="smallScatter"
  155. :data="scatterChartData"
  156. :yTitle="yTitle"
  157. :xTitle="xTitle"
  158. :tooltipsData="tooltipsData"
  159. :showTooltip="true">
  160. </Scatter>
  161. </div>
  162. </div>
  163. </div>
  164. <div class="collapse-btn"
  165. :class="{collapse:collapse}"
  166. @click="collapseLeft()">
  167. </div>
  168. </div>
  169. <!-- Model traceability right column -->
  170. <div class="cl-model-right"
  171. v-if="!loading"
  172. :class="{collapse:collapse}">
  173. <div class="top-area"
  174. v-show="!noData && showEchartPic && !loading">
  175. <div class="select-box"
  176. v-if="!noData &&
  177. (!summaryDirList || (summaryDirList && summaryDirList.length))">
  178. <div v-show="showTable && !noData"
  179. class="select-container">
  180. <!-- multiple collapse-tags -->
  181. <div class="display-column"> {{$t('modelTraceback.displayColumn')}}</div>
  182. <div class="inline-block-set">
  183. <el-select v-model="selectArrayValue"
  184. multiple
  185. collapse-tags
  186. @change="selectValueChange"
  187. :placeholder="$t('public.select')"
  188. @focus="selectinputFocus">
  189. <div class="select-input-button">
  190. <div class="select-inner-input">
  191. <el-input v-model="keyWord"
  192. @input="myfilter"
  193. :placeholder="$t('public.search')"
  194. ref="keyInput"></el-input>
  195. </div>
  196. <button type="text"
  197. @click="allSelect"
  198. class="select-all-button"
  199. :class="[selectCheckAll ? 'checked-color' : 'button-text',
  200. rightAllOptions.length > showOptions.length ? 'btn-disabled' : '']"
  201. :disabled="rightAllOptions.length > showOptions.length">
  202. {{$t('public.selectAll')}}
  203. </button>
  204. <button type="text"
  205. @click="deselectAll"
  206. class="deselect-all-button"
  207. :class="[!selectCheckAll ? 'checked-color' : 'button-text',
  208. rightAllOptions.length > showOptions.length ? 'btn-disabled' : '']"
  209. :disabled="rightAllOptions.length > showOptions.length">
  210. {{$t('public.deselectAll')}}
  211. </button>
  212. </div>
  213. <el-option-group v-for="group in checkOptions"
  214. :key="group.label"
  215. :label="group.label">
  216. <el-option v-for="item in group.options"
  217. :key="item.value"
  218. :label="item.label"
  219. :value="item.value"
  220. :disabled="item.disabled"
  221. :title="item.disabled ? $t('modelTraceback.mustExist') : ''">
  222. </el-option>
  223. </el-option-group>
  224. <div slot="empty">
  225. <div class="select-input-button empty-container">
  226. <div class="select-inner-input">
  227. <el-input v-model="keyWord"
  228. @input="myfilter"
  229. :placeholder="$t('public.search')"
  230. ref="keyEmptyInput"></el-input>
  231. </div>
  232. <button type="text"
  233. class="select-all-button"
  234. disabled>
  235. {{$t('public.selectAll')}}
  236. </button>
  237. <button type="text"
  238. @click="deselectAll"
  239. class="deselect-all-button"
  240. disabled>
  241. {{$t('public.deselectAll')}}
  242. </button>
  243. <div class="search-no-data">{{$t('public.emptyData')}}</div>
  244. </div>
  245. </div>
  246. </el-select>
  247. </div>
  248. <div class="label-legend"
  249. v-if="haveCustomizedParams">
  250. <div>[U]: {{$t('modelTraceback.userDefined')}}</div>
  251. <div>[M]: {{$t('modelTraceback.metric')}}</div>
  252. </div>
  253. </div>
  254. </div>
  255. </div>
  256. <div id="echart"
  257. v-show="!noData && showEchartPic && !loading"></div>
  258. <div class="btns-container"
  259. v-show="showTable && !noData">
  260. <el-button type="primary"
  261. size="mini"
  262. @click="showSelectedModelData"
  263. :disabled="disabledFilterBtnModel"
  264. class="disabled-btn-color"
  265. :class="[!disabledFilterBtnModel ? 'abled-btn-color' : '']"
  266. plain>{{$t('modelTraceback.showSelected')}}</el-button>
  267. <el-button type="primary"
  268. size="mini"
  269. @click="hideSelectedModelRows"
  270. :disabled="disabledHideBtnModel"
  271. class="disabled-btn-color"
  272. :class="[!disabledHideBtnModel ? 'abled-btn-color' : '']"
  273. plain>{{$t('modelTraceback.hideSelected')}}</el-button>
  274. <el-button type="primary"
  275. size="mini"
  276. class="custom-btn"
  277. @click="showAllDatafun"
  278. plain>
  279. {{ $t('modelTraceback.showAllData') }}
  280. </el-button>
  281. </div>
  282. <div class="table-container"
  283. v-show="showTable && !noData">
  284. <div class="disabled-checked"
  285. v-show="!table.data.length"></div>
  286. <el-table ref="table"
  287. :data="table.data"
  288. tooltip-effect="light"
  289. height="calc(100% - 30px)"
  290. @selection-change="selectionChange"
  291. @sort-change="sortChange"
  292. row-key="summary_dir">
  293. <el-table-column type="selection"
  294. width="55"
  295. :reserve-selection="true"
  296. v-show="showTable && !noData">
  297. </el-table-column>
  298. <!--metric table column-->
  299. <el-table-column :label="$t('modelTraceback.metricLabel')"
  300. align="center"
  301. v-if="metricList.length">
  302. <el-table-column v-for="key in metricList"
  303. :key="key"
  304. :prop="key"
  305. :label="table.columnOptions[key].label.substring(3)"
  306. show-overflow-tooltip
  307. min-width="120"
  308. sortable="custom">
  309. <template slot="header"
  310. slot-scope="scope">
  311. <div class="custom-label"
  312. :title="scope.column.label">
  313. {{scope.column.label}}
  314. </div>
  315. </template>
  316. <template slot-scope="scope">
  317. <span>{{formatNumber(key,scope.row[key])}}</span>
  318. </template>
  319. </el-table-column>
  320. </el-table-column>
  321. <!--user Defined table column-->
  322. <el-table-column :label="$t('modelTraceback.userDefinedLabel')"
  323. align="center"
  324. v-if="userDefinedList.length">
  325. <el-table-column v-for="key in userDefinedList"
  326. :key="key"
  327. :prop="key"
  328. :label="table.columnOptions[key].label.substring(3)"
  329. show-overflow-tooltip
  330. min-width="120"
  331. sortable="custom">
  332. <template slot="header"
  333. slot-scope="scope">
  334. <div class="custom-label"
  335. :title="scope.column.label">
  336. {{scope.column.label}}
  337. </div>
  338. </template>
  339. <template slot-scope="scope">
  340. <span>{{formatNumber(key,scope.row[key])}}</span>
  341. </template>
  342. </el-table-column>
  343. </el-table-column>
  344. <!--hyper List table column-->
  345. <el-table-column :label="$t('modelTraceback.hyperLabel')"
  346. align="center"
  347. v-if="hyperList.length">
  348. <el-table-column v-for="key in hyperList"
  349. :key="key"
  350. :prop="key"
  351. :label="table.columnOptions[key].label"
  352. show-overflow-tooltip
  353. min-width="154"
  354. sortable="custom">
  355. <template slot="header"
  356. slot-scope="scope">
  357. <div class="custom-label"
  358. :title="scope.column.label">
  359. {{scope.column.label}}
  360. </div>
  361. </template>
  362. <template slot-scope="scope">
  363. <span>{{formatNumber(key, scope.row[key])}}</span>
  364. </template>
  365. </el-table-column>
  366. </el-table-column>
  367. <!--other column-->
  368. <el-table-column v-for="key in table.otherColumn"
  369. :key="key"
  370. :prop="key"
  371. :label="table.columnOptions[key].label"
  372. :fixed="table.columnOptions[key].label === text ? true : false"
  373. show-overflow-tooltip
  374. min-width="150"
  375. sortable="custom">
  376. <template slot="header"
  377. slot-scope="scope">
  378. <div class="custom-label"
  379. :title="scope.column.label">
  380. {{ scope.column.label }}
  381. </div>
  382. </template>
  383. <template slot-scope="scope">
  384. <a v-if="key === 'summary_dir'"
  385. @click="jumpToTrainDashboard(scope.row[key])">{{ scope.row[key] }}</a>
  386. <span v-else>{{ formatNumber(key, scope.row[key]) }}</span>
  387. </template>
  388. </el-table-column>
  389. <!-- remark column -->
  390. <el-table-column fixed="right"
  391. width="260">
  392. <template slot="header">
  393. <div>
  394. <div class="label-text">{{$t('public.remark')}}</div>
  395. <div class="remark-tip">{{$t('modelTraceback.remarkTips')}}</div>
  396. </div>
  397. </template>
  398. <template slot-scope="scope">
  399. <div class="edit-text-container"
  400. v-show="scope.row.editShow"
  401. :title="scope.row.remark">{{scope.row.remark}}</div>
  402. <div class="inline-block-set">
  403. <i class="el-icon-edit"
  404. @click="editRemarks(scope.row)"
  405. v-show="scope.row.editShow"></i>
  406. <el-input type="text"
  407. v-model="scope.row.remark"
  408. v-show="!scope.row.editShow"
  409. :placeholder="$t('public.enter')"
  410. class="remark-input-style"></el-input>
  411. <i class="el-icon-check"
  412. @click="saveRemarksValue(scope.row)"
  413. v-show="!scope.row.editShow"></i>
  414. <i class="el-icon-close"
  415. @click="cancelRemarksValue(scope.row)"
  416. v-show="!scope.row.editShow"></i>
  417. <div class="validation-error"
  418. v-show="scope.row.isError">
  419. {{$t('modelTraceback.remarkValidation')}}
  420. </div>
  421. </div>
  422. </template>
  423. </el-table-column>
  424. <!-- tag -->
  425. <el-table-column label="tag"
  426. fixed="right"
  427. prop="tag"
  428. sortable="custom">
  429. <template slot-scope="scope">
  430. <div @click="showAllIcon(scope.row, scope, $event)"
  431. class="tag-icon-container">
  432. <img v-if="scope.row.tag"
  433. :class="'img' + scope.$index"
  434. :src="require('@/assets/images/icon' + scope.row.tag + '.svg')">
  435. <img v-else
  436. :class="'img' + scope.$index"
  437. :src="require('@/assets/images/icon-down.svg')">
  438. </div>
  439. </template>
  440. </el-table-column>
  441. </el-table>
  442. <div class="pagination-container">
  443. <el-pagination @current-change="pagination.pageChange"
  444. @size-change="pagination.currentPagesizeChange"
  445. :current-page="pagination.currentPage"
  446. :page-size="pagination.pageSize"
  447. :page-sizes="pagination.pageSizes"
  448. :layout="pagination.layout"
  449. :total="pagination.total">
  450. </el-pagination>
  451. </div>
  452. </div>
  453. <div v-if="noData"
  454. class="no-data-page">
  455. <div class="no-data-img"
  456. :class="{'set-height-class':(summaryDirList && !summaryDirList.length)}">
  457. <img :src="require('@/assets/images/nodata.png')"
  458. alt />
  459. <p class="no-data-text"
  460. v-show="(!summaryDirList || (summaryDirList && summaryDirList.length)) &&
  461. (!hideTableIdList || (hideTableIdList&&!hideTableIdList.length))">
  462. {{ $t('public.noData') }}</p>
  463. <div v-show="(hideTableIdList && hideTableIdList.length) &&
  464. (!summaryDirList || (summaryDirList && summaryDirList.length))">
  465. <p class="no-data-text">{{ $t('modelTraceback.allHide') }}</p>
  466. <p class="no-data-text">
  467. <el-button type="primary"
  468. size="mini"
  469. class="custom-btn"
  470. @click="showAllDatafun"
  471. plain>
  472. {{ $t('modelTraceback.showAllData') }}
  473. </el-button>
  474. </p>
  475. </div>
  476. <div v-show="summaryDirList && !summaryDirList.length">
  477. <p class="no-data-text">{{ $t('modelTraceback.noDataFound') }}</p>
  478. <p class="no-data-text">
  479. <el-button type="primary"
  480. size="mini"
  481. class="custom-btn"
  482. @click="showAllDatafun"
  483. plain>
  484. {{ $t('modelTraceback.showAllData') }}
  485. </el-button>
  486. </p>
  487. </div>
  488. </div>
  489. </div>
  490. </div>
  491. <!-- tag dialog -->
  492. <div v-show="tagDialogShow"
  493. id="tag-dialog"
  494. class="icon-dialog">
  495. <div>
  496. <div class="icon-image-container">
  497. <div class="icon-image"
  498. v-for="item in imageList"
  499. :key="item.number"
  500. :class="[tagScope.row && item.number === tagScope.row.tag ? 'icon-border':'']"
  501. @click="iconValueChange(tagScope.row, item.number, $event)">
  502. <img :src="item.iconAdd">
  503. </div>
  504. </div>
  505. <div class="btn-container-margin">
  506. <div class="tag-button-container">
  507. <el-button type="primary"
  508. size="mini"
  509. class="custom-btn"
  510. @click="iconChangeSave(tagScope)"
  511. plain>
  512. {{$t('public.sure')}}
  513. </el-button>
  514. </div>
  515. <div class="tag-button-container">
  516. <el-button type="primary"
  517. size="mini"
  518. class="custom-btn"
  519. @click="clearIcon(tagScope, $event)"
  520. plain>
  521. {{$t('public.clear')}}
  522. </el-button>
  523. </div>
  524. <div class="tag-button-container">
  525. <el-button type="primary"
  526. size="mini"
  527. class="custom-btn"
  528. @click="cancelChangeIcon(tagScope.row)"
  529. plain>
  530. {{$t('public.cancel')}}
  531. </el-button>
  532. </div>
  533. </div>
  534. </div>
  535. </div>
  536. <!-- echart dialog -->
  537. <div v-show="echartDialogVisible">
  538. <el-dialog :title="$t('modelTraceback.optimizationTitle')"
  539. :visible.sync="echartDialogVisible"
  540. width="50%"
  541. :close-on-click-modal="false"
  542. class="echart-data-list">
  543. <div class="dialog-scatter">
  544. <Scatter ref="dialogScatter"
  545. :data="largeScatterChartData"
  546. :yTitle="yTitle"
  547. :xTitle="xTitle"
  548. :tooltipsData="tooltipsData"
  549. :showTooltip="true">
  550. </Scatter>
  551. </div>
  552. </el-dialog>
  553. </div>
  554. </div>
  555. </div>
  556. </template>
  557. <script>
  558. import RequestService from '../../services/request-service';
  559. import CommonProperty from '@/common/common-property.js';
  560. import Echarts from 'echarts';
  561. import Scatter from '@/components/scatter';
  562. import modelDataFun from '../../mixins/model-data.vue';
  563. export default {
  564. mixins: [modelDataFun],
  565. props: {},
  566. watch: {},
  567. data() {
  568. return {
  569. // left data
  570. searchOptions: [],
  571. baseOptions: [],
  572. // Expand and collapse the left column
  573. collapse: false,
  574. showLeftChart: null,
  575. // pie chart
  576. myPieChart: undefined,
  577. // bar chart
  578. myBarChart: undefined,
  579. barOption: {},
  580. // Check whether the big scatter icon can be clicked
  581. viewBigBtnDisabled: false,
  582. // Options that can be selected in the multiple selection drop-down box on the left
  583. canSelected: [],
  584. targetValue: '',
  585. targetOptions: [],
  586. targetLabel: '',
  587. targetData: [],
  588. scatterData: [],
  589. pieLegendData: [],
  590. pieSeriesData: [],
  591. barYAxisData: [],
  592. barSeriesData: [],
  593. currentBarData: {},
  594. scatterChartData: [],
  595. largeScatterChartData: [],
  596. // Scatter chart tips data
  597. tooltipsData: [],
  598. // The content of the bar graph drop-down box
  599. barNameList: [],
  600. // All values of the drop-down box initially saved
  601. baseSelectOptions: [],
  602. // Whether to select all the drop-down boxes of the histogram
  603. selectedAllBar: false,
  604. // Selected select bar name
  605. selectBarNameList: [],
  606. // input key word
  607. barKeyWord: '',
  608. // List of selected bars
  609. selectedBarArray: [],
  610. // List of all bars
  611. allBararr: [],
  612. yTitle: '',
  613. xTitle: '',
  614. // bar datazoom scroll bar settings
  615. barStart: 100,
  616. barEnd: 0,
  617. tooltipsBarName: '',
  618. echartDialogVisible: false,
  619. // right data
  620. rightAllOptions: [],
  621. showOptions: [],
  622. // Filter button disabled
  623. disabledFilterBtnModel: true,
  624. // Hide button disabled
  625. disabledHideBtnModel: true,
  626. // List of IDs that need to be hidden
  627. hideTableIdList: [],
  628. sortChangeTimer: null,
  629. tagDialogShow: false,
  630. errorData: true,
  631. tagScope: {},
  632. iconValue: 0,
  633. imageList: [],
  634. // Select all
  635. selectCheckAll: true,
  636. delayTime: 500,
  637. showEchartPic: true,
  638. beforeEditValue: '',
  639. keyWord: '',
  640. basearr: [],
  641. labelObj: {metric: '', userDefined: ''},
  642. userOptions: [],
  643. metricOptions: [],
  644. hyperOptions: [],
  645. otherTypeOptions: [],
  646. checkOptions: [],
  647. selectArrayValue: [],
  648. // metric list
  649. metricList: [],
  650. userDefinedList: [],
  651. hyperList: [],
  652. table: {},
  653. summaryDirList: undefined,
  654. text: this.$t('modelTraceback.summaryPath'),
  655. keysOfStringValue: [], // All keys whose values are character strings
  656. keysOfIntValue: [], // All keys whose values are int
  657. keysOfMixed: [],
  658. keysOfListType: [],
  659. echart: {
  660. chart: null,
  661. allData: [],
  662. brushData: [],
  663. showData: [],
  664. },
  665. pagination: {
  666. currentPage: 1,
  667. pageSize: 10,
  668. pageSizes: [10, 20, 50],
  669. total: 0,
  670. layout: 'total, sizes, prev, pager, next, jumper',
  671. pageChange: {},
  672. currentPagesizeChange: {},
  673. },
  674. chartFilter: {}, // chart filter condition
  675. tableFilter: {lineage_type: {in: ['model']}}, // table filter condition
  676. sortInfo: {},
  677. showTable: false,
  678. noData: false,
  679. loading: true,
  680. haveCustomizedParams: false,
  681. replaceStr: {
  682. metric: 'metric/',
  683. userDefined: 'user_defined/',
  684. },
  685. valueType: {
  686. int: 'int',
  687. str: 'str',
  688. mixed: 'mixed',
  689. list: 'list',
  690. category: 'category',
  691. model_size: 'model_size',
  692. dataset_mark: 'dataset_mark',
  693. },
  694. valueName: {
  695. userDefined: 'userDefined',
  696. metric: 'metric',
  697. UserDefined: 'UserDefined',
  698. Metric: 'Metric',
  699. },
  700. labelValue: {
  701. loss: 'loss',
  702. batch_size: 'batch_size',
  703. epoch: 'epoch',
  704. learning_rate: 'learning_rate',
  705. },
  706. };
  707. },
  708. computed: {},
  709. mounted() {
  710. this.setInitListValue();
  711. this.setTableTagImage();
  712. document.title = `${this.$t('summaryManage.modelTraceback')}-MindInsight`;
  713. document.addEventListener('click', this.blurFloat, true);
  714. this.$store.commit('setSelectedBarList', []);
  715. this.setTableColumnData();
  716. this.getStoreList();
  717. this.pagination.pageChange = (page) => {
  718. this.pagination.currentPage = page;
  719. this.queryLineagesData(false);
  720. };
  721. this.pagination.currentPagesizeChange = (pageSize) => {
  722. this.pagination.pageSize = pageSize;
  723. this.queryLineagesData(false);
  724. };
  725. this.$nextTick(() => {
  726. this.init();
  727. });
  728. },
  729. methods: {
  730. /**
  731. * Initialization
  732. */
  733. init() {
  734. this.queryLineagesData(true);
  735. },
  736. /** *** left code***/
  737. /**
  738. * Call the left side to optimize the target interface to obtain data
  739. * @param {Object} params
  740. */
  741. initLeftColumnData(params) {
  742. this.getTargetsData(params);
  743. },
  744. /**
  745. * Call the left side to optimize the target interface to obtain data
  746. * @param {Object} params
  747. */
  748. getTargetsData(params) {
  749. this.targetOptions = [];
  750. RequestService.queryTargetsData(params)
  751. .then(
  752. (resp) => {
  753. if (
  754. resp &&
  755. resp.data &&
  756. resp.data.targets &&
  757. resp.data.targets.length
  758. ) {
  759. this.targetData = JSON.parse(JSON.stringify(resp.data.targets));
  760. this.scatterData = JSON.parse(JSON.stringify(resp.data));
  761. let targetName = '';
  762. for (let i = 0; i < this.targetData.length; i++) {
  763. const obj = {};
  764. targetName = this.targetData[i].name;
  765. obj.value = targetName;
  766. obj.label = targetName;
  767. this.targetOptions.push(obj);
  768. }
  769. this.targetValue = this.targetData[0].name;
  770. this.targetLabel = this.targetData[0].name;
  771. this.setTargetsData(0);
  772. this.$nextTick(() => {
  773. setTimeout(() => {
  774. this.setChartOfPie();
  775. this.setChartOfBar();
  776. }, this.delayTime);
  777. });
  778. } else {
  779. this.leftChartNoData();
  780. }
  781. },
  782. (error) => {
  783. this.leftChartNoData();
  784. },
  785. )
  786. .catch(() => {
  787. this.leftChartNoData();
  788. });
  789. },
  790. /** ***********right column*********** **/
  791. /**
  792. * Querying All Model Version Information
  793. * @param {Boolean} allData Indicates whether to query all data
  794. */
  795. queryLineagesData(allData) {
  796. const params = {
  797. body: {},
  798. };
  799. const tempParam = {
  800. sorted_name: this.sortInfo.sorted_name,
  801. sorted_type: this.sortInfo.sorted_type,
  802. };
  803. // List id to be hidden
  804. this.hideTableIdList = this.$store.state.hideTableIdList;
  805. this.summaryDirList = this.$store.state.summaryDirList;
  806. // Need to pass in the request parameters of the hidden list id
  807. if (this.summaryDirList || this.hideTableIdList) {
  808. this.tableFilter.summary_dir = {
  809. in: this.summaryDirList,
  810. not_in: this.hideTableIdList,
  811. };
  812. } else {
  813. this.tableFilter.summary_dir = undefined;
  814. }
  815. if (!allData) {
  816. tempParam.limit = this.pagination.pageSize;
  817. tempParam.offset = this.pagination.currentPage - 1;
  818. params.body = Object.assign(
  819. params.body,
  820. this.chartFilter,
  821. tempParam,
  822. this.tableFilter,
  823. );
  824. } else {
  825. params.body = Object.assign(params.body, this.tableFilter);
  826. }
  827. // 1.Retrieve the data interface request in the left column (non-table page turning)
  828. if (allData) {
  829. this.initLeftColumnData(params);
  830. }
  831. RequestService.queryLineagesData(params)
  832. .then(
  833. (res) => {
  834. this.loading = false;
  835. if (res && res.data && res.data.object) {
  836. this.errorData = false;
  837. const listTemp = this.setDataOfModel(res.data.object);
  838. const list = JSON.parse(JSON.stringify(listTemp));
  839. if (allData) {
  840. this.setTableColumnData();
  841. this.setSelectOptionsData();
  842. this.setInitListValue();
  843. let customized = {};
  844. if (res.data.customized) {
  845. customized = JSON.parse(JSON.stringify(res.data.customized));
  846. const customizedKeys = Object.keys(customized);
  847. if (customizedKeys.length) {
  848. customizedKeys.forEach((i) => {
  849. if (customized[i].type === this.valueType.int) {
  850. this.keysOfIntValue.push(i);
  851. } else if (customized[i].type === this.valueType.str) {
  852. this.keysOfStringValue.push(i);
  853. } else if (customized[i].type === this.valueType.mixed) {
  854. // list of type mixed
  855. this.keysOfMixed.push(i);
  856. this.keysOfStringValue.push(i);
  857. } else if (customized[i].type === this.valueType.list) {
  858. this.keysOfListType.push(i);
  859. this.keysOfStringValue.push(i);
  860. }
  861. if (i.startsWith(this.replaceStr.userDefined)) {
  862. this.labelObj.userDefined = this.valueName.userDefined;
  863. customized[i].label = customized[i].label.replace(
  864. this.replaceStr.userDefined,
  865. '[U]',
  866. );
  867. const userDefinedObject = {value: '', label: ''};
  868. userDefinedObject.value = customized[i].label;
  869. userDefinedObject.label = customized[i].label;
  870. this.userOptions.push(userDefinedObject);
  871. } else if (i.startsWith(this.replaceStr.metric)) {
  872. customized[i].label = customized[i].label.replace(
  873. this.replaceStr.metric,
  874. '[M]',
  875. );
  876. this.labelObj.metric = this.valueName.metric;
  877. const metricObject = {value: '', label: ''};
  878. metricObject.value = customized[i].label;
  879. metricObject.label = customized[i].label;
  880. metricObject.disabled = true;
  881. this.metricOptions.push(metricObject);
  882. }
  883. });
  884. this.haveCustomizedParams = true;
  885. }
  886. this.checkOptions = [
  887. {
  888. label: '',
  889. options: [
  890. {
  891. value: this.$t('modelTraceback.dataProcess'),
  892. label: this.$t('modelTraceback.dataProcess'),
  893. disabled: true,
  894. },
  895. ],
  896. },
  897. ];
  898. this.basearr = [
  899. {
  900. label: '',
  901. options: [
  902. {
  903. value: this.$t('modelTraceback.dataProcess'),
  904. label: this.$t('modelTraceback.dataProcess'),
  905. disabled: true,
  906. },
  907. ],
  908. },
  909. ];
  910. if (this.labelObj.metric) {
  911. const metricTemp = {
  912. label: this.valueName.Metric,
  913. options: this.metricOptions,
  914. };
  915. this.checkOptions.push(metricTemp);
  916. this.basearr.push(metricTemp);
  917. }
  918. if (this.labelObj.userDefined) {
  919. const userTemp = {
  920. label: this.valueName.UserDefined,
  921. options: this.userOptions,
  922. };
  923. this.checkOptions.push(userTemp);
  924. this.basearr.push(userTemp);
  925. }
  926. Object.keys(this.table.columnOptions).forEach((item) => {
  927. if (
  928. item !== this.labelValue.epoch &&
  929. item !== this.labelValue.learning_rate &&
  930. item !== this.labelValue.batch_size
  931. ) {
  932. const haveItem = this.table.optionsNotInCheckbox.includes(
  933. item,
  934. );
  935. if (!haveItem) {
  936. const otherType = {value: '', label: ''};
  937. otherType.value = this.table.columnOptions[item].label;
  938. otherType.label = this.table.columnOptions[item].label;
  939. if (
  940. otherType.value === this.labelValue.loss ||
  941. otherType.value ===
  942. this.$t('modelTraceback.network') ||
  943. otherType.value ===
  944. this.$t('modelTraceback.optimizer')
  945. ) {
  946. otherType.disabled = true;
  947. }
  948. this.otherTypeOptions.push(otherType);
  949. }
  950. } else {
  951. const hyperObject = {value: '', label: ''};
  952. hyperObject.value = this.table.columnOptions[item].label;
  953. hyperObject.label = this.table.columnOptions[item].label;
  954. this.hyperOptions.push(hyperObject);
  955. }
  956. });
  957. if (this.hyperOptions.length) {
  958. const hyperTemp = {
  959. label: this.$t('modelTraceback.hyperLabel'),
  960. options: this.hyperOptions,
  961. };
  962. this.checkOptions.push(hyperTemp);
  963. this.basearr.push(hyperTemp);
  964. }
  965. if (this.otherTypeOptions.length) {
  966. const otherTemp = {
  967. label: this.$t('modelTraceback.otherLabel'),
  968. options: this.otherTypeOptions,
  969. };
  970. this.checkOptions.push(otherTemp);
  971. this.basearr.push(otherTemp);
  972. }
  973. }
  974. let tempOptions = [];
  975. this.checkOptions.forEach((item) => {
  976. tempOptions = tempOptions.concat(item.options);
  977. item.options.forEach((option) => {
  978. this.selectArrayValue.push(option.label);
  979. });
  980. });
  981. this.showOptions = tempOptions;
  982. // select all options
  983. this.rightAllOptions = tempOptions;
  984. this.table.columnOptions = Object.assign(
  985. {
  986. summary_dir: {
  987. label: this.$t('modelTraceback.summaryPath'),
  988. required: true,
  989. },
  990. dataset_mark: {
  991. label: this.$t('modelTraceback.dataProcess'),
  992. required: true,
  993. },
  994. },
  995. customized,
  996. this.table.columnOptions,
  997. );
  998. this.$store.commit('customizedColumnOptions', customized);
  999. this.noData = !res.data.object.length;
  1000. this.showEchartPic = !!res.data.object.length;
  1001. this.echart.allData = list;
  1002. this.echart.brushData = list;
  1003. this.echart.showData = this.echart.brushData;
  1004. Object.keys(this.table.columnOptions).forEach((i) => {
  1005. this.table.columnOptions[i].selected = true;
  1006. const flag = list.some((val) => {
  1007. return val[i] || val[i] === 0;
  1008. });
  1009. if (!flag) {
  1010. let index = this.table.optionsNotInCheckbox.indexOf(i);
  1011. if (index >= 0) {
  1012. this.table.optionsNotInCheckbox.splice(index, 1);
  1013. }
  1014. index = this.table.optionsNotInEchart.indexOf(i);
  1015. if (index >= 0) {
  1016. this.table.optionsNotInEchart.splice(index, 1);
  1017. }
  1018. index = this.table.optionsNotInTable.indexOf(i);
  1019. if (index >= 0) {
  1020. this.table.optionsNotInTable.splice(index, 1);
  1021. }
  1022. delete this.table.columnOptions[i];
  1023. }
  1024. });
  1025. this.initColumm();
  1026. this.$nextTick(() => {
  1027. this.resizeChart();
  1028. this.initChart();
  1029. });
  1030. this.table.data = list.slice(0, this.pagination.pageSize);
  1031. } else {
  1032. this.table.data = list.slice(0, this.pagination.pageSize);
  1033. }
  1034. this.pagination.total = res.data.count || 0;
  1035. } else {
  1036. this.errorData = true;
  1037. this.noData = allData;
  1038. this.showEchartPic = !allData;
  1039. }
  1040. },
  1041. (error) => {
  1042. this.errorData = true;
  1043. this.loading = false;
  1044. if (allData) {
  1045. this.noData = allData;
  1046. this.showEchartPic = !allData;
  1047. }
  1048. },
  1049. )
  1050. .catch(() => {
  1051. this.errorData = true;
  1052. this.loading = false;
  1053. this.noData = true;
  1054. });
  1055. },
  1056. /**
  1057. * Selected data in the table
  1058. * @param {Array} data
  1059. * @return {Array}
  1060. */
  1061. setDataOfModel(data = []) {
  1062. const modelLineageList = [];
  1063. data.forEach((item) => {
  1064. if (item.model_lineage) {
  1065. item.model_lineage.editShow = true;
  1066. item.model_lineage.isError = false;
  1067. item.model_lineage.summary_dir = item.summary_dir;
  1068. item.model_lineage.remark = item.added_info.remark
  1069. ? item.added_info.remark
  1070. : '';
  1071. item.model_lineage.tag = item.added_info.tag
  1072. ? item.added_info.tag
  1073. : 0;
  1074. const modelData = JSON.parse(JSON.stringify(item.model_lineage));
  1075. const byteNum = 1024;
  1076. modelData.model_size = parseFloat(
  1077. ((modelData.model_size || 0) / byteNum / byteNum).toFixed(2),
  1078. );
  1079. const keys = Object.keys(modelData.metric || {});
  1080. if (keys.length) {
  1081. keys.forEach((key) => {
  1082. if (modelData.metric[key] || modelData.metric[key] === 0) {
  1083. const temp = this.replaceStr.metric + key;
  1084. modelData[temp] = modelData.metric[key];
  1085. }
  1086. });
  1087. delete modelData.metric;
  1088. }
  1089. const udkeys = Object.keys(modelData.user_defined || {});
  1090. if (udkeys.length) {
  1091. udkeys.forEach((key) => {
  1092. if (
  1093. modelData.user_defined[key] ||
  1094. modelData.user_defined[key] === 0
  1095. ) {
  1096. const temp = this.replaceStr.userDefined + key;
  1097. modelData[temp] = modelData.user_defined[key];
  1098. }
  1099. });
  1100. delete modelData.user_defined;
  1101. }
  1102. modelLineageList.push(modelData);
  1103. }
  1104. });
  1105. return modelLineageList;
  1106. },
  1107. /**
  1108. * Column initialization
  1109. */
  1110. initColumm() {
  1111. this.metricList = [];
  1112. this.userDefinedList = [];
  1113. // hyper list
  1114. this.hyperList = [];
  1115. this.table.mandatoryColumn = Object.keys(this.table.columnOptions).filter(
  1116. (i) => {
  1117. return this.table.columnOptions[i].required;
  1118. },
  1119. );
  1120. this.table.optionalColumn = Object.keys(this.table.columnOptions).filter(
  1121. (i) => {
  1122. return !this.table.columnOptions[i].required;
  1123. },
  1124. );
  1125. const columnList = Object.keys(this.table.columnOptions).filter((i) => {
  1126. return (
  1127. !this.table.optionsNotInTable.includes(i) &&
  1128. this.table.columnOptions[i].selected
  1129. );
  1130. });
  1131. const metricArray = [];
  1132. const userDefinedArray = [];
  1133. const columnArray = [];
  1134. const hyperArray = [];
  1135. columnList.forEach((item) => {
  1136. if (item.indexOf('metric/') === 0) {
  1137. metricArray.push(item);
  1138. } else if (item.indexOf('user_defined/') === 0) {
  1139. userDefinedArray.push(item);
  1140. } else if (
  1141. item === this.labelValue.epoch ||
  1142. item === this.labelValue.batch_size ||
  1143. item === this.labelValue.learning_rate
  1144. ) {
  1145. hyperArray.push(item);
  1146. } else {
  1147. columnArray.push(item);
  1148. }
  1149. });
  1150. this.showTable = true;
  1151. this.table.otherColumn = columnArray;
  1152. this.metricList = metricArray;
  1153. this.userDefinedList = userDefinedArray;
  1154. // hyper list
  1155. this.hyperList = hyperArray;
  1156. this.table.selectedColumn = this.table.optionalColumn;
  1157. this.table.selectAll = true;
  1158. this.showTable = true;
  1159. this.$nextTick(() => {
  1160. this.$refs.table.doLayout();
  1161. });
  1162. },
  1163. /**
  1164. * Initializing the Eechart
  1165. */
  1166. initChart() {
  1167. const chartAxis = Object.keys(this.table.columnOptions).filter((i) => {
  1168. return (
  1169. this.table.columnOptions[i].selected &&
  1170. !this.table.optionsNotInEchart.includes(i)
  1171. );
  1172. });
  1173. const data = [];
  1174. this.echart.showData.forEach((i, index) => {
  1175. let item = {};
  1176. item = {
  1177. lineStyle: {
  1178. normal: {
  1179. color: CommonProperty.commonColorArr[index % 10],
  1180. },
  1181. },
  1182. value: [],
  1183. };
  1184. chartAxis.forEach((key) => {
  1185. if (
  1186. (i[key] || i[key] === 0) &&
  1187. this.keysOfMixed &&
  1188. this.keysOfMixed.length &&
  1189. this.keysOfMixed.includes(key)
  1190. ) {
  1191. item.value.push(i[key].toString());
  1192. } else {
  1193. item.value.push(i[key]);
  1194. }
  1195. });
  1196. data.push(item);
  1197. });
  1198. const parallelAxis = [];
  1199. chartAxis.forEach((key, index) => {
  1200. const obj = {dim: index, scale: true, id: key};
  1201. obj.name = this.table.columnOptions[key].label;
  1202. if (this.keysOfStringValue.includes(key)) {
  1203. const values = {};
  1204. this.echart.showData.forEach((i) => {
  1205. if (i[key] || i[key] === 0) {
  1206. values[i[key].toString()] = i[key].toString();
  1207. }
  1208. });
  1209. obj.type = this.valueType.category;
  1210. obj.data = Object.keys(values);
  1211. if (key === this.valueType.dataset_mark) {
  1212. obj.axisLabel = {
  1213. show: false,
  1214. };
  1215. } else {
  1216. obj.axisLabel = {
  1217. formatter: function(val) {
  1218. const strs = val.split('');
  1219. let str = '';
  1220. if (val.length > 100) {
  1221. return val.substring(0, 12) + '...';
  1222. } else {
  1223. if (chartAxis.length < 10) {
  1224. for (let i = 0, s = ''; (s = strs[i++]); ) {
  1225. str += s;
  1226. if (!(i % 16)) {
  1227. str += '\n';
  1228. }
  1229. }
  1230. } else {
  1231. for (let i = 0, s = ''; (s = strs[i++]); ) {
  1232. str += s;
  1233. if (!(i % 12)) {
  1234. str += '\n';
  1235. }
  1236. }
  1237. }
  1238. return str;
  1239. }
  1240. },
  1241. };
  1242. }
  1243. }
  1244. if (this.keysOfIntValue.includes(key)) {
  1245. obj.minInterval = 1;
  1246. }
  1247. parallelAxis.push(obj);
  1248. });
  1249. const echartOption = {
  1250. backgroundColor: 'white',
  1251. parallelAxis: parallelAxis,
  1252. tooltip: {
  1253. trigger: 'axis',
  1254. },
  1255. parallel: {
  1256. top: 25,
  1257. left: 70,
  1258. right: 100,
  1259. bottom: 10,
  1260. parallelAxisDefault: {
  1261. type: 'value',
  1262. nameLocation: 'end',
  1263. nameGap: 6,
  1264. nameTextStyle: {
  1265. color: '#000000',
  1266. fontSize: 14,
  1267. },
  1268. axisLine: {
  1269. lineStyle: {
  1270. color: '#6D7278',
  1271. },
  1272. },
  1273. axisTick: {
  1274. lineStyle: {
  1275. color: '#6D7278',
  1276. },
  1277. },
  1278. axisLabel: {
  1279. textStyle: {
  1280. fontSize: 10,
  1281. color: '#6C7280',
  1282. },
  1283. },
  1284. areaSelectStyle: {
  1285. width: 40,
  1286. },
  1287. tooltip: {
  1288. show: true,
  1289. },
  1290. realtime: false,
  1291. },
  1292. },
  1293. series: {
  1294. type: 'parallel',
  1295. lineStyle: {
  1296. normal: {
  1297. width: 1,
  1298. opacity: 1,
  1299. },
  1300. },
  1301. data: data,
  1302. },
  1303. };
  1304. if (this.echart.chart) {
  1305. this.echart.chart.off('axisareaselected', null);
  1306. window.removeEventListener('resize', this.resizeChart, false);
  1307. } else {
  1308. this.echart.chart = Echarts.init(document.querySelector('#echart'));
  1309. }
  1310. this.echart.chart.setOption(echartOption, true);
  1311. window.addEventListener('resize', this.resizeChart, false);
  1312. this.chartEventsListen(parallelAxis);
  1313. },
  1314. /**
  1315. * Model traceability parallel coordinate system echart frame selection operation monitoring
  1316. * @param {Object} parallelAxis
  1317. */
  1318. chartEventsListen(parallelAxis) {
  1319. this.echart.chart.on('axisareaselected', (params) => {
  1320. const key = params.parallelAxisId;
  1321. if (
  1322. (this.keysOfMixed &&
  1323. this.keysOfMixed.length &&
  1324. this.keysOfMixed.includes(key)) ||
  1325. this.keysOfListType.includes(key)
  1326. ) {
  1327. if (this.keysOfListType.includes(key)) {
  1328. this.$message.error(this.$t('modelTraceback.notSupportSelected'));
  1329. } else {
  1330. this.$message.error(this.$t('modelTraceback.mixedItemMessage'));
  1331. }
  1332. this.$nextTick(() => {
  1333. this.initChart();
  1334. });
  1335. return;
  1336. }
  1337. const list = this.$store.state.selectedBarList || [];
  1338. const selectedAxisId = params.parallelAxisId;
  1339. if (list.length) {
  1340. list.forEach((item, index) => {
  1341. if (item === selectedAxisId) {
  1342. list.splice(index, 1);
  1343. }
  1344. });
  1345. }
  1346. list.push(selectedAxisId);
  1347. this.$store.commit('setSelectedBarList', list);
  1348. let range = params.intervals[0] || [];
  1349. const [axisData] = parallelAxis.filter((i) => {
  1350. return i.id === key;
  1351. });
  1352. const lineLength = 2;
  1353. if (axisData && range.length === lineLength) {
  1354. if (axisData && axisData.id === this.valueType.model_size) {
  1355. const byteNum = 1024;
  1356. range = [
  1357. parseInt(range[0] * byteNum * byteNum, 0),
  1358. parseInt(range[1] * byteNum * byteNum, 0),
  1359. ];
  1360. }
  1361. if (axisData.type === this.valueType.category) {
  1362. const rangeData = {};
  1363. for (let i = range[0]; i <= range[1]; i++) {
  1364. rangeData[axisData.data[i]] = axisData.data[i];
  1365. }
  1366. const rangeDataKey = Object.keys(rangeData);
  1367. this.chartFilter[key] = {
  1368. in: rangeDataKey,
  1369. };
  1370. } else {
  1371. if (this.keysOfIntValue.includes(key)) {
  1372. range[1] = Math.floor(range[1]);
  1373. range[0] = Math.ceil(range[0]);
  1374. }
  1375. this.chartFilter[key] = {
  1376. le: range[1],
  1377. ge: range[0],
  1378. };
  1379. }
  1380. const filterParams = {};
  1381. filterParams.body = Object.assign(
  1382. {},
  1383. this.chartFilter,
  1384. this.tableFilter,
  1385. );
  1386. const tableParams = {};
  1387. tableParams.body = Object.assign(
  1388. {},
  1389. this.chartFilter,
  1390. this.tableFilter,
  1391. this.sortInfo,
  1392. );
  1393. // Call the target interface, and pass in the frame selection parameters
  1394. this.initLeftColumnData(filterParams);
  1395. RequestService.queryLineagesData(filterParams)
  1396. .then(
  1397. (res) => {
  1398. if (res && res.data && res.data.object) {
  1399. this.errorData = false;
  1400. if (res.data.object.length) {
  1401. let customized = {};
  1402. customized = JSON.parse(
  1403. JSON.stringify(res.data.customized),
  1404. );
  1405. const customizedKeys = Object.keys(customized);
  1406. if (customizedKeys.length) {
  1407. this.setInitListValue();
  1408. customizedKeys.forEach((i) => {
  1409. if (customized[i].type === this.valueType.int) {
  1410. this.keysOfIntValue.push(i);
  1411. } else if (customized[i].type === this.valueType.str) {
  1412. this.keysOfStringValue.push(i);
  1413. } else if (
  1414. customized[i].type === this.valueType.mixed
  1415. ) {
  1416. // list of type mixed
  1417. this.keysOfMixed.push(i);
  1418. this.keysOfStringValue.push(i);
  1419. }
  1420. });
  1421. }
  1422. const list = this.setDataOfModel(res.data.object);
  1423. if (!list.length) {
  1424. this.noData = true;
  1425. this.showEchartPic = false;
  1426. // After the echart box is selected, it is empty, and an empty data array needs to be saved
  1427. this.summaryDirList = [];
  1428. this.$store.commit('setSummaryDirList', []);
  1429. return;
  1430. }
  1431. const summaryDirList = list.map((i) => i.summary_dir);
  1432. this.$store.commit('setSummaryDirList', summaryDirList);
  1433. this.echart.showData = this.echart.brushData = list;
  1434. this.$nextTick(() => {
  1435. this.initChart();
  1436. });
  1437. this.getTableList(tableParams);
  1438. } else {
  1439. // After the echart box is selected, it is empty, and an empty data array needs to be saved
  1440. this.summaryDirList = [];
  1441. this.$store.commit('setSummaryDirList', []);
  1442. this.noData = true;
  1443. this.showEchartPic = false;
  1444. }
  1445. } else {
  1446. this.errorData = true;
  1447. }
  1448. },
  1449. (error) => {
  1450. this.errorData = true;
  1451. },
  1452. )
  1453. .catch(() => {
  1454. this.errorData = true;
  1455. });
  1456. }
  1457. });
  1458. },
  1459. /**
  1460. * Get table data
  1461. * @param {Object} tableParams
  1462. */
  1463. getTableList(tableParams) {
  1464. RequestService.queryLineagesData(tableParams)
  1465. .then(
  1466. (res) => {
  1467. if (res && res.data && res.data.object) {
  1468. this.errorData = false;
  1469. if (res.data.object.length) {
  1470. const list = this.setDataOfModel(res.data.object);
  1471. this.table.data = list.slice(0, this.pagination.pageSize);
  1472. this.pagination.currentPage = 1;
  1473. this.pagination.total = this.echart.brushData.length;
  1474. this.$refs.table.clearSelection();
  1475. }
  1476. } else {
  1477. this.errorData = true;
  1478. }
  1479. },
  1480. (error) => {
  1481. this.errorData = true;
  1482. },
  1483. )
  1484. .catch(() => {
  1485. this.errorData = true;
  1486. });
  1487. },
  1488. /**
  1489. * Select all
  1490. */
  1491. allSelect() {
  1492. if (this.selectCheckAll) {
  1493. return;
  1494. }
  1495. this.selectArrayValue = [];
  1496. this.checkOptions.forEach((item) => {
  1497. item.options.forEach((option) => {
  1498. this.selectArrayValue.push(option.label);
  1499. });
  1500. });
  1501. this.selectCheckAll = !this.selectCheckAll;
  1502. let allList = [];
  1503. const listA = [this.$t('modelTraceback.summaryPath')];
  1504. allList = this.selectArrayValue.concat(listA);
  1505. // Set selected of the column data in the table to false;
  1506. Object.keys(this.table.columnOptions).filter((i) => {
  1507. this.table.columnOptions[i].selected = false;
  1508. });
  1509. allList.forEach((item) => {
  1510. Object.keys(this.table.columnOptions).filter((i) => {
  1511. const labelValue = this.table.columnOptions[i].label;
  1512. if (labelValue === item) {
  1513. this.table.columnOptions[i].selected = true;
  1514. }
  1515. });
  1516. });
  1517. this.initColumm();
  1518. this.$nextTick(() => {
  1519. this.initChart();
  1520. this.$refs.table.doLayout();
  1521. });
  1522. },
  1523. /**
  1524. * Deselect all
  1525. */
  1526. deselectAll() {
  1527. this.selectArrayValue = [];
  1528. this.checkOptions.forEach((item) => {
  1529. item.options.forEach((option) => {
  1530. if (option.disabled) {
  1531. this.selectArrayValue.push(option.label);
  1532. }
  1533. });
  1534. });
  1535. this.selectCheckAll = false;
  1536. let allList = [];
  1537. const listA = [this.$t('modelTraceback.summaryPath')];
  1538. allList = this.selectArrayValue.concat(listA);
  1539. // Set selected to false for these columns in the table.
  1540. Object.keys(this.table.columnOptions).filter((i) => {
  1541. this.table.columnOptions[i].selected = false;
  1542. });
  1543. allList.forEach((item) => {
  1544. Object.keys(this.table.columnOptions).filter((i) => {
  1545. const labelValue = this.table.columnOptions[i].label;
  1546. if (labelValue === item) {
  1547. this.table.columnOptions[i].selected = true;
  1548. }
  1549. });
  1550. });
  1551. this.initChart();
  1552. this.initColumm();
  1553. },
  1554. /**
  1555. *After the remark or tag is modified, invoke the interface and save the modification.
  1556. * @param {Object} params
  1557. */
  1558. putChangeToLineagesData(params) {
  1559. RequestService.putLineagesData(params)
  1560. .then(
  1561. (res) => {
  1562. if (res) {
  1563. this.$message.success(this.$t('modelTraceback.changeSuccess'));
  1564. }
  1565. },
  1566. (error) => {},
  1567. )
  1568. .catch(() => {});
  1569. },
  1570. getStoreList() {
  1571. // Get hidden list
  1572. this.hideTableIdList = this.$store.state.hideTableIdList;
  1573. this.summaryDirList = this.$store.state.summaryDirList;
  1574. if (this.summaryDirList || this.hideTableIdList) {
  1575. this.tableFilter.summary_dir = {
  1576. in: this.summaryDirList,
  1577. not_in: this.hideTableIdList,
  1578. };
  1579. } else {
  1580. this.tableFilter.summary_dir = undefined;
  1581. }
  1582. },
  1583. /**
  1584. * Selected data in the table
  1585. */
  1586. selectValueChange() {
  1587. const list = [];
  1588. this.basearr.forEach((item) => {
  1589. item.options.forEach((option) => {
  1590. list.push(option.label);
  1591. });
  1592. });
  1593. if (list.length > this.selectArrayValue.length) {
  1594. this.selectCheckAll = false;
  1595. } else {
  1596. this.selectCheckAll = true;
  1597. }
  1598. let allList = [];
  1599. const listA = [this.$t('modelTraceback.summaryPath')];
  1600. allList = this.selectArrayValue.concat(listA);
  1601. Object.keys(this.table.columnOptions).filter((i) => {
  1602. this.table.columnOptions[i].selected = false;
  1603. });
  1604. allList.forEach((item) => {
  1605. Object.keys(this.table.columnOptions).filter((i) => {
  1606. const labelValue = this.table.columnOptions[i].label;
  1607. if (labelValue === item) {
  1608. this.table.columnOptions[i].selected = true;
  1609. }
  1610. });
  1611. });
  1612. this.$nextTick(() => {
  1613. this.initChart();
  1614. });
  1615. this.initColumm();
  1616. },
  1617. selectedSetBarData() {
  1618. // Set the y-axis coordinate
  1619. const barHyper = [];
  1620. for (let i = 0; i < this.targetData.length; i++) {
  1621. if (this.targetData[i].name === this.yTitle) {
  1622. this.targetData[i].hyper_parameters.forEach((item) => {
  1623. if (!item.unselected) {
  1624. barHyper.unshift(item);
  1625. }
  1626. });
  1627. }
  1628. }
  1629. barHyper.sort(this.sortBy('importance'));
  1630. this.barYAxisData = [];
  1631. this.barSeriesData = [];
  1632. for (let j = 0; j < barHyper.length; j++) {
  1633. const name = barHyper[j].name;
  1634. let importanceValue = barHyper[j].importance;
  1635. const minRange = 1.0e-10;
  1636. const smallerData = 0.0001;
  1637. if (importanceValue < minRange && importanceValue > 0) {
  1638. importanceValue = 0;
  1639. } else if (importanceValue < smallerData && importanceValue > 0) {
  1640. importanceValue = importanceValue.toExponential(4);
  1641. } else {
  1642. importanceValue =
  1643. Math.round(importanceValue * Math.pow(10, 4)) / Math.pow(10, 4);
  1644. }
  1645. if (this.selectedBarArray.includes(name)) {
  1646. this.barYAxisData.push(name);
  1647. this.barSeriesData.push(importanceValue);
  1648. }
  1649. }
  1650. this.selectedAllBar =
  1651. barHyper.length > this.barYAxisData.length ? false : true;
  1652. this.$nextTick(() => {
  1653. this.setChartOfBar();
  1654. });
  1655. },
  1656. /**
  1657. * Sort data in the table
  1658. * @param {Object} column current column
  1659. */
  1660. sortChange(column) {
  1661. if (this.sortChangeTimer) {
  1662. clearTimeout(this.sortChangeTimer);
  1663. this.sortChangeTimer = null;
  1664. }
  1665. this.sortChangeTimer = setTimeout(() => {
  1666. this.sortInfo.sorted_name = column.prop;
  1667. this.sortInfo.sorted_type = column.order;
  1668. this.getStoreList();
  1669. const tempParam = {
  1670. limit: this.pagination.pageSize,
  1671. offset: 0,
  1672. sorted_name: this.sortInfo.sorted_name,
  1673. sorted_type: this.sortInfo.sorted_type,
  1674. };
  1675. const params = {};
  1676. params.body = Object.assign(
  1677. {},
  1678. tempParam,
  1679. this.tableFilter,
  1680. this.chartFilter || {},
  1681. );
  1682. RequestService.queryLineagesData(params)
  1683. .then(
  1684. (res) => {
  1685. if (res && res.data && res.data.object) {
  1686. this.errorData = false;
  1687. const list = this.setDataOfModel(res.data.object);
  1688. this.table.data = list.slice(0, this.pagination.pageSize);
  1689. this.pagination.total = res.data.count || 0;
  1690. this.pagination.currentPage = 1;
  1691. } else {
  1692. this.errorData = true;
  1693. }
  1694. },
  1695. (error) => {
  1696. this.errorData = true;
  1697. },
  1698. )
  1699. .catch(() => {
  1700. this.errorData = true;
  1701. });
  1702. }, this.delayTime);
  1703. },
  1704. },
  1705. /**
  1706. * Destroy the page
  1707. */
  1708. destroyed() {
  1709. if (this.myPieChart) {
  1710. this.myPieChart.clear();
  1711. this.myPieChart = null;
  1712. }
  1713. if (this.myBarChart) {
  1714. this.myBarChart.off('datazoom');
  1715. this.myBarChart.off('click');
  1716. if (this.myBarChart.getZr()) {
  1717. this.myBarChart.getZr().off('click');
  1718. }
  1719. this.myBarChart.off('mouseover');
  1720. this.myBarChart.off('mouseout');
  1721. this.myBarChart.clear();
  1722. this.myBarChart = null;
  1723. }
  1724. this.sortChangeTimer = null;
  1725. if (this.echart.chart) {
  1726. window.removeEventListener('resize', this.resizeChart, false);
  1727. this.echart.chart.clear();
  1728. this.echart.chart = null;
  1729. }
  1730. document.removeEventListener('resize', this.blurFloat);
  1731. },
  1732. components: {
  1733. Scatter,
  1734. },
  1735. };
  1736. </script>
  1737. <style lang="scss">
  1738. .cl-model-traceback {
  1739. height: 100%;
  1740. background-color: #fff;
  1741. }
  1742. // Set the maximum width of the drop-down box
  1743. .el-select-dropdown {
  1744. max-width: 300px;
  1745. li.is-disabled {
  1746. color: #c0c4cc !important;
  1747. }
  1748. }
  1749. .el-select__tags {
  1750. overflow: hidden;
  1751. }
  1752. .traceback-tab {
  1753. height: 51px;
  1754. line-height: 56px;
  1755. padding: 0 24px;
  1756. border-bottom: 1px solid rgba($color: #000000, $alpha: 0.1);
  1757. }
  1758. .traceback-tab-item {
  1759. padding: 0 10px;
  1760. height: 48px;
  1761. -webkit-box-sizing: border-box;
  1762. box-sizing: border-box;
  1763. line-height: 48px;
  1764. display: inline-block;
  1765. list-style: none;
  1766. font-size: 17px;
  1767. color: #303133;
  1768. position: relative;
  1769. }
  1770. .item-active {
  1771. color: #00a5a7;
  1772. font-weight: bold;
  1773. border-bottom: 3px solid rgba($color: #00a5a7, $alpha: 1);
  1774. }
  1775. .traceback-tab-item:hover {
  1776. color: #00a5a7;
  1777. cursor: pointer;
  1778. }
  1779. .label-text {
  1780. line-height: 20px !important;
  1781. padding-top: 20px;
  1782. display: block !important;
  1783. }
  1784. .remark-tip {
  1785. line-height: 20px !important;
  1786. font-size: 12px;
  1787. white-space: pre-wrap !important;
  1788. color: gray;
  1789. display: block !important;
  1790. }
  1791. .el-color-dropdown__main-wrapper,
  1792. .el-color-dropdown__value,
  1793. .el-color-alpha-slider {
  1794. display: none;
  1795. }
  1796. .el-tag.el-tag--info .el-tag__close {
  1797. color: #fff;
  1798. }
  1799. .select-inner-input {
  1800. width: calc(100% - 130px);
  1801. min-width: 78px;
  1802. margin: 2px 4px;
  1803. display: inline-block;
  1804. }
  1805. .select-input-button {
  1806. position: relative;
  1807. }
  1808. .el-select-group__title {
  1809. font-size: 14px;
  1810. font-weight: 700;
  1811. }
  1812. .el-select-dropdown__item.selected {
  1813. font-weight: 400;
  1814. }
  1815. .checked-color {
  1816. color: #00a5a7 !important;
  1817. }
  1818. .el-tag.el-tag--info .el-tag__close {
  1819. display: none;
  1820. }
  1821. .btn-disabled {
  1822. cursor: not-allowed !important;
  1823. }
  1824. .select-all-button {
  1825. padding: 4px 0;
  1826. display: inline-block;
  1827. position: absolute;
  1828. right: 80px;
  1829. padding: 5px;
  1830. height: 32px;
  1831. border: none;
  1832. background: none;
  1833. }
  1834. .deselect-all-button {
  1835. padding: 4px 0;
  1836. display: inline-block;
  1837. position: absolute;
  1838. right: 10px;
  1839. padding: 5px;
  1840. height: 32px;
  1841. border: none;
  1842. background: none;
  1843. }
  1844. .empty-container {
  1845. padding-top: 6px;
  1846. }
  1847. .search-no-data {
  1848. padding: 10px 0;
  1849. margin: 0;
  1850. text-align: center;
  1851. color: #999;
  1852. font-size: 14px;
  1853. }
  1854. #model-traceback-con {
  1855. display: flex;
  1856. height: calc(100% - 51px);
  1857. overflow-y: auto;
  1858. position: relative;
  1859. background: #fff;
  1860. .no-data-page {
  1861. display: flex;
  1862. width: 100%;
  1863. flex: 1;
  1864. justify-content: center;
  1865. align-items: center;
  1866. .set-height-class {
  1867. height: 282px !important;
  1868. }
  1869. .no-data-img {
  1870. background: #fff;
  1871. text-align: center;
  1872. height: 200px;
  1873. width: 310px;
  1874. margin: auto;
  1875. img {
  1876. max-width: 100%;
  1877. }
  1878. }
  1879. .no-data-text {
  1880. font-size: 16px;
  1881. padding-top: 15px;
  1882. text-align: center;
  1883. }
  1884. }
  1885. .echart-data-list {
  1886. .dialog-scatter {
  1887. width: 100%;
  1888. height: 100%;
  1889. }
  1890. .el-dialog__title {
  1891. font-weight: bold;
  1892. }
  1893. .el-dialog__body {
  1894. height: 500px;
  1895. padding-top: 0px;
  1896. margin-bottom: 20px;
  1897. overflow: auto;
  1898. .details-data-title {
  1899. margin-bottom: 20px;
  1900. }
  1901. }
  1902. }
  1903. .el-table th.gutter {
  1904. display: table-cell !important;
  1905. }
  1906. .icon-border {
  1907. border: 1px solid #00a5a7 !important;
  1908. }
  1909. #tag-dialog {
  1910. z-index: 999;
  1911. border: 1px solid #d6c9c9;
  1912. position: fixed;
  1913. width: 326px;
  1914. height: 120px;
  1915. background-color: #efebeb;
  1916. right: 106px;
  1917. border-radius: 4px;
  1918. }
  1919. .custom-btn {
  1920. border: 1px solid #00a5a7;
  1921. border-radius: 2px;
  1922. background-color: white;
  1923. color: #00a5a7;
  1924. }
  1925. .custom-btn:hover {
  1926. color: #00a5a7;
  1927. background: #e9f7f7;
  1928. }
  1929. .disabled-btn-color {
  1930. border-radius: 2px;
  1931. background-color: #f5f5f6;
  1932. border: 1px solid #dfe1e6;
  1933. color: #adb0b8;
  1934. }
  1935. .abled-btn-color {
  1936. border: 1px solid #00a5a7;
  1937. color: #00a5a7;
  1938. background: white;
  1939. }
  1940. .abled-btn-color:hover {
  1941. color: #00a5a7;
  1942. background: #e9f7f7;
  1943. }
  1944. .icon-image {
  1945. display: inline-block;
  1946. padding: 4px;
  1947. height: 30px;
  1948. width: 30px;
  1949. border: 1px solid transparent;
  1950. }
  1951. .icon-image-container {
  1952. margin: 16px 10px 18px;
  1953. }
  1954. .edit-text-container {
  1955. display: inline-block;
  1956. max-width: 190px;
  1957. overflow: hidden;
  1958. text-overflow: ellipsis;
  1959. white-space: nowrap;
  1960. vertical-align: bottom;
  1961. }
  1962. .btn-container-margin {
  1963. margin: 0 10%;
  1964. }
  1965. .tag-button-container {
  1966. display: inline-block;
  1967. width: 33.3%;
  1968. text-align: center;
  1969. }
  1970. .btns-container {
  1971. padding: 6px 32px 4px;
  1972. }
  1973. .table-container .el-icon-edit {
  1974. margin-left: 5px;
  1975. }
  1976. .table-container i {
  1977. font-size: 18px;
  1978. margin: 0 2px;
  1979. color: #00a5a7;
  1980. cursor: pointer;
  1981. }
  1982. .table-container .el-icon-close {
  1983. color: #f56c6c;
  1984. }
  1985. .table-container .validation-error {
  1986. color: #ff0000;
  1987. }
  1988. .select-container {
  1989. padding: 10px 0;
  1990. position: relative;
  1991. display: flex;
  1992. }
  1993. .display-column {
  1994. display: inline-block;
  1995. padding-right: 6px;
  1996. height: 32px;
  1997. line-height: 32px;
  1998. }
  1999. .inline-block-set {
  2000. display: inline-block;
  2001. }
  2002. .remark-input-style {
  2003. width: 190px;
  2004. }
  2005. .tag-icon-container {
  2006. width: 21px;
  2007. height: 21px;
  2008. border: 1px solid #e6e6e6;
  2009. cursor: pointer;
  2010. border-radius: 2px;
  2011. }
  2012. .button-text {
  2013. color: #606266 !important;
  2014. }
  2015. // left module
  2016. .cl-model-left {
  2017. width: 400px;
  2018. background: #edf0f5;
  2019. overflow-y: auto;
  2020. margin: 6px 0px 10px 32px;
  2021. padding: 10px 16px;
  2022. .left-chart-container {
  2023. height: 100%;
  2024. min-height: 774px;
  2025. }
  2026. .left-title {
  2027. height: 30px;
  2028. display: flex;
  2029. .pie-select-style {
  2030. flex: 1;
  2031. }
  2032. .left-select {
  2033. width: 180px;
  2034. .el-select > .el-input {
  2035. width: 180px !important;
  2036. }
  2037. }
  2038. }
  2039. .title-style {
  2040. font-size: 16px;
  2041. flex: 1;
  2042. font-weight: bold;
  2043. line-height: 30px;
  2044. .el-icon-refresh-right {
  2045. font-size: 20px;
  2046. vertical-align: middle;
  2047. cursor: pointer;
  2048. }
  2049. }
  2050. .pie-title {
  2051. margin-right: 110px;
  2052. height: 20px;
  2053. line-height: 20px;
  2054. font-weight: bold;
  2055. }
  2056. .title-container {
  2057. margin-bottom: 10px;
  2058. display: flex;
  2059. .tooltip-container {
  2060. line-height: 20px;
  2061. padding: 10px;
  2062. }
  2063. }
  2064. .pie-module-container {
  2065. padding: 10px 0 0px;
  2066. height: 250px;
  2067. #pie-chart {
  2068. width: 368px;
  2069. height: 200px;
  2070. }
  2071. }
  2072. .bar-module-container {
  2073. height: 270px;
  2074. border-bottom: 1px solid #b9bcc1;
  2075. border-top: 1px solid #b9bcc1;
  2076. padding: 10px 0;
  2077. overflow: hidden;
  2078. .bar-select {
  2079. display: flex;
  2080. flex: 1.35;
  2081. .el-select {
  2082. max-width: 240px;
  2083. }
  2084. }
  2085. .bar-title-container {
  2086. display: flex;
  2087. }
  2088. .bar-title {
  2089. font-weight: bold;
  2090. flex: 1;
  2091. height: 32px;
  2092. line-height: 32px;
  2093. }
  2094. #bar-chart {
  2095. width: 368px;
  2096. height: 220px;
  2097. }
  2098. }
  2099. .scatter-container {
  2100. height: calc(100% - 20px - 250px - 270px);
  2101. padding-top: 10px;
  2102. .scatter-title-container {
  2103. display: flex;
  2104. font-weight: bold;
  2105. flex-direction: row;
  2106. width: 100%;
  2107. .right-view {
  2108. position: relative;
  2109. flex: 1;
  2110. }
  2111. .el-icon-info {
  2112. font-size: 16px;
  2113. margin-left: 5px;
  2114. color: #6c7280;
  2115. }
  2116. .view-big {
  2117. position: absolute;
  2118. right: 10px;
  2119. width: 12px;
  2120. height: 12px;
  2121. cursor: pointer;
  2122. background-image: url('../../assets/images/full-screen.png');
  2123. }
  2124. }
  2125. }
  2126. .left-scatters-container {
  2127. overflow: hidden;
  2128. width: 100%;
  2129. height: calc(100% - 32px);
  2130. }
  2131. .collapse-btn {
  2132. position: absolute;
  2133. width: 31px;
  2134. height: 100px;
  2135. top: 50%;
  2136. left: 423px;
  2137. margin-top: -50px;
  2138. cursor: pointer;
  2139. line-height: 86px;
  2140. z-index: 1999;
  2141. text-align: center;
  2142. background-image: url('../../assets/images/collapse-left.svg');
  2143. }
  2144. .collapse-btn.collapse {
  2145. left: -10px;
  2146. background-image: url('../../assets/images/collapse-right.svg');
  2147. }
  2148. }
  2149. .cl-model-right.collapse {
  2150. width: 100% !important;
  2151. }
  2152. .cl-model-left.collapse {
  2153. width: 0;
  2154. padding: 0px;
  2155. }
  2156. .cl-model-right {
  2157. display: flex;
  2158. flex-direction: column;
  2159. width: 100%;
  2160. flex: 1;
  2161. width: calc(100% - 400px);
  2162. background-color: #fff;
  2163. -webkit-box-shadow: 0 1px 0 0 rgba(200, 200, 200, 0.5);
  2164. box-shadow: 0 1px 0 0 rgba(200, 200, 200, 0.5);
  2165. overflow: hidden;
  2166. // select
  2167. .select-container {
  2168. .el-select > .el-input {
  2169. min-width: 280px !important;
  2170. max-width: 500px !important;
  2171. }
  2172. }
  2173. .top-area {
  2174. margin: 0px 32px 6px;
  2175. display: flex;
  2176. justify-content: flex-end;
  2177. .select-box {
  2178. height: 46px;
  2179. flex-grow: 1;
  2180. .label-legend {
  2181. height: 19px;
  2182. margin-bottom: 4px;
  2183. display: inline-block;
  2184. position: absolute;
  2185. right: 30px;
  2186. height: 32px;
  2187. line-height: 32px;
  2188. div {
  2189. display: inline-block;
  2190. font-size: 12px;
  2191. }
  2192. div + div {
  2193. margin-left: 30px;
  2194. }
  2195. }
  2196. }
  2197. }
  2198. #echart {
  2199. height: 31%;
  2200. padding: 0 12px;
  2201. }
  2202. .echart-no-data {
  2203. height: 31%;
  2204. padding: 0 12px;
  2205. width: 100%;
  2206. }
  2207. .table-container {
  2208. background-color: white;
  2209. height: calc(67% - 78px);
  2210. padding: 6px 32px 0px;
  2211. position: relative;
  2212. .disabled-checked {
  2213. position: absolute;
  2214. top: 9px;
  2215. left: 0px;
  2216. z-index: 1000;
  2217. width: 87px;
  2218. height: 66px;
  2219. cursor: not-allowed;
  2220. }
  2221. .custom-label {
  2222. max-width: calc(100% - 25px);
  2223. padding: 0;
  2224. vertical-align: middle;
  2225. }
  2226. a {
  2227. cursor: pointer;
  2228. }
  2229. .el-pagination {
  2230. float: right;
  2231. margin-right: 32px;
  2232. bottom: 10px;
  2233. }
  2234. .pagination-container {
  2235. height: 40px;
  2236. }
  2237. }
  2238. }
  2239. }
  2240. .tooltip-msg {
  2241. white-space: normal;
  2242. word-break: break-all;
  2243. max-width: 250px;
  2244. }
  2245. </style>