初始化

This commit is contained in:
clay
2021-12-27 18:00:02 +08:00
commit a75166d228
323 changed files with 30338 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
@font-face {font-family: "iconfont";
src: url('iconfont.eot?t=1568972645985'); /* IE9 */
src: url('iconfont.eot?t=1568972645985#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'),
url('iconfont.woff?t=1568972645985') format('woff'),
url('iconfont.ttf?t=1568972645985') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('iconfont.svg?t=1568972645985#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-download:before {
content: "\e68d";
}
.icon-zoom-out:before {
content: "\e69c";
}
.icon-image:before {
content: "\e752";
}
.icon-iconedit:before {
content: "\e650";
}
.icon-actualsize:before {
content: "\e665";
}
.icon-copy:before {
content: "\e61c";
}
.icon-zoom-in:before {
content: "\e600";
}
.icon-clear:before {
content: "\e700";
}
.icon-flow-line:before {
content: "\e660";
}
.icon-redo:before {
content: "\e716";
}
.icon-undo:before {
content: "\e71a";
}
.icon-fit:before {
content: "\e7cb";
}
.icon-to-front:before {
content: "\e7cc";
}
.icon-to-back:before {
content: "\e7cd";
}
.icon-roi-select:before {
content: "\e7ce";
}
.icon-json:before {
content: "\e623";
}
.icon-fullscreen:before {
content: "\e648";
}
.icon-broken:before {
content: "\e9ad";
}
.icon-curve:before {
content: "\e9b0";
}
.icon-paste:before {
content: "\e963";
}
.icon-group:before {
content: "\e915";
}
.icon-ungroup:before {
content: "\e917";
}
.icon-arrow-dropdown:before {
content: "\e601";
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,95 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<!--
2013-9-30: Created.
-->
<svg>
<metadata>
Created by iconfont
</metadata>
<defs>
<font id="iconfont" horiz-adv-x="1024" >
<font-face
font-family="iconfont"
font-weight="500"
font-stretch="normal"
units-per-em="1024"
ascent="896"
descent="-128"
/>
<missing-glyph />
<glyph glyph-name="download" unicode="&#59021;" d="M135.377782 555.885765l277.111319 0L412.4891 830.342628l207.41905 0 0-274.457886 272.656867 0L513.970376 147.641851 135.377782 555.885765 135.377782 555.885765zM892.268258 145.226848l0-66.952878L136.666124 78.27397l0 66.952878L65.878918 145.226848l0-204.12912L136.666124-58.902272l755.603157 0 65.849754 0 0 204.12912L892.268258 145.226848 892.268258 145.226848zM892.268258 145.226848" horiz-adv-x="1024" />
<glyph glyph-name="zoom-out" unicode="&#59036;" d="M950.075-14.436l-225.921 221.773c123.199 146.698 115.857 366.528-22.075 504.482-145.758 145.751-382.898 145.751-528.647 0-145.752-145.745-145.752-382.87 0-528.615 135.794-135.787 350.91-145.037 497.546-27.789l227.045-222.879c13.304-13.055 34.675-12.864 47.736 0.447l4.758 4.84c13.057 13.306 12.86 34.681-0.442 47.741l0 0zM226.091 235.862c-116.713 116.708-116.713 306.595 0 423.301 116.712 116.713 306.604 116.713 423.323 0 116.68-116.706 116.68-306.593 0-423.289-116.72-116.72-306.611-116.72-423.323-0.012l0 0zM214.441 484.734l446.604 0 0-74.435-446.604 0 0 74.435zM214.441 484.734z" horiz-adv-x="1024" />
<glyph glyph-name="image" unicode="&#59218;" d="M896 704 128 704 128 64 896 64 896 704ZM1024 832 1024 832 1024-64 0-64 0 832 1024 832ZM832 128 192 128 192 256 384 576 647.008 256 832 384 832 320ZM640 544A3 3 2520 1 0 832 544 3 3 2520 1 0 640 544z" horiz-adv-x="1024" />
<glyph glyph-name="iconedit" unicode="&#58960;" d="M893.46655 451.99051l0-444.912046c0-35.100426-28.426423-63.558571-63.557548-63.558571L130.761648-56.480106c-35.068703 0-63.558571 28.459169-63.558571 63.558571L67.203076 706.225819c0 35.132148 28.489868 63.558571 63.558571 63.558571l444.911022 0 0-61.540611L128.77541 708.243779l0-701.165314 701.133591 0L829.909002 451.99051 893.46655 451.99051zM487.78397 229.659843l-201.912639-64.520479 64.490803 201.909569L487.78397 229.659843zM398.007271 412.085662l134.848221-134.808312 313.198212 313.199235L711.194226 725.274664 398.007271 412.085662zM935.921477 770.251018l-44.936445 44.938492c-24.827455 24.827455-65.049528 24.827455-89.876983 0l-43.530422-43.532469 134.808312-134.849244 43.535539 43.535539C960.752002 705.17079 960.752002 745.42254 935.921477 770.251018z" horiz-adv-x="1024" />
<glyph glyph-name="actualsize" unicode="&#58981;" d="M716.8 793.6L716.8 725.33333333 853.33333333 725.33333333 853.33333333 588.8 921.6 588.8 921.6 725.33333333 921.6 793.6ZM853.33333333 42.66666667000004L716.8 42.66666667000004 716.8-25.600000000000023 921.6-25.600000000000023 921.6 42.66666667000004 921.6 179.20000000000005 853.33333333 179.20000000000005ZM170.66666667 179.20000000000005L102.4 179.20000000000005 102.4 42.66666667000004 102.4-25.600000000000023 307.2-25.600000000000023 307.2 42.66666667000004 170.66666667 42.66666667000004ZM170.66666667 725.33333333L307.2 725.33333333 307.2 793.6 102.4 793.6 102.4 725.33333333 102.4 588.8 170.66666667 588.8ZM238.93333333 589.0047999999999l0-410.0096C238.93333333 141.85813333 269.38026667 110.93333332999998 306.9952 110.93333332999998l410.0096 0C754.14186667 110.93333332999998 785.06666667 141.38026666999997 785.06666667 178.99519999999995L785.06666667 589.0047999999999C785.06666667 626.14186667 754.61973333 657.06666667 717.0048 657.06666667L306.9952 657.06666667C269.85813333 657.06666667 238.93333333 626.6197333299999 238.93333333 589.0047999999999zM307.2 588.8l409.6 0 0-409.6L307.2 179.20000000000005 307.2 588.8z" horiz-adv-x="1024" />
<glyph glyph-name="copy" unicode="&#58908;" d="M704 256h256v-355.968c0-15.424-12.608-28.032-28.032-28.032h-455.936c-15.424 0-28.032 12.608-28.032 28.032v583.936c0 15.424 12.608 28.032 31.168 28.032h224.832v-256zM768 506.624v-186.624h192l-182.464 186.624h-9.536zM448 826.624v-122.624h128l-118.464 122.624h-9.536zM384 576h192v64h-192v192h-288.832c-18.56 0-31.168-12.608-31.168-28.032v-644.8c0-15.424 12.608-28.032 28.032-28.032h291.968v444.864z" horiz-adv-x="1024" />
<glyph glyph-name="zoom-in" unicode="&#58880;" d="M968.842667-12.501333L726.698667 229.642667A382.293333 382.293333 0 0 1 810.666667 469.333333C810.666667 681.408 638.752 853.333333 426.666667 853.333333 214.592 853.333333 42.666667 681.408 42.666667 469.333333s171.925333-384 384-384c90.666667 0 173.994667 31.413333 239.690666 83.978667l242.144-242.144a42.666667 42.666667 0 0 1 60.341334 60.330667zM426.666667 170.666667c-164.949333 0-298.666667 133.717333-298.666667 298.666666s133.717333 298.666667 298.666667 298.666667c164.96 0 298.666667-133.717333 298.666666-298.666667S591.626667 170.666667 426.666667 170.666667z m170.666666 298.666666a42.666667 42.666667 0 0 0-42.666666-42.666666h-85.333334v-85.333334a42.666667 42.666667 0 0 0-85.333333 0v85.333334h-85.333333a42.666667 42.666667 0 0 0 0 85.333333h85.333333v85.333333a42.666667 42.666667 0 0 0 85.333333 0v-85.333333h85.333334a42.666667 42.666667 0 0 0 42.666666-42.666667z" horiz-adv-x="1024" />
<glyph glyph-name="clear" unicode="&#59136;" d="M791.04 583.68H768V0h-76.8V583.68h-128V0h-76.8V583.68h-128V0h-76.8V583.68H128V-25.6c0-56.32 46.08-102.4 104.96-102.4h558.08c58.88 0 104.96 46.08 104.96 102.4V583.68c0 5.12-46.08 0-104.96 0M947.2 768h-230.4V829.44C716.8 867.84 652.8 896 614.4 896h-204.8c-38.4 0-102.4-28.16-102.4-66.56V768H76.8c-28.16 0-51.2-23.04-51.2-51.2s23.04-51.2 51.2-51.2h870.4c28.16 0 51.2 23.04 51.2 51.2s-23.04 51.2-51.2 51.2M614.4 768h-204.8V793.6h204.8v-25.6m0 0z" horiz-adv-x="1024" />
<glyph glyph-name="flow-line" unicode="&#58976;" d="M563.2 188.2112V579.7888A122.624 122.624 0 0 1 634.88 691.2a122.88 122.88 0 1 1-245.76 0c0-49.5104 29.4912-91.9552 71.68-111.4112v-391.6288A122.5216 122.5216 0 0 1 389.12 76.8a122.88 122.88 0 1 1 245.76 0c0 49.5104-29.44 91.9552-71.68 111.4112zM512 762.112a70.8608 70.8608 0 1 0 0-141.7216 70.8608 70.8608 0 0 0 0 141.7216z m0-756.224a70.912 70.912 0 1 0 0 141.824 70.912 70.912 0 0 0 0-141.824z" horiz-adv-x="1024" />
<glyph glyph-name="redo" unicode="&#59158;" d="M999.551 549.05c13.299 0 24-10.8 24.1-24v-358c0-17.7-14.301-32-32-32h-358.1c-6.4 0-12.5 2.5-17 7-9.4 9.3-9.4 24.5 0 33.9l127 127c-82.201 101.8-208 167-349.001 167-170.3 0-318.4-95-394.2-235 45.7 227 246.2 398 486.7 398 160.101 0 302.399-75.7 393.2-193.3l102.301 102.4c4.5 4.5 10.599 7 17 7z" horiz-adv-x="1024" />
<glyph glyph-name="undo" unicode="&#59162;" d="M41.353 542.029a23.998 23.998 0 0 1-16.97 7.029c-13.255 0-24-10.744-24-24V167c0-17.673 14.327-32 32-32h358.06a24 24 0 0 1 16.969 7.029c9.373 9.373 9.373 24.568 0 33.941L280.418 302.965C362.539 404.832 488.35 470 629.383 470c170.332 0 318.462-95.059 394.234-235.02C977.931 462.016 777.375 633 536.883 633c-160.045 0-302.403-75.725-393.2-193.3L41.353 542.029z" horiz-adv-x="1024" />
<glyph glyph-name="fit" unicode="&#59339;" d="M640 608V800c0 19.2 12.8 32 32 32s32-12.8 32-32v-160h160c19.2 0 32-12.8 32-32s-12.8-32-32-32h-192c-6.4 0-12.8 0-19.2 6.4h-6.4c0 12.8-6.4 19.2-6.4 25.6zM288 832c-19.2 0-32-12.8-32-32v-160H96c-19.2 0-32-12.8-32-32s12.8-32 32-32h192c6.4 0 12.8 0 19.2 6.4h6.4c6.4 6.4 6.4 12.8 6.4 19.2v192C320 819.2 307.2 832 288 832z m576-576h-192c-6.4 0-12.8 0-19.2-6.4h-6.4c-6.4-6.4-6.4-12.8-6.4-19.2v-192c0-19.2 12.8-32 32-32s32 12.8 32 32V192h160c19.2 0 32 12.8 32 32s-12.8 32-32 32z m-550.4-12.8c-6.4 6.4-6.4 6.4 0 0-12.8 6.4-19.2 12.8-25.6 12.8H96c-19.2 0-32-12.8-32-32s12.8-32 32-32h160v-160c0-19.2 12.8-32 32-32s32 12.8 32 32v192c0 6.4-6.4 12.8-6.4 19.2zM480 544c-70.4 0-128-57.6-128-128s57.6-128 128-128 128 57.6 128 128-57.6 128-128 128z" horiz-adv-x="1024" />
<glyph glyph-name="to-front" unicode="&#59340;" d="M768 300.8c-6.4 12.8-12.8 19.2-25.6 19.2l-102.4 12.8 115.2 102.4c6.4 6.4 12.8 19.2 6.4 25.6-6.4 12.8-12.8 19.2-25.6 19.2l-102.4 12.8 115.2 102.4c6.4 6.4 12.8 19.2 6.4 25.6-6.4 12.8-12.8 19.2-25.6 19.2L358.4 697.6c-6.4 0-19.2 0-25.6-6.4l-320-230.4c-6.4-6.4-12.8-19.2-12.8-25.6 0-12.8 12.8-19.2 19.2-19.2l115.2-25.6-121.6-89.6c-6.4-6.4-12.8-19.2-12.8-25.6 0-12.8 12.8-19.2 19.2-19.2l115.2-25.6-121.6-89.6c-6.4-6.4-12.8-19.2-12.8-25.6 0-12.8 12.8-19.2 19.2-19.2l390.4-96c6.4 0 19.2 0 25.6 6.4l307.2 268.8c25.6 6.4 25.6 19.2 25.6 25.6zM217.6 377.6l204.8-51.2c6.4 0 19.2 0 25.6 6.4l134.4 121.6 83.2-12.8L416 224 96 300.8l121.6 76.8z m204.8-320l-320 76.8 108.8 76.8L416 160c6.4 0 19.2 0 25.6 6.4L576 288l83.2-12.8-236.8-217.6z m473.6 448l140.8-179.2h-96c-6.4-115.2-76.8-211.2-179.2-262.4 51.2 70.4 83.2 153.6 83.2 249.6v12.8h-96l147.2 179.2z" horiz-adv-x="1036" />
<glyph glyph-name="to-back" unicode="&#59341;" d="M729.6 320l-96 12.8 115.2 102.4c6.4 6.4 12.8 19.2 6.4 25.6 0 12.8-12.8 19.2-25.6 19.2l-96 12.8 115.2 102.4c6.4 6.4 12.8 19.2 6.4 25.6 0 12.8-12.8 19.2-25.6 19.2L364.8 697.6c-6.4 0-12.8 0-19.2-6.4l-320-230.4c-6.4-6.4-12.8-19.2-12.8-25.6 0-12.8 12.8-19.2 19.2-19.2l108.8-25.6-121.6-89.6c-6.4-6.4-12.8-19.2-12.8-25.6s12.8-19.2 19.2-19.2l108.8-25.6-121.6-89.6c-6.4-6.4-12.8-19.2-12.8-25.6 0-12.8 12.8-19.2 19.2-19.2l384-89.6c6.4 0 19.2 0 25.6 6.4l300.8 268.8c6.4 6.4 12.8 19.2 6.4 25.6 12.8 6.4 6.4 12.8-6.4 12.8zM364.8 646.4l300.8-44.8L416 384l-313.6 76.8 262.4 185.6z m-147.2-268.8l204.8-51.2c6.4 0 19.2 0 25.6 6.4l134.4 121.6 83.2-12.8L416 224l-313.6 76.8 115.2 76.8z m723.2-134.4h96L896 64l-140.8 179.2h96V256c0 96-32 179.2-83.2 249.6 102.4-51.2 172.8-153.6 172.8-262.4z" horiz-adv-x="1036" />
<glyph glyph-name="roi-select" unicode="&#59342;" d="M64 704h64v-64H64V704z m0-128h64v-64H64v64z m0-128h64v-64H64v64z m0-128h64v-64H64v64z m0-128h64v-64H64v64zM64 768V832h64v-64H64z m128 0V832h64v-64H192z m128 0V832h64v-64h-64z m128 0V832h64v-64h-64z m128 0V832h64v-64h-64z m128 0V832h64v-64h-64z m128 64h64v-64h-64V832z m0-128h64v-64h-64V704z m0-128h64v-64h-64v64z m0-128h64v-64h-64v64z m0-128h64v-64h-64v64zM64 0v64h64v-64H64z m128 0v64h64v-64H192z m128 0v64h64v-64h-64z m128 0v64h64v-64h-64z m384 64v128h64v-128h128v-64h-128v-128h-64v128h-128v64h128z m-256-64v64h64v-64h-64z m-128 576v-64h256v64h-256z m0 64h256c38.4 0 64-25.6 64-64v-64c0-38.4-25.6-64-64-64h-256c-38.4 0-64 25.6-64 64v64c0 38.4 25.6 64 64 64zM256 320v-64h256v64H256z m0 64h256c38.4 0 64-25.6 64-64v-64c0-38.4-25.6-64-64-64H256c-38.4 0-64 25.6-64 64v64c0 38.4 25.6 64 64 64z" horiz-adv-x="1024" />
<glyph glyph-name="json" unicode="&#58915;" d="M921.6 716.8L798.72 844.8c-30.72 30.72-76.8 51.2-117.76 51.2H256c-40.96 0-71.68-35.84-71.68-71.68v-353.28h56.32V824.32c0 10.24 5.12 15.36 15.36 15.36h435.2v-235.52h225.28v-660.48c0-10.24-5.12-15.36-15.36-15.36H256c-10.24 0-15.36 5.12-15.36 15.36v107.52H184.32v-102.4c0-40.96 30.72-76.8 71.68-76.8h645.12c40.96 0 71.68 35.84 71.68 71.68V568.32c-5.12 51.2-20.48 102.4-51.2 148.48z m-174.08-61.44V803.84c5.12 0 5.12-5.12 10.24-10.24l128-128 10.24-10.24h-148.48zM798.72 455.68H92.16c-20.48 0-35.84-20.48-35.84-40.96v-276.48c0-20.48 15.36-40.96 40.96-40.96h701.44c20.48 0 40.96 15.36 40.96 40.96V414.72c-5.12 20.48-20.48 40.96-40.96 40.96zM225.28 368.64v-133.12c0-15.36-5.12-30.72-15.36-40.96-10.24-10.24-25.6-15.36-40.96-15.36-10.24 0-20.48 0-30.72 5.12v35.84h20.48c5.12 0 10.24 0 15.36 5.12 5.12 0 5.12 5.12 5.12 5.12v143.36h46.08z m168.96-40.96l-35.84-10.24c-5.12 15.36-15.36 25.6-30.72 20.48-15.36 0-25.6-5.12-25.6-15.36 0-5.12 0-10.24 5.12-10.24 5.12-5.12 15.36-5.12 20.48-10.24 15.36 0 30.72-5.12 40.96-10.24 10.24-5.12 15.36-10.24 20.48-20.48 5.12-10.24 10.24-20.48 10.24-30.72 0-15.36-5.12-30.72-20.48-46.08-15.36-10.24-35.84-15.36-56.32-15.36-20.48 0-35.84 5.12-51.2 15.36-15.36 5.12-25.6 20.48-25.6 35.84l40.96 10.24c5.12-15.36 20.48-30.72 40.96-25.6 10.24 0 15.36 0 20.48 5.12 5.12 5.12 5.12 10.24 5.12 15.36 0 5.12 0 10.24-5.12 15.36-10.24 5.12-15.36 5.12-25.6 10.24-20.48 5.12-35.84 10.24-51.2 20.48-10.24 5.12-15.36 15.36-15.36 30.72s5.12 30.72 20.48 40.96c15.36 10.24 30.72 20.48 51.2 15.36 25.6 5.12 56.32-10.24 66.56-40.96z m102.4-148.48c-25.6 0-46.08 10.24-56.32 30.72-15.36 20.48-20.48 46.08-20.48 71.68 0 25.6 5.12 51.2 20.48 66.56 15.36 20.48 35.84 30.72 61.44 25.6 25.6 0 46.08-10.24 61.44-30.72 15.36-20.48 20.48-40.96 20.48-66.56s-5.12-51.2-20.48-71.68c-20.48-15.36-40.96-25.6-66.56-25.6z m0 158.72c-20.48 0-30.72-20.48-30.72-61.44s10.24-61.44 35.84-61.44c20.48 0 30.72 20.48 30.72 61.44s-10.24 61.44-35.84 61.44z m250.88 30.72V179.2h-35.84l-71.68 128V179.2h-30.72v189.44h46.08l66.56-112.64v107.52l25.6 5.12z" horiz-adv-x="1024" />
<glyph glyph-name="fullscreen" unicode="&#58952;" d="M704 480l188.2 184.4 99.8-99.8V864H704l88.4-96-180.4-192 92-96z m-96-288l184.4-188.2-100-99.8H992V192l-96-88.4-192 180.4-96-92z m-288 96l-188.2-184.4-99.8 100V-96h288l-88.4 96 180.4 192-92 96z m96 288l-184.4 188.2 100 99.8H32v-288l96 88.4 192-180.4 96 92z" horiz-adv-x="1024" />
<glyph glyph-name="broken" unicode="&#59821;" d="M880.71104 160a144.096 144.096 0 0 1-134.08-95.008L746.31104 64h-185.6V800H279.75104c-20.352 56.416-73.44 96-135.776 96A144 144 0 1 1 279.43104 703.008L279.75104 704h184.96v-732.8h279.68c19.424-58.08 73.344-99.2 136.864-99.2a144 144 0 0 1 0 288h-0.576 0.032zM144.71104 694.4a57.6 57.6 0 1 0 57.6 57.6 57.6 57.6 0 0 0-57.6-57.6z m736-736a57.6 57.6 0 1 0 57.6 57.6 57.6 57.6 0 0 0-57.6-57.6z" horiz-adv-x="1025" />
<glyph glyph-name="curve" unicode="&#59824;" d="M927.488273 152.021587V320.758959c0 264.73871-214.628824 479.367534-479.367534 479.367534H279.383367c-20.325183 56.341664-73.343233 95.873507-135.597097 95.873507A143.81026 143.81026 0 1 1 279.063788 703.262293L279.383367 704.252986H448.120739c211.784577 0 383.494028-171.709451 383.494027-383.494027v-169.376529c-56.341664-20.325183-95.873507-73.343233-95.873506-135.597097a143.81026 143.81026 0 1 1 192.737706 135.277518L927.488273 151.38243zM144.5213 694.665636a57.524104 57.524104 0 1 0 57.524104 57.524104 57.524104 57.524104 0 0 0-57.524104-57.524104z m735.03022-735.03022a57.524104 57.524104 0 1 0 57.524104 57.524104 57.524104 57.524104 0 0 0-57.524104-57.524104z" horiz-adv-x="1024" />
<glyph glyph-name="paste" unicode="&#59747;" d="M320 528c0 61.758 50.244 112 112 112h272V784c0 26.51-21.49 48-48 48h-161.22C472.612 870.22 431.274 896 384 896s-88.612-25.78-110.78-64H112C85.49 832 64 810.51 64 784v-672c0-26.51 21.49-48 48-48h208V528z m64 288c26.51 0 48-21.49 48-48s-21.49-48-48-48-48 21.49-48 48 21.49 48 48 48z m368-496h208v-400c0-26.51-21.49-48-48-48H432c-26.51 0-48 21.49-48 48V528c0 26.51 21.49 48 48 48h272v-208c0-26.4 21.6-48 48-48z m208 76.118V384h-192v192h12.118a48 48 0 0 0 33.94-14.058l131.882-131.882a48.004 48.004 0 0 0 14.06-33.942z" horiz-adv-x="1024" />
<glyph glyph-name="group" unicode="&#59669;" d="M912 75.9V692.1c28 9.9 48 36.6 48 67.9 0 39.8-32.2 72-72 72-31.3 0-58-20-67.9-48H203.9C194 812 167.3 832 136 832c-39.8 0-72-32.2-72-72 0-31.3 20-58 48-67.9v-616.2C84 66 64 39.3 64 8c0-39.8 32.2-72 72-72 31.3 0 58 20 67.9 48h616.2c9.9-28 36.6-48 67.9-48 39.8 0 72 32.2 72 72 0 31.3-20 58-48 67.9zM888 784c13.3 0 24-10.7 24-24s-10.7-24-24-24-24 10.7-24 24 10.7 24 24 24zM136-16c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24z m0 752c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24z m704-680H184V712h656v-656z m48-72c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zM288 422h448c8.8 0 16 7.2 16 16V614c0 8.8-7.2 16-16 16H288c-8.8 0-16-7.2-16-16v-176c0-8.8 7.2-16 16-16z m56 136h336v-64H344v64zM288 138h448c8.8 0 16 7.2 16 16V330c0 8.8-7.2 16-16 16H288c-8.8 0-16-7.2-16-16v-176c0-8.8 7.2-16 16-16z m56 136h336v-64H344v64z" horiz-adv-x="1024" />
<glyph glyph-name="ungroup" unicode="&#59671;" d="M736 346H288c-8.8 0-16-7.2-16-16v-176c0-8.8 7.2-16 16-16h448c8.8 0 16 7.2 16 16V330c0 8.8-7.2 16-16 16z m-56-136H344v64h336v-64zM888 80c-39.8 0-72-32.2-72-72s32.2-72 72-72 72 32.2 72 72-32.2 72-72 72z m0-96c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zM736 630H288c-8.8 0-16-7.2-16-16v-176c0-8.8 7.2-16 16-16h448c8.8 0 16 7.2 16 16V614c0 8.8-7.2 16-16 16z m-56-136H344v64h336v-64zM888 688c39.8 0 72 32.2 72 72s-32.2 72-72 72-72-32.2-72-72 32.2-72 72-72z m0 96c13.3 0 24-10.7 24-24s-10.7-24-24-24-24 10.7-24 24 10.7 24 24 24zM136 832c-39.8 0-72-32.2-72-72s32.2-72 72-72 72 32.2 72 72-32.2 72-72 72z m0-96c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zM136 80c-39.8 0-72-32.2-72-72s32.2-72 72-72 72 32.2 72 72-32.2 72-72 72z m0-96c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24z" horiz-adv-x="1024" />
<glyph glyph-name="arrow-dropdown" unicode="&#58881;" d="M512 107.51958124999999l-377.06160075 377.06160074L222.88801761 572.5308003600001 512 283.41881802 801.11198239 572.5308003600001 889.06160075 484.58118199z" horiz-adv-x="1024" />
</font>
</defs></svg>

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@@ -0,0 +1,93 @@
<template>
<button
class="top-button"
@click="handleClick"
:disabled="buttonDisabled"
:class="[
type ? 'top-button--' + type : '',
buttonSize ? 'top-button--' + buttonSize : '',
{
'is-disabled': buttonDisabled,
'is-plain': plain
}
]"
>
<span><slot></slot></span>
</button>
</template>
<script>
export default {
name: 'TopButton',
props: {
type: {
type: String,
default: 'default'
},
size: {
type: String,
default: ''
},
disabled: {
type: Boolean,
default: false
},
plain: {
type: Boolean,
default: false
}
},
computed: {
buttonSize() {
return this.size
},
buttonDisabled() {
return this.disabled
}
},
methods: {
handleClick(evt) {
this.$emit('click', evt)
}
}
}
</script>
<style lang="scss" scoped>
.top-button {
display: inline-block;
line-height: 1;
white-space: nowrap;
cursor: pointer;
background: #fff;
border: 1px solid #dcdfe6;
color: #606266;
-webkit-appearance: none;
text-align: center;
-webkit-box-sizing: border-box;
box-sizing: border-box;
outline: 0;
margin: 0;
-webkit-transition: .1s;
transition: .1s;
font-weight: 500;
padding: 12px 20px;
font-size: 14px;
border-radius: 4px;
}
.top-button:focus, .top-button:hover {
color: #409eff;
border-color: #c6e2ff;
background-color: #ecf5ff;
}
.top-button--mini, .top-button--mini.is-round {
padding: 7px 15px;
}
.top-button--mini, .top-button--small {
font-size: 12px;
border-radius: 3px;
}
</style>

View File

@@ -0,0 +1,79 @@
<template>
<div class="cc-checkbox" :class="{ 'checkbox-checked': checkVal }">
<input
id="checkbox"
type="checkbox"
v-model="checkVal"
@change="handleChange"
/>
<label for="checkbox"></label>
<slot></slot>
</div>
</template>
<script>
export default {
name: 'CcCheckbox',
data() {
return {
checkVal: false
}
},
methods: {
handleChange() {
this.$emit('change', this.checkVal)
}
}
}
</script>
<style lang="scss" scoped>
.cc-checkbox {
display: inline-block;
color: #606266;
font-size: 14px;
input[type='checkbox'] + label {
margin: 0 8px;
cursor: pointer;
}
input[type='checkbox'] + label::before {
content: '\a0';
display: inline-block;
position: relative;
border: 1px solid #dcdfe6;
border-radius: 2px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
width: 14px;
height: 14px;
line-height: 0.9;
background-color: #fff;
z-index: 1;
-webkit-transition: border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46);
transition: border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46);
}
input[type='checkbox']:checked + label::before {
content: '\2714';
color: #fff;
background-color: #409eff;
border-color: #409eff;
}
input[type='checkbox'] {
opacity: 0;
outline: 0;
position: absolute;
margin: 0;
width: 0;
height: 0;
z-index: -1;
}
}
.checkbox-checked {
color: #409eff;
}
</style>

View File

@@ -0,0 +1,228 @@
<template>
<div class="graph-op">
<i v-for="edgeItem in dropdownItems " :class="edgeItem.class" v-on:title="edgeItem.label" style="width: 120px;"
@click="onItemClick(edgeItem.guid, $event)">&nbsp;&nbsp;{{edgeItem.label}}</i>
</div>
</template>
<script>
import $ from 'jquery'
export default {
name: 'CCDropdownList',
props: {
dropdownItems: {
type: Array,
default() {
return [
]
}
},
defaultIndex: {
type: Number,
default() {
return 0
}
}
},
data() {
return {
activeIndex: this.defaultIndex,
timeout: null
}
},
watch: {
activeIndex() {
this.$emit('change', this.activeIndex)
}
},
mounted() {
// $('.iconfonts')[0].style.backgroundColor = '#ebeef2'
},
methods: {
onItemClick(index,e) {
let lineList = $('.iconfonts')
for (let i=0;i<lineList.length;i++){
lineList[i].style.backgroundColor = '#ffffff'
}
if (e.path[0].style.backgroundColor=='rgb(255, 255, 255)'){
e.path[0].style.backgroundColor = '#ebeef2'
}
if (index !== this.activeIndex) {
this.activeIndex = index
}
}
}
}
</script>
<style lang="scss" scoped>
.iconfonts {
color: #666666;
font-size: 12px;
line-height: 20px;
height: 20px;
padding-bottom: 2px;
}
.graph-op {
display: inline-block;
vertical-align: middle;
i {
width: 20px;
height: 20px;
margin: 0 6px;
line-height: 20px;
color: #a8a8a8;
text-align: center;
border-radius: 2px;
display: inline-block;
border: 1px solid rgba(2, 2, 2, 0);
}
i:hover {
cursor: pointer;
border: 1px solid #E9E9E9;
}
.disabled {
color: rgba(0, 0, 0, 0.25);
}
.disabled:hover {
cursor: not-allowed;
border: 1px solid rgba(2, 2, 2, 0);
}
.icon-select {
background-color: #EEEEEE;
}
.separator {
margin: 4px;
border-left: 1px solid #E9E9E9;
}
}
.cc-dropdown {
position: relative;
display: inline-block;
min-width: 100px;
text-align: center;
a {
color: #000;
text-decoration: none;
}
ul,
li {
list-style: none;
}
span {
display: block;
z-index: 2;
height: 30px;
line-height: 30px;
background-color: transparent;
font-size: 14px;
border-radius: 5px;
-webkit-transition: all .2s ease-in;
transition: all .2s ease-in;
}
span a:after {
content: " ";
display: inline-block;
width: 0;
height: 0;
font-size: 0;
line-height: 0;
border-bottom: solid 6px #000;
border-left: solid 4px transparent;
border-right: solid 4px transparent;
vertical-align: 3px;
margin-left: 10px;
-webkit-transition: all .2s ease-in;
transition: all .2s ease-in;
}
}
.cc-dropdown-menu {
position: absolute;
display: none;
top: 50px;
left: 0;
right: 0;
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.2);
border-radius: 5px;
z-index: 1;
/* 一个很重要的三角形*/
li:first-child:before {
display: block; /* 独占一行 */
content: " ";
font-size: 0;
line-height: 0;
margin: 0 auto; /* 居中 */
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.2); /* 配合整体一样的投影 */
background-color: #fff;
width: 10px;
height: 10px;
-webkit-transform: rotate(45deg);
transform: rotate(45deg); /* 一个正方形倾斜四十五度就是三角了但是要把下半部分藏起来 */
position: relative;
top: -5px; /* 露出上半部分*/
z-index: 1; /* 隐藏下半部分 */
-webkit-transition: all .2s ease-in;
transition: all .2s ease-in;
}
li a {
color: #888;
line-height: 46px;
border-bottom: solid 1px #eee;
font-size: 14px;
display: block;
background-color: #fff; /* 要有背景色才能盖住呀*/
position: relative;
z-index: 2; /* 这里很重要 要挡住三角形的下半部分*/
-webkit-transition: all .2s ease-in;
transition: all .2s ease-in;
}
/* 以下两块控制第一个和最后一个li要圆角因为最外边的div没有overflow 也不可以overflow*/
li:first-child a {
border-top-left-radius: 5px;
border-top-right-radius: 5px;
margin-top: -10px;
}
li:last-child a {
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
border-bottom: none;
}
/*hover事件给了li先改变三角 再改变a*/
li:hover:before {
background-color: #ecf5ff;
}
li:hover a {
background-color: #ecf5ff;
color: #66b1ff;
}
}
.cc-dropdown:hover span {
background-color: transparent;
}
.cc-dropdown:hover span a:after {
-webkit-transform: rotate(180deg);
transform: rotate(180deg);
}
</style>

View File

@@ -0,0 +1,17 @@
/**
* @author: clay
* @data: 2019/11/14
* @description: ClayTop内部的通用组件
*/
import Checkbox from './checkbox'
import Button from './button'
import Dropdown from './dropdown'
import Loading from './loading'
export {
Checkbox,
Button,
Dropdown,
Loading
}

View File

@@ -0,0 +1,92 @@
<template>
<div class="model-overlay">
<div class="cc-loading">
<svg class="circular" viewBox="0 0 50 50">
<circle cx="25" cy="25" r="20" fill="none" stroke="#409EFF" stroke-width="5%" stroke-linecap="round"/>
</svg>
</div>
<span class="loading-text">{{ loadingText }}</span>
</div>
</template>
<script>
export default {
name: 'CcLoading',
props: {
loadingText: {
type: String,
default: '加载中...'
}
}
}
</script>
<style lang="scss" scoped>
.model-overlay {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
text-align: center;
z-index: 1000;
overflow: auto;
background-color: transparent;
}
.cc-loading {
position: absolute;
width: 50px;
top: 45%;
left: 50%;
&:before {
content: '';
display: block;
padding-top: 100%;
}
.circular {
position: absolute;
top: 0;
left: 0;
animation: rotate 2s linear infinite;
}
circle {
animation: circle-dash 1.5s ease-in-out infinite;
}
}
@keyframes circle-dash {
0% {
stroke-dasharray: 1, 125;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 100, 125;
stroke-dashoffset: -25px;
}
100% {
stroke-dasharray: 100, 125;
stroke-dashoffset: -125px;
}
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.loading-text {
position: absolute;
top: calc(45% + 60px);
left: calc(50% - 10px);
color: #409EFF;
font-size: 14px;
}
</style>

View File

@@ -0,0 +1,249 @@
import utils from '../utils'
/**
* @author: clay
* @data: 2021/5/14 23:20
* @email: clay@hchyun.com
* @description: node
*/
const isInBBox = (point, bbox) => {
const {
x,
y
} = point;
const {
minX,
minY,
maxX,
maxY
} = bbox;
return x < maxX && x > minX && y > minY && y < maxY;
};
let vm = null;
const sendThis = (_this) => {
vm = _this;
};
export default {
sendThis,
name: 'dice-er-node',
options: {
getDefaultCfg() {
return {
multiple: true,
start:0,
};
},
getEvents() {
return {
itemHeight: 50,
wheel: "scroll",
"node:click": "onNodeClick",
"edge:click": "onEdgeClick",
"node:contextmenu": "onNodeRightClick",
"edge:contextmenu": "onEdgeRightClick",
"canvas:click": "onCanvasClick",
};
},
scroll(e) {
e.preventDefault()
const {
graph
} = this;
const nodes = graph.getNodes().filter((n) => {
const bbox = n.getBBox();
return isInBBox(graph.getPointByClient(e.clientX, e.clientY), bbox);
});
if (nodes) {
nodes.forEach((node) => {
const model = node.getModel();
if (model.columns.length < 9 ) {
return;
}
const idx = model.startIndex || 0;
this.start=idx
let startX = model.startX || 0.5;
let startIndex = idx + e.deltaY * 0.02;
if ((model.columns.length-idx)<10 && startIndex > idx){
return;
}
startX -= e.deltaX;
if (startIndex < 0) {
startIndex = 0;
}
if (startX > 0) {
startX = 0;
}
if (startIndex > model.columns.length - 1) {
startIndex = model.columns.length - 1;
}
graph.update(node, {
startIndex,
startX,
});
});
}
},
onNodeClick(event) {
this.shrinkage(event)
vm.currentFocus = "node";
vm.rightMenuShow = false;
this.updateVmData(event);
},
/**
* 点击连线
* @param event
*/
onEdgeClick(event) {
let clickEdge = event.item;
clickEdge.setState("selected", !clickEdge.hasState("selected"));
vm.currentFocus = "edge";
this.updateVmData(event);
},
onNodeRightClick(event) {
let graph = vm.graph;
let clickNode = event.item;
let clickNodeModel = clickNode.getModel();
let selectedNodes = graph.findAllByState("node", "selected");
let selectedNodeIds = selectedNodes.map(item => {
return item.getModel().id;
});
vm.selectedNode = clickNode;
// 如果当前点击节点是之前选中的某个节点,就进行下面的处理
if (selectedNodes.length > 1 && selectedNodeIds.indexOf(clickNodeModel.id) > -1) {
vm.rightMenuShow = true;
let rightMenu = vm.$refs.rightMenu;
rightMenu.style.left = event.clientX + "px";
rightMenu.style.top = event.clientY + "px";
} else {
// 隐藏右键菜单
vm.rightMenuShow = false;
// 先取消所有节点的选中状态
selectedNodes.forEach(node => {
node.setState("selected", false);
});
// 再添加该节点的选中状态
clickNode.setState("selected", true);
vm.currentFocus = "node";
this.updateVmData(event);
}
graph.paint();
},
/**
*
* @param event
*/
onEdgeRightClick(event) {
let graph = vm.graph;
let clickEdge = event.item;
let clickEdgeModel = clickEdge.getModel();
let selectedEdges = graph.findAllByState("edge", "selected");
// 如果当前点击节点不是之前选中的单个节点,才进行下面的处理
if (!(selectedEdges.length === 1 && clickEdgeModel.id === selectedEdges[0].getModel().id)) {
// 先取消所有节点的选中状态
graph.findAllByState("edge", "selected").forEach(edge => {
edge.setState("selected", false);
});
// 再添加该节点的选中状态
clickEdge.setState("selected", true);
vm.currentFocus = "edge";
this.updateVmData(event);
}
let point = { x: event.x, y: event.y };
},
onCanvasClick() {
vm.currentFocus = "canvas";
vm.rightMenuShow = false;
},
updateVmData(event) {
if (event.item._cfg.type === "node") {
let clickNode = event.item;
if (clickNode.hasState("selected")) {
let clickNodeModel = clickNode.getModel();
vm.selectedNode = clickNode;
let nodeAppConfig = { ...vm.nodeAppConfig };
Object.keys(nodeAppConfig).forEach(function(key) {
nodeAppConfig[key] = "";
});
vm.selectedNodeParams = {
label: clickNodeModel.label || "",
columns:clickNodeModel.columns,
appConfig: { ...nodeAppConfig, ...clickNodeModel.appConfig }
};
}
} else if (event.item._cfg.type === "edge") {
// 更新vm的data: selectedEdge 和 selectedEdgeParams
let clickEdge = event.item;
if (clickEdge.hasState("selected")) {
let clickEdgeModel = clickEdge.getModel();
vm.selectedEdge = clickEdge;
let edgeAppConfig = { ...vm.edgeAppConfig };
Object.keys(edgeAppConfig).forEach(function(key) {
edgeAppConfig[key] = "";
});
vm.selectedEdgeParams = {
label: clickEdgeModel.label || "",
relationalItem: clickEdgeModel.relationalItem,
sourceColumn:clickEdgeModel.sourceColumn,
targetColumn:clickEdgeModel.targetColumn,
appConfig: { ...edgeAppConfig, ...clickEdgeModel.appConfig }
};
}
}
},
shrinkage(e){
const {
graph
} = this;
const item = e.item;
const shape = e.shape;
if (!item) {
return;
}
if (shape.get("name") === "collapse") {
graph.updateItem(item, {
collapsed: true,
size: [300, 50],
height:44,
});
setTimeout(() => graph.layout(), 100);
} else if (shape.get("name") === "expand") {
let updateGraph = graph.updateItem(item, {
collapsed: false,
size: [300, 500],
height:316,
});
// utils.anchor.update({height:100,}, graph)
setTimeout(() => graph.layout(), 100);
}else {
// eslint-disable-next-line no-unused-vars
const model = item.getModel();
// console.log(JSON.stringify(model));
// console.log(model.style.default.fill = '#4eb922');
// console.log(model.style.selected.shadowColor = '#4eb922');
}
},
moves(e) {
const name = e.shape.get("name");
const item = e.item;
if (!name.startsWith("marker")){
if (name && name.startsWith("item")) {
this.graph.updateItem(item, {
selectedIndex: Number(name.split("-")[1]),
});
} else {
this.graph.updateItem(item, {
selectedIndex: NaN,
});
}
}
},
}
}

View File

@@ -0,0 +1,220 @@
/**
* @author: clay
* @data: 2019/07/16
* @description: edit mode: 通过拖拽节点上的锚点添加连线
*/
import utils from "../utils";
// 用来获取调用此js的vue组件实例this
let vm = null;
const sendThis = (_this) => {
vm = _this;
};
import G6 from "@antv/g6";
import theme from "../theme";
export default {
sendThis, // 暴露函数
name: "drag-add-edge",
options: {
getEvents() {
return {
"node:mousedown": "onNodeMousedown",
"node:mouseup": "onNodeMouseup",
"edge:mouseup": "onEdgeMouseup",
"mousemove": "onMousemove"
};
},
onNodeMousedown(event) {
let self = this;
// 交互过程中的信息
self.evtInfo = {
action: null,
node: event.item,
target: event.target,
};
if (self.evtInfo.target && self.evtInfo.target.attrs.name) {
// todo...未来可能针对锚点增加其它功能(例如拖拽调整大小)
switch (self.evtInfo.target.attrs.name) {
case "anchor":
self.evtInfo.action = "drawEdge";
break;
}
}
if (self.evtInfo && self.evtInfo.action) {
self[self.evtInfo.action].start.call(self, event);
}
},
onNodeMouseup(event) {
let self = this;
if (self.evtInfo && self.evtInfo.action) {
self[self.evtInfo.action].stop.call(self, event);
}
},
onEdgeMouseup(event) {
let self = this;
if (self.evtInfo && self.evtInfo.action === "drawEdge") {
self[self.evtInfo.action].stop.call(self, event);
}
},
onMousemove(event) {
let self = this;
if (self.evtInfo && self.evtInfo.action) {
self[self.evtInfo.action].move.call(self, event);
}
},
drawEdge: {
isMoving: false,
currentLine: null,
start: function(event) {
let self = this;
let themeStyle = theme.defaultStyle; // todo...先使用默认主题,后期可能增加其它风格的主体
// ************** 暂存【连线】前的数据状态 start **************
let graph = vm.graph;
self.historyData = JSON.stringify(graph.save());
// ************** 暂存【连线】前的数据状态 end **************
let sourceAnchor = self.evtInfo.node.getAnchorPoints();
let sourceNodeModel = self.evtInfo.node.getModel();
// 锚点数据
let anchorPoints = self.evtInfo.node.getAnchorPoints();
// 处理线条目标点
if (anchorPoints && anchorPoints.length) {
// 获取距离指定坐标最近的一个锚点
sourceAnchor = self.evtInfo.node.getLinkPoint({
x: event.x,
y: event.y
})
}
let relational = vm.relationalMap.map(item => {
if (item.mainId === sourceNodeModel.tableId) {
return item
}
})
//item.columnName+':'+item.columnComment
let columns = []
for (let i = 0; i < sourceNodeModel.columns.length; i++) {
let column = {
columnName:sourceNodeModel.columns[i].columnName,
columnComment:sourceNodeModel.columns[i].columnComment
}
columns.push(column)
}
self.drawEdge.currentLine = self.graph.addItem("edge", {
// id: G6.Util.uniqueId(), // 这种生成id的方式有bug会重复
id: utils.generateUUID(),
// 起始节点
source: sourceNodeModel.id,
sourceColumn:columns,
sourceAnchor: sourceAnchor ? sourceAnchor.anchorIndex : "",
// 终止节点/位置
relational: relational,
target: {
x: event.x,
y: event.y
},
type: self.graph.$C.edge.type || "top-cubic",
style: themeStyle.edgeStyle.default|| self.graph.$C.edge.style
});
self.drawEdge.isMoving = true;
},
move(event) {
let self = this;
if (self.drawEdge.isMoving && self.drawEdge.currentLine) {
self.graph.updateItem(self.drawEdge.currentLine, {
target: {
x: event.x,
y: event.y
}
});
}
},
stop(event) {
let self = this;
if (self.drawEdge.isMoving) {
if (self.drawEdge.currentLine === event.item) {
// 画线过程中点击则移除当前画线
self.graph.removeItem(event.item);
} else {
let targetNode = event.item;
let targetNodeModel = targetNode.getModel();
let targetAnchor = null;
// 锚点数据
let anchorPoints = targetNode.getAnchorPoints();
// 处理线条目标点
let relational = self.drawEdge.currentLine.getModel().relational
let starts = false;
let relationalItem = null;
relational.map(item => {
if (item){
if (item.childId === targetNodeModel.tableId) {
starts = true
relationalItem = item
}
}
})
if (starts) {
if (anchorPoints && anchorPoints.length) {
// 获取距离指定坐标最近的一个锚点
targetAnchor = targetNode.getLinkPoint({
x: event.x,
y: event.y
});
}
let columns = []
for (let i = 0; i < targetNodeModel.columns.length; i++) {
let column = {
columnName:targetNodeModel.columns[i].columnName,
columnComment:targetNodeModel.columns[i].columnComment
}
columns.push(column)
}
self.graph.updateItem(self.drawEdge.currentLine, {
target: targetNodeModel.id,
relationalItem:relationalItem,
targetAnchor: targetAnchor ? targetAnchor.anchorIndex : "",
targetColumn: columns,
});
// ************** 记录historyData的逻辑 start **************
if (this.historyData) {
let graph = this.graph;
// 如果当前点过【撤销】了,拖拽节点后没有【重做】功能
// 重置undoCount拖拽后的数据给(当前所在historyIndex + 1),且清空这个时间点之后的记录
if (vm.undoCount > 0) {
vm.historyIndex = vm.historyIndex - vm.undoCount; // 此时的historyIndex应当更新为【撤销】后所在的索引位置
for (let i = 1; i <= vm.undoCount; i++) {
let key = `graph_history_${vm.historyIndex + i}`;
vm.removeHistoryData(key);
}
vm.undoCount = 0;
} else {
// 正常顺序执行的情况,记录拖拽前的数据状态
let key = `graph_history_${vm.historyIndex}`;
vm.addHistoryData(key, this.historyData);
}
// 记录拖拽后的数据状态
vm.historyIndex += 1;
let key = `graph_history_${vm.historyIndex}`;
let currentData = JSON.stringify(graph.save());
vm.addHistoryData(key, currentData);
}
}else {
self.graph.removeItem(self.drawEdge.currentLine);
vm.msgError("两表之间无关联关系")
}
// ************** 记录historyData的逻辑 end **************
}
}
self.drawEdge.currentLine = null;
self.drawEdge.isMoving = false;
self.evtInfo = null;
}
}
}
};

View File

@@ -0,0 +1,53 @@
/**
* @author: clay
* @data: 2019/07/16
* @description: edit mode: 鼠标拖动节点的交互(记录拖拽前后的数据,用于【撤销】和【重做】)
*/
// 用来获取调用此js的vue组件实例this
let vm = null
const sendThis = (_this) => {
vm = _this
}
export default {
sendThis, // 暴露函数
name: 'drag-event-edit',
options: {
getEvents() {
return {
'node:dragstart': 'onNodeDragstart',
'node:dragend': 'onNodeDragend'
}
},
onNodeDragstart() {
let graph = vm.graph
this.historyData = JSON.stringify(graph.save())
},
onNodeDragend() {
if (this.historyData) {
let graph = this.graph
// 如果当前点过【撤销】了,拖拽节点后没有【重做】功能
// 重置undoCount拖拽后的数据给(当前所在historyIndex + 1),且清空这个时间点之后的记录
if (vm.undoCount > 0) {
vm.historyIndex = vm.historyIndex - vm.undoCount // 此时的historyIndex应当更新为【撤销】后所在的索引位置
for (let i = 1; i <= vm.undoCount; i++) {
let key = `graph_history_${vm.historyIndex + i}`
vm.removeHistoryData(key)
}
vm.undoCount = 0
} else {
// 正常顺序执行的情况,记录拖拽前的数据状态
let key = `graph_history_${vm.historyIndex}`
vm.addHistoryData(key, this.historyData)
}
// 记录拖拽后的数据状态
vm.historyIndex += 1
let key = `graph_history_${vm.historyIndex}`
let currentData = JSON.stringify(graph.save())
vm.addHistoryData(key, currentData)
}
}
}
}

View File

@@ -0,0 +1,74 @@
/**
* @author: clay
* @data: 2019/07/16
* @description: edit mode: 悬浮交互
*/
// 用来获取调用此js的vue组件实例this
let vm = null;
var hourItem = null;
const sendThis = (_this) => {
vm = _this;
};
export default {
sendThis, // 暴露函数
name: "hover-event-edit",
options: {
getEvents() {
return {
"node:mouseover": "onNodeHover",
"node:mouseout": "onNodeOut",
"node:mouseleave":"onNodeLeave",
};
},
onNodeHover(event) {
let graph = vm.graph;
let hoverNode = event.item;
const name = event.shape.get("name");
const item = event.item;
if (name && name.startsWith("item")) {
graph.updateItem(item, {
selectedIndex: Number(name.split("-")[1])
});
} else {
graph.updateItem(item, {
selectedIndex: NaN
});
}
if (name && name.startsWith("marker")) {
hoverNode.setState("hover", true, graph);
hourItem=hoverNode;
}else {
if (hourItem!=null){
try {
hourItem.setState("hover", false)
}catch (e){
}
}
}
},
onNodeOut(event) {
const name = event.shape.get("name");
let hoverNode = event.item;
if (name && name.startsWith("marker")) {
hoverNode.setState("hover", false);
}
if (hourItem!=null&&hourItem.destroyed){
try {
hourItem.setState("hover", false)
}catch (e){
}
}
hoverNode.setState("hover", false);
},
onNodeLeave(event) {
if (hourItem!=null){
try {
hourItem.setState("hover", false)
}catch (e){
}
}
}
}
};

View File

@@ -0,0 +1,28 @@
/**
* @author: clay
* @data: 2019/07/16
* @description: register behaviors
*/
import dragAddEdge from './drag-add-edge'
import hoverEventEdit from './hover-event-edit'
import dragEventEdit from './drag-event-edit'
import keyupEventEdit from './keyup-event-edit'
import diceErNode from './dice-er-node'
const obj = {
dragAddEdge,
hoverEventEdit,
dragEventEdit,
keyupEventEdit,
diceErNode,
}
export default {
obj,
register(G6) {
Object.values(obj).map(item => {
G6.registerBehavior(item.name, item.options)
})
}
}

View File

@@ -0,0 +1,63 @@
/**
* @author: clay
* @data: 2019/07/16
* @description: edit mode: 键盘事件的交互,主要是删除节点和连线(记录删除前后的数据,用于【撤销】和【重做】)
*/
// 用来获取调用此js的vue组件实例this
let vm = null
const sendThis = (_this) => {
vm = _this
}
export default {
sendThis, // 暴露函数
name: 'keyup-event-edit',
options: {
getEvents() {
return {
'keyup': 'onKeyup'
}
},
onKeyup(event) {
let graph = this.graph
let selectedNodes = graph.findAllByState('node', 'selected')
let selectedEdges = graph.findAllByState('edge', 'selected')
if (event.keyCode === 46 && (selectedNodes.length > 0 || selectedEdges.length > 0)) {
// ************** 记录【删除】前的数据状态 start **************
let historyData = JSON.stringify(graph.save())
let key = `graph_history_${vm.historyIndex}`
vm.addHistoryData(key, historyData)
// ************** 记录【删除】前的数据状态 end **************
// 开始删除
for (let i = 0; i < selectedNodes.length; i++) {
graph.removeItem(selectedNodes[i])
}
for (let i = 0; i < selectedEdges.length; i++) {
graph.removeItem(selectedEdges[i])
}
// ************** 记录【删除】后的数据状态 start **************
// 如果当前点过【撤销】了,拖拽节点后将取消【重做】功能
// 重置undoCount【删除】后的数据状态给(当前所在historyIndex + 1),且清空这个时间点之后的记录
if (vm.undoCount > 0) {
vm.historyIndex = vm.historyIndex - vm.undoCount // 此时的historyIndex应当更新为【撤销】后所在的索引位置
for (let i = 1; i <= vm.undoCount; i++) {
let key = `graph_history_${vm.historyIndex + i}`
vm.removeHistoryData(key)
}
vm.undoCount = 0
}
// 记录【删除】后的数据状态
vm.historyIndex += 1
key = `graph_history_${vm.historyIndex}`
let currentData = JSON.stringify(graph.save())
vm.addHistoryData(key, currentData)
// ************** 记录【删除】后的数据状态 end **************
}
}
}
}

View File

@@ -0,0 +1,13 @@
/**
* @author: clay
* @data: 2019/08/16
* @description: 线条的后期设置
*/
export default {
type: 'top-cubic',
style: {
startArrow: false,
endArrow: true
}
}

View File

@@ -0,0 +1,11 @@
/**
* @author: clay
* @data: 2019/08/16
* @description: 配置
*/
import edge from './edge'
export default {
edge
}

View File

@@ -0,0 +1,30 @@
/**
* @author: Clay
* @data: 2019/07/18
* @description: 线公共方法
*/
import utils from '../utils'
export default {
draw(cfg, group) {
const { startPoint, endPoint } = cfg
const keyShape = group.addShape('path', {
className: 'edge-shape',
attrs: {
...cfg.style,
path: [
['M', startPoint.x, startPoint.y],
['L', endPoint.x, endPoint.y]
]
},
name: 'edge-shape'
})
keyShape.attrs.endArrow = true
return keyShape
},
setState(name, value, item) {
// 设置边状态
utils.edge.setState(name, value, item)
}
}

View File

@@ -0,0 +1,18 @@
/**
* @author: clay
* @data: 2019/07/18
* @description: register edges
*/
import topCubic from './top-cubic'
const obj = {
topCubic
}
export default function(G6) {
Object.values(obj).map(item => {
G6.registerEdge(item.name, item.options, item.extendName)
})
}

View File

@@ -0,0 +1,14 @@
/**
* @author: Clay
* @data: 2019/07/18
* @description: 曲线
*/
import base from './base'
export default {
name: 'top-cubic',
extendName: 'cubic',
options: {
...base
}
}

View File

@@ -0,0 +1,160 @@
/**
* @author: clay
* @data: 2019/07/05
* @description: 图的布局方式/图的初始化
*/
import d3 from '../plugins/d3-installer'
import theme from '../theme'
/**
* 图的布局方式/图的初始化
* @type {{commonGraph: (function(*, *): G6.Graph)}}
*/
const initGraph = {
/**
* 一般布局
* @param G6
* @param options
* @returns {G6.Graph}
*/
commonGraph: function(G6, options) {
let graphData = options.graphData
let themeStyle = theme.defaultStyle // todo...先使用默认主题,后期可能增加其它风格的主体
// 生成G6实例
let graph = new G6.Graph({
plugins: options.plugins,
container: options.container,
width: options.width,
height: options.height,
// layout: {
// type: 'random',
// width: options.width,
// height: options.height
// },
defaultNode: {
type: 'dice-er-box',
labelCfg: {
position: 'bottom'
}
},
defaultEdge: {
type: 'top-cubic',
labelCfg: {
position: 'center',
autoRotate: false
}
},
nodeStateStyles: themeStyle.nodeStyle,
// nodeStyle: {
// selected: {
// shadowColor: '#626262',
// shadowBlur: 8,
// shadowOffsetX: -1,
// shadowOffsetY: 3
// }
// },
edgeStateStyles:{
edgeStyle: {
default: {
stroke: '#e2e2e2',
lineWidth: 3,
lineAppendWidth: 10
},
selected: {
shadowColor: '#626262',
shadowBlur: 3
}
},
},
modes: options.modes
})
// 将 read 方法分解成 data() 和 render 方法,便于整个生命周期的管理
graph.read(graphData)
graph.render()
// 返回G6实例
return graph
},
/**
* 力导布局
* @param G6
* @param options
* @returns {*}
*/
forceLayoutGraph: function(resolve, G6, options) {
let graphData = options.graphData
let themeStyle = theme.defaultStyle // todo...先使用默认主题,后期可能增加其它风格的主体
// 生成G6实例
let graph = new G6.Graph({
container: options.container,
width: options.width,
height: options.height,
nodeStateStyles: themeStyle.nodeStyle,
edgeStateStyles: themeStyle.edgeStyle
})
// 初始化力导布局
let simulation = d3
.forceSimulation()
.force(
'link',
d3
.forceLink()
.id(function(d) {
return d.id
})
.distance(linkDistance)
.strength(0.5)
)
.force('charge', d3.forceManyBody().strength(-500).distanceMax(500).distanceMin(100))
.force('center', d3.forceCenter(options.width / 2, options.height / 2))
// 定义节点数据
simulation.nodes(graphData.nodes).on('tick', ticked)
// 定义连线数据
let edges = []
for (let i = 0; i < graphData.edges.length; i++) {
edges.push({
id: graphData.edges[i].id,
source: graphData.edges[i].source,
target: graphData.edges[i].target
})
}
simulation.force('link').links(edges)
graph.data(graphData)
graph.render()
function linkDistance(d) {
return 150
}
function ticked() {
// protect: planA: 移除事件监听器 planB: 手动停止力模拟
if (graph.destroyed) {
// simulation.nodes(graphData.nodes).on('tick', null)
simulation.stop()
return
}
if (!graph.get('data')) {
// 若是第一次渲染,定义数据,渲染
graph.data(graphData)
graph.render()
} else {
// 后续渲染,直接刷新所有点和边的位置
graph.refreshPositions()
}
}
// 控制时间: 只布局10秒
let t = setTimeout(function() {
simulation.stop()
resolve(graph)
}, 10000)
// 判断force-layout结束
simulation.on('end', () => {
clearTimeout(t)
resolve(graph)
})
}
}
export default initGraph

View File

@@ -0,0 +1,286 @@
/**
* @author: clay
* @data: 2021/5/15 0:16
* @email: clay@hchyun.com
* @description: node
*/
import utils from '../utils/index'
let vm = null;
const sendThis = (_this) => {
vm = _this;
};
const itemHeight = 30;
export default {
sendThis,
name: 'dice-er-box',
options: {
setState(name, value, item) {
// 设置节点状态
utils.node.setState(name, value, item)
// 设置锚点状态
// if (vm.graphMode === 'edit') {
utils.anchor.setState(name, value, item)
// }
},
draw(cfg, group) {
const width = 250;
const height = 316;
const itemCount = 10;
const boxStyle = {
stroke: "#096DD9",
radius: 4,
};
const {
columns = [],
startIndex = 0,
selectedIndex,
collapsed,
icon,
} = cfg;
const list = columns;
const afterList = list.slice(
Math.floor(startIndex),
Math.floor(startIndex + itemCount - 1)
);
const offsetY = (0.5 - (startIndex % 1)) * itemHeight + 30;
group.addShape("rect", {
attrs: {
fill: boxStyle.stroke,
height: 30,
width,
radius: [boxStyle.radius, boxStyle.radius, 0, 0],
},
draggable: true,
});
let fontLeft = 12;
if (icon && icon.show !== false) {
group.addShape("image", {
attrs: {
x: 8,
y: 8,
height: 16,
width: 16,
...icon,
},
});
fontLeft += 18;
}
group.addShape("text", {
attrs: {
y: 22,
x: fontLeft,
fill: "#fff",
text: cfg.label,
fontSize: 12,
fontWeight: 500,
},
});
group.addShape("rect", {
attrs: {
x: 0,
y: collapsed ? 30 : 300,
height: 15,
width,
fill: "#eee",
radius: [0, 0, boxStyle.radius, boxStyle.radius],
cursor: "pointer",
},
name: collapsed ? "expand" : "collapse",
});
group.addShape("text", {
attrs: {
x: width / 2 - 6,
y: (collapsed ? 30 : 300) + 12,
text: collapsed ? "+" : "-",
width,
fill: "#000",
radius: [0, 0, boxStyle.radius, boxStyle.radius],
cursor: "pointer",
},
name: collapsed ? "expand" : "collapse",
});
const keyshape = group.addShape("rect", {
attrs: {
x: 0,
y: 0,
width,
height: collapsed ? 45 : height,
...boxStyle,
},
draggable: true,
});
if (collapsed) {
return keyshape;
}
const listContainer = group.addGroup({});
listContainer.setClip({
type: "rect",
attrs: {
x: -8,
y: 30,
width: width + 16,
height: 300 - 30,
},
});
listContainer.addShape({
type: "rect",
attrs: {
x: 1,
y: 30,
width: width - 2,
height: 300 - 30,
fill: "#fff",
},
draggable: true,
});
if (list.length > itemCount) {
const barStyle = {
width: 4,
padding: 0,
boxStyle: {
stroke: "#00000022",
},
innerStyle: {
fill: "#00000022",
},
};
listContainer.addShape("rect", {
attrs: {
y: 30,
x: width - barStyle.padding - barStyle.width,
width: barStyle.width,
height: height - 30,
...barStyle.boxStyle,
},
});
const indexHeight =
afterList.length > itemCount ?
(afterList.length / list.length) * height :
10;
listContainer.addShape("rect", {
attrs: {
y: 30 +
barStyle.padding +
(startIndex / (list.length-8)) * (height - 30),
x: width - barStyle.padding - barStyle.width,
width: barStyle.width,
height: Math.min(height, indexHeight),
...barStyle.innerStyle,
},
});
}
if (afterList) {
afterList.forEach((e, i) => {
const isSelected =
Math.floor(startIndex) + i === Number(selectedIndex);
let {
columnName = "", columnType,columnComment
} = e;
if (columnComment){
columnName+= " : " + columnComment
}
if (columnType) {
columnName += " - " + columnType;
}
const label = columnName.length > 26 ? columnName.slice(0, 24) + "..." : columnName;
listContainer.addShape("rect", {
attrs: {
x: 1,
y: i * itemHeight - itemHeight / 2 + offsetY,
width: width - 4,
height: itemHeight,
radius: 2,
lineWidth: 1,
cursor: "pointer",
},
name: `item-${Math.floor(startIndex) + i}-content`,
draggable: true,
});
//未来设置字段之间有锚点
// if (!cfg.hideDot) {
// utils.anchor.erDrawLeft(group, label, 0, i * itemHeight + offsetY)
// utils.anchor.erDrawLeft(group,label,width,i * itemHeight + offsetY)
// listContainer.addShape("marker", {
// attrs: {
// x: 0,
// y: i * itemHeight + offsetY,
// r: 3,
// stroke: boxStyle.stroke,
// fill: "white",
// radius: 2,
// lineWidth: 1,
// cursor: "crosshair",
// },
//
// name: 'marker-shape'
// });
// listContainer.addShape("marker", {
// attrs: {
// x: width,
// y: i * itemHeight + offsetY,
// r: 3,
// stroke: boxStyle.stroke,
// fill: "white",
// radius: 2,
// lineWidth: 1,
// cursor: "crosshair",
//
//
// },
// name: 'marker-shape'
// });
// }
listContainer.addShape("text", {
attrs: {
x: 12,
y: i * itemHeight + offsetY + 6,
text: label,
fontSize: 12,
fill: "#000",
fontFamily: "Avenir,-apple-system,BlinkMacSystemFont,Segoe UI,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol",
full: e,
fontWeight: isSelected ? 500 : 100,
cursor: "pointer",
},
name: `item-${Math.floor(startIndex) + i}`,
});
});
}
return keyshape;
},
// getAnchorPoints() {
// return [
// [0, 0],
// [1, 0],
// ];
// },
// 绘制后附加锚点
afterDraw(cfg, group) {
// 绘制锚点
utils.anchor.drawMark(cfg, group)
},
}
}

View File

@@ -0,0 +1,20 @@
/**
* @author: clay
* @data: 2019/07/05
* @description: register nodes
*/
import diceErBox from './dice-er-box'
const obj = {
diceErBox
}
export default {
obj,
register(G6) {
Object.values(obj).map(item => {
G6.registerNode(item.name, item.options, item.extendName)
})
}
}

View File

@@ -0,0 +1,9 @@
/**
* @author: clay
* @data: 2019/07/05
* @description: install 3rd plugins
*/
import * as d3 from 'd3-force/dist/d3-force'
export default d3

View File

@@ -0,0 +1,177 @@
/**
* @author: clay
* @data: 2019/11/20
* @description: dark style
*/
export default {
// 节点样式
nodeStyle: {
default: {
stroke: '#CED4D9',
fill: 'transparent',
shadowOffsetX: 0,
shadowOffsetY: 4,
shadowBlur: 10,
shadowColor: 'rgba(13, 26, 38, 0.08)',
lineWidth: 1,
radius: 4,
strokeOpacity: 0.7
},
selected: {
shadowColor: '#ff240b',
shadowBlur: 4,
shadowOffsetX: 0,
shadowOffsetY: 0
// shadowColor: '#626262',
// shadowBlur: 8,
// shadowOffsetX: -1,
// shadowOffsetY: 3
},
unselected: {
shadowColor: ''
}
},
// 节点标签样式
nodeLabelCfg: {
positions: 'center',
style: {
fill: '#FFF'
}
},
// 连线样式
edgeStyle: {
default: {
stroke: '#53da3a',
lineWidth: 2,
strokeOpacity: 0.92,
lineAppendWidth: 10
// endArrow: true
},
active: {
shadowColor: 'red',
shadowBlur: 4,
shadowOffsetX: 0,
shadowOffsetY: 0
},
inactive: {
shadowColor: ''
},
selected: {
shadowColor: '#ff240b',
shadowBlur: 4,
shadowOffsetX: 0,
shadowOffsetY: 0
},
unselected: {
shadowColor: ''
}
},
// 锚点样式
anchorStyle: {
default: {
radius: 3,
symbol: 'circle',
fill: '#FFFFFF',
fillOpacity: 0,
stroke: '#1890FF',
strokeOpacity: 0,
cursor: 'crosshair'
},
hover: {
fillOpacity: 1,
strokeOpacity: 1
},
unhover: {
fillOpacity: 0,
strokeOpacity: 0
},
active: {
fillOpacity: 1,
strokeOpacity: 1
},
inactive: {
fillOpacity: 0,
strokeOpacity: 0
}
},
// 锚点背景样式
anchorBgStyle: {
default: {
radius: 10,
symbol: 'circle',
fill: '#1890FF',
fillOpacity: 0,
stroke: '#1890FF',
strokeOpacity: 0,
cursor: 'crosshair'
},
hover: {
fillOpacity: 1,
strokeOpacity: 1
},
unhover: {
fillOpacity: 0,
strokeOpacity: 0
},
active: {
fillOpacity: 0.3,
strokeOpacity: 0.5
},
inactive: {
fillOpacity: 0,
strokeOpacity: 0
}
},
nodeActivedOutterStyle: { lineWidth: 0 },
groupSelectedOutterStyle: { stroke: '#E0F0FF', lineWidth: 2 },
nodeSelectedOutterStyle: { stroke: '#E0F0FF', lineWidth: 2 },
edgeActivedStyle: { stroke: '#1890FF', strokeOpacity: .92 },
nodeActivedStyle: { fill: '#F3F9FF', stroke: '#1890FF' },
groupActivedStyle: { stroke: '#1890FF' },
edgeSelectedStyle: { lineWidth: 2, strokeOpacity: .92, stroke: '#A3B1BF' },
nodeSelectedStyle: { fill: '#F3F9FF', stroke: '#1890FF', fillOpacity: .4 },
groupSelectedStyle: { stroke: '#1890FF', fillOpacity: .92 },
groupBackgroundPadding: [40, 10, 10, 10],
groupLabelOffsetX: 10,
groupLabelOffsetY: 10,
edgeLabelStyle: { fill: '#666', textAlign: 'center', textBaseline: 'middle' },
edgeLabelRectPadding: 4,
edgeLabelRectStyle: { fill: 'white' },
nodeLabelStyle: { fill: '#666', textAlign: 'center', textBaseline: 'middle' },
groupStyle: { stroke: '#CED4D9', radius: 4 },
groupLabelStyle: { fill: '#666', textAlign: 'left', textBaseline: 'top' },
multiSelectRectStyle: { fill: '#1890FF', fillOpacity: .08, stroke: '#1890FF', opacity: .1 },
dragNodeHoverToGroupStyle: { stroke: '#1890FF', lineWidth: 2 },
dragNodeLeaveFromGroupStyle: { stroke: '#BAE7FF', lineWidth: 2 },
anchorPointStyle: { radius: 3.5, fill: '#fff', stroke: '#1890FF', lineAppendWidth: 12 },
anchorHotsoptStyle: { radius: 12, fill: '#1890FF', fillOpacity: .25 },
anchorHotsoptActivedStyle: { radius: 14 },
anchorPointHoverStyle: { radius: 4, fill: '#1890FF', fillOpacity: 1, stroke: '#1890FF' },
nodeControlPointStyle: { radius: 4, fill: '#fff', shadowBlur: 4, shadowColor: '#666' },
edgeControlPointStyle: { radius: 6, symbol: 'square', lineAppendWidth: 6, fillOpacity: 0, strokeOpacity: 0 },
nodeSelectedBoxStyle: { stroke: '#C2C2C2' },
cursor: {
panningCanvas: '-webkit-grabbing',
beforePanCanvas: '-webkit-grab',
hoverNode: 'move',
hoverEffectiveAnchor: 'crosshair',
hoverEdge: 'default',
hoverGroup: 'move',
hoverUnEffectiveAnchor: 'default',
hoverEdgeControllPoint: 'crosshair',
multiSelect: 'crosshair'
},
nodeDelegationStyle: {
stroke: '#1890FF',
fill: '#1890FF',
fillOpacity: .08,
lineDash: [4, 4],
radius: 4,
lineWidth: 1
},
edgeDelegationStyle: { stroke: '#1890FF', lineDash: [4, 4], lineWidth: 1 }
}

View File

@@ -0,0 +1,179 @@
/**
* @author: clay
* @data: 2019/08/15
* @description: default style
*/
export default {
// 节点样式
nodeStyle: {
default: {
stroke: '#CED4D9',
fill: 'transparent',
// shadowOffsetX: 0,
// shadowOffsetY: 4,
shadowBlur: 10,
shadowColor: 'rgba(13, 26, 38, 0.08)',
lineWidth: 1,
radius: 4,
strokeOpacity: 0.7
},
selected: {
shadowColor: '#ff240b',
shadowBlur: 2,
// shadowOffsetX: 0,
// shadowOffsetY: 0,
// fontSize:'50'
// shadowColor: '#626262',
// shadowBlur: 8,
// shadowOffsetX: -1,
// shadowOffsetY: 3
},
unselected: {
shadowColor: ''
}
},
// 节点标签样式
nodeLabelCfg: {
positions: 'center',
style: {
fill: '#000'
}
},
// 连线样式
edgeStyle: {
default: {
stroke: '#A3B1BF',
lineWidth: 2,
strokeOpacity: 0.92,
lineAppendWidth: 10
// endArrow: true
},
active: {
shadowColor: 'red',
shadowBlur: 4,
shadowOffsetX: 0,
shadowOffsetY: 0
},
inactive: {
shadowColor: ''
},
selected: {
shadowColor: '#ff240b',
shadowBlur: 4,
shadowOffsetX: 0,
shadowOffsetY: 0
},
unselected: {
shadowColor: ''
}
},
// 锚点样式
anchorStyle: {
default: {
r: 3,
symbol: 'circle',
lineWidth: 1,
fill: '#FFFFFF',
fillOpacity: 1,
stroke: '#096DD9',
strokeOpacity: 1,
cursor: 'crosshair'
},
hover: {
fillOpacity: 0.3,
strokeOpacity: 0.5
},
unhover: {
fillOpacity: 0,
strokeOpacity: 0
},
active: {
fillOpacity: 1,
strokeOpacity: 1
},
inactive: {
fillOpacity: 0,
strokeOpacity: 0
}
},
// 锚点背景样式
anchorBgStyle: {
default: {
r: 10,
symbol: 'circle',
fill: '#1890FF',
fillOpacity: 0,
stroke: '#1890FF',
strokeOpacity: 0,
cursor: 'crosshair'
},
hover: {
fillOpacity: 1,
strokeOpacity: 1
},
unhover: {
fillOpacity: 0,
strokeOpacity: 0
},
active: {
fillOpacity: 0.3,
strokeOpacity: 0.5
},
inactive: {
fillOpacity: 0,
strokeOpacity: 0
}
},
nodeActivedOutterStyle: { lineWidth: 0 },
groupSelectedOutterStyle: { stroke: '#E0F0FF', lineWidth: 2 },
nodeSelectedOutterStyle: { stroke: '#E0F0FF', lineWidth: 2 },
edgeActivedStyle: { stroke: '#1890FF', strokeOpacity: .92 },
nodeActivedStyle: { fill: '#F3F9FF', stroke: '#1890FF' },
groupActivedStyle: { stroke: '#1890FF' },
edgeSelectedStyle: { lineWidth: 2, strokeOpacity: .92, stroke: '#A3B1BF' },
nodeSelectedStyle: { fill: '#F3F9FF', stroke: '#1890FF', fillOpacity: .4 },
groupSelectedStyle: { stroke: '#1890FF', fillOpacity: .92 },
groupBackgroundPadding: [40, 10, 10, 10],
groupLabelOffsetX: 10,
groupLabelOffsetY: 10,
edgeLabelStyle: { fill: '#666', textAlign: 'center', textBaseline: 'middle' },
edgeLabelRectPadding: 4,
edgeLabelRectStyle: { fill: 'white' },
nodeLabelStyle: { fill: '#666', textAlign: 'center', textBaseline: 'middle' },
groupStyle: { stroke: '#CED4D9', radius: 4 },
groupLabelStyle: { fill: '#666', textAlign: 'left', textBaseline: 'top' },
multiSelectRectStyle: { fill: '#1890FF', fillOpacity: .08, stroke: '#1890FF', opacity: .1 },
dragNodeHoverToGroupStyle: { stroke: '#1890FF', lineWidth: 2 },
dragNodeLeaveFromGroupStyle: { stroke: '#BAE7FF', lineWidth: 2 },
anchorPointStyle: { radius: 3.5, fill: '#fff', stroke: '#1890FF', lineAppendWidth: 12 },
anchorHotsoptStyle: { radius: 12, fill: '#1890FF', fillOpacity: .25 },
anchorHotsoptActivedStyle: { radius: 14 },
anchorPointHoverStyle: { radius: 4, fill: '#1890FF', fillOpacity: 1, stroke: '#1890FF' },
nodeControlPointStyle: { radius: 4, fill: '#fff', shadowBlur: 4, shadowColor: '#666' },
edgeControlPointStyle: { radius: 6, symbol: 'square', lineAppendWidth: 6, fillOpacity: 0, strokeOpacity: 0 },
nodeSelectedBoxStyle: { stroke: '#C2C2C2' },
cursor: {
panningCanvas: '-webkit-grabbing',
beforePanCanvas: '-webkit-grab',
hoverNode: 'move',
hoverEffectiveAnchor: 'crosshair',
hoverEdge: 'default',
hoverGroup: 'move',
hoverUnEffectiveAnchor: 'default',
hoverEdgeControllPoint: 'crosshair',
multiSelect: 'crosshair'
},
nodeDelegationStyle: {
stroke: '#1890FF',
fill: '#1890FF',
fillOpacity: .08,
lineDash: [4, 4],
radius: 4,
lineWidth: 1
},
edgeDelegationStyle: { stroke: '#1890FF', lineDash: [4, 4], lineWidth: 1 }
}

View File

@@ -0,0 +1,15 @@
/**
* @author: clay
* @data: 2019/08/15
* @description: 编辑器主题样式 - 节点、连线的预设样式
*/
import defaultStyle from './default-style'
import darkStyle from './dark-style'
import officeStyle from './office-style'
export default {
defaultStyle,
darkStyle,
officeStyle
}

View File

@@ -0,0 +1,177 @@
/**
* @author: clay
* @data: 2019/11/21
* @description: office style
*/
export default {
// 节点样式
nodeStyle: {
default: {
stroke: '#CED4D9',
fill: '#FFFFFF',
shadowOffsetX: 0,
shadowOffsetY: 4,
shadowBlur: 10,
shadowColor: 'rgba(13, 26, 38, 0.08)',
lineWidth: 1,
radius: 4,
strokeOpacity: 0.7
},
selected: {
shadowColor: '#ff240b',
shadowBlur: 4,
shadowOffsetX: 1,
shadowOffsetY: 1
// shadowColor: '#626262',
// shadowBlur: 8,
// shadowOffsetX: -1,
// shadowOffsetY: 3
},
unselected: {
shadowColor: ''
}
},
// 节点标签样式
nodeLabelCfg: {
positions: 'center',
style: {
fill: '#000'
}
},
// 连线样式
edgeStyle: {
default: {
stroke: '#41c23a',
lineWidth: 2,
strokeOpacity: 0.92,
lineAppendWidth: 10
// endArrow: true
},
active: {
shadowColor: 'red',
shadowBlur: 4,
shadowOffsetX: 0,
shadowOffsetY: 0
},
inactive: {
shadowColor: ''
},
selected: {
shadowColor: '#ff240b',
shadowBlur: 4,
shadowOffsetX: 0,
shadowOffsetY: 0
},
unselected: {
shadowColor: ''
}
},
// 锚点样式
anchorStyle: {
default: {
radius: 3,
symbol: 'circle',
fill: '#FFFFFF',
fillOpacity: 0,
stroke: '#1890FF',
strokeOpacity: 0,
cursor: 'crosshair'
},
hover: {
fillOpacity: 1,
strokeOpacity: 1
},
unhover: {
fillOpacity: 0,
strokeOpacity: 0
},
active: {
fillOpacity: 1,
strokeOpacity: 1
},
inactive: {
fillOpacity: 0,
strokeOpacity: 0
}
},
// 锚点背景样式
anchorBgStyle: {
default: {
radius: 10,
symbol: 'circle',
fill: '#1890FF',
fillOpacity: 0,
stroke: '#1890FF',
strokeOpacity: 0,
cursor: 'crosshair'
},
hover: {
fillOpacity: 1,
strokeOpacity: 1
},
unhover: {
fillOpacity: 0,
strokeOpacity: 0
},
active: {
fillOpacity: 0.3,
strokeOpacity: 0.5
},
inactive: {
fillOpacity: 0,
strokeOpacity: 0
}
},
nodeActivedOutterStyle: { lineWidth: 0 },
groupSelectedOutterStyle: { stroke: '#E0F0FF', lineWidth: 2 },
nodeSelectedOutterStyle: { stroke: '#E0F0FF', lineWidth: 2 },
edgeActivedStyle: { stroke: '#1890FF', strokeOpacity: .92 },
nodeActivedStyle: { fill: '#F3F9FF', stroke: '#1890FF' },
groupActivedStyle: { stroke: '#1890FF' },
edgeSelectedStyle: { lineWidth: 2, strokeOpacity: .92, stroke: '#A3B1BF' },
nodeSelectedStyle: { fill: '#F3F9FF', stroke: '#1890FF', fillOpacity: .4 },
groupSelectedStyle: { stroke: '#1890FF', fillOpacity: .92 },
groupBackgroundPadding: [40, 10, 10, 10],
groupLabelOffsetX: 10,
groupLabelOffsetY: 10,
edgeLabelStyle: { fill: '#666', textAlign: 'center', textBaseline: 'middle' },
edgeLabelRectPadding: 4,
edgeLabelRectStyle: { fill: 'white' },
nodeLabelStyle: { fill: '#666', textAlign: 'center', textBaseline: 'middle' },
groupStyle: { stroke: '#CED4D9', radius: 4 },
groupLabelStyle: { fill: '#666', textAlign: 'left', textBaseline: 'top' },
multiSelectRectStyle: { fill: '#1890FF', fillOpacity: .08, stroke: '#1890FF', opacity: .1 },
dragNodeHoverToGroupStyle: { stroke: '#1890FF', lineWidth: 2 },
dragNodeLeaveFromGroupStyle: { stroke: '#BAE7FF', lineWidth: 2 },
anchorPointStyle: { radius: 3.5, fill: '#fff', stroke: '#1890FF', lineAppendWidth: 12 },
anchorHotsoptStyle: { radius: 12, fill: '#1890FF', fillOpacity: .25 },
anchorHotsoptActivedStyle: { radius: 14 },
anchorPointHoverStyle: { radius: 4, fill: '#1890FF', fillOpacity: 1, stroke: '#1890FF' },
nodeControlPointStyle: { radius: 4, fill: '#fff', shadowBlur: 4, shadowColor: '#666' },
edgeControlPointStyle: { radius: 6, symbol: 'square', lineAppendWidth: 6, fillOpacity: 0, strokeOpacity: 0 },
nodeSelectedBoxStyle: { stroke: '#C2C2C2' },
cursor: {
panningCanvas: '-webkit-grabbing',
beforePanCanvas: '-webkit-grab',
hoverNode: 'move',
hoverEffectiveAnchor: 'crosshair',
hoverEdge: 'default',
hoverGroup: 'move',
hoverUnEffectiveAnchor: 'default',
hoverEdgeControllPoint: 'crosshair',
multiSelect: 'crosshair'
},
nodeDelegationStyle: {
stroke: '#1890FF',
fill: '#1890FF',
fillOpacity: .08,
lineDash: [4, 4],
radius: 4,
lineWidth: 1
},
edgeDelegationStyle: { stroke: '#1890FF', lineDash: [4, 4], lineWidth: 1 }
}

View File

@@ -0,0 +1,167 @@
<template>
<div class="toolbar">
<div class="left">
<!--<el-checkbox class="edge-enabled" title="连线模式" @change="$parent.enableEdgeHandler"></el-checkbox>-->
<!-- <top-dropdown-->
<!-- class="edge-shape"-->
<!-- :dropdown-items="$parent.edgeShapeList"-->
<!-- @change="$parent.changeEdgeShapeHandler"-->
<!-- >-->
<!-- </top-dropdown>-->
<top-button size="mini" @click="$parent.reBack">返回</top-button>
</div>
<div class="center">
<div class="graph-ops">
<i class="iconfont icon-undo" title="撤销" :class="$parent.disableUndo ? 'disabled':''"
@click="$parent.undoHandler"></i>
<i class="iconfont icon-redo" title="重做" :class="$parent.disableRedo ? 'disabled':''"
@click="$parent.redoHandler"></i>
<span class="separator"></span>
<i class="iconfont icon-copy" title="复制" :class="$parent.disableCopy ? 'disabled':''"
@click="$parent.copyHandler"></i>
<i class="iconfont icon-paste" title="粘贴" :class="$parent.disablePaste ? 'disabled':''"
@click="$parent.pasteHandler"></i>
<i class="iconfont icon-clear" title="删除" :class="$parent.disableDelete ? 'disabled':''"
@click="$parent.deleteHandler"></i>
<span class="separator"></span>
<i class="iconfont icon-zoom-in" id="zoom-in" title="放大" @click="$parent.zoomInHandler"></i>
<i class="iconfont icon-zoom-out" title="缩小" @click="$parent.zoomOutHandler"></i>
<i class="iconfont icon-fit" title="适应画布" @click="$parent.autoZoomHandler"></i>
<i class="iconfont icon-actualsize" title="实际尺寸" @click="$parent.resetZoomHandler"></i>
<span class="separator"></span>
<i class="iconfont icon-roi-select" id="multi-select" title="框选" @click="$parent.multiSelectHandler"></i>
<div v-if="$parent.$data.graphMode === 'edit'" class="iconfont zx">
<top-dropdown
class="edge-shape"
:dropdown-items="$parent.edgeShapeList"
@change="$parent.changeEdgeShapeHandler">
</top-dropdown>
</div>
</div>
</div>
<div class="right">
<top-button size="mini" @click="$parent.forceLayoutHandler">自动布局</top-button>
<!--<el-button size="mini" @click="$parent.circularLayoutHandler">环形布局</el-button>-->
<!--<el-button size="mini" @click="$parent.radialLayoutHandler">辐射</el-button>-->
<!--<el-button size="mini" @click="$parent.mdsLayoutHandler">MDS</el-button>-->
<!--<el-button size="mini" @click="$parent.dagreLayoutHandler">层次</el-button>-->
<!--<el-button size="mini" @click="$parent.autoLayoutHandler">自动old</el-button>-->
<el-button size="mini" v-hasPermi="['top:preview']" @click="$parent.searchPreview">预览</el-button>
<el-button size="mini" v-hasPermi="['top:online']" @click="$parent.searchOnLine">上线</el-button>
<!-- 返回到预览模式 -->
<!-- <top-button size="mini" @click="$parent.changeModeHandler('preview')">返回</top-button>-->
<top-button size="mini" v-hasPermi="['top:edit']" @click="$parent.saveDataHandler">保存</top-button>
</div>
</div>
</template>
<script>
import { Button, Dropdown } from '../../elements';
export default {
name: "ToolbarEdit",
components: {
"top-button": Button,
"top-dropdown": Dropdown
}
};
</script>
<style lang="scss" scoped>
.zx{
float: right;
}
.toolbar {
/*z-index: 3;*/
/*width: 100%;*/
/*height: 42px;*/
color: #333;
text-align: left;
vertical-align: middle;
line-height: 42px;
background-color: #ffffff;
border: 1px solid #E9E9E9;
box-shadow: 0 8px 12px 0 rgba(0, 52, 107, 0.04);
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
.left {
display: inline-block;
width: 12%;
}
.center {
display: inline-block;
width: 58%;
}
.right {
display: inline-block;
width: 30%;
padding-right: 10px;
text-align: right;
}
.edge-enabled {
width: 40%;
text-align: center;
}
.edge-shape {
width: 100%;
/*margin-right: 20px;*/
line-height: 25px;
text-align: center;
/*border-right: 1px solid #E6E9ED;*/
}
.graph-ops {
display: inline-block;
vertical-align: middle;
margin-left: 20px;
i {
width: 20px;
height: 20px;
margin: 0 6px;
line-height: 20px;
color: #a8a8a8;
text-align: center;
border-radius: 2px;
display: inline-block;
border: 1px solid rgba(2, 2, 2, 0);
}
i:hover {
cursor: pointer;
border: 1px solid #E9E9E9;
}
.disabled {
color: rgba(0, 0, 0, 0.25);
}
.disabled:hover {
cursor: not-allowed;
border: 1px solid rgba(2, 2, 2, 0);
}
.icon-select {
background-color: #EEEEEE;
}
.separator {
margin: 4px;
border-left: 1px solid #E9E9E9;
}
}
.top-button {
margin: 0 5px;
}
}
</style>

View File

@@ -0,0 +1,171 @@
<template>
<div class="toolbar">
<div class="left">
<cc-dropdown
class="theme-style"
ref="themeOptions"
:dropdown-items="themeOptions"
@change="toggleThemeChange"
>
</cc-dropdown>
</div>
<div class="center">
<div class="graph-ops">
<i class="iconfont icon-zoom-in" id="zoom-in" title="放大" @click="$parent.zoomInHandler"></i>
<i class="iconfont icon-zoom-out" title="缩小" @click="$parent.zoomOutHandler"></i>
<i class="iconfont icon-fit" title="适应画布" @click="$parent.autoZoomHandler"></i>
<i class="iconfont icon-actualsize" title="实际尺寸" @click="$parent.resetZoomHandler"></i>
<span class="separator"></span>
<cc-checkbox @change="$parent.enableMinimapHandler">导航器</cc-checkbox>
<cc-dropdown :dropdown-items="refreshOptions" @change="toggleAutoRefresh"></cc-dropdown>
</div>
</div>
<div class="right">
<cc-button size="mini" @click="$parent.manualRefreshHandler">刷新</cc-button>
<cc-button size="mini" @click="$parent.changeModeHandler('edit')">编辑</cc-button>
</div>
</div>
</template>
<script>
import { Checkbox, Button, Dropdown } from '../../elements'
export default {
name: 'ToolbarEdit',
components: {
'cc-checkbox': Checkbox,
'cc-button': Button,
'cc-dropdown': Dropdown
},
data() {
return {
themeOptions: [
{ value: 'defaultStyle', label: '默认主题' },
{ value: 'darkStyle', label: '暗黑风格' },
{ value: 'officeStyle', label: '办公风格' }
],
refreshOptions: [
{ value: -1, label: '不自动刷新' },
{ value: 10000, label: '10秒自动刷新' },
{ value: 30000, label: '30秒自动刷新' },
{ value: 60000, label: '60秒自动刷新' }
]
}
},
methods: {
toggleThemeChange(clickItem) {
this.$parent.changeGraphTheme(clickItem.value)
},
toggleAutoRefresh(clickItem) {
this.$parent.autoRefreshHandler(clickItem.value)
},
// 给父组件调用(代码触发主题修改)
changeThemeActiveIndex(index) {
this.$refs.themeOptions.activeIndex = index
}
}
}
</script>
<style lang="scss" scoped>
.toolbar {
/*height: 42px;*/
color: #333;
text-align: left;
vertical-align: middle;
line-height: 42px;
background-color: #ffffff;
border: 1px solid #E9E9E9;
box-shadow: 0 8px 12px 0 rgba(0, 52, 107, 0.04);
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
.left {
display: inline-block;
width: 12%;
}
.center {
display: inline-block;
width: 58%;
}
.right {
display: inline-block;
width: 30%;
text-align: right;
}
.edge-enabled {
width: 40%;
text-align: center;
}
.edge-type {
width: 60%;
line-height: 25px;
text-align: left;
}
.theme-style {
width: 100%;
line-height: 25px;
text-align: center;
}
.graph-ops {
display: inline-block;
vertical-align: middle;
margin-left: 20px;
i {
width: 20px;
height: 20px;
margin: 0 6px;
line-height: 20px;
color: #a8a8a8;
text-align: center;
border-radius: 2px;
display: inline-block;
border: 1px solid rgba(2, 2, 2, 0);
}
i:hover {
cursor: pointer;
border: 1px solid #E9E9E9;
}
.disabled {
color: rgba(0, 0, 0, 0.25);
}
.disabled:hover {
cursor: not-allowed;
border: 1px solid rgba(2, 2, 2, 0);
}
.icon-select {
background-color: #EEEEEE;
}
.separator {
margin: 4px;
border-left: 1px solid #E9E9E9;
}
.auto-refresh {
margin: 0 8px 0 12px;
}
.cc-checkbox {
margin: 0 6px;
}
}
.cc-button {
margin: 0 5px;
}
}
</style>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,57 @@
import theme from '../../theme'
export default function(cfg, group) {
const themeStyle = theme.defaultStyle // todo...先使用默认主题,后期可能增加其它风格的主体
// console.log("cfg",cfg)
let { anchorPoints, width, height, id } = cfg
// console.log("基础信息",anchorPoints,"宽",width,"高",height,"节点id",id)
if (anchorPoints && anchorPoints.length) {
for (let i = 0, len = anchorPoints.length; i < len; i++) {
let [x, y] = anchorPoints[i]
// 计算Marker中心点坐标
let anchorX = x * width
let anchorY = y * height
// 添加锚点背景
let anchorBgShape = group.addShape('marker', {
id: id + '_anchor_bg_' + i,
attrs: {
name: 'anchorBg',
x: anchorX,
y: anchorY,
// 锚点默认样式
...themeStyle.anchorBgStyle.default
},
draggable: false,
name: 'markerBg-shape'
})
// 添加锚点Marker形状
// eslint-disable-next-line no-unused-vars
let anchorShape = group.addShape('marker', {
id: id + '_anchor_' + i,
attrs: {
name: 'anchor',
x: anchorX,
y: anchorY,
// 锚点默认样式
...themeStyle.anchorStyle.default
},
draggable: false,
name: 'marker-shape'
})
anchorShape.on('mouseenter', function() {
anchorBgShape.attr({
...themeStyle.anchorBgStyle.active
})
})
anchorShape.on('mouseleave', function() {
anchorBgShape.attr({
...themeStyle.anchorBgStyle.inactive
})
})
}
}
}

View File

@@ -0,0 +1,44 @@
import theme from '../../theme'
export default function(group,label,x,y,i) {
const themeStyle = theme.defaultStyle // todo...先使用默认主题,后期可能增加其它风格的主体
let anchorBgShape = group.addShape('marker', {
id: label+ '_anchor_bg_lift_' + i,
attrs: {
name: 'anchorBg',
x: x,
y: y,
...themeStyle.anchorBgStyle.default
},
draggable: false,
name: 'markerBg-shape'
})
let anchorShape = group.addShape('marker', {
id: label+ '_anchor_bg_lift_' + i,
attrs: {
name: 'anchor',
x: x,
y: y,
...themeStyle.anchorStyle.default
},
draggable: false,
name: 'marker-shape'
})
anchorShape.on('mouseenter', function() {
anchorBgShape.attr({
...themeStyle.anchorBgStyle.active
})
})
anchorShape.on('mouseleave', function() {
anchorBgShape.attr({
...themeStyle.anchorBgStyle.inactive
})
})
}

View File

@@ -0,0 +1,17 @@
/**
* @author: clay
* @data: 2019/08/15
* @description: anchor
*/
import erDrawLeft from './er-draw-left'
import setState from './set-state'
import drawMark from './draw_mark'
import update from './update'
export default {
setState,
erDrawLeft,
drawMark,
update
}

View File

@@ -0,0 +1,28 @@
/**
* @author: clay
* @data: 2019/08/15
* @description: set anchor state
*/
import theme from '../../theme'
export default function(name, value, item) {
const themeStyle = theme.defaultStyle // todo...先使用默认主题,后期可能增加其它风格的主体
if (name === 'hover') {
// console.log(item)
let group = item.getContainer()
let children = group.get('children')
for (let i = 0, len = children.length; i < len; i++) {
let child = children[i]
// 处理锚点状态
// console.log(child.attrs.name)
if (child.attrs.name === 'anchorBg') {
if (value) {
child.attr(themeStyle.anchorStyle.hover)
} else {
child.attr(themeStyle.anchorStyle.unhover)
}
}
}
}
}

View File

@@ -0,0 +1,31 @@
/**
* @author: clay
* @data: 2019/08/15
* @description: update anchor
*/
export default function(cfg, group) {
let { anchorPoints, width, height, id } = cfg
if (anchorPoints && anchorPoints.length) {
for (let i = 0, len = anchorPoints.length; i < len; i++) {
let [x, y] = anchorPoints[i]
// 计算Marker中心点坐标
let originX = -width / 2
let originY = -height / 2
let anchorX = x * width + originX
let anchorY = y * height + originY
// 锚点背景
let anchorBgShape = group.findById(id + '_anchor_bg_' + i)
// 锚点
let anchorShape = group.findById(id + '_anchor_' + i)
anchorBgShape.attr({
x: anchorX,
y: anchorY
})
anchorShape.attr({
x: anchorX,
y: anchorY
})
}
}
}

View File

@@ -0,0 +1,11 @@
/**
* @author: clay
* @data: 2021/5/11 17:28
* @email: clay@hchyun.com
* @description: node
*/
import setState from './set-state'
export default {
setState
}

View File

@@ -0,0 +1,33 @@
/**
* @author: clay
* @data: 2021/5/11 17:28
* @email: clay@hchyun.com
* @description: node
*/
export default function(e){
const {
graph
} = this;
const {
y
} = e;
const item = e.item;
const shape = e.shape;
if (!item) {
return;
}
if (shape.get("name") === "collapse") {
graph.updateItem(item, {
collapsed: true,
size: [300, 50],
});
setTimeout(() => graph.layout(), 100);
} else if (shape.get("name") === "expand") {
graph.updateItem(item, {
collapsed: false,
size: [300, 500],
});
setTimeout(() => graph.layout(), 100);
}
}

View File

@@ -0,0 +1,11 @@
/**
* @author: clay
* @data: 2019/08/15
* @description: edge
*/
import setState from './set-state'
export default {
setState
}

View File

@@ -0,0 +1,26 @@
/**
* @author: clay
* @data: 2019/08/15
* @description: set edge state
*/
import theme from '../../theme'
export default function(name, value, item) {
const group = item.getContainer()
const shape = group.get('children')[0] // 顺序根据 draw 时确定
const themeStyle = theme.defaultStyle // todo...先使用默认主题,后期可能增加其它风格的主体
if (name === 'active') {
if (value) {
shape.attr(themeStyle.edgeStyle.active)
} else {
shape.attr(themeStyle.edgeStyle.inactive)
}
} else if (name === 'selected') {
if (value) {
shape.attr(themeStyle.edgeStyle.selected)
} else {
shape.attr(themeStyle.edgeStyle.unselected)
}
}
}

View File

@@ -0,0 +1,66 @@
/**
* @author: clay
* @data: 2019/08/15
* @description: graph utils
*/
import node from './node'
import anchor from './anchor'
import edge from './edge'
import collapse from './collapse'
/**
* 比较两个对象的内容是否相同(两个对象的键值都相同)
* @param obj1
* @param obj2
* @returns {*}
*/
const isObjectValueEqual = function(obj1, obj2) {
let o1 = obj1 instanceof Object
let o2 = obj2 instanceof Object
// 不是对象的情况
if (!o1 || !o2) {
return obj1 === obj2
}
// 对象的属性key值个数不相等
if (Object.keys(obj1).length !== Object.keys(obj2).length) {
return false
}
// 判断每个属性(如果属性值也是对象则需要递归)
for (let attr in obj1) {
let t1 = obj1[attr] instanceof Object
let t2 = obj2[attr] instanceof Object
if (t1 && t2) {
return isObjectValueEqual(obj1[attr], obj2[attr])
} else if (obj1[attr] !== obj2[attr]) {
return false
}
}
return true
}
/**
* 生成uuid算法,碰撞率低于1/2^^122
* @returns {string}
*/
const generateUUID = function() {
let d = new Date().getTime()
// x 是 0-9 或 a-f 范围内的一个32位十六进制数
let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
let r = (d + Math.random() * 16) % 16 | 0
d = Math.floor(d / 16)
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16)
})
return uuid
}
export default {
node,
anchor,
edge,
collapse,
// 通用工具类函数
isObjectValueEqual,
generateUUID
}

View File

@@ -0,0 +1,11 @@
/**
* @author: clay
* @data: 2019/08/15
* @description: node
*/
import setState from './set-state'
export default {
setState
}

View File

@@ -0,0 +1,27 @@
/**
* @author: clay
* @data: 2019/08/15
* @description: set node state
*/
import theme from '../../theme'
export default function(name, value, item) {
const group = item.getContainer()
const shape = group.get('children')[0] // 顺序根据 draw 时确定
const themeStyle = theme.defaultStyle // todo...先使用默认主题,后期可能增加其它风格的主体
if (name === 'active') {
if (value) {
shape.attr(themeStyle.nodeStyle.active)
} else {
shape.attr(themeStyle.nodeStyle.inactive)
}
} else if (name === 'selected') {
if (value) {
group.attr(themeStyle.nodeStyle.selected)
} else {
group.attr(themeStyle.nodeStyle.default)
}
}
}