html关系图、关系网

效果图:

html代码如下:

<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

        <title>demo</title>
    <link  id="bootstrap_221"  rel="stylesheet"  type="text/css"  class="library"  href="./bootstrap.min.css">
            <script  id="others_raphael_210"  type="text/javascript"  class="library"  src="./raphael-min.js"></script>
    <script  id="jquery_172"  type="text/javascript"  class="library"  src="./jquery-1.7.2.min.js"></script>
    <script  id="bootstrap_221"  type="text/javascript"  class="library"  src="./bootstrap.min.js"></script>
    </head>
    <body>

        <span  id="forkongithub"><a  href="https://github.com/lynndon/cloudrelation"  target="_blank">Fork me on GitHub</a></span>

        <table>
            <tbody><tr>
                <td  valign="top">
                        <div  id="svg-container-view"><div  id="cloudSpectrum-1"><svg  height="400"  version="1.1"  width="600"  xmlns="http://www.w3.org/2000/svg"  style="overflow: hidden; position: relative;"><path  fill="none"  stroke="#c6d9ec"  d="M300,200L399.55535766263915,128.58974528404738"  stroke-width="2px"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><path  fill="none"  stroke="#c6d9ec"  d="M300,200L352.52941850425896,73.6938076840904"  stroke-width="2px"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><path  fill="none"  stroke="#c6d9ec"  d="M242.2011641578457,34.82041719603569L300,200"  stroke-width="2px"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><path  fill="none"  stroke="#c6d9ec"  d="M221.16522405853834,162.03517282721367L242.2011641578457,34.82041719603569"  stroke-width="2px"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><path  fill="none"  stroke="#c6d9ec"  d="M221.16522405853834,162.03517282721367L193.9867423278565,60.76570394568833"  stroke-width="2px"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><path  fill="none"  stroke="#c6d9ec"  d="M221.16522405853834,162.03517282721367L156.14963679661577,100.34021369552093"  stroke-width="2px"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><path  fill="none"  stroke="#c6d9ec"  d="M221.16522405853834,162.03517282721367L132.39360708013714,147.28283012908383"  stroke-width="2px"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><path  fill="none"  stroke="#c6d9ec"  d="M221.16522405853834,162.03517282721367L125.04405888506136,203.9266612517659"  stroke-width="2px"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><path  fill="none"  stroke="#c6d9ec"  d="M221.16522405853834,162.03517282721367L134.82041719603566,251.5488358421543"  stroke-width="2px"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><path  fill="none"  stroke="#c6d9ec"  d="M300,200L221.16522405853834,162.03517282721367"  stroke-width="2px"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><path  fill="none"  stroke="#c6d9ec"  d="M221.16522405853834,237.96482717278633L201.84860977965974,328.4201229908319"  stroke-width="2px"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><path  fill="none"  stroke="#c6d9ec"  d="M300,200L221.16522405853834,237.96482717278633"  stroke-width="2px"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><path  fill="none"  stroke="#c6d9ec"  d="M297.52941827882256,281.3061923159096L201.84860977965974,328.4201229908319"  stroke-width="2px"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><path  fill="none"  stroke="#c6d9ec"  d="M297.52941827882256,281.3061923159096L391.22792401789303,333.6036031331298"  stroke-width="2px"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><path  fill="none"  stroke="#c6d9ec"  d="M300,200L297.52941827882256,281.3061923159096"  stroke-width="2px"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><path  fill="none"  stroke="#c6d9ec"  d="M300,200L416.55535766263915,254.4102547159526"  stroke-width="2px"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><path  fill="none"  stroke="#c6d9ec"  d="M300,200L422.5000000000001,189.00000000000006"  stroke-width="2px"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path><desc  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Created with Raphaël 2.1.0</desc><defs  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></defs><path  fill="#ff0000"  stroke="#ff0000"  d="M285,225.98076211353316L315,225.98076211353316L330,200L315,174.01923788646684L285,174.01923788646684L270,200"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer;"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0003308879599382"></path><text  x="300"  y="200"  text-anchor="middle"  font="10px "Arial""  stroke="none"  fill="#ffffff"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: 400; font-size: 14px; line-height: normal; font-family: Arial; cursor: pointer;"  font-size="14px"  font-weight="400"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0003308879599382"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="5">贾政</tspan></text><circle  cx="422.50000000000006"  cy="189.00000000000006"  r="25"  fill="#f16729"  stroke="#f16729"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer;"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000008980791537"></circle><text  x="422.50000000000006"  y="189.00000000000006"  text-anchor="middle"  font="10px "Arial""  stroke="none"  fill="#ffffff"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: 400; font-size: 14px; line-height: normal; font-family: Arial; cursor: pointer;"  font-size="14px"  font-weight="400"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000008980791537"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="5.000000000000057">王夫人</tspan></text><circle  cx="416.55535766263915"  cy="254.4102547159526"  r="25"  fill="#ca0d86"  stroke="#ca0d86"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer;"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0001600282913357"></circle><text  x="416.55535766263915"  y="254.4102547159526"  text-anchor="middle"  font="10px "Arial""  stroke="none"  fill="#ffffff"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: 400; font-size: 14px; line-height: normal; font-family: Arial; cursor: pointer;"  font-size="14px"  font-weight="400"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0001600282913357"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.99619221595259">赵姨娘</tspan></text><circle  cx="297.52941827882256"  cy="281.3061923159096"  r="25"  fill="#1f1f1f"  stroke="#1f1f1f"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer;"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000013638603131"></circle><text  x="297.52941827882256"  y="281.3061923159096"  text-anchor="middle"  font="10px "Arial""  stroke="none"  fill="#ffffff"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: 400; font-size: 14px; line-height: normal; font-family: Arial; cursor: pointer;"  font-size="14px"  font-weight="400"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000013638603131"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="5.001504815909584">贾珠</tspan></text><circle  cx="221.16522405853834"  cy="237.96482717278633"  r="25"  fill="#f89322"  stroke="#f89322"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer;"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000458191916175"></circle><text  x="221.16522405853834"  y="237.96482717278633"  text-anchor="middle"  font="10px "Arial""  stroke="none"  fill="#ffffff"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: 400; font-size: 14px; line-height: normal; font-family: Arial; cursor: pointer;"  font-size="14px"  font-weight="400"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000458191916175"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="5.003889672786329">贾元春</tspan></text><circle  cx="221.16522405853834"  cy="162.03517282721367"  r="25"  fill="#f89322"  stroke="#f89322"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer;"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.000068243010055"></circle><text  x="221.16522405853834"  y="162.03517282721367"  text-anchor="middle"  font="10px "Arial""  stroke="none"  fill="#ffffff"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: 400; font-size: 14px; line-height: normal; font-family: Arial; cursor: pointer;"  font-size="14px"  font-weight="400"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.000068243010055"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.996110327213671">贾宝玉</tspan></text><circle  cx="352.52941850425896"  cy="73.6938076840904"  r="25"  fill="#764394"  stroke="#764394"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer;"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.00000103678679"></circle><text  x="352.52941850425896"  y="73.6938076840904"  text-anchor="middle"  font="10px "Arial""  stroke="none"  fill="#ffffff"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: 400; font-size: 14px; line-height: normal; font-family: Arial; cursor: pointer;"  font-size="14px"  font-weight="400"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.00000103678679"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.998495184090402">贾探春</tspan></text><circle  cx="399.55535766263915"  cy="128.58974528404738"  r="25"  fill="#ca0d86"  stroke="#ca0d86"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer;"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000010922699756"></circle><text  x="399.55535766263915"  y="128.58974528404738"  text-anchor="middle"  font="10px "Arial""  stroke="none"  fill="#ffffff"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: 400; font-size: 14px; line-height: normal; font-family: Arial; cursor: pointer;"  font-size="14px"  font-weight="400"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000010922699756"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="5.003807784047382">贾环</tspan></text><circle  cx="391.22792401789303"  cy="333.6036031331298"  r="25"  fill="#87b11d"  stroke="#87b11d"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer;"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000161778477783"></circle><text  x="391.22792401789303"  y="333.6036031331298"  text-anchor="middle"  font="10px "Arial""  stroke="none"  fill="#ffffff"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: 400; font-size: 14px; line-height: normal; font-family: Arial; cursor: pointer;"  font-size="14px"  font-weight="400"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000161778477783"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="5.002040633129809">李执</tspan></text><circle  cx="201.84860977965974"  cy="328.4201229908319"  r="25"  fill="#3277b5"  stroke="#3277b5"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer;"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000013760168998"></circle><text  x="201.84860977965974"  y="328.4201229908319"  text-anchor="middle"  font="10px "Arial""  stroke="none"  fill="#ffffff"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: 400; font-size: 14px; line-height: normal; font-family: Arial; cursor: pointer;"  font-size="14px"  font-weight="400"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000013760168998"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="5.006060490831885">贾兰</tspan></text><path  fill="#ffcf14"  stroke="#ffcf14"  d="M113.1697821014247,270.2988358421543L156.47105229064664,270.2988358421543L134.82041719603566,232.7988358421543"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer;"></path><text  x="134.82041719603566"  y="257.7988358421543"  text-anchor="middle"  font="10px "Arial""  stroke="none"  fill="#ffffff"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: 400; font-size: 14px; line-height: normal; font-family: Arial; cursor: pointer;"  font-size="14px"  font-weight="400"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.99414834215429">袭人</tspan></text><rect  x="100.04405888506136"  y="178.9266612517659"  width="50"  height="50"  r="10"  rx="10"  ry="10"  fill="#ffea0d"  stroke="#ffea0d"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer;"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.000001355088498"></rect><text  x="125.04405888506136"  y="203.9266612517659"  text-anchor="middle"  font="10px "Arial""  stroke="none"  fill="#ffffff"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: 400; font-size: 14px; line-height: normal; font-family: Arial; cursor: pointer;"  font-size="14px"  font-weight="400"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.000001355088498"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.996973751765893">晴雯</tspan></text><path  fill="#87b11d"  stroke="#87b11d"  d="M117.69897577282532,169.89554255877067L147.08823838744897,169.89554255877067L156.17001998751599,141.94469284002332L132.39360708013714,124.670117699397L108.6171941727583,141.94469284002332"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer;"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.000001216319446"></path><text  x="132.39360708013714"  y="149.670117699397"  text-anchor="middle"  font="10px "Arial""  stroke="none"  fill="#ffffff"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: 400; font-size: 14px; line-height: normal; font-family: Arial; cursor: pointer;"  font-size="14px"  font-weight="400"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.000001216319446"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="5.006055199396997">茜雪</tspan></text><circle  cx="156.14963679661577"  cy="100.34021369552093"  r="25"  fill="#008253"  stroke="#008253"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer;"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.000010259427918"></circle><text  x="156.14963679661577"  y="100.34021369552093"  text-anchor="middle"  font="10px "Arial""  stroke="none"  fill="#ffffff"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: 400; font-size: 14px; line-height: normal; font-family: Arial; cursor: pointer;"  font-size="14px"  font-weight="400"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.000010259427918"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="5.00427619552093">麝月</tspan></text><ellipse  cx="193.9867423278565"  cy="60.76570394568833"  rx="25"  ry="15"  fill="#3277b5"  stroke="#3277b5"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer;"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000431424976306"></ellipse><text  x="193.9867423278565"  y="60.76570394568833"  text-anchor="middle"  font="10px "Arial""  stroke="none"  fill="#ffffff"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: 400; font-size: 14px; line-height: normal; font-family: Arial; cursor: pointer;"  font-size="14px"  font-weight="400"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000431424976306"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.99226644568833">秋纹</tspan></text><rect  x="217.20116415784574"  y="9.820417196035692"  width="50"  height="50"  r="0"  rx="0"  ry="0"  fill="#4c549f"  stroke="#4c549f"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer;"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000003948005014"></rect><text  x="242.20116415784574"  y="34.82041719603569"  text-anchor="middle"  font="10px "Arial""  stroke="none"  fill="#ffffff"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: 400; font-size: 14px; line-height: normal; font-family: Arial; cursor: pointer;"  font-size="14px"  font-weight="400"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000003948005014"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="5.000104696035692">惠香</tspan></text><circle  cx="361.25000000000006"  cy="194.50000000000003"  r="8"  fill="#bed8ec"  stroke="#c6d9ec"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.00003175730467"></circle><text  x="361.25000000000006"  y="194.50000000000003"  text-anchor="middle"  font="10px "Arial""  stroke="#ffffff"  fill="#000000"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: normal; font-size: 10px; line-height: normal; font-family: Arial; cursor: pointer;"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.00003175730467"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.500000000000028">?</tspan></text><circle  cx="358.2776788313196"  cy="227.2051273579763"  r="8"  fill="#bed8ec"  stroke="#c6d9ec"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><text  x="358.2776788313196"  y="227.2051273579763"  text-anchor="middle"  font="10px "Arial""  stroke="#ffffff"  fill="#000000"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: normal; font-size: 10px; line-height: normal; font-family: Arial; cursor: pointer;"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.494189857976295">?</tspan></text><circle  cx="298.76470913941125"  cy="240.6530961579548"  r="8"  fill="#bed8ec"  stroke="#c6d9ec"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000445024748408"></circle><text  x="298.76470913941125"  y="240.6530961579548"  text-anchor="middle"  font="10px "Arial""  stroke="#ffffff"  fill="#000000"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: normal; font-size: 10px; line-height: normal; font-family: Arial; cursor: pointer;"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000445024748408"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.504658657954792">?</tspan></text><circle  cx="344.3786711483578"  cy="307.4548977245197"  r="8"  fill="#bed8ec"  stroke="#c6d9ec"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000000998670169"></circle><text  x="344.3786711483578"  y="307.4548977245197"  text-anchor="middle"  font="10px "Arial""  stroke="#ffffff"  fill="#000000"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: normal; font-size: 10px; line-height: normal; font-family: Arial; cursor: pointer;"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000000998670169"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.493960224519697">?</tspan></text><circle  cx="249.68901402924115"  cy="304.86315765337076"  r="8"  fill="#bed8ec"  stroke="#c6d9ec"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000012013995987"></circle><text  x="249.68901402924115"  y="304.86315765337076"  text-anchor="middle"  font="10px "Arial""  stroke="#ffffff"  fill="#000000"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: normal; font-size: 10px; line-height: normal; font-family: Arial; cursor: pointer;"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000012013995987"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.495970153370763">?</tspan></text><circle  cx="260.58261202926917"  cy="218.98241358639316"  r="8"  fill="#bed8ec"  stroke="#c6d9ec"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><text  x="260.58261202926917"  y="218.98241358639316"  text-anchor="middle"  font="10px "Arial""  stroke="#ffffff"  fill="#000000"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: normal; font-size: 10px; line-height: normal; font-family: Arial; cursor: pointer;"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.5058510863931645">?</tspan></text><circle  cx="211.50691691909904"  cy="283.1924750818091"  r="8"  fill="#bed8ec"  stroke="#c6d9ec"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000103346233973"></circle><text  x="211.50691691909904"  y="283.1924750818091"  text-anchor="middle"  font="10px "Arial""  stroke="#ffffff"  fill="#000000"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: normal; font-size: 10px; line-height: normal; font-family: Arial; cursor: pointer;"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000103346233973"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.497162581809107">?</tspan></text><circle  cx="260.58261202926917"  cy="181.01758641360684"  r="8"  fill="#bed8ec"  stroke="#c6d9ec"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><text  x="260.58261202926917"  y="181.01758641360684"  text-anchor="middle"  font="10px "Arial""  stroke="#ffffff"  fill="#000000"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: normal; font-size: 10px; line-height: normal; font-family: Arial; cursor: pointer;"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.4941489136068355">?</tspan></text><circle  cx="177.99282062728702"  cy="206.79200433468398"  r="8"  fill="#bed8ec"  stroke="#c6d9ec"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><text  x="177.99282062728702"  y="206.79200433468398"  text-anchor="middle"  font="10px "Arial""  stroke="#ffffff"  fill="#000000"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: normal; font-size: 10px; line-height: normal; font-family: Arial; cursor: pointer;"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.5029418346839805">?</tspan></text><circle  cx="173.10464147179985"  cy="182.98091703948978"  r="8"  fill="#bed8ec"  stroke="#c6d9ec"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><text  x="173.10464147179985"  y="182.98091703948978"  text-anchor="middle"  font="10px "Arial""  stroke="#ffffff"  fill="#000000"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: normal; font-size: 10px; line-height: normal; font-family: Arial; cursor: pointer;"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.504354539489782">?</tspan></text><circle  cx="176.77941556933774"  cy="154.65900147814875"  r="8"  fill="#bed8ec"  stroke="#c6d9ec"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><text  x="176.77941556933774"  y="154.65900147814875"  text-anchor="middle"  font="10px "Arial""  stroke="#ffffff"  fill="#000000"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: normal; font-size: 10px; line-height: normal; font-family: Arial; cursor: pointer;"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.4949389781487525">?</tspan></text><circle  cx="188.65743042757705"  cy="131.18769326136731"  r="8"  fill="#bed8ec"  stroke="#c6d9ec"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><text  x="188.65743042757705"  y="131.18769326136731"  text-anchor="middle"  font="10px "Arial""  stroke="#ffffff"  fill="#000000"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: normal; font-size: 10px; line-height: normal; font-family: Arial; cursor: pointer;"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.492380761367315">?</tspan></text><circle  cx="207.57598319319743"  cy="111.400438386451"  r="8"  fill="#bed8ec"  stroke="#c6d9ec"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><text  x="207.57598319319743"  y="111.400438386451"  text-anchor="middle"  font="10px "Arial""  stroke="#ffffff"  fill="#000000"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: normal; font-size: 10px; line-height: normal; font-family: Arial; cursor: pointer;"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.502000886451">?</tspan></text><circle  cx="231.68319410819203"  cy="98.42779501162468"  r="8"  fill="#bed8ec"  stroke="#c6d9ec"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><text  x="231.68319410819203"  y="98.42779501162468"  text-anchor="middle"  font="10px "Arial""  stroke="#ffffff"  fill="#000000"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: normal; font-size: 10px; line-height: normal; font-family: Arial; cursor: pointer;"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.498107511624681">?</tspan></text><circle  cx="271.10058207892286"  cy="117.41020859801785"  r="8"  fill="#bed8ec"  stroke="#c6d9ec"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><text  x="271.10058207892286"  y="117.41020859801785"  text-anchor="middle"  font="10px "Arial""  stroke="#ffffff"  fill="#000000"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: normal; font-size: 10px; line-height: normal; font-family: Arial; cursor: pointer;"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.496146098017846">?</tspan></text><circle  cx="326.2647092521295"  cy="136.8469038420452"  r="8"  fill="#bed8ec"  stroke="#c6d9ec"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000145437404957"></circle><text  x="326.2647092521295"  y="136.8469038420452"  text-anchor="middle"  font="10px "Arial""  stroke="#ffffff"  fill="#000000"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: normal; font-size: 10px; line-height: normal; font-family: Arial; cursor: pointer;"  transform="matrix(1,0,0,1,0,0)"  stroke-width="1.0000145437404957"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.495341342045208">?</tspan></text><circle  cx="349.7776788313196"  cy="164.29487264202368"  r="8"  fill="#bed8ec"  stroke="#c6d9ec"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><text  x="349.7776788313196"  y="164.29487264202368"  text-anchor="middle"  font="10px "Arial""  stroke="#ffffff"  fill="#000000"  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-style: normal; font-variant: normal; font-weight: normal; font-size: 10px; line-height: normal; font-family: Arial; cursor: pointer;"><tspan  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"  dy="4.505810142023677">?</tspan></text></svg></div></div>
                </td>
                <td>
                    <b>使用方法:</b><br>
                    <code>
                            var relation = new Relation({node: '#svg-container-view', width:600, height:400, mode: 'edit'});
                            relation.render(data);
                    </code>
                    <br>
                    数据json格式:<br>
                    <code>
                        {"id":"300003",       //节点Id<br>
                           "name":"",     //节点名称<br>
                           "parent":"0",      //父节点<br>
                           "type":"people",   //节点类型<br>
                           "color":"#ff0000", //形状颜色<br>
                           "shape":6,         //形状类型<br>
                           "weight":15,       //权重<br>
                           "childNodes":[{"id":"400008",<br>
                               "name":"王夫人",<br>
                               "parent":"300002",<br>
                               "weight":10,<br>
                               "type":"place",<br>
                               "color":"#F16729",<br>
                               "shape":1,<br>
                            "childNodes":[...]}<br>
                               ]<br>
                        }<br>
                    </code>

                    <br>
                    node: Dom节点<br>
                    mode:有两种模式,编辑模式和显示模式,编辑模式下形状可以拖动,显示模式下不可以<br>

                    <b>方法:</b><br>
                    relation.preview(); //得到树形数据,包含形状形状的坐标<br>
                    ralation.save();    //得到数据数组,平面数据<br>

                    <b>事件:</b><br>
                    relation.on('nodeClick', function(e){});       //节点点击事件<br>
                    ralation.on('relationClick', function(e){});   //两节点关系单击事件<br>
                    <br>
                    e:{x: 967, y: 371, id: "500001", parentId: "400010"}<br>
                    <br><br>
                    <a  href="http://top.baidu.com/detail?b=258&w=%CD%F5%D1%C7%C6%BD"  class="btn btn-large btn-primary"  target="_blank"  type="button">类似于百度  图谱      点击查看</a>
                </td>
            </tr>
        </tbody></table>







        <style>button{
    border:1px solid #ccc;
    cursor:pointer;
  display:block;
  margin:auto;
  position:relative;
  top:100px;
}

#forkongithub a{background:#000;color:#fff;text-decoration:none;font-family:arial, sans-serif;text-align:center;font-weight:bold;padding:5px 40px;font-size:1rem;line-height:2rem;position:relative;transition:0.5s;}
#forkongithub a:hover{background:#060;color:#fff;}
#forkongithub a::before,#forkongithub a::after{content:"";width:100%;display:block;position:absolute;top:1px;left:0;height:1px;background:#fff;}
#forkongithub a::after{bottom:1px;top:auto;}
@media screen and (min-width:800px){#forkongithub{position:absolute;display:block;top:0;right:0;width:200px;overflow:hidden;height:200px;}
    #forkongithub a{width:200px;position:absolute;top:60px;right:-60px;transform:rotate(45deg);-webkit-transform:rotate(45deg);box-shadow:4px 4px 10px rgba(0,0,0,0.8);}
}


#newsPanel{position:absolute;left:0;top:0;background:#fff;border:1px #000 solid;padding:10px;width:300px;font-size:14px;}#newsPanel .arrow{position:absolute;width:0;height:0;border:15px dashed transparent;border-right:15px solid #000;top:50%;margin-top:-15px;margin-left:-40px;}#newsPanel .arrow2{position:absolute;width:0;height:0;border:15px dashed transparent;border-right:15px solid #fff;top:50%;margin-top:-15px;margin-left:-39px;}#newsPanel ul,#newsPanel li{margin:0;padding:0;}#newsPanel li{list-style:none;display:block;margin-top:4px;margin-bottom:4px;width:280px;height:16px;overflow:hidden;text-overflow:ellipsis;}#newsPanel a{text-decoration:none;}#newsPanel .close{position:absolute;right:10px;top:0;width:10px;height:10px;font-size:20px;cursor:pointer;}
</style>
                <script>var Relation = (function(){
    var _uuid = 0;
    function CloudRelation(opt) {
        'use strict';
        var _DEFAULT = {
            node: '',
            width: 600,
            height: 400,
            mode: 'edit'
        };
        this.cfg = this.merge(_DEFAULT, opt);
        this.eventHandlers = [];
        this.cache = {};
        this._init();
    }

CloudRelation.prototype = {
    constructor: CloudRelation,
    _init: function(){
        var self = this, cfg = self.cfg, w=cfg.width, h=cfg.height;
        node = self.dom().get(cfg.node);
        node.width(w);
        node.height(h);
        var divId = 'cloudSpectrum-'+self._guid();
        node.html('<div id="'+divId+'"></div>');
        self.paper = Raphael(divId, w, h);
        //self.paper.rect(0, 0, w, h, 10).attr({'stroke': "#666"});

        //Rapheal插件扩展
        Raphael.fn.connection = function (obj1, obj2, nodeOption) {
            var line;
            if (obj1.line && obj1.from && obj1.to) {
                line = obj1;
                obj1 = line.from;
                obj2 = line.to;
            }
            var bb1 = obj1.getBBox(),
                bb2 = obj2.getBBox(),
                po = [{x: bb1.x + bb1.width / 2, y: bb1.y + bb1.height / 2},
                      {x: bb2.x + bb2.width / 2, y: bb2.y + bb2.height / 2},
                      {x: bb2.x + bb2.width / 2, y: bb2.y + bb2.height / 2}],
                poc = {x: (po[1].x + po[0].x)/2, y: (po[1].y + po[0].y)/2};
            //var path = ["M", x1.toFixed(3), y1.toFixed(3), "L", x2, y2, x3, y3, x4.toFixed(3), y4.toFixed(3)].join(",");
            var path = ["M", po[0].x, po[0].y, "L", po[1].x, po[1].y].join(",");
            if (line && line.line) {
                line.line.toBack().attr({path: path});
                line.lineNode.attr({x: poc.x, y:poc.y, cx: poc.x, cy: poc.y});
            } else {
                var color = typeof line == "string" ? line : "#000";
                return {
                    line: this.path(path).toBack().attr({'stroke': '#C6D9EC', 'stroke-width': '2px', fill: "none"}),
                    from: obj1,
                    to: obj2,
                    lineNode: self.paper.set().push(this.circle(poc.x, poc.y, 8).attr({fill: '#BED8EC', stroke: '#C6D9EC'}), this.text(poc.x, poc.y, '?').attr({stroke: '#fff', cursor: 'pointer'})),
                    lineOpt: nodeOption
                };
            }
        };
    },

    render: function(data){
        var self = this, cfg = self.cfg, dom = self.dom(), r = self.paper;
        self.connections = [],
        self.shapes = [];      //svg形状集合
        self.flatData = [];    //平面数据(非树状)
        self.data = data;
        self.cache = {};
        self.cache.w = cfg.width;  //画布宽
        self.cache.h = cfg.height;  //画布高

        self.objects = {}; //所有元素缓存

        var shapes = self.shapes, cache = self.cache,
            objs = self.objects, flatData = self.flatData;

        //样式
        var CENTER_STYLE = {'fill': '#5782C2', 'stroke': '#5782C2'},
            TEXT_STYLE = {'fill': '#fff', 'font-size': '14px', 'font-weight': '400'};

        //极径
        var min = Math.round(Math.max(cache.w, cache.h)/6), circleRadius = Math.round(min/4);
        self.circleRadius = circleRadius;
        var _stack = [], levelStack=[], level=1;
        _stack.push(data);
        draw(_stack); //绘制

        var ms=false, tar, mar, tardata, delay = false;
        function dragger() {
            if(this.data('setIndex') && this.data('dataIndex') != undefined){
                tar = shapes[this.data('setIndex')];
                tardata = flatData[this.data('dataIndex')];
                var btar = tar.getBBox();
                mar = {};
                ms = true;
                mar.ox = btar.x;
                mar.oy = btar.y;
                mar.cox = btar.x + btar.width / 2;
                mar.coy = btar.y + btar.height / 2;
            }
        }
        function move(dx, dy){
            if(ms){
                var finalx = mar.cox + dx, finaly = mar.coy + dy;
                var att = {'x': finalx, 'y': finaly, 'cx': finalx, 'cy': finaly};
                if(!delay){
                    tar.attr(att);
                    tardata.theta = Raphael.rad(Raphael.angle(finalx, finaly, cache.w/2, cache.h/2));
                    tardata.radius = self._computeLength(cache.w/2, cache.h/2, finalx, finaly);

                    delay = true;
                    setTimeout(function(){
                        delay = false;
                    }, 40);
                }
                for (var i = connections.length; i--;) {
                    r.connection(connections[i]);
                }
                r.safari();
            }
        }
        function up(){
            if(ms){
                ms = false;
            }
        }
        for(var i = 0, ii = shapes.length; i < ii; i++) {
            var color = Raphael.getColor();
            var s = shapes[i];
            s.attr({cursor: "pointer"});
            if(cfg.mode == 'edit'){
                s.attr({cursor: "move"});
                s.drag(move, dragger, up); //拖动
            }
            (function(sha){
                sha.mouseover(function () {
                    sha.stop().animate({transform: "s1.2 1.2"}, 500, "backOut");
                }).mouseout(function () {
                    sha.stop().animate({transform: ""}, 500, "backOut");
                });

                if(cfg.mode == 'view'){
                    sha.click(function(e){
                        var di = this.data('dataIndex');
                        alert(di);
                        self._publish('nodeClick', {x:e.pageX, y:e.pageY, id: flatData[di].id});
                    });
                }else{
                    sha.dblclick(function(e){
                        var di = this.data('dataIndex');
                        self._publish('nodeClick', {x:e.pageX, y:e.pageY, id: flatData[di].id});
                    });
                }
            })(s);
        }

        var connections = [];
        connect(data, data.childNodes);
        function connect(parent, children, pc){
            var pobj = objs[parent.id];
            if(children.length > 0){
                for(var i=0; i<children.length; i++){
                    if(children[i]){
                        var child = children[i], id = child.id, obj = objs[id];
                        connections.push(r.connection(shapes[pobj.index], shapes[obj.index], {pid: parent.id, id:id}));

                        connect(child, child.childNodes);
                    }
                }
            }
        }

        for (var i = 0, ii = connections.length; i < ii; i++) {
            var cs = connections[i];
            (function(cln, opt){
                if(cln){
                    cln.mouseover(function () {
                        cln.stop().animate({'transform': "s1.2 1.2"}, 500, "backOut");
                    }).mouseout(function () {
                        cln.stop().animate({'transform': ""}, 500, "backOut");
                    });
                    cln.click(function(e){
                        var clickX = e.pageX;
                        var clickY = e.pageY;
                        self._publish('relationClick', {x: clickX, y:clickY, id: opt.id, parentId: opt.pid});
                    });
                }
            })(cs.lineNode, cs.lineOpt);
        }

        /**
         * 遍历绘制节点
         *@param 栈(先进后出)
         */
        function draw(stack){
            var pc = 0;
            while(stack.length>0){
                var node = stack.shift();
                if(node){
                    if(node.parent == 0){
                        //根节点
                        var x = cache.w/2, y = cache.h/2;
                        //中心点
                        var idx = self.shapes.length;
                        var sha = drawShape(node.shape+'', [x, y], circleRadius*1.2);
                        sha.attr({'fill': node.color, 'stroke': node.color}).data('setIndex', idx);
                        shapes.push(r.set().push(sha, r.text(x, y, node.name).attr(TEXT_STYLE).data('setIndex', idx).data('dataIndex', idx)));
                        objs[node.id] = {'x': x, 'y': y, 'theta':0, 'index':0};
                        node.theta = 0;
                        node.radius = 0;
                        flatData.push(self.clone(node));
                        //第一层节点
                        if(node.childNodes.length > 0){
                            levelStack.push(node.childNodes.length);
                        }
                        drawChildNode({x: x, y: y}, node.childNodes);
                        stack = stack.concat(node.childNodes);
                        level++;
                    }else{
                        var pos = objs[node.id];
                        //var x = pos.x, y = pos.y;
                        //var rad = Math.round(circleRadius), idx = self.shapes.length;
                        if(pc == levelStack[0]){
                            levelStack.shift();
                            pc = 0;
                            level++;
                            levelStack.push(node.childNodes.length);
                        } else {
                            if(levelStack[1]){
                                levelStack[1] = levelStack[1] + node.childNodes.length;
                            }else{
                                levelStack[1] = node.childNodes.length;
                            }
                        }
                        drawChildNode(pos, node.childNodes);
                        stack = stack.concat(node.childNodes);
                        pc++;
                    }
                }
            }
        }

        /**
         * 绘制子节点
         *@param pos 父节点位置对象,x,y坐标和极角
         *@param chidren 子节点数组
         *@param angle 极角
         */
        function drawChildNode(pos, children){
            if(!children.length){
                return;
            }
            var len = children.length, averWeight = self._getAverageWeight(children);
            if(pos.theta !== undefined){
                //var averAngle = Math.atan(circleRadius*2.2/polarRadius);
                //var averAngle = Math.PI/6;
                //var a0 = Math.PI/2 - averAngle*(len-1)/2 - pos.theta;

                var averAngle = Math.PI/len;
                if(level == 2){
                    averAngle = Math.PI/10;
                }
                if(level == 3){
                    if(averAngle>Math.PI/24){
                        averAngle = Math.PI/24;
                    }
                }
                var a0 = averAngle*(len-1)/2 - pos.theta;
                //var rad =polarRadius + cache.level*circleRadius;
                for(var i=0; i<len; i++){
                    //var rad =polarRadius*children[i].weight/averWeight;
                    drawSingleNode(children[i], pos, (level*3.5)*circleRadius, -a0+i*averAngle);
                }
            }else{
                //第一层子节点场合
                var averAngle = 2*Math.PI/len;
                for(var i=0; i<len; i++){
                    //var rad =polarRadius*children[i].weight/averWeight;
                    drawSingleNode(children[i], pos, (level*3.5)*circleRadius, i*averAngle);
                }
            }
        }

        /**
         * 绘制单个节点
         *@param pos 父节点位置对象
         *@param rad 极径
         *@param angle 极角
         */
        function drawSingleNode(node, pos, rad, angle){
            if(objs[node.id]){
                return;
            }
            var index = flatData.length;
            var p, idx = self.shapes.length;
            if(cfg.mode == 'edit'){
                p = self._polarToXY(pos, rad, angle);
            }else{
                p = self._polarToXY(pos, node.radius, node.theta);
            }
            var nodeShape;
            if(cfg.mode == 'edit'){
                nodeShape = drawShape('3', p, circleRadius).attr({'fill': node.color, 'stroke': node.color}).data('setIndex', idx);
            }else{
                nodeShape = drawShape(node.shape+'', p, circleRadius).attr({'fill': node.color, 'stroke': node.color}).data('setIndex', idx);
            }
            shapes.push(r.set().push(nodeShape, r.text(p[0], p[1], node.name).attr(TEXT_STYLE).data('setIndex', idx).data('dataIndex', index)));
            objs[node.id] = {'x': p[0], 'y': p[1], 'theta': angle, 'index': idx};
            node.theta = angle;
            node.radius = rad;
            flatData.push(self.clone(node));
        }

        function drawShape(shapeType, p, circleRadius){
            var shape;
            switch(shapeType){
                case '1':
                    shape = r.rect(p[0]-circleRadius, p[1]-circleRadius, circleRadius*2, circleRadius*2);
                break;
                case '2':
                    shape = r.ellipse(p[0], p[1], circleRadius, circleRadius*0.6);
                break;
                case '3':
                    shape = r.circle(p[0], p[1], circleRadius);
                break;
                case '4':
                    shape = drawPentagonal(p[0], p[1], circleRadius);
                break;
                case '5':
                    shape = drawTriangle(p[0], p[1], circleRadius);
                break;
                case '6':
                    shape = drawHexagon(p[0], p[1], circleRadius);
                break;
                case '7':
                    shape = r.rect(p[0]-circleRadius, p[1]-circleRadius, circleRadius*2, circleRadius*2, 10);
                break;
                default:
                    shape = r.circle(p[0], p[1], circleRadius);
                break;
            };
            return shape;
        }

        //三角形
        function drawTriangle(x, y, rad){
            var cos = rad*Math.cos(Math.PI/3), sin = rad*Math.sin(Math.PI/3);
            var x1 = x-sin, y1 = y+cos,
                x2 = x+sin, y2 = y+cos,
                x3 = x, y3 = y-rad;
            var path = ['M', x1, y1, 'L', x2, y2, 'L', x3, y3].join(' ');
            return r.path(path);
        }
        //五角形
        function drawPentagonal(x, y, rad){
            var cos36 = rad*Math.cos(36*Math.PI/180), sin36 = rad*Math.sin(36*Math.PI/180),
                cos18 = rad*Math.cos(18*Math.PI/180), sin18 = rad*Math.sin(18*Math.PI/180);
            var x1 = x-sin36, y1 = y+cos36,
                x2 = x+sin36, y2 = y+cos36,
                x3 = x+cos18, y3 = y-sin18,
                x4 = x,       y4 = y-rad,
                x5 = x-cos18, y5 = y-sin18;
            var path = ['M', x1, y1, 'L', x2, y2, 'L', x3, y3, 'L', x4, y4, 'L', x5, y5].join(' ');
            return r.path(path);
        }
        //六角形
        function drawHexagon(x, y, rad){
            var cos30 = rad*Math.cos(Math.PI/6), sin30 = rad*Math.sin(Math.PI/6);
            var x1 = x-sin30, y1 = y+cos30,
                x2 = x+sin30, y2 = y+cos30,
                x3 = x+rad,   y3 = y,
                x4 = x+sin30, y4 = y-cos30,
                x5 = x-sin30, y5 = y-cos30,
                x6 = x-rad,   y6 =y;
            var path = ['M', x1, y1, 'L', x2, y2, 'L', x3, y3, 'L', x4, y4, 'L', x5, y5, 'L', x6, y6].join(' ');
            return r.path(path);
        }
    },

    save: function(){
        var self = this, result=[];
        for(var i=self.flatData.length-1; i>=0; i--){
            var item = self.flatData[i];
            result.push(item);
        }
        return result;
    },

    preview: function(){
        var self = this, data=self.data, flatData=self.flatData;

        function iterate(nodes){
            for(var i=0, ii=nodes.length; i<ii; i++){
                var cur = nodes[i];
                for(var j=0; j<flatData.length; j++){
                    if(cur.id == flatData[j].id){
                        cur.theta = flatData[j].theta;
                        cur.radius = flatData[j].radius;
                    }
                    iterate(cur.childNodes);
                }
            }
        }
        iterate([data]);
        return data;
    },

    on: function(type, func){
        var self = this;
        self.eventHandlers[type] = func;
    },

    _publish: function(type, data){
        var self = this, handlers = self.eventHandlers;
        if(handlers[type]){
            handlers[type].call(null, data);
        }
    },

    //generate global unique id
    _guid: function(){
        return ++_uuid;
    },

    //极坐标转直角坐标
    _polarToXY: function(pos, rad, angle){
        var self = this, cache = self.cache, x = cache.w/2, y = cache.h/2, radis = self.circleRadius;
        //var a = Raphael.angle(x, y, pos.x+radis*Math.cos(angle), pos.y+radis*Math.sin(angle))*Math.PI/180;
        return [x+rad*Math.cos(angle), y+rad*Math.sin(angle)];
    },

    //计算长度
    _computeLength: function(x1, y1, x2, y2){
        return Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
    },

    //取得平均权值
    _getAverageWeight: function(arr){
        if(!arr.length) return 0;
        var sum=0;
        for(var i=0, ii=arr.length; i<ii; i++){
            sum += arr[i].weight;
        }
        return sum/arr.length
    },

    //merge
    merge: function(obj1, obj2){
        return obj2;
    },

    clone: function(obj){
        var objClone = new Object();
        for(var key in obj){
            if (Object.prototype.toString.call(obj[key]) == '[object Array]'){
                objClone[key] = [];
            }else{
                objClone[key] = obj[key];
            }
        }
        return objClone;
    },

    util: {
        substitute: function(str, obj){
            if (!(Object.prototype.toString.call(str) === '[object String]')) {
                return '';
            }
            if(!(Object.prototype.toString.call(obj) === '[object Object]' && 'isPrototypeOf' in obj)) {
                return str;
            }
            // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/replace
            return str.replace(/\{([^{}]+)\}/g, function(match, key) {
                var value = obj[key];
                return ( value !== undefined) ? ''+value :'';
            });
        }
    },

    //dom封装
    dom: function(){
        function Dom(){
            this.elements=[];
            EventTarget.call(this);
        }

        Dom.prototype = {
            constructor: Dom,
            _events: [],
            get: function(selector, parent){
                var element;
                if(typeof arguments[0]=="string"){
                    element=arguments[0];
                    var prefix=element.slice(0, 1);
                    if(prefix == '#'){
                        element = document.getElementById(element.slice(1));
                        this.elements.push(element); 
                    }else{
                        if(document.querySelectorAll){
                            this.elements.concat(document.querySelectorAll(element, parent.elements));
                        } else {
                            var es = document.body.getElementsByTagName('*'); 
                            for (var i = 0, j = es.length; i < j; i++) { 
                                if (element.indexOf(es[i].className) != -1) { 
                                    this.elements.push(es[i]); 
                                } 
                            }
                        }
                    }
                }else{ 
                    element=this; 
                    this.elements.push(element); 
                }
                return this;
            },
            each: function(fn){ 
                for(var i=0,l=this.elements.length;i<l;i++){ 
                    fn.call(this, this.elements[i], i); 
                }
                return this;
            },
            css: function(prop,v){ 
                if(v){
                    this.each(function(el){
                        el.style[prop]=v; 
                    });
                }else{
                    return this.elements[0].style[prop];
                }
            },
            width: function(v){
                if(v){
                    this.elements[0].style.width = v;
                    return this;
                }else{
                    return this.elements[0].offsetWidth;
                }
            },
            height: function(v){
                if(v){
                    this.elements[0].style.height = v;
                    return this;
                }else{
                    return this.elements[0].offsetHeight;
                }
            },
            html: function(ele){
                this.elements[0].innerHTML = ele;
            },
            show: function(){
                this.each(function(el){
                    el.style.display = 'block'; 
                });
            },
            hide: function(){
                this.each(function(el){
                    el.style.display = 'none'; 
                });
            },
            ua: {
                ie: navigator.userAgent.indexOf("IE") < 0 ? false : true,
                firefox: navigator.userAgent.indexOf("Firefox") < 0 ? false : true,
                chrome: navigator.userAgent.indexOf(&q