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.

debugger.vue 76 kB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333
  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="deb-wrap">
  15. <div class="left-wrap"
  16. :class="{collapse:leftShow}">
  17. <div class="left"
  18. v-show="!leftShow">
  19. <div class="header">
  20. {{radio1==='tree' ? $t('debugger.nodeList') : $t('debugger.curHitNode')}}
  21. <div class="radio-tabs">
  22. <el-radio-group v-model="radio1"
  23. size='mini'
  24. @change="getWatchpointHits">
  25. <el-radio-button label="tree">
  26. <i class="el-icon-s-grid"></i>
  27. </el-radio-button>
  28. <el-radio-button label="hit">
  29. <i class="el-icon-s-fold"></i>
  30. </el-radio-button>
  31. </el-radio-group>
  32. </div>
  33. </div>
  34. <div class="content"
  35. v-show="radio1==='tree'">
  36. <div class="node-type">
  37. <div class="label">{{ $t('debugger.graphFile') }}</div>
  38. <el-select v-model="graphFiles.value"
  39. @change="queryGraphByFile">
  40. <el-option v-for="item in graphFiles.options"
  41. :key="item"
  42. :value="item">
  43. </el-option>
  44. </el-select>
  45. </div>
  46. <div class="node-type">
  47. <div class="label">{{$t('debugger.nodeTypes')}}</div>
  48. <el-select v-model="nodeTypes.value"
  49. @change="nodeTypesChange">
  50. <el-option v-for="item in nodeTypes.options"
  51. :key="item"
  52. :label="nodeTypes.label[item]"
  53. :value="item"
  54. :class="{'deb-indent': item != 'all'}">
  55. </el-option>
  56. </el-select>
  57. </div>
  58. <div class="select-wrap">
  59. <el-input :placeholder="$t('graph.inputNodeName')"
  60. v-model="searchWord"
  61. class="input-with-select"
  62. @input="filterChange"
  63. @keyup.enter.native="filter"
  64. clearable>
  65. </el-input>
  66. </div>
  67. <div class="tree-wrap">
  68. <div class="select-all-files"
  69. v-if="curWatchPointId && treeFlag">
  70. <el-button type="primary"
  71. size="mini"
  72. class="custom-btn"
  73. @click="selectAllFiles(true)">{{ $t('public.selectAll') }}</el-button>
  74. <el-button type="primary"
  75. size="mini"
  76. class="custom-btn"
  77. @click="selectAllFiles(false)">{{ $t('public.deselectAll') }}</el-button>
  78. </div>
  79. <el-tree v-show="treeFlag"
  80. :props="props"
  81. :load="loadNode"
  82. @node-collapse="nodeCollapse"
  83. @node-click="handleNodeClick"
  84. node-key="name"
  85. :default-checked-keys="defaultCheckedArr"
  86. :expand-on-click-node="false"
  87. :lazy="lazy"
  88. :highlight-current="true"
  89. ref="tree"
  90. @check="check"
  91. :show-checkbox="!!curWatchPointId">
  92. <span class="custom-tree-node"
  93. slot-scope="{ node ,data }">
  94. <span>
  95. <img v-if="data.type ==='name_scope'"
  96. :src="require('@/assets/images/name-scope.svg')"
  97. class="image-type" />
  98. <img v-else-if="data.type ==='Const'"
  99. :src="require('@/assets/images/constant-node.svg')"
  100. class="image-type" />
  101. <img v-else-if="data.type ==='aggregation_scope'"
  102. :src="require('@/assets/images/polymetric.svg')"
  103. class="image-type" />
  104. <img v-else
  105. :src="require('@/assets/images/operator-node.svg')"
  106. class="image-type" />
  107. </span>
  108. <span class="custom-tree-node">{{ node.label }}</span>
  109. </span>
  110. </el-tree>
  111. <el-tree v-show="!treeFlag"
  112. :props="defaultProps"
  113. :load="loadSearchNode"
  114. :lazy="true"
  115. node-key="name"
  116. :default-checked-keys="searchCheckedArr"
  117. :expand-on-click-node="false"
  118. @node-click="handleNodeClick"
  119. ref="searchTree">
  120. <span class="custom-tree-node"
  121. slot-scope="{ node ,data }">
  122. <span>
  123. <img v-if="data.type ==='name_scope'"
  124. :src="require('@/assets/images/name-scope.svg')"
  125. class="image-type" />
  126. <img v-else-if="data.type ==='Const'"
  127. :src="require('@/assets/images/constant-node.svg')"
  128. class="image-type" />
  129. <img v-else-if="data.type ==='aggregation_scope'"
  130. :src="require('@/assets/images/polymetric.svg')"
  131. class="image-type" />
  132. <img v-else
  133. :src="require('@/assets/images/operator-node.svg')"
  134. class="image-type" />
  135. </span>
  136. <span class="custom-tree-node">{{ node.label }}</span>
  137. </span>
  138. </el-tree>
  139. </div>
  140. <div class="watch-point-wrap">
  141. <div class="title-wrap">
  142. {{$t('debugger.watchList')}}
  143. <div class="check-wrap">
  144. <i class="el-icon-circle-check"
  145. :title="$t('debugger.recheck')"
  146. :class="{disable: !enableRecheck}"
  147. @click="recheckWatchpoint()"></i>
  148. </div>
  149. <div class="delete-wrap">
  150. <i class="el-icon-delete"
  151. :title="$t('debugger.clearWatchpoint')"
  152. :class="{disable: !watchPointArr.length}"
  153. @click="deleteWatchpoint()"></i>
  154. </div>
  155. <div class="add-wrap">
  156. <i class="el-icon-circle-plus"
  157. :title="$t('debugger.createWP')"
  158. @click="addWatchPoint"></i>
  159. </div>
  160. </div>
  161. <div class="content-wrap">
  162. <ul id="watch-point-list"
  163. class="list-wrap"
  164. v-show="allWatchPointFlag">
  165. <li class="list"
  166. v-for="(item,key) in watchPointArr"
  167. :key="key"
  168. :title="getWatchPointContent(item)">
  169. <div class="name"
  170. :class="{selected:item.selected}"
  171. @click="selectWatchPoint(key)">
  172. <div class="item-content">
  173. {{getWatchPointContent(item)}}
  174. </div>
  175. <i class="el-icon-check"
  176. v-if="item.selected"
  177. @click.stop="showOrigin()"></i>
  178. <i class="el-icon-close"
  179. v-if="item.selected"
  180. @click.stop="deleteWatchpoint(item)"></i>
  181. </div>
  182. </li>
  183. </ul>
  184. </div>
  185. </div>
  186. </div>
  187. <div class="content"
  188. v-show="radio1==='hit'">
  189. <div class="hit-list-wrap">
  190. <el-table :data="watchPointHits"
  191. row-key="id"
  192. :expand-row-keys="expandKeys">
  193. <el-table-column type="expand"
  194. width="40">
  195. <template slot-scope="props">
  196. <ul>
  197. <li v-for="(i, index) in props.row.lists"
  198. :key="index">{{i.name}}</li>
  199. </ul>
  200. </template>
  201. </el-table-column>
  202. <el-table-column prop="name"
  203. :label="$t('graph.name')">
  204. <template slot-scope="scope">
  205. <div class="hit-item"
  206. :class="{selected:scope.row.selected}"
  207. @click="updateTensorValue(scope.$index)">
  208. {{scope.row.graph_name}}/{{scope.row.name}}
  209. </div>
  210. </template>
  211. </el-table-column>
  212. </el-table>
  213. </div>
  214. </div>
  215. <div class="btn-wrap">
  216. <div class="step">
  217. <el-tooltip class="item"
  218. effect="light"
  219. :content="$t('debugger.inputTip')"
  220. placement="top-start">
  221. <el-input v-model="step"
  222. :placeholder="$t('debugger.inputStep')"
  223. @input="stepChange"
  224. @keyup.native.enter="control(0)">
  225. </el-input>
  226. </el-tooltip>
  227. <el-button type="primary"
  228. size="mini"
  229. class="custom-btn green"
  230. :disabled="!step || metadata.state==='running' || metadata.state==='pending'"
  231. @click="control(0)">{{ $t('public.sure') }}</el-button>
  232. </div>
  233. <div class="btn-two">
  234. <el-button size="mini"
  235. class="custom-btn white"
  236. :disabled="metadata.state==='running'|| metadata.state==='pending'"
  237. @click="control(1)">{{$t('debugger.continue')}}</el-button>
  238. <el-button size="mini"
  239. class="custom-btn white"
  240. :disabled="metadata.state!=='running'"
  241. @click="control(3)">{{$t('debugger.pause')}}</el-button>
  242. <el-button size="mini"
  243. class="custom-btn white"
  244. :disabled="metadata.state==='pending'"
  245. @click="terminate">{{$t('debugger.terminate')}}</el-button>
  246. </div>
  247. </div>
  248. </div>
  249. <div class="collapse-btn"
  250. :class="{collapse:leftShow}"
  251. @click="collapseBtnClick">
  252. </div>
  253. </div>
  254. <div class="right"
  255. :class="{collapse:leftShow}">
  256. <div class="header">
  257. <span class="item">
  258. {{$t('debugger.clientIp') + $t('symbols.colon')}}
  259. <span class="content">
  260. {{ metadata.ip !== undefined ? metadata.ip : '--' }}
  261. </span>
  262. </span>
  263. <span class="item">{{$t('debugger.deviceId') + $t('symbols.colon')}}
  264. <span class="content">
  265. {{ metadata.device_name !== undefined ? metadata.device_name : '--' }}
  266. </span>
  267. </span>
  268. <span class="item">{{$t('debugger.currentStep') + $t('symbols.colon')}}
  269. <span class="content">
  270. {{ metadata.step !== undefined ? metadata.step : '--'}}
  271. </span>
  272. </span>
  273. {{ $t('debugger.stepTip')}}
  274. </div>
  275. <div class="svg-wrap"
  276. :class="{collapse: collapseTable}">
  277. <div class="graph-container">
  278. <div id="graph"></div>
  279. <div id="contextMenu">
  280. <ul>
  281. <li>{{ $t('debugger.continueTo')}}</li>
  282. </ul>
  283. </div>
  284. </div>
  285. <div class="btn-wrap">
  286. <el-button v-if="version==='Ascend'"
  287. type="primary"
  288. size="mini"
  289. class="custom-btn green notShow"
  290. @click="getNodeByBfs(false)">
  291. {{ $t('debugger.previousNode')}}
  292. </el-button>
  293. <el-button v-if="version==='GPU'"
  294. type="primary"
  295. size="mini"
  296. class="custom-btn green"
  297. :disabled="!currentNodeName"
  298. :class="{disabled:!currentNodeName}"
  299. @click="getCurrentNodeInfo">
  300. {{ $t('debugger.currentNode')}}
  301. </el-button>
  302. <el-button v-if="version==='Ascend'"
  303. type="primary"
  304. size="mini"
  305. class="custom-btn white notShow"
  306. @click="getNodeByBfs(true)">
  307. {{ $t('debugger.nextNode')}}
  308. </el-button>
  309. <el-button v-if="version==='GPU'"
  310. type="primary"
  311. size="mini"
  312. class="custom-btn white"
  313. @click="getNextNodeInfo">
  314. {{ $t('debugger.nextNode')}}
  315. </el-button>
  316. </div>
  317. </div>
  318. <div class="table-container"
  319. :class="{collapse: collapseTable}">
  320. <img :src="require('@/assets/images/all-drop-down.png')"
  321. v-show="collapseTable"
  322. @click="rightCollapse()"
  323. alt="" />
  324. <img :src="require('@/assets/images/all-uptake.png')"
  325. v-show="!collapseTable"
  326. @click="rightCollapse()"
  327. alt="" />
  328. <el-tabs v-model="tabs.activeName">
  329. <el-tab-pane :label="$t('debugger.tensorMsg')"
  330. name="tensor">
  331. <div class="table-content">
  332. <div class="table-wrap">
  333. <el-table ref="singleTable"
  334. :data="tableData"
  335. :header-cell-style="discountHeaderStyle"
  336. :span-method="objectSpanMethod"
  337. :row-class-name="tableRowClassName"
  338. tooltip-effect="light">
  339. <el-table-column :label="$t('graph.name')">
  340. <el-table-column property="type"
  341. width="80"></el-table-column>
  342. <el-table-column label=""
  343. show-overflow-tooltip>
  344. <template slot-scope="scope">
  345. <span class="value"
  346. @click="queryAllTreeData(scope.row.name,false,scope.row.graph_name)">
  347. {{ scope.row.name }}
  348. </span>
  349. </template>
  350. </el-table-column>
  351. </el-table-column>
  352. <el-table-column property="step"
  353. :label="$t('debugger.step')"
  354. width="80">
  355. </el-table-column>
  356. <el-table-column property="dtype"
  357. :label="$t('debugger.dType')"
  358. width="200">
  359. </el-table-column>
  360. <el-table-column property="shape"
  361. :label="$t('debugger.shape')"
  362. width="120">
  363. </el-table-column>
  364. <el-table-column :label="$t('debugger.value')"
  365. width="260">
  366. <template slot="header">
  367. <span class="center">{{ $t('debugger.value')}}</span>
  368. </template>
  369. <template slot-scope="scope">
  370. <div class="value-wrap">
  371. <el-button size="mini"
  372. type="text"
  373. v-if="scope.row.value === 'click to view'"
  374. @click="viewValueDetail(scope.row)">
  375. {{ $t('debugger.view') }}
  376. </el-button>
  377. <span v-else
  378. class="value-tip"
  379. :title="isNaN(scope.row.value)?'':scope.row.value">{{ scope.row.value }}</span>
  380. <el-button size="mini"
  381. type="text"
  382. :disabled="!scope.row.has_prev_step"
  383. @click="tensorComparisons(scope.row)">
  384. {{ $t('debugger.compareToPre') }}
  385. </el-button>
  386. </div>
  387. </template>
  388. </el-table-column>
  389. </el-table>
  390. </div>
  391. </div>
  392. </el-tab-pane>
  393. <el-tab-pane :label="$t('graph.nodeInfo')"
  394. name="detail">
  395. <div class="table-content">
  396. <div class="table-wrap">
  397. <el-table ref="nodeInfo"
  398. :data="selectedNode.IOInfo"
  399. :header-cell-style="discountHeaderStyle"
  400. :span-method="objectSpanMethod"
  401. :row-class-name="tableRowClassName"
  402. tooltip-effect="light">
  403. <el-table-column :label="$t('graph.name')">
  404. <el-table-column property="IOType"
  405. width="80"></el-table-column>
  406. <el-table-column label=""
  407. show-overflow-tooltip>
  408. <template slot-scope="scope">
  409. <span class="value"
  410. @click="queryAllTreeData(scope.row.name,false,scope.row.graph_name)">
  411. {{ scope.row.name }}
  412. </span>
  413. </template>
  414. </el-table-column>
  415. </el-table-column>
  416. </el-table>
  417. </div>
  418. </div>
  419. </el-tab-pane>
  420. </el-tabs>
  421. </div>
  422. </div>
  423. <div class="deb-con"
  424. v-if="tensorCompareFlag">
  425. <div class="deb-con-title">
  426. <div class="deb-con-title-left"
  427. :title="curRowObj.name">
  428. {{ curRowObj.name }}
  429. </div>
  430. <div class="deb-con-title-middle">
  431. MIN
  432. <div class="grident">0</div>
  433. MAX
  434. </div>
  435. <div class="deb-con-title-right">
  436. <div class="close-btn">
  437. <img src="@/assets/images/close-page.png"
  438. @click="tensorCompareFlag=false;dims=null;tolerance=0;">
  439. </div>
  440. </div>
  441. </div>
  442. <div class="deb-con-slide">
  443. <div class="deb-con-slide-left"
  444. v-if="gridType === 'compare'">
  445. <div class="deb-slide-title">{{ $t('debugger.tolerance') }}</div>
  446. <div class="deb-slide-width">
  447. <el-slider v-model="tolerance"
  448. :format-tooltip="formatTolenrance"
  449. @change="tensorComparisons(curRowObj,dims)"
  450. @input="toleranceInputChange()"></el-slider>
  451. </div>
  452. <div class="deb-slide-input">
  453. <el-input v-model="toleranceInput"
  454. @input="toleranceValueChange"
  455. @keyup.native.enter="tensorComparisons(curRowObj,dims)"></el-input>
  456. </div>
  457. </div>
  458. <div class="deb-con-slide-right">
  459. <el-button size="mini"
  460. class="custom-btn"
  461. :class="{green:gridType==='value'}"
  462. @click="tabChange('value')">{{ $t('debugger.curValue') }}</el-button>
  463. <el-button size="mini"
  464. class="custom-btn"
  465. :class="{green:gridType==='compare'}"
  466. :disabled="!curRowObj.has_prev_step"
  467. @click="tabChange('compare')">{{ $t('debugger.compareToPre') }}</el-button>
  468. </div>
  469. </div>
  470. <div class="deb-con-table">
  471. <div class="deb-compare-wrap">
  472. <debuggerGridTable v-if="gridType==='value'"
  473. :fullData="tensorValue"
  474. :showFilterInput="showFilterInput"
  475. ref="tensorValue"
  476. gridType="value"
  477. @martixFilterChange="tensorFilterChange($event)">
  478. </debuggerGridTable>
  479. <debuggerGridTable v-else
  480. :fullData="tensorValue"
  481. :showFilterInput="showFilterInput"
  482. ref="tensorValue"
  483. gridType="compare"
  484. @martixFilterChange="tensorFilterChange($event)">
  485. </debuggerGridTable>
  486. </div>
  487. <div class="deb-compare-detail">
  488. <span>{{ $t('tensors.dimension') }} {{ curRowObj.shape }}</span>
  489. <div v-for="(statistics,key) in statisticsArr"
  490. :key="key">
  491. <label v-if="key===0">{{$t('debugger.curStatisticsLabel')}}<span>{{ metadata.step }}</span></label>
  492. <label v-if="key===1">{{$t('debugger.preStatisticsLabel')}}<span>{{ metadata.step-1 }}</span></label>
  493. <label v-if="key===2">{{$t('debugger.diffStatisticsLabel')}}</label>
  494. <span>{{ $t('debugger.max') }} {{ statistics.overall_max }}</span>
  495. <span>{{ $t('debugger.min') }} {{ statistics.overall_min }}</span>
  496. <span>{{ $t('debugger.mean') }} {{ statistics.overall_avg }}</span>
  497. <span>{{ $t('debugger.nan') }} {{ statistics.overall_nan_count }}</span>
  498. <span>{{ $t('debugger.negativeInf') }} {{ statistics.overall_neg_inf_count }}</span>
  499. <span>{{ $t('debugger.inf') }} {{ statistics.overall_pos_inf_count }}</span>
  500. <span>{{ $t('debugger.zero') }} {{ statistics.overall_zero_count }}</span>
  501. <span>{{ $t('debugger.negativeNum') }} {{ statistics.overall_neg_zero_count }}</span>
  502. <span>{{ $t('debugger.positiveNum') }} {{ statistics.overall_pos_zero_count }}</span>
  503. </div>
  504. </div>
  505. </div>
  506. </div>
  507. <el-dialog :title="$t('debugger.createWP')"
  508. :visible.sync="createWPDialogVisible"
  509. :show-close="false"
  510. :close-on-click-modal="false"
  511. :modal-append-to-body="false"
  512. class="creat-watch-point-dialog"
  513. width="900px">
  514. <div class="conditions-container">
  515. <div class="condition-item"
  516. v-for="(item, index) in createWatchPointArr"
  517. :key="index">
  518. <el-select v-model="item.collection.selectedId"
  519. class="collection"
  520. @change="collectionChange(item)">
  521. <el-option v-for="i in conditionCollections"
  522. :key="i.id"
  523. :label="transCondition(i.id)"
  524. :value="i.id">
  525. </el-option>
  526. </el-select>
  527. <el-select v-model="item.condition.selectedId"
  528. class="condition"
  529. @change="conditionChange(item)">
  530. <el-option v-for="i in item.condition.options"
  531. :key="i.id"
  532. :label="transCondition(i.id)"
  533. :value="i.id">
  534. </el-option>
  535. </el-select>
  536. <el-select v-model="item.param.name"
  537. @change="paramChange(item)"
  538. v-if="item.param.options.length"
  539. class="param">
  540. <el-option v-for="i in item.param.options"
  541. :key="i.name"
  542. :label="transCondition(i.name)"
  543. :value="i.name">
  544. </el-option>
  545. </el-select>
  546. <el-input v-model="item.param.value"
  547. :placeholder="$t('scalar.placeHolderNumber')"
  548. v-if="item.param.options.length &&
  549. item.param.type !== 'BOOL'"
  550. @input="validateParam(item)"
  551. class="param-value"></el-input>
  552. <el-select v-model="item.param.value"
  553. v-if="item.param.options.length &&
  554. item.param.type === 'BOOL'"
  555. class="param-value">
  556. <el-option :key="true"
  557. label="true"
  558. :value="true">
  559. </el-option>
  560. <el-option :key="false"
  561. label="false"
  562. :value="false">
  563. </el-option>
  564. </el-select>
  565. </div>
  566. </div>
  567. <span slot="footer"
  568. class="dialog-footer">
  569. <el-button type="primary"
  570. size="mini"
  571. class="custom-btn green"
  572. :disabled="!validPram"
  573. @click="createWatchPoint(true)">{{$t('public.sure')}}</el-button>
  574. <el-button type="primary"
  575. size="mini"
  576. class="custom-btn"
  577. @click="createWatchPoint(false)">
  578. {{ $t('public.cancel') }}
  579. </el-button>
  580. </span>
  581. </el-dialog>
  582. <el-dialog :title="$t('public.notice')"
  583. :visible.sync="dialogVisible"
  584. :show-close="false"
  585. :close-on-click-modal="false"
  586. :modal-append-to-body="false"
  587. class="pendingTips"
  588. width="420px">
  589. <span class="dialog-icon">
  590. <span class="el-icon-warning"></span>
  591. </span>
  592. <span v-if="initFail"
  593. class="dialog-content">{{ $t('debugger.debuggerError') }}</span>
  594. <span v-else
  595. class="dialog-content">{{ $t('debugger.pendingTips') }}</span>
  596. <span slot="footer"
  597. class="dialog-footer">
  598. <el-button type="primary"
  599. size="mini"
  600. class="custom-btn green"
  601. @click="toSummeryList()">{{$t('debugger.toSummeryList')}}</el-button>
  602. </span>
  603. </el-dialog>
  604. </div>
  605. </template>
  606. <script>
  607. import {select, selectAll, zoom, dispatch} from 'd3';
  608. import 'd3-graphviz';
  609. import debuggerGridTable from '../../components/debuggerGridTableSimple.vue';
  610. const d3 = {select, selectAll, zoom, dispatch};
  611. import RequestService from '@/services/request-service';
  612. import commonGraph from '../../mixins/commonGraph.vue';
  613. import debuggerMixin from '../../mixins/debuggerMixin.vue';
  614. export default {
  615. mixins: [commonGraph, debuggerMixin],
  616. data() {
  617. return {
  618. leftShow: false,
  619. searchWord: '',
  620. tableData: [],
  621. currentRow: null,
  622. tipsFlag: false,
  623. props: {
  624. label: 'label',
  625. children: 'children',
  626. isLeaf: 'leaf',
  627. },
  628. defaultProps: {
  629. children: 'nodes',
  630. label: 'label',
  631. isLeaf: 'leaf',
  632. },
  633. curNodeData: [],
  634. lazy: true,
  635. radio1: 'tree',
  636. nodeTypes: {
  637. options: ['all', 'weight', 'activation', 'gradient'],
  638. label: {},
  639. value: 'all',
  640. },
  641. watchPointArr: [],
  642. allWatchPointFlag: true,
  643. enableRecheck: false,
  644. dynamicTreeData: [],
  645. watchPointHits: [],
  646. defaultCheckedArr: [],
  647. origialTree: [],
  648. conditionCollections: [],
  649. createWatchPointArr: [],
  650. createWPDialogVisible: false,
  651. validPram: false,
  652. curWatchPointId: null,
  653. step: '',
  654. metadata: {},
  655. searchTreeData: [],
  656. treeFlag: true,
  657. curCheckedName: '',
  658. isSelected: false,
  659. searchCheckedArr: [],
  660. curHalfCheckedKeys: [],
  661. tensorValue: [],
  662. loadingOption: {
  663. lock: true,
  664. text: this.$t('public.dataLoading'),
  665. spinner: 'el-icon-loading',
  666. background: 'rgba(0, 0, 0, 0.3)',
  667. },
  668. outputLength: 0,
  669. inputLength: 0,
  670. curLeafNodeName: null,
  671. graphFiles: {
  672. options: [],
  673. value: '',
  674. graphs: {},
  675. },
  676. allGraphData: {}, // Graph Original input data
  677. firstFloorNodes: [], // ID array of the first layer node.
  678. nodesCountLimit: 1500, // Maximum number of sub-nodes in a namespace.
  679. maxChainNum: 70,
  680. scaleRange: [0.001, 1000], // Graph zooms in and zooms out.
  681. graphviz: null,
  682. graphvizTemp: null,
  683. graph: {},
  684. selectedNode: {},
  685. svg: {},
  686. contextmenu: {
  687. point: {},
  688. id: 'contextMenu',
  689. dom: null,
  690. },
  691. code: '',
  692. version: 'Ascend',
  693. nodeName: '',
  694. pollInit: true,
  695. collapseTable: false,
  696. dialogVisible: false,
  697. initFail: false,
  698. isIntoView: true,
  699. tolerance: 0,
  700. tensorCompareFlag: false,
  701. gridType: 'compare',
  702. curRowObj: {},
  703. dims: null,
  704. node: null,
  705. resolve: null,
  706. toleranceInput: 0,
  707. showFilterInput: true,
  708. currentNodeName: '',
  709. statisticsArr: [],
  710. tabs: {
  711. activeName: 'tensor',
  712. },
  713. searchNode: null,
  714. searchResolve: null,
  715. isCurrentGraph: true, // Check whether the new and old graphs are the same.
  716. expandKeys: [],
  717. isHitIntoView: true,
  718. };
  719. },
  720. components: {debuggerGridTable},
  721. computed: {},
  722. mounted() {
  723. document.title = `${this.$t('debugger.debugger')}-MindInsight`;
  724. window.addEventListener(
  725. 'resize',
  726. this.debounce(this.resizeCallback, 200),
  727. false,
  728. );
  729. this.nodeTypes.label = this.$t('debugger.nodeType');
  730. },
  731. watch: {
  732. 'metadata.state': {
  733. handler(newValue, oldValue) {
  734. if (newValue === 'pending' && oldValue !== undefined) {
  735. location.reload();
  736. }
  737. if (oldValue === 'pending' && newValue === 'waiting') {
  738. this.loadNode(this.node, this.resolve);
  739. }
  740. if (oldValue === 'running' && newValue === 'waiting') {
  741. this.getWatchpointHits();
  742. }
  743. if (newValue === 'pending') {
  744. this.dialogVisible = true;
  745. } else {
  746. this.dialogVisible = false;
  747. }
  748. },
  749. deep: true,
  750. },
  751. },
  752. methods: {
  753. queryGraphByFile() {
  754. this.searchWord = '';
  755. this.nodeTypes.value = 'all';
  756. this.treeFlag = true;
  757. const params = {
  758. mode: 'node',
  759. params: {
  760. watch_point_id: this.curWatchPointId ? this.curWatchPointId : 0,
  761. graph_name: this.graphFiles.value,
  762. },
  763. };
  764. if (this.graphFiles.value === this.$t('debugger.all')) {
  765. delete params.params.graph_name;
  766. }
  767. RequestService.retrieve(params).then(
  768. (res) => {
  769. if (res.data && res.data.metadata) {
  770. this.dealMetadata(res.data.metadata);
  771. }
  772. if (res.data && res.data.graph) {
  773. const graph = res.data.graph;
  774. this.origialTree = res.data.graph.nodes.map((val) => {
  775. return {
  776. label: val.name.split('/').pop(),
  777. leaf:
  778. val.type === 'name_scope' || val.type === 'aggregation_scope'
  779. ? false
  780. : true,
  781. ...val,
  782. };
  783. });
  784. this.node.childNodes = [];
  785. this.resolve(this.origialTree);
  786. this.defaultCheckedArr = this.origialTree
  787. .filter((val) => {
  788. return val.watched === 2;
  789. })
  790. .map((val) => val.name);
  791. this.node.childNodes.forEach((val) => {
  792. if (val.data.watched === 1) {
  793. val.indeterminate = true;
  794. }
  795. if (val.data.watched === 0) {
  796. val.checked = false;
  797. }
  798. if (val.data.watched === 2) {
  799. val.checked = true;
  800. }
  801. });
  802. this.firstFloorNodes = [];
  803. this.allGraphData = {};
  804. d3.select('#graph svg').remove();
  805. this.selectedNode.name = '';
  806. this.dealGraphData(JSON.parse(JSON.stringify(graph.nodes)));
  807. }
  808. },
  809. (err) => {
  810. this.showErrorMsg(err);
  811. this.resolve([]);
  812. },
  813. );
  814. },
  815. selectAllFiles(type) {
  816. if (
  817. !type &&
  818. !this.$refs.tree.getCheckedKeys().length &&
  819. !this.$refs.tree.getHalfCheckedKeys().length
  820. ) {
  821. return;
  822. }
  823. if (type && !this.node.childNodes.find((val) => val.checked === false)) {
  824. return;
  825. }
  826. const watchNodes = [];
  827. this.node.childNodes.forEach((val) => {
  828. if (type !== val.checked || (!type && val.indeterminate)) {
  829. watchNodes.push(val.data.name);
  830. }
  831. val.indeterminate = false;
  832. val.checked = type;
  833. if (val.childNodes) {
  834. this.dealCheckPro(val.childNodes, type);
  835. }
  836. });
  837. if (this.curWatchPointId) {
  838. const params = {
  839. watch_point_id: this.curWatchPointId ? this.curWatchPointId : 0,
  840. watch_nodes: watchNodes,
  841. mode: type ? 1 : 0,
  842. graph_name: this.graphFiles.value,
  843. };
  844. if (this.graphFiles.value === this.$t('debugger.all')) {
  845. delete params.graph_name;
  846. }
  847. RequestService.updateWatchpoint(params).then(
  848. (res) => {
  849. this.defaultCheckedArr = this.$refs.tree.getCheckedKeys();
  850. },
  851. (err) => {
  852. this.showErrorMsg(err);
  853. },
  854. );
  855. }
  856. },
  857. nodeTypesChange() {
  858. if (this.nodeTypes.value === 'all' && !this.searchWord) {
  859. this.treeFlag = true;
  860. this.node.level = 0;
  861. this.queryGraphByFile();
  862. } else {
  863. this.treeFlag = false;
  864. this.filter();
  865. }
  866. },
  867. /**
  868. * Query graph data by watchpoint id
  869. * @param {Number} id Wacthpoint id
  870. */
  871. queryGraphByWatchpoint(id) {
  872. const params = {
  873. mode: 'watchpoint',
  874. params: {watch_point_id: id, graph_name: this.graphFiles.value},
  875. };
  876. if (this.graphFiles.value === this.$t('debugger.all')) {
  877. delete params.params.graph_name;
  878. }
  879. RequestService.retrieve(params).then(
  880. (res) => {
  881. if (res.data && res.data.graph) {
  882. const graph = res.data.graph;
  883. this.curNodeData = graph.nodes.map((val) => {
  884. return {
  885. label: val.name.split('/').pop(),
  886. ...val,
  887. };
  888. });
  889. this.node.childNodes = [];
  890. this.curWatchPointId = id;
  891. this.resolve(this.curNodeData);
  892. this.$refs.tree.getCheckedKeys().forEach((val) => {
  893. this.$refs.tree.setChecked(val, false);
  894. });
  895. this.defaultCheckedArr = this.curNodeData
  896. .filter((val) => {
  897. return val.watched === 2;
  898. })
  899. .map((val) => val.name);
  900. const halfSelectArr = this.curNodeData
  901. .filter((val) => {
  902. return val.watched === 1;
  903. })
  904. .map((val) => val.name);
  905. this.node.childNodes.forEach((val) => {
  906. if (halfSelectArr.indexOf(val.data.name) !== -1) {
  907. val.indeterminate = true;
  908. }
  909. });
  910. this.firstFloorNodes = [];
  911. this.allGraphData = {};
  912. d3.select('#graph svg').remove();
  913. this.selectedNode.name = '';
  914. this.dealGraphData(JSON.parse(JSON.stringify(graph.nodes)));
  915. }
  916. },
  917. (err) => {
  918. this.showErrorMsg(err);
  919. },
  920. );
  921. },
  922. /** ************************ graph **********************/
  923. /**
  924. * Get watchpoint messages
  925. * @param {Object} item Wacthpoint data
  926. * @return {String}
  927. */
  928. getWatchPointContent(item) {
  929. let param = '';
  930. if (item.params.length) {
  931. item.params.forEach((i, ind) => {
  932. const name = this.transCondition(i.name);
  933. if (!ind) {
  934. param += `${name}:${i.value}`;
  935. } else {
  936. param += `, ${name}:${i.value}`;
  937. }
  938. });
  939. param = `(${param})`;
  940. }
  941. const str = `${this.$t('debugger.watchPoint')} ${
  942. item.id
  943. }: ${this.transCondition(item.condition)} ${param}`;
  944. return str;
  945. },
  946. /** ************************ graph **********************/
  947. /**
  948. * Add the location attribute to each node to facilitate the obtaining of node location parameters.
  949. */
  950. afterInitGraph() {
  951. setTimeout(() => {
  952. if (this.graphviz) {
  953. this.graphviz._data = null;
  954. this.graphviz._dictionary = null;
  955. this.graphviz = null;
  956. }
  957. if (this.graphvizTemp) {
  958. this.graphvizTemp._data = null;
  959. this.graphvizTemp._dictionary = null;
  960. this.graphvizTemp = null;
  961. }
  962. }, 100);
  963. this.fitGraph('graph');
  964. this.transplantChildrenDom();
  965. const svg = document.querySelector('#subgraphTemp svg');
  966. if (svg) {
  967. svg.remove();
  968. }
  969. const elements = d3.select('#graph').selectAll('g.node, g.edge').nodes();
  970. elements.forEach((ele) => {
  971. if (!ele.hasAttribute('transform')) {
  972. ele.setAttribute('transform', 'translate(0,0)');
  973. }
  974. // The title value needs to be manually set for the virtual node.
  975. if (Array.prototype.includes.call(ele.classList, 'plain')) {
  976. const title = ele.querySelector('title');
  977. title.textContent = title.textContent.split('^')[0];
  978. }
  979. });
  980. // The graph generated by the plug-in has a useless title and needs to be deleted.
  981. const title = document.querySelector('#graph g#graph0 title');
  982. if (title) {
  983. title.remove();
  984. }
  985. this.graph.dom = document.querySelector(`#graph #graph0`);
  986. const graphRect = this.graph.dom.getBoundingClientRect();
  987. let transform = '';
  988. if (this.graph.dom.getAttribute('transform')) {
  989. // transform information of graph
  990. transform = this.graph.dom.getAttribute('transform').split(/[(,)]/);
  991. } else {
  992. transform = ['translate', '0', '0', ' scale', '1'];
  993. }
  994. this.graph.transform = {
  995. k: parseFloat(transform[4]),
  996. x: parseFloat(transform[1]),
  997. y: parseFloat(transform[2]),
  998. };
  999. this.graph.minScale =
  1000. Math.min(
  1001. this.svg.rect.width / 2 / graphRect.width,
  1002. this.svg.rect.height / 2 / graphRect.height,
  1003. ) * this.graph.transform.k;
  1004. this.startApp();
  1005. },
  1006. /**
  1007. * Initialization method executed after the graph rendering is complete
  1008. */
  1009. startApp() {
  1010. const nodes = d3.selectAll('g.node, g.cluster');
  1011. nodes.on(
  1012. 'click',
  1013. (target, index, nodesList) => {
  1014. this.clickEvent(target, index, nodesList, 'debugger');
  1015. },
  1016. false,
  1017. );
  1018. // namespaces Expansion or Reduction
  1019. nodes.on(
  1020. 'dblclick',
  1021. (target, index, nodesList) => {
  1022. this.dblclickEvent(target, index, nodesList, 'debugger');
  1023. },
  1024. false,
  1025. );
  1026. this.initZooming('debugger');
  1027. this.initContextMenu();
  1028. if (this.selectedNode.name) {
  1029. this.selectNode(true, true);
  1030. }
  1031. },
  1032. /**
  1033. * Initialize the right-click menu
  1034. */
  1035. initContextMenu() {
  1036. this.contextmenu.dom = document.querySelector('#contextMenu');
  1037. const svgDom = document.querySelector('#graph svg');
  1038. const ignoreType = [
  1039. 'Parameter',
  1040. 'Const',
  1041. 'Depend',
  1042. 'make_tuple',
  1043. 'tuple_getitem',
  1044. 'ControlDepend',
  1045. ];
  1046. const dispatch = d3
  1047. .dispatch('start', 'contextmenu')
  1048. .on('start', (event) => {
  1049. this.contextmenu.dom.style.display = 'none';
  1050. this.contextmenu.point = {x: event.x, y: event.y};
  1051. })
  1052. .on('contextmenu', (target) => {
  1053. const svgRect = svgDom.getBoundingClientRect();
  1054. this.contextmenu.dom.style.left = `${
  1055. this.contextmenu.point.x - svgRect.x
  1056. }px`;
  1057. this.contextmenu.dom.style.top = `${
  1058. this.contextmenu.point.y - svgRect.y
  1059. }px`;
  1060. this.contextmenu.dom.style.display = 'block';
  1061. this.selectedNode.name = target.name;
  1062. this.selectNode(false, true);
  1063. });
  1064. const nodes = d3.selectAll('g.node, g.cluster');
  1065. nodes.on(
  1066. 'contextmenu',
  1067. (target, index, nodesList) => {
  1068. event.preventDefault();
  1069. const node = this.allGraphData[
  1070. nodesList[index].id.replace('_unfold', '')
  1071. ];
  1072. if (node) {
  1073. if (
  1074. !(
  1075. this.version !== 'GPU' ||
  1076. ignoreType.includes(node.type) ||
  1077. node.type.endsWith('_scope') ||
  1078. node.type.endsWith('Summary')
  1079. )
  1080. ) {
  1081. setTimeout(() => {
  1082. dispatch.call('contextmenu', this, node);
  1083. }, 10);
  1084. }
  1085. }
  1086. },
  1087. true,
  1088. );
  1089. document.oncontextmenu = (event) => {
  1090. dispatch.apply('start', this, [event]);
  1091. };
  1092. document.onmousedown = () => {
  1093. this.contextmenu.dom.style.display = 'none';
  1094. };
  1095. this.contextmenu.dom.onmousedown = () => {
  1096. this.continueTo();
  1097. };
  1098. },
  1099. /**
  1100. * Continue to
  1101. */
  1102. continueTo() {
  1103. this.watchPointHits = [];
  1104. const params = {
  1105. mode: 'continue',
  1106. level: 'node',
  1107. name: this.selectedNode.name.replace('_unfold', ''),
  1108. graph_name: this.graphFiles.value,
  1109. };
  1110. if (this.graphFiles.value === this.$t('debugger.all')) {
  1111. delete params.graph_name;
  1112. }
  1113. RequestService.control(params).then(
  1114. (res) => {
  1115. if (res && res.data) {
  1116. }
  1117. },
  1118. (error) => {
  1119. this.showErrorMsg(error);
  1120. },
  1121. );
  1122. },
  1123. /**
  1124. * Double-click the processing to be performed on the node to expand or narrow the namespace or aggregation node.
  1125. * @param {String} name Name of the current node (also the ID of the node)
  1126. */
  1127. dealDoubleClick(name) {
  1128. name = name.replace('_unfold', '');
  1129. if (this.allGraphData[name].isUnfold) {
  1130. this.selectedNode.name = name;
  1131. this.deleteNamespace(name);
  1132. } else {
  1133. this.queryGraphData(name);
  1134. }
  1135. },
  1136. /**
  1137. * Close the expanded namespace.
  1138. * @param {String} name The name of the namespace to be closed.
  1139. */
  1140. deleteNamespace(name) {
  1141. if (!this.selectedNode.more) {
  1142. this.packageDataToObject(name, false);
  1143. this.layoutController(name);
  1144. } else {
  1145. this.allGraphData[name].isUnfold = true;
  1146. this.selectedNode.name = `${name}_unfold`;
  1147. this.layoutNamescope(name, true);
  1148. }
  1149. },
  1150. /**
  1151. * Controls the invoking method of the next step.
  1152. * @param {String} name Name of the namespace to be expanded.
  1153. */
  1154. layoutController(name) {
  1155. if (name.includes('/')) {
  1156. const subPath = name.split('/').slice(0, -1).join('/');
  1157. this.layoutNamescope(subPath, true);
  1158. } else {
  1159. const svg = document.querySelector('#graph svg');
  1160. if (svg) {
  1161. svg.remove();
  1162. }
  1163. const dot = this.packageGraphData();
  1164. this.initGraph(dot);
  1165. }
  1166. },
  1167. /**
  1168. * To obtain graph data, initialize and expand the namespace or aggregate nodes.
  1169. * @param {String} name Name of the current node.
  1170. */
  1171. queryGraphData(name) {
  1172. const type = this.allGraphData[name]
  1173. ? this.allGraphData[name].type
  1174. : 'name_scope';
  1175. const mode = name ? 'node' : 'all';
  1176. const params = {
  1177. mode: mode,
  1178. };
  1179. if (name) {
  1180. params.params = {
  1181. watch_point_id: this.curWatchPointId ? this.curWatchPointId : 0,
  1182. name: name,
  1183. node_type: type,
  1184. single_node: false,
  1185. graph_name: this.graphFiles.value,
  1186. };
  1187. if (this.graphFiles.value === this.$t('debugger.all')) {
  1188. delete params.params.graph_name;
  1189. }
  1190. }
  1191. RequestService.retrieve(params)
  1192. .then(
  1193. (response) => {
  1194. if (response && response.data && response.data.graph) {
  1195. const graph = response.data.graph;
  1196. const nodes = JSON.parse(JSON.stringify(graph.nodes));
  1197. this.nodeExpandLinkage(nodes, name);
  1198. this.dealGraphData(nodes, name);
  1199. }
  1200. },
  1201. (error) => {
  1202. this.showErrorMsg(error);
  1203. },
  1204. )
  1205. .catch((error) => {
  1206. // A non-Google Chrome browser may not work properly.
  1207. if (error && error.includes('larger than maximum 65535 allowed')) {
  1208. this.$message.error(this.$t('graph.dataTooLarge'));
  1209. } else {
  1210. this.$bus.$emit('showWarmText', true);
  1211. }
  1212. if (name && this.allGraphData[name]) {
  1213. this.allGraphData[name].isUnfold = false;
  1214. this.allGraphData[name].children = [];
  1215. this.allGraphData[name].size = [];
  1216. this.allGraphData[name].html = '';
  1217. }
  1218. });
  1219. },
  1220. /**
  1221. * Process graph data
  1222. * @param {Object} nodes Nodes data
  1223. * @param {String} name Node name
  1224. */
  1225. dealGraphData(nodes, name) {
  1226. const namescopeChildLimit = 3500;
  1227. const nodesCountLimit = name ? this.nodesCountLimit : namescopeChildLimit;
  1228. const independentLayout = this.allGraphData[name]
  1229. ? this.allGraphData[name].independent_layout
  1230. : false;
  1231. if (!independentLayout && nodes.length > nodesCountLimit) {
  1232. this.$message.error(this.$t('graph.tooManyNodes'));
  1233. this.packageDataToObject(name, false);
  1234. } else {
  1235. if (nodes && nodes.length) {
  1236. this.packageDataToObject(name, true, nodes);
  1237. // If the name is empty, it indicates the outermost layer.
  1238. if (!name) {
  1239. const dot = this.packageGraphData();
  1240. this.initGraph(dot);
  1241. } else {
  1242. if (this.allGraphData[name].type === 'aggregation_scope') {
  1243. this.dealAggregationNodes(name);
  1244. if (this.allGraphData[name].maxChainNum > this.maxChainNum) {
  1245. this.$message.error(this.$t('graph.tooManyChain'));
  1246. this.allGraphData[name].isUnfold = true;
  1247. this.selectedNode.name = name;
  1248. this.deleteNamespace(name);
  1249. return;
  1250. }
  1251. }
  1252. this.allGraphData[name].isUnfold = true;
  1253. this.selectedNode.name = `${name}_unfold`;
  1254. this.layoutNamescope(name, true);
  1255. }
  1256. }
  1257. }
  1258. },
  1259. /**
  1260. * Selecting a node
  1261. * @param {Boolean} needFocus Whether to focus on the node
  1262. * @param {Boolean} isQueryTensor Whether to query tensorValue
  1263. */
  1264. selectNode(needFocus = false, isQueryTensor) {
  1265. window.getSelection().removeAllRanges();
  1266. d3.selectAll(
  1267. '.node polygon, .node ellipse, .node rect, .node path',
  1268. ).classed('selected', false);
  1269. const path = this.selectedNode.name.split('^');
  1270. const node = {};
  1271. let id = path[0].replace('_unfold', '');
  1272. this.selectedNode.name = id;
  1273. node.data = this.allGraphData[id];
  1274. if (node.data) {
  1275. id = this.allGraphData[id].isUnfold ? `${id}_unfold` : id;
  1276. node.dom = document.querySelector(`#graph g[id="${id}"]`);
  1277. if (node.dom) {
  1278. const needDelay = path.length > 1;
  1279. if ((needFocus || needDelay) && node.dom) {
  1280. this.selectNodePosition(id, needDelay);
  1281. }
  1282. d3.select(`#graph g[id="${id}"]`)
  1283. .select('polygon, rect, ellipse, path')
  1284. .classed('selected', true);
  1285. this.highlightProxyNodes(id.replace('_unfold', ''));
  1286. this.highLightEdges(node.data);
  1287. this.$refs.tree.setCurrentKey(id.replace('_unfold', ''));
  1288. if (this.isIntoView) {
  1289. this.$nextTick(() => {
  1290. setTimeout(() => {
  1291. const dom = document.querySelector(
  1292. '.el-tree-node.is-current.is-focusable',
  1293. );
  1294. if (dom) {
  1295. dom.scrollIntoView();
  1296. }
  1297. }, 800);
  1298. });
  1299. }
  1300. this.isIntoView = true;
  1301. const type = this.allGraphData[path[0].replace('_unfold', '')].type;
  1302. const ignoreType = ['name_scope', 'aggregation_scope'];
  1303. if (
  1304. isQueryTensor &&
  1305. !this.selectedNode.name.includes('more...') &&
  1306. !ignoreType.includes(type)
  1307. ) {
  1308. if (this.graph.timer) {
  1309. clearTimeout(this.graph.timer);
  1310. }
  1311. this.graph.timer = setTimeout(() => {
  1312. const name = path[0].replace('_unfold', '');
  1313. if (this.graphFiles.value === this.$t('debugger.all')) {
  1314. this.retrieveTensorHistory(
  1315. {name: name.replace(`${name.split('/')[0]}/`, '')},
  1316. name.split('/')[0],
  1317. );
  1318. } else {
  1319. this.retrieveTensorHistory(
  1320. {
  1321. name,
  1322. },
  1323. this.graphFiles.value,
  1324. );
  1325. }
  1326. }, 500);
  1327. }
  1328. if (ignoreType.includes(type)) {
  1329. this.tableData = [];
  1330. } else {
  1331. if (this.graphFiles.value === this.$t('debugger.all')) {
  1332. this.nodeName = this.selectedNode.name.replace(
  1333. `${this.selectedNode.name.split('/')[0]}/`,
  1334. '',
  1335. );
  1336. } else {
  1337. this.nodeName = this.selectedNode.name;
  1338. }
  1339. }
  1340. }
  1341. }
  1342. this.setSelectedNodeData(node.data);
  1343. if (
  1344. this.watchPointHits.length &&
  1345. this.radio1 === 'hit' &&
  1346. this.isHitIntoView
  1347. ) {
  1348. this.focusWatchpointHit();
  1349. }
  1350. this.isHitIntoView = true;
  1351. },
  1352. /**
  1353. * The node information of the selected node.
  1354. * @param {Object} selectedNode Node data
  1355. */
  1356. setSelectedNodeData(selectedNode = {}) {
  1357. this.selectedNode.IOInfo = [];
  1358. this.selectedNode.inputNum = 0;
  1359. this.selectedNode.outputNum = 0;
  1360. if (selectedNode.output) {
  1361. Object.keys(selectedNode.output).forEach((key) => {
  1362. let graphName = this.graphFiles.value;
  1363. if (this.graphFiles.value === this.$t('debugger.all')) {
  1364. graphName = key.split('/')[0];
  1365. key = key.replace(`${graphName}/`, '');
  1366. }
  1367. const obj = {name: key, IOType: 'output', graph_name: graphName};
  1368. this.selectedNode.IOInfo.push(obj);
  1369. this.selectedNode.outputNum++;
  1370. });
  1371. }
  1372. if (selectedNode.input) {
  1373. Object.keys(selectedNode.input).forEach((key) => {
  1374. let graphName = this.graphFiles.value;
  1375. if (this.graphFiles.value === this.$t('debugger.all')) {
  1376. graphName = key.split('/')[0];
  1377. key = key.replace(`${graphName}/`, '');
  1378. }
  1379. const obj = {name: key, IOType: 'input', graph_name: graphName};
  1380. this.selectedNode.IOInfo.push(obj);
  1381. this.selectedNode.inputNum++;
  1382. });
  1383. }
  1384. },
  1385. /**
  1386. * The position is offset to the current node in the center of the screen.
  1387. * @param {String} nodeId Selected Node id
  1388. * @param {Boolean} needDelay Delay required
  1389. */
  1390. selectNodePosition(nodeId, needDelay) {
  1391. const nodeDom = document.querySelector(`#graph0 g[id="${nodeId}"]`);
  1392. const nodeRect = nodeDom.getBoundingClientRect();
  1393. const graphObj = {};
  1394. graphObj.rect = this.graph.dom.getBoundingClientRect();
  1395. graphObj.initWidth = graphObj.rect.width / this.graph.transform.k;
  1396. graphObj.initHeight = graphObj.rect.height / this.graph.transform.k;
  1397. const screenChange = {
  1398. x:
  1399. nodeRect.left +
  1400. nodeRect.width / 2 -
  1401. (this.svg.rect.left + this.svg.rect.width / 2),
  1402. y:
  1403. nodeRect.top +
  1404. nodeRect.height / 2 -
  1405. (this.svg.rect.top + this.svg.rect.height / 2),
  1406. };
  1407. this.graph.transform.x -=
  1408. screenChange.x * (this.svg.originSize.width / graphObj.initWidth);
  1409. this.graph.transform.y -=
  1410. screenChange.y * (this.svg.originSize.height / graphObj.initHeight);
  1411. this.graph.dom.setAttribute(
  1412. 'transform',
  1413. `translate(${this.graph.transform.x},` +
  1414. `${this.graph.transform.y}) scale(${this.graph.transform.k})`,
  1415. );
  1416. const transitionTime = Math.min(
  1417. Math.abs(screenChange.x) * 2,
  1418. Math.abs(screenChange.y) * 2,
  1419. needDelay ? 800 : 0,
  1420. );
  1421. this.graph.dom.style.transition = `${transitionTime / 1000}s`;
  1422. this.graph.dom.style['transition-timing-function'] = 'linear';
  1423. setTimeout(() => {
  1424. this.graph.dom.style.transition = '';
  1425. }, transitionTime);
  1426. },
  1427. /**
  1428. * Reset graph and data
  1429. */
  1430. resetGraph() {
  1431. const temp = {};
  1432. this.firstFloorNodes.forEach((key) => {
  1433. const node = this.allGraphData[key];
  1434. node.isUnfold = false;
  1435. node.children = [];
  1436. node.size = [];
  1437. node.html = '';
  1438. temp[node.name] = node;
  1439. });
  1440. this.allGraphData = JSON.parse(JSON.stringify(temp));
  1441. d3.select('#graph svg').remove();
  1442. this.selectedNode.name = '';
  1443. const dot = this.packageGraphData();
  1444. this.initGraph(dot);
  1445. },
  1446. /**
  1447. * Search for all data of a specific node and its namespace.
  1448. * @param {Object} graphs Selected node data object
  1449. * @param {String} name Node name
  1450. * @param {Boolean} isQueryTensor Whether to query tensorValue
  1451. */
  1452. querySingleNode(graphs, name, isQueryTensor) {
  1453. this.selectedNode.name = name;
  1454. this.selectedNode.more = false;
  1455. // If a node exists on the map, select the node.
  1456. if (this.allGraphData[name]) {
  1457. if (d3.select(`g[id="${name}"], g[id="${name}_unfold"]`).size()) {
  1458. // If the namespace or aggregation node is expanded, you need to close it and select
  1459. this.selectNode(true, isQueryTensor);
  1460. } else {
  1461. const parentId = name.substring(0, name.lastIndexOf('/'));
  1462. if (
  1463. this.allGraphData[parentId] &&
  1464. this.allGraphData[parentId].isUnfold
  1465. ) {
  1466. const aggregationNode = this.allGraphData[parentId];
  1467. if (aggregationNode && aggregationNode.childIdsList) {
  1468. for (let i = 0; i < aggregationNode.childIdsList.length; i++) {
  1469. if (aggregationNode.childIdsList[i].includes(name)) {
  1470. aggregationNode.index = i;
  1471. break;
  1472. }
  1473. }
  1474. }
  1475. this.selectedNode.name = name;
  1476. this.layoutNamescope(parentId, true);
  1477. }
  1478. }
  1479. } else {
  1480. const data = this.findStartUnfoldNode(graphs.children);
  1481. if (data) {
  1482. this.dealAutoUnfoldNamescopesData(data);
  1483. }
  1484. }
  1485. },
  1486. /**
  1487. * Processes all data of the queried node and the namespace to which the node belongs.
  1488. * @param {Object} data All data of the node and the namespace to which the node belongs
  1489. * @return {Object} The data object of the namespace to expand.
  1490. */
  1491. dealAutoUnfoldNamescopesData(data) {
  1492. if (!data.scope_name) {
  1493. return this.dealAutoUnfoldNamescopesData(data.children);
  1494. } else {
  1495. if (this.allGraphData[data.scope_name].isUnfold) {
  1496. return this.dealAutoUnfoldNamescopesData(data.children);
  1497. } else {
  1498. // If the namespace is a namespace and the number of subnodes exceeds the upper limit,
  1499. // an error is reported and the namespace is selected.
  1500. if (
  1501. this.allGraphData[data.scope_name].type === 'name_scope' &&
  1502. data.nodes.length > this.nodesCountLimit
  1503. ) {
  1504. this.selectedNode.name = data.scope_name;
  1505. this.querySingleNode(data, data.scope_name, true);
  1506. this.selectNode(true, true);
  1507. this.$message.error(this.$t('graph.tooManyNodes'));
  1508. } else {
  1509. // Normal expansion
  1510. const nodes = JSON.parse(JSON.stringify(data.nodes));
  1511. this.packageDataToObject(data.scope_name, true, nodes);
  1512. if (
  1513. this.allGraphData[data.scope_name].type === 'aggregation_scope'
  1514. ) {
  1515. this.dealAggregationNodes(data.scope_name);
  1516. const aggregationNode = this.allGraphData[data.scope_name];
  1517. if (aggregationNode) {
  1518. for (let i = 0; i < aggregationNode.childIdsList.length; i++) {
  1519. if (
  1520. aggregationNode.childIdsList[i].includes(
  1521. this.selectedNode.name,
  1522. )
  1523. ) {
  1524. aggregationNode.index = i;
  1525. break;
  1526. }
  1527. }
  1528. }
  1529. if (
  1530. this.allGraphData[data.scope_name].maxChainNum >
  1531. this.maxChainNum
  1532. ) {
  1533. this.selectedNode.name = data.scope_name;
  1534. this.allGraphData[data.scope_name].isUnfold = false;
  1535. this.deleteNamespace(data.scope_name);
  1536. this.$message.error(this.$t('graph.tooManyChain'));
  1537. return;
  1538. }
  1539. }
  1540. if (data.children.scope_name) {
  1541. this.dealAutoUnfoldNamescopesData(data.children);
  1542. } else {
  1543. this.layoutNamescope(data.scope_name, true);
  1544. }
  1545. }
  1546. }
  1547. }
  1548. },
  1549. /**
  1550. * Show error message
  1551. * @param {Object} error Error data
  1552. */
  1553. showErrorMsg(error) {
  1554. if (
  1555. error &&
  1556. error.response &&
  1557. error.response.data &&
  1558. error.response.data.error_code
  1559. ) {
  1560. if (this.$t('error')[`${error.response.data.error_code}`]) {
  1561. this.$message.error(
  1562. this.$t('error')[`${error.response.data.error_code}`],
  1563. );
  1564. } else {
  1565. if (error.response.data.error_code === '5054B101') {
  1566. // The error "The graph does not exist" should not display in front page;
  1567. return;
  1568. }
  1569. this.$message.error(error.response.data.error_msg);
  1570. }
  1571. }
  1572. },
  1573. /**
  1574. * To summery list page
  1575. */
  1576. toSummeryList() {
  1577. this.dialogVisible = false;
  1578. this.$router.push({
  1579. path: '/summary-manage',
  1580. });
  1581. },
  1582. rightCollapse() {
  1583. this.collapseTable = !this.collapseTable;
  1584. setTimeout(() => {
  1585. this.initSvg(false);
  1586. }, 500);
  1587. },
  1588. },
  1589. destroyed() {
  1590. window.removeEventListener(
  1591. 'resize',
  1592. this.debounce(this.resizeCallback, 200),
  1593. false,
  1594. );
  1595. },
  1596. };
  1597. </script>
  1598. <style lang="scss">
  1599. .deb-wrap {
  1600. height: 100%;
  1601. background-color: white;
  1602. position: relative;
  1603. overflow: hidden;
  1604. & > div {
  1605. float: left;
  1606. height: 100%;
  1607. }
  1608. .left-wrap {
  1609. width: 400px;
  1610. padding-right: 25px;
  1611. height: 100%;
  1612. background-color: white;
  1613. position: relative;
  1614. transition: width 0.2s;
  1615. -moz-transition: width 0.2s; /* Firefox 4 */
  1616. -webkit-transition: width 0.2s; /* Safari and Chrome */
  1617. -o-transition: width 0.2s; /* Opera */
  1618. .left {
  1619. height: 100%;
  1620. background: #fff;
  1621. box-shadow: 0 2px 2px rgba(0, 0, 0, 0.22);
  1622. .header {
  1623. padding: 15px;
  1624. border-bottom: 1px solid #ebeef5;
  1625. position: relative;
  1626. font-weight: bold;
  1627. .radio-tabs {
  1628. position: absolute;
  1629. right: 10px;
  1630. top: 10px;
  1631. }
  1632. }
  1633. .content {
  1634. height: calc(100% - 145px);
  1635. .node-type {
  1636. height: 50px;
  1637. padding: 15px 15px 0 15px;
  1638. .label {
  1639. display: inline-block;
  1640. width: 80px;
  1641. }
  1642. .el-select {
  1643. width: calc(100% - 80px);
  1644. }
  1645. }
  1646. .select-wrap {
  1647. padding: 10px 15px;
  1648. font-size: 14px;
  1649. .el-select .el-input {
  1650. width: 100%;
  1651. }
  1652. .input-with-select .el-input-group__prepend {
  1653. background-color: #fff;
  1654. }
  1655. .el-input--suffix .el-input__inner {
  1656. padding-left: 5px;
  1657. padding-right: 30px;
  1658. font-size: 12px;
  1659. }
  1660. }
  1661. .tree-wrap {
  1662. height: calc(70% - 155px);
  1663. overflow-y: auto;
  1664. padding: 0 15px 15px;
  1665. position: relative;
  1666. z-index: 2;
  1667. .image-type {
  1668. width: 20px;
  1669. height: 10px;
  1670. margin-right: 10px;
  1671. }
  1672. .el-tree {
  1673. & > .el-tree-node {
  1674. min-width: 100%;
  1675. display: inline-block;
  1676. }
  1677. }
  1678. }
  1679. .watch-point-wrap {
  1680. height: 30%;
  1681. border-top: 1px solid #ebeef5;
  1682. .title-wrap {
  1683. height: 30px;
  1684. line-height: 30px;
  1685. padding: 0 20px;
  1686. position: relative;
  1687. border-bottom: 1px solid #ebeef5;
  1688. font-weight: bold;
  1689. }
  1690. .check-wrap {
  1691. position: absolute;
  1692. right: 60px;
  1693. top: 0px;
  1694. .el-icon-circle-check {
  1695. color: #00a5a7;
  1696. cursor: pointer;
  1697. display: none;
  1698. }
  1699. .disable:before {
  1700. cursor: not-allowed;
  1701. color: #adb0b8;
  1702. }
  1703. }
  1704. .delete-wrap {
  1705. position: absolute;
  1706. right: 35px;
  1707. top: 0px;
  1708. .el-icon-delete:before {
  1709. color: #00a5a7;
  1710. cursor: pointer;
  1711. }
  1712. .disable:before {
  1713. cursor: not-allowed;
  1714. color: #adb0b8;
  1715. }
  1716. }
  1717. .add-wrap {
  1718. position: absolute;
  1719. right: 10px;
  1720. top: 0px;
  1721. .el-icon-circle-plus:before {
  1722. color: #00a5a7;
  1723. cursor: pointer;
  1724. }
  1725. }
  1726. .content-wrap {
  1727. padding-left: 20px;
  1728. position: relative;
  1729. height: calc(100% - 30px);
  1730. .list-wrap {
  1731. max-height: 100%;
  1732. overflow: auto;
  1733. padding: 10px 0;
  1734. .list {
  1735. margin-bottom: 10px;
  1736. .name {
  1737. .item-content {
  1738. display: inline-block;
  1739. width: 310px;
  1740. text-overflow: ellipsis;
  1741. white-space: nowrap;
  1742. overflow: hidden;
  1743. }
  1744. }
  1745. .name:hover {
  1746. cursor: pointer;
  1747. color: #00a5a7;
  1748. }
  1749. .name.selected {
  1750. color: #00a5a7;
  1751. position: relative;
  1752. .el-icon-close {
  1753. position: absolute;
  1754. right: 10px;
  1755. top: 3px;
  1756. }
  1757. .el-icon-check {
  1758. position: absolute;
  1759. right: 30px;
  1760. top: 3px;
  1761. }
  1762. }
  1763. }
  1764. }
  1765. }
  1766. }
  1767. .custom-tree-node {
  1768. padding-right: 8px;
  1769. }
  1770. .custom-tree-node.highlight {
  1771. color: red;
  1772. }
  1773. .hit-list-wrap {
  1774. height: 100%;
  1775. overflow-y: auto;
  1776. padding: 10px;
  1777. .hit-item {
  1778. word-break: break-all;
  1779. line-height: 18px;
  1780. padding: 10px;
  1781. &:hover {
  1782. cursor: pointer;
  1783. }
  1784. }
  1785. .selected {
  1786. color: #00a5a7;
  1787. }
  1788. .el-table__expanded-cell[class*='cell'] {
  1789. padding: 0px 10px 0 50px;
  1790. ul {
  1791. background-color: #f5f7fa;
  1792. li {
  1793. line-height: 18px;
  1794. padding: 10px;
  1795. word-break: break-all;
  1796. border-top: 1px solid white;
  1797. border-bottom: 1px solid white;
  1798. &:hover {
  1799. background-color: #ebeef5;
  1800. }
  1801. }
  1802. }
  1803. }
  1804. }
  1805. }
  1806. .btn-wrap {
  1807. padding: 10px 20px;
  1808. border-top: 1px solid #ebeef5;
  1809. .step {
  1810. width: 100%;
  1811. display: flex;
  1812. justify-content: space-between;
  1813. .custom-btn {
  1814. margin-left: 10px;
  1815. }
  1816. }
  1817. .btn-two {
  1818. width: 100%;
  1819. .custom-btn {
  1820. height: 30px;
  1821. margin-top: 10px;
  1822. }
  1823. }
  1824. .el-button + .el-button {
  1825. margin-left: 0px;
  1826. }
  1827. .el-button:not(:last-child) {
  1828. margin-right: 10px;
  1829. }
  1830. }
  1831. }
  1832. .collapse-btn {
  1833. position: absolute;
  1834. right: 2px;
  1835. width: 31px;
  1836. height: 100px;
  1837. top: 50%;
  1838. margin-top: -50px;
  1839. cursor: pointer;
  1840. line-height: 86px;
  1841. z-index: 1;
  1842. text-align: center;
  1843. background-image: url('../../assets/images/collapse-left.svg');
  1844. }
  1845. .collapse-btn.collapse {
  1846. background-image: url('../../assets/images/collapse-right.svg');
  1847. }
  1848. }
  1849. .left-wrap.collapse {
  1850. width: 0px;
  1851. }
  1852. .right {
  1853. width: calc(100% - 400px);
  1854. height: 100%;
  1855. padding-right: 20px;
  1856. transition: width 0.2s;
  1857. -moz-transition: width 0.2s; /* Firefox 4 */
  1858. -webkit-transition: width 0.2s; /* Safari and Chrome */
  1859. -o-transition: width 0.2s; /* Opera */
  1860. .header {
  1861. padding: 15px;
  1862. border-bottom: 1px solid #ebeef5;
  1863. position: relative;
  1864. background: #fff;
  1865. .link {
  1866. color: #00a5a7;
  1867. }
  1868. .host {
  1869. margin-left: 25px;
  1870. }
  1871. span.item {
  1872. margin-right: 15px;
  1873. .content {
  1874. color: #00a5a7;
  1875. }
  1876. }
  1877. }
  1878. .svg-wrap {
  1879. height: 50%;
  1880. border-bottom: 1px solid #ebeef5;
  1881. position: relative;
  1882. .btn-wrap {
  1883. position: absolute;
  1884. top: 10px;
  1885. right: 10px;
  1886. }
  1887. .graph-container {
  1888. height: 100%;
  1889. width: 100%;
  1890. position: relative;
  1891. #graph {
  1892. height: 100%;
  1893. background-color: #f7faff;
  1894. .node:hover > path,
  1895. .node:hover > ellipse,
  1896. .node:hover > polygon,
  1897. .node:hover > rect {
  1898. stroke-width: 2px;
  1899. }
  1900. .node.cluster > rect:hover {
  1901. stroke: #8df1f2;
  1902. }
  1903. .selected {
  1904. stroke: red !important;
  1905. stroke-width: 2px;
  1906. }
  1907. #graph0 > polygon {
  1908. fill: transparent;
  1909. }
  1910. .node {
  1911. cursor: pointer;
  1912. }
  1913. .edge {
  1914. path {
  1915. stroke: rgb(120, 120, 120);
  1916. }
  1917. polygon {
  1918. fill: rgb(120, 120, 120);
  1919. }
  1920. }
  1921. .edge.highlighted {
  1922. path {
  1923. stroke: red;
  1924. }
  1925. polygon {
  1926. stroke: red;
  1927. fill: red;
  1928. }
  1929. marker {
  1930. path {
  1931. fill: red;
  1932. }
  1933. }
  1934. }
  1935. .node.aggregation > polygon {
  1936. stroke: #e3aa00;
  1937. fill: #ffe794;
  1938. }
  1939. .node.cluster.aggregation > rect {
  1940. stroke: #e3aa00;
  1941. fill: #ffe794;
  1942. stroke-dasharray: 3, 3;
  1943. }
  1944. .node > polygon {
  1945. stroke: #00a5a7;
  1946. fill: rgb(141, 241, 242);
  1947. }
  1948. .node > ellipse {
  1949. stroke: #4ea6e6;
  1950. fill: #b8e0ff;
  1951. }
  1952. .plain > path,
  1953. .plain ellipse {
  1954. stroke: #e37d29;
  1955. fill: #ffd0a6;
  1956. stroke-dasharray: 1.5, 1.5;
  1957. }
  1958. .edge-point ellipse {
  1959. stroke: #a7a7a7;
  1960. fill: #a7a7a7;
  1961. }
  1962. text {
  1963. fill: black;
  1964. }
  1965. }
  1966. #contextMenu {
  1967. display: none;
  1968. position: absolute;
  1969. min-width: 150px;
  1970. border: 1px solid #d4d4d4;
  1971. ul {
  1972. background-color: #e2e2e2;
  1973. border-radius: 2px;
  1974. li {
  1975. padding: 5px 18px;
  1976. cursor: pointer;
  1977. &:hover {
  1978. background-color: rgb(120, 120, 120);
  1979. color: white;
  1980. }
  1981. }
  1982. }
  1983. }
  1984. }
  1985. }
  1986. .table-container {
  1987. background: #fff;
  1988. height: calc(50% - 60px);
  1989. position: relative;
  1990. img {
  1991. position: absolute;
  1992. right: 10px;
  1993. top: 12px;
  1994. cursor: pointer;
  1995. z-index: 99;
  1996. }
  1997. .el-tabs.el-tabs--top {
  1998. height: 100%;
  1999. .el-tabs__content {
  2000. height: calc(100% - 60px);
  2001. .el-tab-pane {
  2002. height: 100%;
  2003. }
  2004. }
  2005. }
  2006. .table-content {
  2007. height: 100%;
  2008. overflow: hidden;
  2009. position: relative;
  2010. .table-wrap {
  2011. height: 100%;
  2012. overflow-y: auto;
  2013. .el-table .success-row {
  2014. background: #f0f9eb;
  2015. }
  2016. }
  2017. .value-wrap {
  2018. text-align: right;
  2019. }
  2020. .center {
  2021. display: inline-block;
  2022. text-align: center;
  2023. width: 100%;
  2024. }
  2025. .value {
  2026. white-space: nowrap;
  2027. overflow: hidden;
  2028. text-overflow: ellipsis;
  2029. cursor: pointer;
  2030. color: #00a5a7;
  2031. display: inline-block;
  2032. width: 100%;
  2033. }
  2034. .value-tip {
  2035. white-space: nowrap;
  2036. overflow: hidden;
  2037. text-overflow: ellipsis;
  2038. width: 50px;
  2039. display: inline-block;
  2040. vertical-align: middle;
  2041. text-align: center;
  2042. }
  2043. .el-table--border {
  2044. border-right: none;
  2045. border-left: none;
  2046. }
  2047. .el-table--border td {
  2048. border-right: none;
  2049. border-left: none;
  2050. }
  2051. .el-table--border th {
  2052. border-right: none;
  2053. border-left: none;
  2054. }
  2055. .el-table th > .cell {
  2056. border-left: 1px solid #d9d8dd;
  2057. word-break: keep-all;
  2058. white-space: nowrap;
  2059. overflow: hidden;
  2060. text-overflow: ellipsis;
  2061. }
  2062. .el-table-column--selection .cell {
  2063. border-left: none !important;
  2064. }
  2065. }
  2066. }
  2067. .svg-wrap.collapse {
  2068. height: calc(100% - 100px);
  2069. }
  2070. .table-container.collapse {
  2071. height: 35px;
  2072. .el-tabs__header {
  2073. margin: 0;
  2074. }
  2075. .table-content {
  2076. display: none;
  2077. }
  2078. }
  2079. }
  2080. .right.collapse {
  2081. width: calc(100% - 25px);
  2082. }
  2083. .custom-btn {
  2084. border: 1px solid #00a5a7;
  2085. border-radius: 2px;
  2086. background-color: white;
  2087. color: #00a5a7;
  2088. }
  2089. .custom-btn:hover {
  2090. background-color: #e9f7f7;
  2091. }
  2092. .custom-btn.green {
  2093. background-color: #00a5a7;
  2094. color: white;
  2095. }
  2096. .custom-btn.green:hover {
  2097. background-color: #33b7b9;
  2098. }
  2099. .is-disabled.custom-btn {
  2100. background-color: #f5f5f6;
  2101. border: 1px solid #dfe1e6 !important;
  2102. color: #adb0b8;
  2103. &:hover {
  2104. background-color: #f5f5f6;
  2105. }
  2106. }
  2107. .notShow {
  2108. display: none;
  2109. }
  2110. .conditions-container {
  2111. .collection {
  2112. width: 200px;
  2113. }
  2114. .condition {
  2115. margin-left: 10px;
  2116. width: 200px;
  2117. }
  2118. .param {
  2119. margin-left: 10px;
  2120. width: 200px;
  2121. }
  2122. .param-value {
  2123. margin-left: 10px;
  2124. width: 200px;
  2125. }
  2126. }
  2127. .el-dialog__wrapper.pendingTips {
  2128. position: absolute;
  2129. .dialog-icon {
  2130. .el-icon-warning {
  2131. font-size: 24px;
  2132. color: #e37d29;
  2133. vertical-align: bottom;
  2134. }
  2135. }
  2136. .el-dialog__body {
  2137. padding: 2px 20px 32px 20px;
  2138. .dialog-content {
  2139. line-height: 24px;
  2140. margin-left: 10px;
  2141. }
  2142. }
  2143. .el-dialog__footer {
  2144. text-align: center;
  2145. padding: 10px 20px 32px;
  2146. }
  2147. }
  2148. .el-dialog__wrapper.pendingTips + .v-modal {
  2149. position: absolute;
  2150. }
  2151. .deb-con {
  2152. position: absolute;
  2153. top: 0px;
  2154. width: 100%;
  2155. height: 100%;
  2156. background-color: #fff;
  2157. z-index: 999;
  2158. display: flex;
  2159. flex-direction: column;
  2160. .deb-con-title {
  2161. height: 56px;
  2162. line-height: 56px;
  2163. flex-shrink: 0;
  2164. position: relative;
  2165. .deb-con-title-left {
  2166. position: absolute;
  2167. left: 32px;
  2168. font-weight: bold;
  2169. font-size: 16px;
  2170. width: 50%;
  2171. white-space: nowrap;
  2172. overflow: hidden;
  2173. text-overflow: ellipsis;
  2174. }
  2175. .deb-con-title-middle {
  2176. position: absolute;
  2177. left: calc(50% + 32px);
  2178. width: 300px;
  2179. padding: 10px 0;
  2180. line-height: 36px;
  2181. .grident {
  2182. display: inline-block;
  2183. width: calc(100% - 70px);
  2184. background-image: linear-gradient(
  2185. to right,
  2186. rgba(227, 125, 41),
  2187. #fff,
  2188. rgba(0, 165, 167)
  2189. );
  2190. text-align: center;
  2191. color: transparent;
  2192. }
  2193. }
  2194. .deb-con-title-right {
  2195. position: absolute;
  2196. right: 32px;
  2197. .close-btn {
  2198. width: 20px;
  2199. height: 20px;
  2200. vertical-align: -3px;
  2201. cursor: pointer;
  2202. display: inline-block;
  2203. line-height: 20px;
  2204. margin-left: 32px;
  2205. }
  2206. }
  2207. }
  2208. .deb-con-slide {
  2209. height: 40px;
  2210. line-height: 40px;
  2211. flex-shrink: 0;
  2212. position: relative;
  2213. .deb-con-slide-left {
  2214. position: absolute;
  2215. left: 32px;
  2216. display: flex;
  2217. .deb-slide-title {
  2218. margin-right: 20px;
  2219. }
  2220. .deb-slide-width {
  2221. width: 400px;
  2222. }
  2223. .deb-slide-input {
  2224. width: 100px;
  2225. margin-left: 10px;
  2226. }
  2227. }
  2228. .deb-con-slide-right {
  2229. position: absolute;
  2230. right: 32px;
  2231. .custom-btn {
  2232. border: 1px solid #00a5a7;
  2233. border-radius: 2px;
  2234. }
  2235. .green {
  2236. background-color: #00a5a7;
  2237. color: white;
  2238. }
  2239. .white {
  2240. background-color: white;
  2241. color: #00a5a7;
  2242. }
  2243. }
  2244. }
  2245. .deb-con-table {
  2246. margin-top: 20px;
  2247. flex: 1;
  2248. padding: 0 32px;
  2249. .deb-compare-wrap {
  2250. height: calc(100% - 120px);
  2251. }
  2252. .deb-compare-detail {
  2253. span {
  2254. margin-right: 15px;
  2255. }
  2256. & > div {
  2257. margin-top: 10px;
  2258. }
  2259. label {
  2260. display: inline-block;
  2261. min-width: 100px;
  2262. }
  2263. }
  2264. }
  2265. }
  2266. }
  2267. .deb-indent {
  2268. padding-left: 40px;
  2269. }
  2270. #graphTemp,
  2271. #subgraphTemp {
  2272. position: absolute;
  2273. bottom: 0;
  2274. visibility: hidden;
  2275. }
  2276. </style>