This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking-rocketbot-ui.git
The following commit(s) were added to refs/heads/master by this push:
new 77816b4 Feat: Update topology chart (#257)
77816b4 is described below
commit 77816b421df0dc40a7f18efd1231c30d40bce979
Author: Allen Wang <[email protected]>
AuthorDate: Fri Mar 6 10:53:14 2020 +0800
Feat: Update topology chart (#257)
* update
* update
---
src/assets/index.ts | 1 -
src/assets/styles/style.scss | 12 +-
src/assets/svg/honeycomb-selector.svg | 359 -----------
src/store/modules/alarm/index.ts | 12 +-
src/store/modules/topology/index.ts | 5 -
src/store/mutation-types.ts | 1 -
src/views/components/alarm/alarm-table.vue | 3 +
src/views/components/alarm/alarm-tool.vue | 57 +-
src/views/components/topology/assets/CUBE.png | Bin 0 -> 1722 bytes
src/views/components/topology/assets/CUBEERROR.png | Bin 0 -> 2071 bytes
.../topology/assets/{KAFKALOGO.png => KAFKA.png} | Bin
.../assets/{KAFKALOGO.png => KAFKACONSUMER.png} | Bin
.../topology/assets/{Local2.png => LOCAL.png} | Bin
src/views/components/topology/assets/cube21.png | Bin 1444 -> 0 bytes
src/views/components/topology/assets/cube22.png | Bin 1284 -> 0 bytes
src/views/components/topology/chart/topo.vue | 235 +++++++
src/views/components/topology/chart/utils/icons.js | 15 +
.../components/topology/chart/utils/linkElement.js | 18 +
.../components/topology/chart/utils/nodeElement.js | 52 ++
.../components/topology/chart/utils/simulation.js | 24 +
src/views/components/topology/chart/utils/tool.js | 45 ++
.../components/topology/chart/utils/tool/ALARM.png | Bin 0 -> 5916 bytes
.../components/topology/chart/utils/tool/API.png | Bin 0 -> 4070 bytes
.../topology/chart/utils/tool/INSTANCE.png | Bin 0 -> 6844 bytes
.../components/topology/chart/utils/tool/TRACE.png | Bin 0 -> 4853 bytes
src/views/components/topology/chart/utils/zoom.js | 10 +
src/views/components/topology/topo-chart.vue | 171 +++---
.../topology/topo-instance-dependency.vue | 8 +-
src/views/components/topology/topo.vue | 681 ---------------------
src/views/components/trace/trace-search.vue | 4 -
src/views/containers/alarm.vue | 22 +-
src/views/containers/topology/topology.vue | 15 +-
src/views/containers/topology/window-alarm.vue | 4 +-
src/views/containers/topology/window-trace.vue | 8 +-
vue.config.js | 2 +-
35 files changed, 530 insertions(+), 1234 deletions(-)
diff --git a/src/assets/index.ts b/src/assets/index.ts
index ffb7ad8..4b548c4 100644
--- a/src/assets/index.ts
+++ b/src/assets/index.ts
@@ -32,7 +32,6 @@ import './svg/file-addition.svg';
import './svg/file-deletion.svg';
import './svg/file-modified.svg';
import './svg/file-tree.svg';
-import './svg/honeycomb-selector.svg';
import './svg/issue-child.svg';
import './svg/issue-close.svg';
import './svg/issue-open-m.svg';
diff --git a/src/assets/styles/style.scss b/src/assets/styles/style.scss
index b17d68a..a805edd 100644
--- a/src/assets/styles/style.scss
+++ b/src/assets/styles/style.scss
@@ -23,8 +23,7 @@
opacity: 0;
}
-.d3-tip,
-.d3-tip-grey {
+.d3-tip {
line-height: 1;
padding: 8px;
color: #eee;
@@ -34,11 +33,7 @@
.d3-tip {
background: #252a2f;
}
-.d3-tip-grey {
- background: #252a2fcc;
-}
-.d3-tip-grey:after,
.d3-tip:after {
box-sizing: border-box;
display: block;
@@ -51,11 +46,6 @@
text-align: center;
}
-.d3-tip-grey:after {
- color: #252a2fcc;
-}
-
-.d3-tip-grey.n:after,
.d3-tip.n:after {
margin: -2px 0 0 0;
top: 100%;
diff --git a/src/assets/svg/honeycomb-selector.svg
b/src/assets/svg/honeycomb-selector.svg
deleted file mode 100644
index 9a5e936..0000000
--- a/src/assets/svg/honeycomb-selector.svg
+++ /dev/null
@@ -1,359 +0,0 @@
-<!-- Licensed to the Apache Software Foundation (ASF) under one or more
-contributor license agreements. See the NOTICE file distributed with
-this work for additional information regarding copyright ownership.
-The ASF licenses this file to You under the Apache License, Version 2.0
-(the "License"); you may not use this file except in compliance with
-the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License. -->
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- version="1.0"
- preserveAspectRatio="xMidYMid meet"
- inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
- sodipodi:docname="honeycomb-selector.svg"
- id="honeycomb-1">
- <metadata
- id="metadata40">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <defs
- id="defs38">
- <style
- id="style42"
- type="text/css" />
- <style
- id="style64"
- type="text/css" />
- <style
- id="style393"
- type="text/css" />
- <style
- id="style412"
- type="text/css" />
- <style
- id="style431"
- type="text/css" />
- <style
- id="style445"
- type="text/css" />
- <style
- id="style445-7"
- type="text/css" />
- <style
- id="style608"
- type="text/css" />
- <style
- id="style587"
- type="text/css" />
- <filter
- x="0"
- y="0"
- width="1"
- height="1"
- id="text-background">
- <feFlood
- flood-color="#333840"
- id="feFlood20"
- result="result1" />
- <feComposite
- in="SourceGraphic"
- in2="result1"
- id="feComposite22" />
- </filter>
- <style
- id="style166"
- type="text/css" />
- </defs>
- <sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="3840"
- inkscape:window-height="2097"
- id="namedview36"
- showgrid="false"
- inkscape:zoom="6.774083"
- inkscape:cx="-20.989356"
- inkscape:cy="43.84884"
- inkscape:window-x="-8"
- inkscape:window-y="-8"
- inkscape:window-maximized="1"
- inkscape:current-layer="honeycomb-group-below-left"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:snap-bbox-midpoints="true"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-smooth-nodes="true"
- inkscape:snap-midpoints="true"
- inkscape:snap-object-midpoints="true"
- inkscape:snap-center="true"
- inkscape:snap-text-baseline="true"
- inkscape:snap-page="true" />
- <g
- transform="matrix(0.01651539,0,0,-0.01622068,-55.951684,120.57061)"
- id="honeycomb-frames"
- style="fill:rgba(76, 102, 175, 0.8);stroke:none">
- <g
- id="honeycomb-group-background">
- <path
-
style="opacity:0.2;fill:#f6f5f8;stroke:#f6f5f8;stroke-width:20.88499069px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.6"
- d="M 5292.9503,6231.545 4146.073,4308.891 5271.4539,2377.4855 l
2283.5692,2.556 1140.8217,1924.4562 -1119.7003,1896.0701 z"
- id="honeycomb-background" />
- <ellipse
- id="honeycomb-area"
- cx="6402.2075"
- cy="4293.6963"
- rx="3754.0742"
- ry="3698.9817"
- style="fill:#313446;fill-opacity:0.00090003;stroke-width:64.14954376"
/>
- <path
- d="m 5783.2167,5365.8532 c -17,-10 -120,-176 -318.9999,-517.9999
-250,-427 -295,-509 -295,-543 -1,-34 39,-109 283.9999,-538 157,-275 295,-509
308,-522 12,-12 36,-25 53,-29 18,-3 289,-6 603.0001,-6 438,0 577,3 595.9999,13
18,9 98.0001,137 268,427 352.0001,602 354,605 354,643 0,25 -69,154 -282,527
-154.9999,272 -295,508.9999 -310.9999,524.9999 l -29.0001,30 -603,2 c -496,2
-606,0 -627,-11 z m 1164,-156 c 22,-24 526,-906.9999 525,-921.9999 0,-7
-120.9999,-218 -267,-468 l -267,-455 [...]
- id="honeycomb-frame-core" />
- </g>
- <g
- id="honeycomb-group-top">
- <text
- xml:space="preserve"
-
style="font-style:normal;font-weight:normal;font-size:977.55462646px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:61.09716415;filter:url(#text-background)"
- x="4535.1201"
- y="-7931.6621"
- id="honeycomb-text-top"
- transform="scale(0.99103755,-1.0090435)"><tspan
- sodipodi:role="line"
- id="tspan3862"
- x="4535.1201"
- y="-7039.8096"
- style="font-size:977.55462646px;stroke-width:61.09716415" /></text>
- <path
- d="m 5820,7785.2006 c -11,-5 -27,-17 -36,-27 -24,-28 -579,-982
-591,-1016 -8,-22 -6,-39 6,-71 9,-23 141,-260 294,-527 215,-375 284,-488
307,-501 27,-16 88,-18 622,-21 588,-3 592,-3 620,18 18,13 136,206 321,524
229,392 294,511 294,538 0,26 -66,149 -290,540 -179,313 -300,514 -316,527 -27,19
-42,20 -619,22 -326,1 -601,-2 -612,-6 z m 950,-150 200,-6 262,-455 c 143,-250
261,-462 261,-470 0,-8 -120,-220 -266,-470 l -267,-455 -510,-3 c -280,-1 -524,0
-542,3 -31,5 -45,29 -297,470 l -265 [...]
- id="honeycomb-frame-top" />
- <path
-
style="fill:#7e57c2;stroke:#7e57c2;stroke-width:10px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 5889,7644.2006 -543,-931.0001 532.8223,-935.2377
1081.1776,1.2377 540.1329,931.8727 L 6970,7629.2006 Z"
- id="honeycomb-content-top" />
- </g>
- <g
- id="honeycomb-group-top-right"
- class="cp">
- <text
- xml:space="preserve"
-
style="font-style:normal;font-weight:normal;font-size:977.55462646px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:61.09716415;filter:url(#text-background)"
- x="9546.2422"
- y="-6248.0264"
- id="honeycomb-text-top-right"
-
transform="matrix(0.99103755,0,0,-1.0090435,40.655424,-100.13444)"><tspan
- sodipodi:role="line"
- id="tspan3868"
- x="9546.2422"
- y="-6248.0264"
-
style="font-size:488.77731323px;stroke-width:61.09716415">Alarm</tspan></text>
- <path
- d="m 7940.7129,6638.8004 c -37,-17 -31,-7 -360,-571 -231,-395
-268,-466 -268,-500 0,-34 43,-116 289,-544 189,-329 300,-512 318,-525 28,-21
40,-21 620,-24 550,-2 594,-1 620,15 21,13 111,158 323,523 162,277 295,514
295,525 1,11 0,29 -1,40 -1,11 -133,249 -293,528 -209,365 -299,512 -317,522
-39,20 -1183,31 -1226,11 z m 1413,-611 c 145,-253 263,-464 263,-469 0,-6
-120,-216 -267,-468 l -267,-458 h -541 -540 l -265,466 c -146,256 -264,468
-263,473 1,4 122,213 268,464 l 267,457 541,-2 5 [...]
- id="honeycomb-frame-top-right" />
- <path
-
style="fill:#5c6bc0;stroke:#5c6bc0;stroke-width:10px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 8009.7129,6502.8004 -543,-931.0001 532.8223,-935.2377
1081.1776,1.2377 540.1329,931.8727 -530.1328,918.1274 z"
- id="honeycomb-content-top-right" />
- <g
- id="honeycomb-button-alarm"
- transform="matrix(1.2614497,0,0,-1.2614497,7897.3545,6205.4705)"
- style="fill:#e6e6e6">
- <path
- id="path449"
- p-id="40349"
- d="m 192,832 a 32,32 0 0 0 0,64 h 640 a 32,32 0 0 0 0,-64 z m 0,-64
h 640 a 96,96 0 0 1 0,192 H 192 a 96,96 0 0 1 0,-192 z"
- inkscape:connector-curvature="0" />
- <path
- id="path451"
- p-id="40350"
- d="m 816,208 m -48,0 a 48,48 0 1 0 96,0 48,48 0 1 0 -96,0 z"
- inkscape:connector-curvature="0" />
- <path
- id="path453"
- p-id="40351"
- d="m 208,208 m -48,0 a 48,48 0 1 0 96,0 48,48 0 1 0 -96,0 z"
- inkscape:connector-curvature="0" />
- <path
- id="path455"
- p-id="40352"
- d="m 480,608 a 32,32 0 0 1 64,0 v 160 a 32,32 0 0 1 -64,0 z"
- inkscape:connector-curvature="0" />
- <path
- id="path457"
- p-id="40353"
- d="m 512,640 a 112,112 0 1 1 0,-224 112,112 0 0 1 0,224 z m 0,-64 a
48,48 0 1 0 0,-96 48,48 0 0 0 0,96 z m 352,-96 a 32,32 0 0 1 0,-64 h 96 a 32,32
0 0 1 0,64 z m -800,0 a 32,32 0 0 1 0,-64 h 96 a 32,32 0 0 1 0,64 z M 480,64 a
32,32 0 0 1 64,0 v 96 a 32,32 0 0 1 -64,0 z"
- inkscape:connector-curvature="0" />
- <path
- id="path459"
- p-id="40354"
- d="m 272.448,800 h -64 V 512 a 304,304 0 0 1 608,0 v 288 h -64 V
512 a 240,240 0 0 0 -480,0 z"
- inkscape:connector-curvature="0" />
- </g>
- <path
-
style="fill:#5c6bc0;stroke:#5c6bc0;stroke-width:10px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.001;opacity:0.001"
- d="m 8009.7129,6502.8004 -543,-931.0001 532.8223,-935.2377
1081.1776,1.2377 540.1329,931.8727 -530.1328,918.1274 z"
- id="honeycomb-shade-top-right" />
- </g>
- <g
- id="honeycomb-group-below-right"
- class="cp">
- <text
- xml:space="preserve"
-
style="font-style:normal;font-weight:normal;font-size:977.55462646px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:61.09716415;filter:url(#text-background)"
- x="9684.0586"
- y="-1623.2797"
- id="honeycomb-text-below-right"
-
transform="matrix(0.99103755,0,0,-1.0090435,-25.91292,2075.4611)"><tspan
- sodipodi:role="line"
- id="tspan3872"
- x="9684.0586"
- y="-1623.2797"
-
style="font-size:488.77731323px;stroke-width:61.09716415">Trace</tspan></text>
- <path
- d="m 8070.3706,4111.3108 c -11,-5 -27,-17 -36,-27 -24,-28
-578.9999,-982 -590.9999,-1016 -8,-22 -6,-39 6,-71 9,-23 141,-260 294,-527
214.9999,-375 283.9999,-487.9999 306.9999,-500.9998 27,-16.0002 88,-18 622,-21
588,-3 591.9999,-3 620.0001,18 18,12.9999 135.9999,205.9998 321,523.9998
228.9999,392.0001 294,511 294,538 0,26 -66,149 -290.0001,540 -179.0001,313
-300,514 -315.9999,527 -27,19 -42,20 -619,22 -326.0001,1 -601.0001,-2
-612.0001,-6 z m 950,-150 200.0001,-6 261.9999,-455 c [...]
- id="honeycomb-frame-below-right" />
- <path
-
style="fill:#2196f3;stroke:#2196f3;stroke-width:10px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 8139.3707,3970.3108 -543,-931.0001 532.8223,-935.2377
1081.1776,1.2377 540.1329,931.8727 -530.1328,918.1274 z"
- id="honeycomb-content-below-right" />
- <g
- id="honeycomb-button-link-analyze"
- transform="matrix(1.182609,0,0,-1.2040956,8055.4274,3604.8517)">
- <path
- id="path416"
- p-id="5238"
- d="M 1019.2751,950.97678 801.88042,733.58209 c 62.39848,-77.29811
99.69757,-175.69571 99.69757,-282.7931 0,-43.19894 -6.09985,-84.89792
-17.39958,-124.39696 -8.49979,1.39997 -17.19958,1.99995 -25.89936,1.99995 l
-28.7993,44.9989 c 5.09987,24.99939 7.69981,50.89876 7.69981,77.29812
0,213.39479 -172.99578,386.39056 -386.39057,386.39056 -213.39479,0
-386.390562,-172.89578 -386.390562,-386.29057 0,-213.39479
172.995772,-386.390563 386.390562,-386.390562 92.49775,0 177.49567,32.499 [...]
- inkscape:connector-curvature="0"
- style="fill:#e6e6e6" />
- <path
- id="path418"
- p-id="5239"
- d="m 601.9853,475.68839 c -12.1997,-5.29987 -25.79937,-8.2998
-39.99902,-8.2998 -14.09966,0 -27.59933,2.89993 -39.79903,8.1998 L
426.78958,356.09131 c 5.79986,-11.09973 9.09978,-23.69943 9.09978,-37.0991
0,-44.49891 -36.09912,-80.49803 -80.49804,-80.49803 -44.49891,0
-80.49803,36.09912 -80.49803,80.49803 0,11.39972 2.39994,22.29946
6.69984,32.09922 l -63.59845,79.89805 c -5.59987,-1.39997 -11.49972,-2.19995
-17.59957,-2.19995 -39.69903,0 -71.89825,32.19922 -71.89825,71.89825 0 [...]
- inkscape:connector-curvature="0"
- style="fill:#e6e6e6" />
- </g>
- <path
-
style="fill:#2196f3;stroke:#2196f3;stroke-width:10px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.001;opacity:0.001"
- d="m 8139.3707,3970.3108 -543,-931.0001 532.8223,-935.2377
1081.1776,1.2377 540.1329,931.8727 -530.1328,918.1274 z"
- id="honeycomb-shade-below-right" />
- </g>
- <g
- id="honeycomb-group-below">
- <text
- xml:space="preserve"
-
style="font-style:normal;font-weight:normal;font-size:977.55462646px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:61.09716415;filter:url(#text-background)"
- x="4518.5239"
- y="32.803318"
- id="honeycomb-text-below"
- transform="scale(0.99103755,-1.0090435)"><tspan
- sodipodi:role="line"
- id="tspan3876"
- x="4518.5239"
- y="924.65607"
- style="stroke-width:61.09716415" /></text>
- <path
- d="m 5790,2951.7994 c -17,-10 -120,-176 -319,-518 -250,-427 -295,-509
-295,-543 -1,-34 39,-109 284,-538 157,-275 295,-508.99994 308,-521.99994 12,-12
36,-25 53,-29 18,-3 289,-6 603,-6 438,0 577,3 596,13 18,9 98,136.99997
268,426.99994 352,602 354,605 354,643 0,25 -69,154 -282,527 -155,272 -295,509
-311,525 l -29,30 -603,2 c -496,2 -606,0 -627,-11 z m 1164,-156 c 22,-24
526,-907 525,-922 0,-7 -121,-218 -267,-468 l -267,-454.99997 -360,-3 c -198,-2
-442,0 -542,3 l -183,7 -264,463. [...]
- id="honeycomb-frame-below" />
- <path
-
style="fill:#b39ddb;stroke:#b39ddb;stroke-width:10px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 5867.8672,2806.9268 -543,-931.0001 532.8223,-935.23767
1081.1776,1.2377 L 7479,1873.7994 6948.8672,2791.9268 Z"
- id="honeycomb-content-below" />
- </g>
- <g
- id="honeycomb-group-below-left"
- class="cp">
- <text
- xml:space="preserve"
-
style="font-style:normal;font-weight:normal;font-size:977.55462646px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:61.09716415;filter:url(#text-background)"
- x="-558.66388"
- y="-1667.5137"
- id="honeycomb-text-below-left"
-
transform="matrix(0.99103755,0,0,-1.0090435,1590.8923,1916.1963)"><tspan
- sodipodi:role="line"
- id="tspan3880"
- x="-558.66388"
- y="-1667.5137"
-
style="font-size:488.77731323px;stroke-width:61.09716415">Instances</tspan></text>
- <path
- d="m 3662.6334,4102.4305 c -30,-16 -75,-88 -329,-523 -229,-393
-295,-513 -296,-541 0,-30 50,-124 290,-544 182,-319 301,-517 318,-530 27,-20
41,-20 614,-23 547,-2 589,-1 621,15 30,16 76,89 329,523 256,439 295,510 295,545
-1,34 -46,119 -290,545 -180,312 -300,512 -317,525 -27,19 -42,20 -614,23 -546,2
-589,1 -621,-15 z m 1314,-429 c 89,-154 209,-364 267,-466 l 105,-184 -271,-464
-271,-463 -42,1 c -24,0 -267,1 -540,1 l -498,1 -252,443 c -138,243 -257,454
-264,469 -12,29 -16,22 442,80 [...]
- id="honeycomb-frame-below-left" />
- <path
-
style="fill:#9fa8da;stroke:#9fa8da;stroke-width:10px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 3735.6335,3961.4306 -543,-931.0001 532.8223,-935.2377
1081.1776,1.2377 540.1329,931.8727 -530.1328,918.1274 z"
- id="honeycomb-content-below-left" />
- <path
- id="honeycomb-button-instances"
- p-id="22603"
- d="m 3645.7653,3382.5746 586.6173,337.4231 a 24.219541,24.659417 0 0
0 23.8157,0 l 586.3143,-337.3211 c 9.0826,-4.9313 9.0826,-19.2133 0,-24.2486 l
-571.3792,-328.9975 a 56.512263,57.538641 0 0 0 -53.7869,0 l -571.4802,328.7925
c -9.0827,5.0343 -9.0827,19.3163 0,24.3516 z m 1197.5553,-264.8834 c
9.0817,-5.1373 9.0817,-18.4952 -0.808,-24.3516 l -571.4802,-328.8945 a
56.512263,57.538641 0 0 0 -53.7869,0 l -571.1782,328.7915 c -9.0816,5.0354
-9.0816,19.3173 0,24.4546 l 120.4927,69. [...]
- inkscape:connector-curvature="0"
- style="fill:#e6e6e6;stroke-width:1.19338608" />
- <path
-
style="fill:#9fa8da;stroke:#9fa8da;stroke-width:10px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.001;opacity:0.001"
- d="m 3735.6335,3961.4306 -543,-931.0001 532.8223,-935.2377
1081.1776,1.2377 540.1329,931.8727 -530.1328,918.1274 z"
- id="honeycomb-shade-below-left" />
- </g>
- <g
- id="honeycomb-group-top-left"
- class="cp">
- <text
- xml:space="preserve"
-
style="font-style:normal;font-size:977.55462646px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:61.09716415;filter:url(#text-background)"
- x="1448.0989"
- y="-6241.5234"
- id="honeycomb-text-top-left"
-
transform="matrix(0.99103755,0,0,-1.0090435,876.42187,-80.613427)"><tspan
- sodipodi:role="line"
- id="tspan3884"
- x="1448.0989"
- y="-6241.5234"
-
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:488.77731323px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:center;text-anchor:middle;stroke-width:61.09716415">Endpoint</tspan></text>
- <path
- d="m 3679.4124,6649.5817 c -11,-5 -27,-17 -36,-27 -24,-28 -579,-982
-591,-1016 -8,-22 -6,-39 6,-71 9,-23 141,-260 294,-527 215,-375 284,-487.9999
307,-500.9999 27,-16.0001 88,-18 621.9999,-21 588,-3 592,-3 620.0001,18 18,13
135.9999,205.9999 321,523.9999 228.9999,392.0001 294,511 294,538 0,26 -66,149
-290.0001,540 -179,313 -300,514 -315.9999,527 -27,19 -42,20 -619,22 -326,1
-601,-2 -612,-6 z m 949.9999,-150 200.0001,-6 261.9999,-455 c 143.0001,-250
261,-462 261,-470 0,-8 -120,-2 [...]
- id="honeycomb-frame-top-left" />
- <path
-
style="fill:#ab47bc;stroke:#ab47bc;stroke-width:10px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 3748.4124,6508.5817 -543,-931.0001 532.8223,-935.2377
1081.1776,1.2377 540.1329,931.8727 -530.1328,918.1274 z"
- id="honeycomb-content-top-left" />
- <path
- id="honeycomb-button-endpoint"
- d="m 4838.6178,5846.1686 v 76.5834 h -67.6949 v 68.9252 c 0,68.9253
-52.652,122.5342 -120.3479,122.5342 h -97.7819 v 91.8997 h -75.2169 v -99.5578
h -195.5638 v 99.5578 h -75.2169 v -99.5578 h -203.0858 v 99.5578 h -75.2169 v
-99.5578 h -90.2599 c -67.6949,0 -120.3469,-53.609 -120.3469,-114.8761 v
-68.9252 h -75.2169 v -76.5834 h 75.2169 v -206.7747 h -75.2169 v -76.5844 h
75.2169 v -206.7747 h -75.2169 v -76.5834 h 75.2169 v -68.9252 c 0,-68.9253
52.652,-122.5342 120.3469,-122. [...]
- inkscape:connector-curvature="0"
- style="stroke-width:1.18589246;fill:#e6e6e6" />
- <path
- inkscape:connector-curvature="0"
-
style="opacity:0.00100002;fill:#ab47bc;stroke:#ab47bc;stroke-width:10px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.00100002"
- d="m 3747.9433,6503.5692 -543,-931.0001 532.8223,-935.2377
1081.1776,1.2377 540.133,931.8727 -530.1329,918.1274 z"
- id="honeycomb-shade-top-left"
- sodipodi:nodetypes="ccccccc" />
- </g>
- </g>
-</svg>
diff --git a/src/store/modules/alarm/index.ts b/src/store/modules/alarm/index.ts
index 3c08822..2e82942 100644
--- a/src/store/modules/alarm/index.ts
+++ b/src/store/modules/alarm/index.ts
@@ -36,14 +36,13 @@ const getters = {};
// mutations
const mutations: MutationTree<State> = {
- [types.SET_ALARM](state: State, data: Alarm[]): void {
- state.alarmService = data;
- },
- [types.SET_ALARM_TOTAL](state: State, total: number): void {
- state.total = total;
+ [types.SET_ALARM](state: State, data: {items: Alarm[], total: number}): void
{
+ state.alarmService = data.items;
+ state.total = data.total;
},
[types.CLEAR_ALARM](state: State): void {
state.alarmService = [];
+ state.total = 0;
},
};
@@ -58,8 +57,7 @@ const actions: ActionTree<State, any> = {
.params(params)
.then((res: AxiosResponse<any>) => {
if (res.data.data.getAlarm.items) {
- context.commit(types.SET_ALARM, res.data.data.getAlarm.items);
- context.commit(types.SET_ALARM_TOTAL, res.data.data.getAlarm.total);
+ context.commit(types.SET_ALARM, res.data.data.getAlarm);
}
});
},
diff --git a/src/store/modules/topology/index.ts
b/src/store/modules/topology/index.ts
index 28d7225..b9fd73e 100644
--- a/src/store/modules/topology/index.ts
+++ b/src/store/modules/topology/index.ts
@@ -60,7 +60,6 @@ export interface State {
getSLATrend: number[];
getThroughputTrend: number[];
responsePercentile: { [key: string]: number[] };
- honeycombNode: any;
showDialog: boolean;
showDialogType: string;
instanceDependency: {
@@ -90,7 +89,6 @@ const initState: State = {
getSLATrend: [],
getThroughputTrend: [],
responsePercentile: {},
- honeycombNode: {},
showDialog: false,
showDialogType: '',
instanceDependency: {
@@ -107,9 +105,6 @@ const getters = {};
// mutations
const mutations = {
- [types.SET_HONEYCOMB_NODE](state: State, data: any) {
- state.honeycombNode = data;
- },
[types.SET_SHOW_DIALOG](state: State, type: string) {
state.showDialog = !!type;
state.showDialogType = type;
diff --git a/src/store/mutation-types.ts b/src/store/mutation-types.ts
index 60d780c..58efb0e 100644
--- a/src/store/mutation-types.ts
+++ b/src/store/mutation-types.ts
@@ -60,7 +60,6 @@ export const SET_SEARCH_ENDPOINTS = 'SET_SEARCH_ENDPOINTS';
// alarm
export const SET_ALARM = 'SET_ALARM';
-export const SET_ALARM_TOTAL = 'SET_ALARM_TOTAL';
export const CLEAR_ALARM = 'CLEAR_ALARM';
// trace
diff --git a/src/views/components/alarm/alarm-table.vue
b/src/views/components/alarm/alarm-table.vue
index 5d38571..2653066 100644
--- a/src/views/components/alarm/alarm-table.vue
+++ b/src/views/components/alarm/alarm-table.vue
@@ -51,6 +51,9 @@ specific language governing permissions and * limitations
under the License. */
<style lang="scss" scoped>
.rk-alarm-table {
padding: 30px 20px 20px 40px;
+ flex-grow: 1;
+ overflow: auto;
+ height: 100%;
}
.rk-alarm-time-line {
padding: 14px 30px;
diff --git a/src/views/components/alarm/alarm-tool.vue
b/src/views/components/alarm/alarm-tool.vue
index 80b3d14..b4d4ede 100644
--- a/src/views/components/alarm/alarm-tool.vue
+++ b/src/views/components/alarm/alarm-tool.vue
@@ -12,16 +12,17 @@ specific language governing permissions and * limitations
under the License. */
<template>
<nav class="rk-alarm-tool flex-h">
<AlarmSelect
- v-show="!inTopo"
:title="$t('filterScope')"
- :value="alarmScope"
- @input="handleFilter"
+ :value="alarmOption"
+ @input="(option) => {
+ alarmOption = option;
+ handleRefresh(1);
+ }"
:data="alarmOptions"
/>
<div class="mr-10" style="padding: 3px 15px 0">
<div class="sm grey">{{ $t('searchKeyword') }}</div>
<input
- :disabled="inTopo"
type="text"
v-model="keyword"
class="rk-alarm-tool-input"
@@ -32,7 +33,7 @@ specific language governing permissions and * limitations
under the License. */
class="mt-15"
:currentSize="20"
:currentPage="pageNum"
- @changePage="handlePage"
+ @changePage="(pageNum) => handleRefresh(pageNum)"
:total="total"
/>
</nav>
@@ -41,47 +42,30 @@ specific language governing permissions and * limitations
under the License. */
<script lang="ts">
import Vue from 'vue';
import { Component, Prop } from 'vue-property-decorator';
- import { Action, Mutation } from 'vuex-class';
+ import { Action, Mutation, Getter } from 'vuex-class';
import AlarmSelect from './alarm-select.vue';
+ interface Option {
+ key: string | number;
+ label: string | number;
+ }
+
@Component({ components: { AlarmSelect } })
export default class AlarmTool extends Vue {
+ @Getter('durationTime') private durationTime: any;
@Mutation('SET_EVENTS') private SET_EVENTS: any;
@Action('rocketAlarm/GET_ALARM') private GET_ALARM: any;
- @Prop() private durationTime: any;
@Prop() private total!: number;
private pageNum: number = 1;
- @Prop({ type: Object, default: () => ({ label: 'All', key: '' }) })
- private alarmScope: any;
- @Prop({ default: false, type: Boolean })
- private inTopo!: boolean;
- private alarmOptions: any = [
+ private alarmOption: Option = { label: 'All', key: '' };
+ private alarmOptions: Option[] = [
{ label: 'All', key: '' },
{ label: 'Service', key: 'Service' },
{ label: 'ServiceInstance', key: 'ServiceInstance' },
{ label: 'Endpoint', key: 'Endpoint' },
];
-
private keyword: string = '';
- @Prop()
- private propKeyword!: string;
-
- private created() {
- if (this.propKeyword) {
- this.keyword = this.propKeyword;
- }
- }
-
- private handlePage(pageNum: number) {
- this.handleRefresh(pageNum);
- }
-
- private handleFilter(i: any) {
- this.alarmScope = i;
- this.handleRefresh(1);
- }
-
private handleRefresh(pageNum: number) {
this.pageNum = pageNum;
const params: any = {
@@ -92,8 +76,8 @@ specific language governing permissions and * limitations
under the License. */
needTotal: true,
},
};
- if (this.alarmScope.key) {
- params.scope = this.alarmScope.key;
+ if (this.alarmOption.key) {
+ params.scope = this.alarmOption.key;
}
if (this.keyword) {
params.keyword = this.keyword;
@@ -102,14 +86,9 @@ specific language governing permissions and * limitations
under the License. */
}
private beforeMount() {
- this.SET_EVENTS([
- () => {
- this.handleRefresh(1);
- },
- ]);
+ this.SET_EVENTS([() => { this.handleRefresh(1); }]);
this.handleRefresh(1);
}
-
private beforeDestroy() {
this.SET_EVENTS([]);
}
diff --git a/src/views/components/topology/assets/CUBE.png
b/src/views/components/topology/assets/CUBE.png
new file mode 100755
index 0000000..412000b
Binary files /dev/null and b/src/views/components/topology/assets/CUBE.png
differ
diff --git a/src/views/components/topology/assets/CUBEERROR.png
b/src/views/components/topology/assets/CUBEERROR.png
new file mode 100755
index 0000000..9405c89
Binary files /dev/null and b/src/views/components/topology/assets/CUBEERROR.png
differ
diff --git a/src/views/components/topology/assets/KAFKALOGO.png
b/src/views/components/topology/assets/KAFKA.png
similarity index 100%
copy from src/views/components/topology/assets/KAFKALOGO.png
copy to src/views/components/topology/assets/KAFKA.png
diff --git a/src/views/components/topology/assets/KAFKALOGO.png
b/src/views/components/topology/assets/KAFKACONSUMER.png
similarity index 100%
rename from src/views/components/topology/assets/KAFKALOGO.png
rename to src/views/components/topology/assets/KAFKACONSUMER.png
diff --git a/src/views/components/topology/assets/Local2.png
b/src/views/components/topology/assets/LOCAL.png
similarity index 100%
rename from src/views/components/topology/assets/Local2.png
rename to src/views/components/topology/assets/LOCAL.png
diff --git a/src/views/components/topology/assets/cube21.png
b/src/views/components/topology/assets/cube21.png
deleted file mode 100755
index 1b52675..0000000
Binary files a/src/views/components/topology/assets/cube21.png and /dev/null
differ
diff --git a/src/views/components/topology/assets/cube22.png
b/src/views/components/topology/assets/cube22.png
deleted file mode 100755
index 9825437..0000000
Binary files a/src/views/components/topology/assets/cube22.png and /dev/null
differ
diff --git a/src/views/components/topology/chart/topo.vue
b/src/views/components/topology/chart/topo.vue
new file mode 100644
index 0000000..678add2
--- /dev/null
+++ b/src/views/components/topology/chart/topo.vue
@@ -0,0 +1,235 @@
+/** * Licensed to the Apache Software Foundation (ASF) under one or more *
+contributor license agreements. See the NOTICE file distributed with * this
work
+for additional information regarding copyright ownership. * The ASF licenses
+this file to You under the Apache License, Version 2.0 * (the "License"); you
+may not use this file except in compliance with * the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * *
Unless
+required by applicable law or agreed to in writing, software * distributed
under
+the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR
+CONDITIONS OF ANY KIND, either express or implied. * See the License for the
+specific language governing permissions and * limitations under the License. */
+
+<template>
+ <div class="micro-topo-chart"></div>
+</template>
+<script lang="js">
+import * as d3 from 'd3';
+import d3tip from 'd3-tip';
+import zoom from './utils/zoom';
+import { simulationInit, simulationSkip } from './utils/simulation';
+import nodeElement from './utils/nodeElement';
+import { linkElement, anchorElement } from './utils/linkElement';
+import tool from './utils/tool';
+export default {
+ props: {
+ current: {
+ type: Object,
+ default: () => ({}),
+ },
+ nodes: {
+ type: Array,
+ default: () => [],
+ },
+ links: {
+ type: Array,
+ default: () => [],
+ },
+ },
+ data() {
+ return {
+ height: 600,
+ simulation: '',
+ };
+ },
+ beforeDestroy() {
+ window.removeEventListener('resize', this.resize);
+ },
+ mounted() {
+ window.addEventListener('resize', this.resize);
+ this.svg = d3
+ .select(this.$el)
+ .append('svg')
+ .attr('class', 'topo-svg')
+ .attr('height', this.$el.clientHeight);
+ this.tip = d3tip()
+ .attr('class', 'd3-tip')
+ .offset([-8, 0]);
+ this.graph = this.svg.append('g').attr('class', 'topo-svg_graph');
+ this.graph.call(this.tip);
+ this.simulation = simulationInit(d3, this.nodes, this.links, this.ticked);
+ this.svg.call(zoom(d3, this.graph));
+ this.node = this.graph.append('g').selectAll('.topo-node');
+ this.link = this.graph.append('g').selectAll('.topo-line');
+ this.anchor = this.graph.append('g').selectAll('.topo-line-anchor');
+ this.tool = tool(this.graph, [
+ {icon: 'API', click: this.handleGoEndpoint},
+ {icon: 'INSTANCE', click: this.handleGoInstance},
+ {icon: 'TRACE', click: this.handleGoTrace},
+ {icon: 'ALARM', click: this.handleGoAlarm},
+ {icon: ''},
+ {icon: ''},
+ ]);
+ this.svg.on('click', (d, i) => {
+ event.stopPropagation();
+ event.preventDefault();
+ this.$store.commit('rocketTopo/SET_NODE', {});
+ this.$store.dispatch('rocketTopo/CLEAR_TOPO_INFO');
+ this.tool.attr('style', 'display: none');
+ });
+ },
+ watch: {
+ nodes: 'update',
+ links: 'update',
+ },
+ methods: {
+ handleGoAlarm() {
+ this.$store.commit('rocketTopo/SET_SHOW_DIALOG', 'alarm');
+ },
+ handleGoTrace() {
+ this.$store.commit('rocketTopo/SET_SHOW_DIALOG', 'trace');
+ },
+ handleGoInstance() {
+ this.$store.dispatch('SELECT_SERVICE', {
+ service: { key: this.current.id, label: this.current.name },
+ duration: this.$store.getters.durationTime,
+ });
+ this.$store.commit('rocketTopo/SET_SHOW_DIALOG', 'instance');
+ },
+ handleGoEndpoint() {
+ this.$store.dispatch('SELECT_SERVICE', {
+ service: { key: this.current.id, label: this.current.name },
+ duration: this.$store.getters.durationTime,
+ });
+ this.$store.commit('rocketTopo/SET_SHOW_DIALOG', 'endpoint');
+ },
+ handleNodeClick(d) {
+ this.$emit('setCurrent', { key: d.id, label: d.name });
+ const {x, y, vx, vy, fx, fy, index, ...rest} = d;
+ this.$store.dispatch('rocketTopo/CLEAR_TOPO_INFO');
+ this.$store.commit('rocketTopo/SET_NODE', rest);
+ },
+ handleLinkClick(d) {
+ event.stopPropagation();
+ this.$store.commit('rocketTopo/SET_NODE', {});
+ this.$store.dispatch('rocketTopo/CLEAR_TOPO_INFO');
+ this.$store.commit('rocketTopo/SET_MODE', d.detectPoints);
+ this.$store.dispatch(this.$store.state.rocketTopo.mode ?
'rocketTopo/GET_TOPO_SERVICE_INFO' : 'rocketTopo/GET_TOPO_CLIENT_INFO', { ...d,
duration: this.$store.getters.durationTime });
+ this.$store.commit('rocketTopo/SET_CALLBACK', () => {
+ this.$store.dispatch(this.$store.state.rocketTopo.mode ?
'rocketTopo/GET_TOPO_SERVICE_INFO' : 'rocketTopo/GET_TOPO_CLIENT_INFO', { ...d,
duration: this.$store.getters.durationTime });
+ });
+ },
+ resize() {
+ this.svg.attr('height', this.$el.clientHeight);
+ },
+ update() {
+ // node element
+ const that = this;
+ this.node = this.node.data(this.nodes);
+ this.node.exit().remove();
+ this.node = nodeElement(d3, this.node.enter(), this.tool, {
+ dragstart: this.dragstart,
+ dragged: this.dragged,
+ dragended: this.dragended,
+ handleNodeClick: this.handleNodeClick,
+ }, this.tip).merge(this.node);
+ // line element
+ this.link = this.link.data(this.links, (d) => d.id);
+ this.link.exit().remove();
+ this.link = linkElement(this.link.enter()).merge(this.link);
+ // anchorElement
+ this.anchor = this.anchor.data(this.links, (d) => d.id);
+ this.anchor.exit().remove();
+ this.anchor = anchorElement(this.anchor.enter(), {
+ handleLinkClick: this.handleLinkClick,
+ $tip: (data) =>
+ `
+ <div class="mb-5"><span class="grey">${this.$t('cpm')}:
</span>${data.cpm}</div>
+ <div class="mb-5"><span class="grey">${this.$t('latency')}:
</span>${data.latency}</div>
+ <div><span
class="grey">${this.$t('detectPoint')}:</span>${data.detectPoints.join(' |
')}</div>
+ `,
+ }, this.tip).merge(this.anchor);
+ // force element
+ this.simulation.nodes(this.nodes);
+ this.simulation.force('link').links(this.links).id((d) => d.id);
+ simulationSkip(d3, this.simulation, this.ticked);
+ },
+ ticked() {
+ this.link.attr('d', (d) => `M${d.source.x} ${d.source.y} Q ${(d.source.x
+ d.target.x) / 2} ${(d.target.y + d.source.y) / 2 - 90} ${d.target.x}
${d.target.y}`);
+ this.anchor.attr('transform', (d) => `translate(${(d.source.x +
d.target.x) / 2}, ${(d.target.y + d.source.y) / 2 - 45})`);
+ this.node.attr('transform', (d) => `translate(${d.x - 22},${d.y - 22})`);
+ },
+ dragstart(d) {
+ this.node._groups[0].forEach((g) => {
+ g.__data__.fx = g.__data__.x;
+ g.__data__.fy = g.__data__.y;
+ });
+ if (!d3.event.active) {
+ this.simulation.alphaTarget(0.1).restart();
+ }
+ d3.event.sourceEvent.stopPropagation();
+ },
+ dragged(d) {
+ d.fx = d3.event.x;
+ d.fy = d3.event.y;
+ d.x = d.fx;
+ d.y = d.fy;
+ },
+ dragended() {
+ if (!d3.event.active) {
+ this.simulation.alphaTarget(0);
+ }
+ },
+ },
+};
+</script>
+<style lang="scss">
+.micro-topo-chart {
+ height: 100%;
+ width: 100%;
+ .topo-svg {
+ display: block;
+ width: 100%;
+ }
+ .topo-line {
+ stroke-linecap: round;
+ stroke-width: 1.3px !important;
+ stroke-dasharray: 13 7;
+ fill: none;
+ animation: topo-dash 1s linear infinite !important;
+ }
+ .topo-line-anchor {
+ cursor: pointer;
+ }
+ .topo-text {
+ font-family: 'Lato', 'Source Han Sans CN', 'Microsoft YaHei', sans-serif;
+ fill: #ddd;
+ font-size: 11px;
+ opacity: 0.8;
+ }
+ .topo-tool {
+ display: none;
+ }
+ .topo-tool-i {
+ cursor: pointer;
+ .tool-hexagon {
+ fill: #3f4450;
+ stroke: #217ef2;
+ stroke-width: 2;
+ stroke-opacity: 0.5;
+ }
+ &:hover {
+ .tool-hexagon {
+ stroke-opacity: 1;
+ }
+ }
+ }
+}
+@keyframes topo-dash {
+ from {
+ stroke-dashoffset: 20;
+ }
+ to {
+ stroke-dashoffset: 0;
+ }
+}
+</style>
diff --git a/src/views/components/topology/chart/utils/icons.js
b/src/views/components/topology/chart/utils/icons.js
new file mode 100755
index 0000000..033d3ef
--- /dev/null
+++ b/src/views/components/topology/chart/utils/icons.js
@@ -0,0 +1,15 @@
+const requireComponent = require.context('../../assets', false, /\.png$/);
+
+const result = {};
+function capitalizeFirstLetter(str) {
+ return str.toUpperCase();
+}
+function validateFileName(str) {
+ return /^\S+\.png$/.test(str) && str.replace(/^\S+\/(\w+)\.png$/, (rs, $1)
=> capitalizeFirstLetter($1));
+}
+requireComponent.keys().forEach((filePath) => {
+ const componentConfig = requireComponent(filePath);
+ const fileName = validateFileName(filePath);
+ result[fileName] = componentConfig;
+});
+export default result;
diff --git a/src/views/components/topology/chart/utils/linkElement.js
b/src/views/components/topology/chart/utils/linkElement.js
new file mode 100644
index 0000000..aa87b56
--- /dev/null
+++ b/src/views/components/topology/chart/utils/linkElement.js
@@ -0,0 +1,18 @@
+export const linkElement = (graph) => {
+ const linkEnter = graph
+ .append('path').attr('class', 'topo-line')
+ .attr('stroke', d => d.cpm ? '#217EF25f' : '#6a6d7777');;
+ return linkEnter;
+}
+export const anchorElement = (graph, funcs, tip) => {
+ const linkEnter = graph
+ .append('circle').attr('class', 'topo-line-anchor')
+ .attr('r', 5)
+ .attr('fill', d => d.cpm ? '#217EF25f' : '#6a6d7777')
+ .on('mouseover', function(d) { tip.html(funcs.$tip).show(d, this)})
+ .on('mouseout', function() { tip.hide(this)})
+ .on('click', d => {
+ funcs.handleLinkClick(d);
+ });
+ return linkEnter;
+}
\ No newline at end of file
diff --git a/src/views/components/topology/chart/utils/nodeElement.js
b/src/views/components/topology/chart/utils/nodeElement.js
new file mode 100644
index 0000000..3f94e72
--- /dev/null
+++ b/src/views/components/topology/chart/utils/nodeElement.js
@@ -0,0 +1,52 @@
+import icons from './icons';
+
+icons['KAFKA-CONSUMER'] = icons.KAFKA;
+export default (d3, graph, tool, funcs, tip) => {
+ const nodeEnter = graph
+ .append('g').call(d3.drag()
+ .on('start', funcs.dragstart)
+ .on('drag', funcs.dragged)
+ .on('end', funcs.dragended))
+ .on('mouseover', function(d) { tip.html((data) =>
`<div>${data.name}</div>`).show(d, this)})
+ .on('mouseout', function() { tip.hide(this)})
+ .on('click', (d) => {
+ event.stopPropagation();
+ event.preventDefault();
+ tool.attr('style', 'display: none');
+ funcs.handleNodeClick(d);
+ if(d.isReal){
+ tool.attr('transform', `translate(${d.x},${d.y - 20})`).attr('style',
'display: block');
+ }
+ });
+ nodeEnter
+ .append('image')
+ .attr('width', 49)
+ .attr('height', 49)
+ .attr('x', 2)
+ .attr('y', 10)
+ .attr('style', 'cursor: move;')
+ .attr('xlink:href', (d) => d.sla < 98 ? icons.CUBEERROR : icons.CUBE);
+ nodeEnter
+ .append('image')
+ .attr('width',32)
+ .attr('height', 32)
+ .attr('x', 6)
+ .attr('y', -10)
+ .attr('style', 'opacity: 0.5;')
+ .attr('xlink:href',icons.LOCAL);
+ nodeEnter
+ .append('image')
+ .attr('width', 18)
+ .attr('height', 18)
+ .attr('x', 13)
+ .attr('y', -7)
+ .attr('xlink:href', (d) => (!d.type || d.type === 'N/A') ? icons.UNDEFINED
: icons[d.type.toUpperCase().replace('-','')]);
+ nodeEnter
+ .append('text')
+ .attr('class', 'topo-text')
+ .attr('text-anchor', 'middle')
+ .attr('x', 22)
+ .attr('y', 70)
+ .text(d => d.name.length > 20 ? `${d.name.substring(0, 20)}...`: d.name);
+ return nodeEnter;
+}
\ No newline at end of file
diff --git a/src/views/components/topology/chart/utils/simulation.js
b/src/views/components/topology/chart/utils/simulation.js
new file mode 100644
index 0000000..0b7c589
--- /dev/null
+++ b/src/views/components/topology/chart/utils/simulation.js
@@ -0,0 +1,24 @@
+export const simulationInit = (d3, data_nodes, data_links, ticked) => {
+ const simulation = d3
+ .forceSimulation(data_nodes)
+ .force('collide', d3.forceCollide().radius(() => 60))
+ .force('yPos', d3.forceY().strength(1))
+ .force('xPos', d3.forceX().strength(1))
+ .force('charge', d3.forceManyBody().strength(-520))
+ .force( 'link', d3.forceLink(data_links).id((d) => d.id))
+ .force('center', d3.forceCenter(window.innerWidth / 2, window.innerHeight /
2 - 20))
+ .on('tick', ticked)
+ .stop();
+ simulationSkip(d3, simulation, ticked)
+ return simulation;
+}
+
+export const simulationSkip = (d3, simulation, ticked) => {
+ d3.timeout(() => {
+ const n = Math.ceil( Math.log(simulation.alphaMin()) / Math.log(1 -
simulation.alphaDecay()));
+ for ( let i = 0; i < n; i += 1 ) {
+ simulation.tick();
+ ticked();
+ }
+ });
+}
diff --git a/src/views/components/topology/chart/utils/tool.js
b/src/views/components/topology/chart/utils/tool.js
new file mode 100644
index 0000000..2ae4472
--- /dev/null
+++ b/src/views/components/topology/chart/utils/tool.js
@@ -0,0 +1,45 @@
+const requireComponent = require.context('./tool', false, /\.png$/);
+
+const icons = {};
+function capitalizeFirstLetter(str) {
+ return str.toUpperCase();
+}
+function validateFileName(str) {
+ return /^\S+\.png$/.test(str) && str.replace(/^\S+\/(\w+)\.png$/, (rs, $1)
=> capitalizeFirstLetter($1));
+}
+requireComponent.keys().forEach((filePath) => {
+ const componentConfig = requireComponent(filePath);
+ const fileName = validateFileName(filePath);
+ icons[fileName] = componentConfig;
+});
+
+
+const Hexagon = (side, r, cx, cy) => {
+ let path = '';
+ for (let i = 0; i < side; i += 1) {
+ let x = Math.cos((2 / side * i + 1 / side) * Math.PI) * r + cx;
+ let y = -Math.sin((2 / side * i + 1 / side) * Math.PI) * r + cy;
+ path += !i ? `M${x},${y} ` : `L${x},${y} `;
+ if (i == side -1 ) path += 'Z';
+ }
+ return path
+};
+
+export default (graph, data) => {
+ const tool = graph.append('g').attr('class', 'topo-tool');
+ const side = 6;
+ for (let i = 0; i < data.length; i += 1) {
+ let x = Math.cos((2 / side * i) * Math.PI) * 34;
+ let y = -Math.sin((2 / side * i) * Math.PI) * 34;
+ const tool_g = tool.append('g').attr('class', 'topo-tool-i').on('click',
data[i].click);
+ tool_g.append('path').attr('class', 'tool-hexagon').attr('d', Hexagon(6,
17, x, y));
+ tool_g.append('svg:image')
+ .attr('width', 14)
+ .attr('height', 14)
+ .attr('x', x - 7)
+ .attr('y', y - 7)
+ .attr('style', 'opacity: 0.8')
+ .attr('xlink:href',icons[data[i].icon]);
+ }
+ return tool;
+};
diff --git a/src/views/components/topology/chart/utils/tool/ALARM.png
b/src/views/components/topology/chart/utils/tool/ALARM.png
new file mode 100644
index 0000000..85009cb
Binary files /dev/null and
b/src/views/components/topology/chart/utils/tool/ALARM.png differ
diff --git a/src/views/components/topology/chart/utils/tool/API.png
b/src/views/components/topology/chart/utils/tool/API.png
new file mode 100644
index 0000000..385dcaf
Binary files /dev/null and
b/src/views/components/topology/chart/utils/tool/API.png differ
diff --git a/src/views/components/topology/chart/utils/tool/INSTANCE.png
b/src/views/components/topology/chart/utils/tool/INSTANCE.png
new file mode 100644
index 0000000..f0f1dbf
Binary files /dev/null and
b/src/views/components/topology/chart/utils/tool/INSTANCE.png differ
diff --git a/src/views/components/topology/chart/utils/tool/TRACE.png
b/src/views/components/topology/chart/utils/tool/TRACE.png
new file mode 100644
index 0000000..2fe870f
Binary files /dev/null and
b/src/views/components/topology/chart/utils/tool/TRACE.png differ
diff --git a/src/views/components/topology/chart/utils/zoom.js
b/src/views/components/topology/chart/utils/zoom.js
new file mode 100644
index 0000000..8a40e6f
--- /dev/null
+++ b/src/views/components/topology/chart/utils/zoom.js
@@ -0,0 +1,10 @@
+export default (d3, graph) =>
+ d3
+ .zoom()
+ .scaleExtent([0.3, 10])
+ .on('zoom', () => {
+ graph.attr(
+ 'transform',
+
`translate(${d3.event.transform.x},${d3.event.transform.y})scale(${d3.event.transform.k})`,
+ );
+ });
diff --git a/src/views/components/topology/topo-chart.vue
b/src/views/components/topology/topo-chart.vue
index ad08f9b..88087be 100644
--- a/src/views/components/topology/topo-chart.vue
+++ b/src/views/components/topology/topo-chart.vue
@@ -1,99 +1,100 @@
-/** * Licensed to the Apache Software Foundation (ASF) under one or more *
-contributor license agreements. See the NOTICE file distributed with * this
work
-for additional information regarding copyright ownership. * The ASF licenses
-this file to You under the Apache License, Version 2.0 * (the "License"); you
-may not use this file except in compliance with * the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * *
Unless
-required by applicable law or agreed to in writing, software * distributed
under
-the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR
-CONDITIONS OF ANY KIND, either express or implied. * See the License for the
-specific language governing permissions and * limitations under the License. */
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
<template>
<div>
- <div class="grey sm mb-5">{{ title }}</div>
- <h5 class="mt-0 mb-0">{{ unit === '%' ? content.toFixed(2) * 100 :
content.toFixed(2) }} {{ unit }}</h5>
- <RkEcharts height="80px" :option="responseConfig" />
+ <div class="grey sm mb-5">{{title}}</div>
+ <h5 class="mt-0 mb-0">{{content.toFixed(2)}} {{unit}}</h5>
+ <RkEcharts height="100px" :option="responseConfig"/>
</div>
+
</template>
<script lang="ts">
- import Vue from 'vue';
- import { Component, Prop } from 'vue-property-decorator';
+import Vue from 'vue';
+import { Component, Prop } from 'vue-property-decorator';
- @Component
- export default class TopoChart extends Vue {
- @Prop() private title!: string;
- @Prop() private data!: any;
- @Prop() private unit!: string;
- @Prop() private intervalTime!: number[];
- @Prop() private precent!: boolean;
- get content() {
- if (!this.data.length) {
- return 0;
- }
- const noZero = this.data.filter((i: any) => i);
- const sum = noZero.length
- ? noZero.reduce(
- (
- preValue: number,
- curValue: number,
- index: number,
- array: number[],
- ) => preValue + curValue,
- ) / noZero.length
- : 0;
- return this.precent ? sum / 100 : sum;
- }
- get responseConfig() {
- return {
- color: ['#3f96e3ee', '#6be6c1'],
- tooltip: {
- trigger: 'axis',
- backgroundColor: '#333844',
- textStyle: {
- fontSize: 13,
- },
+@Component
+export default class TopoChart extends Vue {
+ @Prop() private title!: string;
+ @Prop() private data!: any;
+ @Prop() private unit!: string;
+ @Prop() private intervalTime!: number[];
+ @Prop() private precent!: boolean;
+ get content() {
+ if (!this.data.length) {return 0; }
+ const noZero = this.data.filter((i: any) => i);
+ const sum = noZero.length ? noZero
+ .reduce((preValue: number, curValue: number, index: number, array:
number[]) => preValue + curValue)
+ / noZero.length : 0;
+ return this.precent ? sum / 100 : sum;
+ }
+ get responseConfig() {
+ return {
+ color: [
+ '#3f96e3ee',
+ '#6be6c1',
+ ],
+ tooltip: {
+ trigger: 'axis',
+ backgroundColor: '#333844',
+ textStyle: {
+ fontSize: 13,
},
- grid: {
- top: 4,
- left: 0,
- right: 0,
- bottom: 7,
- containLabel: true,
+ },
+ grid: {
+ top: 4,
+ left: 0,
+ right: 0,
+ bottom: 7,
+ containLabel: true,
+ },
+ xAxis: {
+ type: 'category',
+ axisTick: {
+ lineStyle: { color: '#c1c5ca41' },
+ alignWithLabel: true,
},
- xAxis: {
- type: 'category',
- axisTick: {
- lineStyle: { color: '#c1c5ca41' },
- alignWithLabel: true,
+ splitLine: { show: false },
+ axisLine: { lineStyle: { color: 'rgba(0,0,0,0)' } },
+ axisLabel: { color: '#9da5b2', fontSize: '11' },
+ },
+ yAxis: {
+ type: 'value',
+ axisLine: { show: false },
+ axisTick: { show: false },
+ splitLine: { lineStyle: { color: '#c1c5ca41', type: 'dashed' } },
+ axisLabel: { color: '#9da5b2', fontSize: '11' },
+ },
+ series: [
+ {
+ data: this.data.map((i: any, index: number) => [
+ this.intervalTime[index],
+ i,
+ ]),
+ type: this.precent ? 'bar' : 'line',
+ symbol: 'none',
+ barMaxWidth: 5,
+ lineStyle: {
+ width: 1,
},
- splitLine: { show: false },
- axisLine: { lineStyle: { color: 'rgba(0,0,0,0)' } },
- axisLabel: { color: '#9da5b2', fontSize: '11' },
},
- yAxis: {
- type: 'value',
- axisLine: { show: false },
- axisTick: { show: false },
- splitLine: { lineStyle: { color: '#c1c5ca41', type: 'dashed' } },
- axisLabel: { color: '#9da5b2', fontSize: '11' },
- },
- series: [
- {
- data: this.data.map((i: any, index: number) => [
- this.intervalTime[index],
- i,
- ]),
- type: this.precent ? 'bar' : 'line',
- symbol: 'none',
- barMaxWidth: 5,
- lineStyle: {
- width: 1,
- },
- },
- ],
- };
- }
+ ],
+ };
}
+}
</script>
diff --git a/src/views/components/topology/topo-instance-dependency.vue
b/src/views/components/topology/topo-instance-dependency.vue
index 91e612f..cac8c09 100644
--- a/src/views/components/topology/topo-instance-dependency.vue
+++ b/src/views/components/topology/topo-instance-dependency.vue
@@ -80,9 +80,8 @@ specific language governing permissions and * limitations
under the License. */
<script lang="ts">
import { Vue, Component, Prop } from 'vue-property-decorator';
import { State, Action, Getter, Mutation } from 'vuex-class';
-
import { State as topoState } from '@/store/modules/topology';
- import Topo from './topo.vue';
+ import Topo from './chart/topo.vue';
import TopoChart from './topo-chart.vue';
import DependencySankey from './dependency-sankey.vue';
import ChartLine from './chart-line.vue';
@@ -133,15 +132,14 @@ specific language governing permissions and * limitations
under the License. */
}
.rk-instance-dependency-metrics {
width: 320px;
- margin-top: 20px;
- margin-right: 20px;
+ height: 650px;
+ margin-top: 10px;
background: #252a2f;
padding: 20px;
}
.rk-dependency-chart {
width: 850px;
height: 100%;
- flex-grow: 1;
}
}
</style>
diff --git a/src/views/components/topology/topo.vue
b/src/views/components/topology/topo.vue
deleted file mode 100644
index 33f952a..0000000
--- a/src/views/components/topology/topo.vue
+++ /dev/null
@@ -1,681 +0,0 @@
-/** * Licensed to the Apache Software Foundation (ASF) under one or more *
-contributor license agreements. See the NOTICE file distributed with * this
work
-for additional information regarding copyright ownership. * The ASF licenses
-this file to You under the Apache License, Version 2.0 * (the "License"); you
-may not use this file except in compliance with * the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * *
Unless
-required by applicable law or agreed to in writing, software * distributed
under
-the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR
-CONDITIONS OF ANY KIND, either express or implied. * See the License for the
-specific language governing permissions and * limitations under the License. */
-
-<template>
- <div class="micro-topo-chart"></div>
-</template>
-<script lang="js">
- import CssHelper from '@/utils/cssHelper';
- import * as d3 from 'd3';
- import d3tip from 'd3-tip';
- /* tslint:disable */
- const diagonal = d3.linkHorizontal()
- .x(function (d) { return d.x })
- .y(function (d) { return d.y });
- const diagonalvertical = d3.linkVertical()
- .x(function (d) { return d.x })
- .y(function (d) { return d.y });
-
- export default {
- props: {
- datas: {
- type: Object,
- default() {
- return {
- nodes: [],
- calls: [],
- };
- },
- },
- },
- data() {
- return {
- LOCAL: require('./assets/Local2.png'),
- ARMERIA: require('./assets/ARMERIA.png'),
- CUBE: require('./assets/cube22.png'),
- CUBEERROR: require('./assets/cube21.png'),
- USER: require('./assets/USER.png'),
- UNKNOWN: require('./assets/UNKNOWN.png'),
- UNKNOWNCLOUD: require('./assets/UNKNOWN_CLOUD.png'),
- UNDEFINED: require('./assets/UNDEFINED.png'),
- KAFKA: require('./assets/KAFKALOGO.png'),
- KAFKACONSUMER: require('./assets/KAFKALOGO.png'),
- H2:require('./assets/H2.png'),
- REDIS:require('./assets/REDIS.png'),
- TOMCAT: require('./assets/TOMCAT.png'),
- HTTPCLIENT: require('./assets/HTTPCLIENT.png'),
- DUBBO: require('./assets/DUBBO.png'),
- MOTAN: require('./assets/MOTAN.png'),
- RESIN: require('./assets/RESIN.png'),
- OKHTTP: require('./assets/OKHTTP.png'),
- SPRINGMVC: require('./assets/SPRINGMVC.png'),
- STRUTS2: require('./assets/STRUTS2.png'),
- NUTZMVC: require('./assets/SPRINGMVC.png'),
- NUTZHTTP: require('./assets/HTTPCLIENT.png'),
- JETTY:require('./assets/JETTY.png'),
- JETTYSERVER: require('./assets/JETTYSERVER.png'),
- GRPC: require('./assets/GRPC.png'),
- ORACLE: require('./assets/ORACLE.png'),
- MYSQL: require('./assets/MYSQL.png'),
- MYSQLGROUP: require('./assets/MYSQL.png'),
- MSSQLSERVER: require('./assets/MYSQL.png'),
- MSSQLSERVERGROUP: require('./assets/MYSQL.png'),
- MONGODB: require('./assets/MONGODB.png'),
- MONGODBGROUP: require('./assets/MONGODB.png'),
- ACTIVEMQ: require('./assets/ACTIVEMQ.png'),
- ELASTICSEARCH: require('./assets/ELASTICSEARCH.png'),
- FEIGNDEFAULTHTTP: require('./assets/FEIGNDEFAULTHTTP.png'),
- HPROSE: require('./assets/HPROSE.png'),
- HPROSE: require('./assets/POSTGRESQL.png'),
- RESIN: require('./assets/RESIN.png'),
- RABBITMQ: require('./assets/RABBITMQ.png'),
- SOFARPC: require('./assets/SOFARPC.png'),
- ROCKETMQ: require('./assets/ROCKETMQ.png'),
- ROCKETMQCONSUMER: require('./assets/ROCKETMQ.png'),
- HTTP: require('./assets/HTTPCLIENT.png'),
- RESTEASY: require('./assets/RESTEASY.png'),
- SOLR: require('./assets/SOLR.png'),
- ZOOKEEPER: require('./assets/ZOOKEEPER.png'),
- CASSANDRA: require('./assets/CASSANDRA.png'),
- LIGHT4J: require('./assets/LIGHT4J.png'),
- PULSAR: require('./assets/PULSAR.png'),
- SERVICECOMB: require('./assets/SERVICECOMB.png'),
- SERVICECOMBMESHER: require('./assets/SERVICECOMBMESHER.png'),
- SERVICECOMBSERVICECENTER:
require('./assets/SERVICECOMBSERVICECENTER.png'),
- PLAY: require('./assets/PLAY.png'),
- AVRO: require('./assets/AVRO.png'),
- width: 600,
- height: 600,
- force: '',
- svg: '',
- graph: '',
- link: '',
- node: '',
- zoom: '',
- };
- },
- beforeDestroy() {
- this.tip.hide({}, this);
- window.removeEventListener('resize', this.resize);
- d3.selectAll('.d3-tip-grey').remove();
- // this.$store.commit('skywalking/setCurrentNode', []);
- },
- mounted() {
- window.addEventListener('resize', this.resize);
- this.tip = d3tip()
- .attr('class', 'd3-tip-grey')
- .offset([-8, 0])
- .html(d => {
- return `
- <div class="mb-5"><span class="grey">${this.$t('cpm')}:
</span>${d.cpm}</div>
- <div class="mb-5"><span class="grey">${this.$t('detectPoint')}:
</span>${this.$store.state.rocketTopo.detectPoints.join(' | ')}</div>
- <div><span class="grey">${this.$t('latency')}:
</span>${d.latency}</div>
- `});
- this.tipName = d3tip()
- .attr('class', 'd3-tip-grey')
- .offset([-8, 0])
- .html(d => {
- return `<div>${d.name}</div>`});
- this.height = this.$el.clientHeight;
- this.svg = d3
- .select(this.$el)
- .append('svg')
- .style('display','block')
- .attr('width', '100%')
- .attr('height', this.height);
- },
- watch: {
- 'datas.nodes': 'draw',
- },
- methods: {
- removeHoneycomb(that) {
- const appGovernTopoHoneycombFrames =
d3.select('#app-govern-topo-honeycomb-frames');
- appGovernTopoHoneycombFrames.nodes().forEach((node) => {
- const childrenArray = Array.from(node.children).reverse();
- _.forEach(childrenArray, (ele, index) => {
- ele.classList.toggle('reverse');
- setTimeout(() => {
- ele.remove();
- }, 130 * index);
- });
- });
- setTimeout(() => {
- appGovernTopoHoneycombFrames.remove();
- }, 780);
- },
- draw(value, oldValue) {
- // Avoid unnecessary repetitive rendering
- const diffNodes = _.difference(_.sortBy(value, 'id'),
_.sortBy(oldValue, 'id'));
- if(value && value.length > 0 && diffNodes && diffNodes.length <=0) {
- return;
- }
- const codeId = this.datas.nodes.map(i => i.id);
- for (let i = 0; i < this.datas.calls.length; i += 1) {
- const element = this.datas.calls[i];
- if(codeId.indexOf(element.target) === -1 ) {
- this.datas.calls[i].target = this.datas.calls[i].source;
- }
- }
- this.svg.select(`.graph_${this.datas.type || ''}`).remove();
- this.force = d3
- .forceSimulation(this.datas.nodes)
- .force('collide', d3.forceCollide().radius(() => 65))
- .force('yPos', d3.forceY().strength(1))
- .force('xPos', d3.forceX().strength(1))
- .force('charge', d3.forceManyBody().strength(-520))
- .force( 'link', d3.forceLink(this.datas.calls).id(d => d.id))
- .force('center', d3.forceCenter(window.innerWidth / 2 + 100,
this.height / 2))
- .on('tick', this.tick)
- .stop();
- this.graph = this.svg.append('g').attr('class',
`graph_${this.datas.type || ''}`);
- this.svg.call(this.getZoomBehavior(this.graph));
- this.graph.call(this.tip);
- this.graph.call(this.tipName);
- this.svg.on('click', (d, i) => {
- event.stopPropagation();
- event.preventDefault();
- this.$store.commit('rocketTopo/SET_NODE', {});
- this.$store.dispatch('rocketTopo/CLEAR_TOPO_INFO');
- that.tip.hide({}, this);
- this.toggleNode(this.node, d, false);
- this.toggleLine(this.line, d, false);
- this.toggleLine(this.lineNode, d, false);
- });
- this.defs = this.graph.append('defs');
- this.arrowMarker = this.defs
- .append('marker')
- .attr('id', 'arrow')
- .attr('markerUnits', 'strokeWidth')
- .attr('markerWidth', '12')
- .attr('markerHeight', '12')
- .attr('viewBox', '0 0 12 12')
- .attr('refX', '11')
- .attr('refY', '6')
- .attr('orient', 'auto');
- const arrow_path = 'M2,2 L10,6 L2,10 L3,6 L2,2';
- this.arrowMarker.append('path').attr('d', arrow_path).attr('fill',
'#217EF2');
- this.gnode = this.graph.append('g').selectAll('.node');
- const that = this;
- this.node = this.gnode.data(this.datas.nodes)
- .enter()
- .append('g')
- .call(d3.drag()
- .on('start', this.dragstart)
- .on('drag', this.dragged)
- .on('end', function(d, i) {
- that.tipName.show(d, this);
- }))
- .on('mouseover', function(d, i) {
- that.tipName.show(d, this);
- })
- .on('mouseout', function(d, i) {
- that.tipName.hide(d, this);
- })
- .on('click', function(d, i) {
- event.stopPropagation();
- // active selected nodes and disable another nodes of non-relations
- that.clickNodesToUpdate(d, this);
- if (d.isReal) {
- // show some entrance icons for service nodes, such as alarm,
instance, endpoint
- that.dashboardEntranceIcons(d, this);
- }
- });
- this.node
- .append('image')
- .attr('width', 49)
- .attr('height', 49)
- .attr('x', 2)
- .attr('y', 10)
- .attr('style', 'cursor: move;')
- .attr('xlink:href',d => {
- const type = d.type;
- if( d.sla < 98 ) {
- return this.CUBEERROR;
- }
- return this.CUBE;
- });
- this.node
- .append('image')
- .attr('width',32)
- .attr('height', 32)
- .attr('x', 6)
- .attr('y', -10)
- .attr('style', 'opacity: 0.5;')
- .attr('xlink:href',this.LOCAL);
- this.node
- .append('image')
- .attr('width', 18)
- .attr('height', 18)
- .attr('x', 13)
- .attr('y', -7)
- .attr('xlink:href',d => {
- if( !d.type || d.type === 'N/A') {
- return this['UNDEFINED']
- }
- return this[d.type.toUpperCase().replace('-','')];
- });
- this.node
- .append('text')
- .attr('class', 'node-text')
- .attr('text-anchor', 'middle')
- .attr('x', 22)
- .attr('y', 70)
- // .text(d => d.name)
- .text(d => d.name.length > 20 ? `${d.name.substring(0, 20)}...`:
d.name)
- this.glink = this.graph.append('g').selectAll('.link');
- this.link = this.glink.data(this.datas.calls).enter();
- this.line = this.link.append('path').attr('class', 'link')
- .attr('stroke-dasharray', '13 7')
- .attr('stroke', d => d.cpm ? '#217EF25f' : '#6a6d7777');
- const handleSelectLine = function(d, i) {
- that.tip.hide({}, this);
- }
- this.lineNode = this.link.append('rect').attr('class', 'link-node cp')
- .attr('width', 10)
- .attr('height', 10)
- .attr('rx', 5)
- .attr('ry', 5)
- .attr('fill', d => d.cpm ? '#217EF299' : '#6a6d7799')
- .on('click', function(d, i) {
- that.clickLinkNodes(d, this);
- });
- d3.timeout(() => {
- for (
- let i = 0,
- n = Math.ceil(
- Math.log(this.force.alphaMin()) /
- Math.log(1 - this.force.alphaDecay())
- );
- i < n;
- i += 1
- ) {
- this.force.tick();
- this.tick();
- }
- });
- },
- clickLinkNodes(d, that) {
- this.$store.commit('rocketTopo/SET_NODE', {});
- this.$store.dispatch('rocketTopo/CLEAR_TOPO_INFO');
- this.$store.commit('rocketTopo/SET_MODE', d.detectPoints);
- event.stopPropagation();
- this.tip.hide({}, that);
- this.tip.show(d, that);
- this.$store.dispatch(this.$store.state.rocketTopo.mode ?
'rocketTopo/GET_TOPO_SERVICE_INFO' : 'rocketTopo/GET_TOPO_CLIENT_INFO',
{...d,duration: this.$store.getters.durationTime});
- this.$store.commit('rocketTopo/SET_CALLBACK', () => {
- this.tip.hide({}, that);
- this.tip.show(d, that);
- this.$store.dispatch(this.$store.state.rocketTopo.mode ?
'rocketTopo/GET_TOPO_SERVICE_INFO' : 'rocketTopo/GET_TOPO_CLIENT_INFO',
{...d,duration: this.$store.getters.durationTime});
- })
- },
- clickNodesToUpdate(d, that) {
- this.tip.hide({}, that);
- this.node.attr('class', '');
- d3.select(that).attr('class', 'node-active');
- const copyD = JSON.parse(JSON.stringify(d));
- delete copyD.x;
- delete copyD.y;
- delete copyD.vx;
- delete copyD.vy;
- delete copyD.fx;
- delete copyD.fy;
- delete copyD.index;
- this.$store.dispatch('rocketTopo/CLEAR_TOPO_INFO');
- this.$store.commit('rocketTopo/SET_NODE', copyD);
- this.toggleNode(this.node, d, true);
- this.toggleLine(this.line, d, true);
- this.toggleLine(this.lineNode, d, true);
- },
- dashboardEntranceIcons(d, context) {
- const that = this;
- const honeycombFrames =
d3.select('#honeycomb-selector_honeycomb-frames');
- const appGovernTopoHoneycombFrames = this.graph.append('g')
- .attr('id', 'app-govern-topo-honeycomb-frames')
- .attr('style', honeycombFrames.attr('style'))
- .attr('stroke',
honeycombFrames.attr('stroke')).html(honeycombFrames.html())
- .on('mouseleave', function () {
- that.removeHoneycomb(that);
- });
- const nodeTranslate =
CssHelper.translateSerialization(context.getAttribute('transform'));
- const appGovernTopoHoneycombFramesTranslate =
CssHelper.matrixSerialization(honeycombFrames.attr('transform'));
- appGovernTopoHoneycombFramesTranslate.tx = nodeTranslate.x - 83;
- appGovernTopoHoneycombFramesTranslate.ty = nodeTranslate.y + 72;
- appGovernTopoHoneycombFrames.attr('transform',
CssHelper.matrixDeserialization(appGovernTopoHoneycombFramesTranslate));
-
- that.$store.commit('rocketTopo/SET_HONEYCOMB_NODE', d);
-
- d3.selectAll('#honeycomb-selector_honeycomb-group-top-left').on('click',
() => {
- that.$store.commit('SET_CURRENT_SERVICE', { key: d.id, label: d.name
});
- that.$store.commit('rocketTopo/SET_SHOW_DIALOG', 'endpoint');
- that.removeHoneycomb(that);
- });
-
d3.selectAll('#honeycomb-selector_honeycomb-group-below-left').on('click', ()
=> {
- that.$store.commit('SET_CURRENT_SERVICE', { key: d.id, label: d.name
});
- that.$store.commit('rocketTopo/SET_SHOW_DIALOG', 'instance');
- that.removeHoneycomb(that);
- });
-
d3.selectAll('#honeycomb-selector_honeycomb-group-top-right').on('click', () =>
{
- that.$store.commit('rocketTopo/SET_SHOW_DIALOG', 'alarm');
- that.removeHoneycomb(that);
- });
-
d3.selectAll('#honeycomb-selector_honeycomb-group-below-right').on('click', ()
=> {
- this.$store.commit('rocketTopo/SET_SHOW_DIALOG', 'trace');
- that.removeHoneycomb(that);
- });
- },
- isLinkNode(currNode, node) {
- if (currNode.id === node.id) {
- return true;
- }
- return this.datas.calls.filter(i =>
- (i.source.id === currNode.id || i.target.id === currNode.id) &&
- (i.source.id === node.id || i.target.id === node.id)
- ).length;
- },
- toggleNode(nodeCircle, currNode, isHover) {
- if (isHover) {
- nodeCircle.sort((a, b) => a.id === currNode.id ? 1 : -1);
- nodeCircle
- .style('opacity', .2)
- .filter(node => this.isLinkNode(currNode, node))
- .style('opacity', 1);
- } else {
- nodeCircle.style('opacity', 1);
- }
- },
- toggleLine(linkLine, currNode, isHover) {
- if (isHover) {
- linkLine
- .style('opacity', .05)
- .style('animation', 'none')
- .filter(link => this.isLinkLine(currNode, link))
- .style('opacity', 1)
- .style('animation', 'dash 1s linear infinite');
- // .classed('link-active', true);
- } else {
- linkLine
- .style('opacity', 1)
- .style('animation', 'dash 1s linear infinite');
- // .classed('link-active', false);
- }
- },
- isLinkLine(node, link) {
- return link.source.id == node.id || link.target.id == node.id;
- },
- toggleLineText(lineText, currNode, isHover) {
- if (isHover) {
- lineText
- .style('fill-opacity', link => this.isLinkLine(currNode, link) ? 1.0 :
0.0);
- } else {
- lineText
- .style('fill-opacity', '1.0');
- }
- },
- toggleMarker(marker, currNode, isHover) {
- if (isHover) {
- marker.filter(link => this.isLinkLine(currNode, link))
- .style('transform', 'scale(1.5)');
- } else {
- marker
- .attr('refX', nodeConf.radius.Company)
- .style('transform', 'scale(1)');
- }
- },
- resize() {
- this.svg.attr('height', document.body.clientHeight - 50);
- },
- tick() {
- this.line
- .attr('d', d => `M${d.source.x} ${d.source.y} Q ${(d.source.x +
d.target.x)/2} ${(d.target.y + d.source.y)/2 - 80} ${d.target.x}
${d.target.y}`);
- this.lineNode.attr('transform', d => `translate(${(d.source.x +
d.target.x)/2 - 3},${(d.target.y + d.source.y)/2 - 43})`);
- // this.linkText.attr('transform',d =>`translate(${(d.source.x +
d.target.x) / 2},${(d.source.y + d.target.y) / 2})`);
- this.node.attr('transform', d => `translate(${d.x - 22},${d.y -
22})`);
- },
- getZoomBehavior(g) {
- const that = this;
- return d3
- .zoom()
- .scaleExtent([0.3, 10])
- .on('zoom', () => {
- that.tip.hide({}, this);
- that.tipName.hide({}, this);
- g.attr(
- 'transform',
-
`translate(${d3.event.transform.x},${d3.event.transform.y})scale(${
- d3.event.transform.k
- })`
- );
- });
- },
- dragstart(d) {
- const that = this;
- that.tipName.hide({}, this);
- this.node._groups[0].forEach(d => {
- d.__data__.fx = d.__data__.x;
- d.__data__.fy = d.__data__.y;
- });
- if (!d3.event.active) {
- this.force.alphaTarget(0.01).restart();
- }
- d3.event.sourceEvent.stopPropagation();
- },
- dragged(d) {
- const that = this;
- that.tipName.hide({}, this);
- d.fx = d3.event.x;
- d.fy = d3.event.y;
- },
- dragended() {
- if (!d3.event.active) {
- this.force.alphaTarget(0);
- }
- },
- },
- };
-</script>
-<style lang="scss">
- .micro-topo-chart {
- height: 100%;
- width: 100%;
- .node-name {
- cursor: move;
- font-size: 14px;
- fill: #ddd;
- }
- .link {
- stroke-linecap: round;
- stroke-width: 1.3px !important;
- fill: none;
- animation: topo-dash 1s linear infinite !important;
- }
- @keyframes topo-dash {
- from {
- stroke-dashoffset: 20;
- }
- to {
- stroke-dashoffset: 0;
- }
- }
- .node-text {
- font-family: 'Lato', 'Source Han Sans CN', 'Microsoft YaHei', sans-serif;
- fill: #ddd;
- font-size: 11px;
- opacity: 0.8;
- }
- .link-text {
- font-family: 'Lato', 'Source Han Sans CN', 'Microsoft YaHei', sans-serif;
- fill: #ddd;
- font-size: 11px;
- opacity: 0.8;
- }
- .node {
- cursor: move;
- fill: #333840;
- stroke-width: 0;
- }
- .link-node {
- stroke-width: 6px;
- stroke: rgba(255, 255, 255, 0);
- }
-
- #honeycomb-selector_honeycomb-group-background {
- opacity: 0.6;
- animation: honeycombXTopBackground 0.1s linear;
- }
-
- #honeycomb-selector_honeycomb-group-top {
- opacity: 1;
- animation: honeycombXTop 0.2s linear;
- }
-
- #honeycomb-selector_honeycomb-group-top-right {
- opacity: 1;
- animation: honeycombXTop 0.3s linear;
- }
-
- #honeycomb-selector_honeycomb-group-below-right {
- opacity: 1;
- animation: honeycombXTop 0.4s linear;
- }
-
- #honeycomb-selector_honeycomb-group-below {
- opacity: 1;
- animation: honeycombXTop 0.5s linear;
- }
-
- #honeycomb-selector_honeycomb-group-below-left {
- opacity: 1;
- animation: honeycombXTop 0.6s linear;
- }
-
- #honeycomb-selector_honeycomb-group-top-left {
- opacity: 1;
- animation: honeycombXTop 0.7s linear;
- }
-
- #honeycomb-selector_honeycomb-group-background.reverse {
- opacity: 0;
- animation: honeycombXTopBackgroundReverse 0.7s linear;
- }
-
- #honeycomb-selector_honeycomb-group-top.reverse {
- opacity: 0;
- animation: honeycombXTopReverse 0.6s linear;
- }
-
- #honeycomb-selector_honeycomb-group-top-right.reverse {
- opacity: 0;
- animation: honeycombXTopReverse 0.5s linear;
- }
-
- #honeycomb-selector_honeycomb-group-below-right.reverse {
- opacity: 0;
- animation: honeycombXTopReverse 0.4s linear;
- }
-
- #honeycomb-selector_honeycomb-group-below.reverse {
- opacity: 0;
- animation: honeycombXTopReverse 0.3s linear;
- }
-
- #honeycomb-selector_honeycomb-group-below-left.reverse {
- opacity: 0;
- animation: honeycombXTopReverse 0.2s linear;
- }
-
- #honeycomb-selector_honeycomb-group-top-left.reverse {
- opacity: 0;
- animation: honeycombXTopReverse 0.1s linear;
- }
-
- #honeycomb-selector_honeycomb-select-top-left {
- opacity: 0.1;
- }
-
- /*#honeycomb-selector_honeycomb-group-top:hover,*/
- #honeycomb-selector_honeycomb-group-top-right:hover,
- /*#honeycomb-selector_honeycomb-group-below:hover,*/
- #honeycomb-selector_honeycomb-group-below-left:hover,
- #honeycomb-selector_honeycomb-group-top-left:hover {
- fill: #0ae;
- }
-
- #honeycomb-selector_honeycomb-group-below-right:hover {
- fill: #24c1ab;
- }
-
- @keyframes honeycombXTop {
- from {
- opacity: 0;
- }
- to {
- opacity: 1;
- }
- }
-
- @keyframes honeycombXTopBackground {
- from {
- opacity: 0;
- }
- to {
- opacity: 0.2;
- }
- }
-
- @keyframes honeycombXTopReverse {
- from {
- opacity: 1;
- }
- to {
- opacity: 0;
- }
- }
-
- @keyframes honeycombXTopBackgroundReverse {
- from {
- opacity: 1;
- }
- to {
- opacity: 0;
- }
- }
-
- #honeycomb-selector_honeycomb-group-top
- #honeycomb-selector_honeycomb-text-top,
- #honeycomb-selector_honeycomb-group-top-right
- #honeycomb-selector_honeycomb-text-top-right,
- #honeycomb-selector_honeycomb-group-below-right
- #honeycomb-selector_honeycomb-text-below-right,
- #honeycomb-selector_honeycomb-group-below
- #honeycomb-selector_honeycomb-text-below,
- #honeycomb-selector_honeycomb-group-below-left
- #honeycomb-selector_honeycomb-text-below-left,
- #honeycomb-selector_honeycomb-group-top-left
- #honeycomb-selector_honeycomb-text-top-left {
- display: none;
- }
-
- #honeycomb-selector_honeycomb-group-top:hover
- #honeycomb-selector_honeycomb-text-top,
- #honeycomb-selector_honeycomb-group-top-right:hover
- #honeycomb-selector_honeycomb-text-top-right,
- #honeycomb-selector_honeycomb-group-below-right:hover
- #honeycomb-selector_honeycomb-text-below-right,
- #honeycomb-selector_honeycomb-group-below:hover
- #honeycomb-selector_honeycomb-text-below,
- #honeycomb-selector_honeycomb-group-below-left:hover
- #honeycomb-selector_honeycomb-text-below-left,
- #honeycomb-selector_honeycomb-group-top-left:hover
- #honeycomb-selector_honeycomb-text-top-left {
- display: block;
- }
- }
-</style>
diff --git a/src/views/components/trace/trace-search.vue
b/src/views/components/trace/trace-search.vue
index a93b51a..4f37aee 100644
--- a/src/views/components/trace/trace-search.vue
+++ b/src/views/components/trace/trace-search.vue
@@ -257,11 +257,7 @@ language governing permissions and * limitations under the
License. */
this.traceId = this.$route.query.traceid ?
this.$route.query.traceid.toString() : this.traceId;
this.time = [this.rocketbotGlobal.durationRow.start,
this.rocketbotGlobal.durationRow.end];
}
-
private mounted() {
- if (this.inTopo) {
- this.service = this.propsService;
- }
this.getTraceList();
if (this.service && this.service.key) {
this.GET_INSTANCES({
diff --git a/src/views/containers/alarm.vue b/src/views/containers/alarm.vue
index 1663ca7..db7c913 100644
--- a/src/views/containers/alarm.vue
+++ b/src/views/containers/alarm.vue
@@ -11,39 +11,23 @@ specific language governing permissions and * limitations
under the License. */
<template>
<div class="rk-alarm flex-v">
- <AlarmTool
- :durationTime="durationTime"
- :total="rocketAlarm.total"
- :alarmScope="alarmScope"
- :inTopo="inTopo"
- :prop-keyword="keyword"
- />
- <div style="flex-grow: 1;overflow: auto;height: 100%;">
- <AlarmTable :data="rocketAlarm.alarmService" />
- </div>
+ <AlarmTool :total="rocketAlarm.total" />
+ <AlarmTable :data="rocketAlarm.alarmService" />
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import Component from 'vue-class-component';
- import { Prop } from 'vue-property-decorator';
import AlarmTool from '../components/alarm/alarm-tool.vue';
import AlarmTable from '../components/alarm/alarm-table.vue';
- import { State, Action, Getter } from 'vuex-class';
+ import { State } from 'vuex-class';
@Component({
components: { AlarmTool, AlarmTable },
})
export default class Alarm extends Vue {
@State('rocketAlarm') private rocketAlarm!: any;
- @Getter('durationTime') private durationTime: any;
- @Prop({ default: () => ({ label: 'All', key: '' }) })
- private alarmScope: any;
- @Prop({ default: false, type: Boolean })
- private inTopo!: boolean;
- @Prop({ default: '' })
- private keyword!: string;
}
</script>
diff --git a/src/views/containers/topology/topology.vue
b/src/views/containers/topology/topology.vue
index cff77c9..154f538 100644
--- a/src/views/containers/topology/topology.vue
+++ b/src/views/containers/topology/topology.vue
@@ -12,7 +12,7 @@ specific language governing permissions and * limitations
under the License. */
<template>
<div class="rk-topo">
<TopoAside />
- <Topo :datas="{ nodes: stateTopo.nodes, calls: stateTopo.calls }" />
+ <Topo :current="current" @setCurrent="setCurrent" :nodes="stateTopo.nodes"
:links="stateTopo.calls"/>
<rk-sidebox :show.sync="stateTopo.showDialog" :fixed="true" width="80%">
<window-endpoint
v-if="stateTopo.showDialogType === 'endpoint'"
@@ -24,15 +24,12 @@ specific language governing permissions and * limitations
under the License. */
/>
<window-trace
v-else-if="stateTopo.showDialogType === 'trace'"
- :service="{
- label: stateTopo.honeycombNode.name,
- key: stateTopo.honeycombNode.id,
- }"
+ :service="this.current"
/>
<window-alarm
v-else-if="stateTopo.showDialogType === 'alarm'"
:alarmScope="{ label: 'Service', key: 'Service' }"
- :keyword="stateTopo.honeycombNode.name"
+ :keyword="this.current.label"
/>
</rk-sidebox>
</div>
@@ -45,7 +42,7 @@ specific language governing permissions and * limitations
under the License. */
import WindowInstance from '@/views/containers/topology/window-instance.vue';
import WindowTrace from '@/views/containers/topology/window-trace.vue';
import WindowAlarm from '@/views/containers/topology/window-alarm.vue';
- import Topo from '../../components/topology/topo.vue';
+ import Topo from '../../components/topology/chart/topo.vue';
import TopoAside from '../../components/topology/topo-aside.vue';
import { State as topoState } from '@/store/modules/topology';
@@ -68,6 +65,10 @@ specific language governing permissions and * limitations
under the License. */
@Action('rocketTopo/CLEAR_TOPO_INFO') private CLEAR_TOPO_INFO: any;
@Getter('durationTime') private durationTime: any;
+ private current: any = {};
+ private setCurrent(d: any): void {
+ this.current = d;
+ }
private beforeMount(): void {
this.SET_EVENTS([this.getTopo]);
}
diff --git a/src/views/containers/topology/window-alarm.vue
b/src/views/containers/topology/window-alarm.vue
index 8fdc826..9e72aa3 100644
--- a/src/views/containers/topology/window-alarm.vue
+++ b/src/views/containers/topology/window-alarm.vue
@@ -15,7 +15,7 @@ specific language governing permissions and * limitations
under the License. */
:durationTime="durationTime"
:total="rocketAlarm.total"
:alarmScope="alarmScope"
- :inTopo="inTopo"
+ :inTopo="true"
:prop-keyword="keyword"
/>
<div style="flex-grow: 1;overflow: auto;height: 100%;">
@@ -40,8 +40,6 @@ specific language governing permissions and * limitations
under the License. */
@Getter('durationTime') private durationTime: any;
@Prop({ default: () => ({ label: 'All', key: '' }) })
private alarmScope: any;
- @Prop({ default: false, type: Boolean })
- private inTopo!: boolean;
@Prop({ default: '' })
private keyword!: string;
}
diff --git a/src/views/containers/topology/window-trace.vue
b/src/views/containers/topology/window-trace.vue
index ea8eb34..ec5cf09 100644
--- a/src/views/containers/topology/window-trace.vue
+++ b/src/views/containers/topology/window-trace.vue
@@ -11,7 +11,7 @@ specific language governing permissions and * limitations
under the License. */
<template>
<div class="rk-trace flex-v">
- <TraceSearch :propsService="service" :inTopo="inTopo" />
+ <TraceSearch ref="search" :propsService="service" :inTopo="true" />
<div class="rk-trace-inner">
<TraceTable />
<TraceDetail
@@ -24,7 +24,7 @@ specific language governing permissions and * limitations
under the License. */
<script lang="ts">
import { Option } from '@/types/global';
- import { Component, Vue, Prop, PropSync } from 'vue-property-decorator';
+ import { Component, Vue, Prop, PropSync, Watch } from
'vue-property-decorator';
import { State, Action, Mutation } from 'vuex-class';
import TraceSearch from '@/views/components/trace/trace-search.vue';
import TraceTable from '@/views/components/trace/trace-table.vue';
@@ -45,10 +45,6 @@ specific language governing permissions and * limitations
under the License. */
private isShowSync!: boolean;
@Prop({ default: { label: 'All', key: '' } })
private service!: Option;
-
- @Prop({ default: false, type: Boolean })
- private inTopo!: boolean;
-
private show: boolean = true;
private beforeMount() {
this.SET_EVENTS([]);
diff --git a/vue.config.js b/vue.config.js
index 62f17f7..38a3e0c 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -19,7 +19,7 @@ module.exports = {
devServer: {
proxy: {
'/graphql': {
- target: `${process.env.SW_PROXY_TARGET || "http://127.0.0.1:12800"}`,
+ target: `${process.env.SW_PROXY_TARGET ||
"http://122.112.182.72:8080/"}`,
changeOrigin: true,
},
},