• Edit
  • Download
    1. <!DOCTYPE html>
    2. <html>
    3.  
    4. <head>
    5. <meta charset="utf-8">
    6. <title>ZingChart Demo: Xmas Tree</title>
    7. <script nonce="undefined" src="https://cdn.zingchart.com/zingchart.min.js"></script>
    8. <style>
    9. .zc-body {
    10. margin: 10px;
    11. padding: 10px;
    12. background: #fbfbfb;
    13. }
    14.  
    15. .zc-info {
    16. margin-bottom: 10px;
    17. border-bottom: 1px solid #ccc;
    18. }
    19.  
    20. .zc-info ol {
    21. margin: 0 0 22px;
    22. padding: 0 0 0 1rem;
    23. font-size: 14px;
    24. }
    25.  
    26. .zc-info p {
    27. color: #dc1257;
    28. }
    29.  
    30. .zc-controls {
    31. padding: 5px 0;
    32. }
    33.  
    34. .zc-controls input {
    35. height: 40px;
    36. border: 1px solid #ebebeb;
    37. border-radius: 4px;
    38. box-sizing: border-box;
    39. font-size: 1rem;
    40. padding: 0 10px;
    41. }
    42.  
    43. .zc-controls input:focus {
    44. font-size: 1rem;
    45. }
    46.  
    47. .zc-controls button {
    48. color: #fff;
    49. background: #073c4e;
    50. border: 1px solid #ebebeb;
    51. border-radius: 4px;
    52. cursor: pointer;
    53. font-size: .8125rem;
    54. padding: 0 10px;
    55. height: 40px;
    56. }
    57.  
    58. .zc-controls button[disabled] {
    59. cursor: not-allowed;
    60. }
    61. </style>
    62. </head>
    63.  
    64. <body class="zc-body">
    65.  
    66. <div class="zc-info">
    67. <ol>
    68. <li>Enter your full name in the text box and press <strong>Render Tree</strong>.</li>
    69. <li>Based on your name, a unique, force-directed graph will be generated. While the structure will always be the same, the position of the nodes may (slightly) differ every time.</li>
    70. <li>After render, you may make adjustments by dragging nodes around.</li>
    71. <li>Right-click on the tree and choose <strong>View as PNG</strong>.</li>
    72. <li>Right-click again and save your holiday tree.</li>
    73. </ol>
    74. <p>Enjoy! Happy Holidays from ZingChart!</p>
    75. </div>
    76.  
    77. <div class="zc-controls">
    78. <input type="text" id="renderInput" placeholder="Your full name here" value="world">
    79. <button id="renderBtn">Render Tree</button>
    80. </div>
    81.  
    82. <div id="myChart"></div>
    83.  
    84. <script>
    85. ZC.LICENSE = ["569d52cefae586f634c54f86dc99e6a9", "b55b025e438fa8a98e32482b5f768ff5"]; // INIT
    86. // -----------------------------
    87. // Define Module Location
    88. zingchart.MODULESDIR = "https://cdn.zingchart.com/modules/";
    89.  
    90. // DEFINE CHART
    91. // -----------------------------
    92. // Main chart render location
    93. let chartId = 'myChart';
    94.  
    95. // DOM ELEMENTS
    96. // -----------------------------
    97. let renderBtn = document.querySelector('#renderBtn');
    98. let renderInput = document.querySelector('#renderInput');
    99.  
    100.  
    101. // RENDER BUTTON EVENTS
    102. // -----------------------------
    103. renderBtn.addEventListener('click', renderChart);
    104.  
    105.  
    106. // HELPER FNS
    107. // -----------------------------
    108.  
    109. // Render Chart
    110. function renderChart() {
    111. // Disable render button
    112. renderBtn.setAttribute('disabled', 'disabled')
    113.  
    114. // Define constants
    115. const COLORS = [
    116. '#99ccff #336699',
    117. '#6CB359 #0F4800',
    118. '#9A5E9A #430443',
    119. '#FFA153 #AC4E00',
    120. '#FF653D #A62300',
    121. '#57B8C6 #095B67',
    122. '#FFE66D #AF930B',
    123. '#EF668F #9D0A36'
    124. ];
    125. const NAME = renderInput.value.trim() || 'Santa Claus';
    126. let width = '100%';
    127. let height = 560;
    128. let colorSequence = 0;
    129. let sequence = 0;
    130. let tick = null;
    131.  
    132. // Define data
    133. let chartConfig = {
    134. type: 'tree',
    135. title: {
    136. text: 'Hello ' + NAME + ', here\'s your holiday tree',
    137. color: '#333333',
    138. fontSize: '17px',
    139. padding: '25px'
    140. },
    141. options: {
    142. aspect: 'graph',
    143. attractionConstant: 0.1,
    144. minSize: '16px',
    145. maxSize: '16px',
    146. minLinkWidth: '1px',
    147. maxLinkWidth: '1px',
    148. repulsionConstant: 400,
    149. repulsionDistanceFactor: 5,
    150. springLength: '35px',
    151. textAttr: 'id',
    152. weightedLinks: 1,
    153. weightedNodes: 1,
    154. link: {
    155. lineColor: '#000000'
    156. },
    157. node: {
    158. backgroundColor: 'none',
    159. backgroundPosition: '45% 45%',
    160. backgroundRepeat: 'no-repeat',
    161. borderWidth: 0,
    162. fillOffsetX: '-5px',
    163. fillOffsetY: '-5px',
    164. fillType: 'radial',
    165. label: {
    166. visible: false
    167. },
    168. tooltip: {
    169. visible: false
    170. }
    171. }
    172. },
    173. plotarea: {
    174. margin: '60px 40px 40px 60px'
    175. },
    176. images: [{
    177. src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas0.png',
    178. visible: false
    179. },
    180. {
    181. src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas1.png',
    182. visible: false
    183. },
    184. {
    185. src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas2.png',
    186. visible: false
    187. },
    188. {
    189. src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas3.png',
    190. visible: false
    191. },
    192. {
    193. src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas4.png',
    194. visible: false
    195. },
    196. {
    197. src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas5.png',
    198. visible: false
    199. },
    200. {
    201. src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas6.png',
    202. visible: false
    203. },
    204. {
    205. src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas7.png',
    206. visible: false
    207. },
    208. {
    209. src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas8.png',
    210. visible: false
    211. },
    212. {
    213. src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas9.png',
    214. visible: false
    215. }
    216. ],
    217. shapes: [],
    218. source: {
    219. fontSize: '12px',
    220. margin: 'auto 25px 25px 25px',
    221. text: 'Happy Holidays from ZingChart!'
    222. },
    223. series: []
    224. };
    225.  
    226. // Build layout
    227. let rows = Math.round(height / 20);
    228. let cols = Math.round(width / 20);
    229. let iCharCode;
    230. for (let row = 0; row < rows; row++) {
    231. iCharCode = NAME.charCodeAt(row % NAME.length);
    232. chartConfig.shapes.push({
    233. type: 'star5',
    234. flat: true,
    235. backgroundColor: COLORS[iCharCode % COLORS.length],
    236. size: 4 + iCharCode % 4,
    237. x: 10,
    238. y: 10 + row * 20
    239. }, {
    240. type: 'star5',
    241. flat: true,
    242. backgroundColor: COLORS[iCharCode % COLORS.length],
    243. size: 4 + iCharCode % 4,
    244. x: width - 10,
    245. y: 10 + row * 20
    246. });
    247. }
    248. for (let col = 1; col < cols - 1; col++) {
    249. iCharCode = NAME.charCodeAt(col % NAME.length);
    250. chartConfig.shapes.push({
    251. type: 'star5',
    252. flat: true,
    253. backgroundColor: COLORS[iCharCode % COLORS.length],
    254. size: 4 + iCharCode % 4,
    255. x: 10 + col * 20,
    256. y: 10
    257. }, {
    258. type: 'star5',
    259. flat: true,
    260. backgroundColor: COLORS[iCharCode % COLORS.length],
    261. size: 4 + iCharCode % 4,
    262. x: 10 + col * 20,
    263. y: height - 10
    264. });
    265. }
    266.  
    267. // Render the chart
    268. zingchart.render({
    269. id: chartId,
    270. width,
    271. height,
    272. output: 'canvas',
    273. data: chartConfig,
    274. events: {
    275. load: function() {
    276. tick = window.setInterval(fnStep, 150);
    277. }
    278. }
    279. });
    280.  
    281. function fnStep() {
    282. let i, sSource, sTarget, aPairs, oLink;
    283. let iCharCode = NAME.charCodeAt((sequence + colorSequence) % NAME.length);
    284. let iColorCharCode = NAME.charCodeAt(colorSequence % NAME.length);
    285. // get data from graph
    286. let aData = zingchart.exec(chartId, 'tree.getdata') || [];
    287. // count links for each node
    288. let oNodesLinks = {},
    289. aNodesIds = [],
    290. aLinksIds = [];
    291. for (i = 0; i < aData.length; i++) {
    292. if (aData[i].type === 'link') {
    293. oNodesLinks[aData[i].source] = ++oNodesLinks[aData[i].source] || 1;
    294. oNodesLinks[aData[i].target] = ++oNodesLinks[aData[i].target] || 1;
    295. aLinksIds.push(aData[i].source + '-' + aData[i].target);
    296. aLinksIds.push(aData[i].target + '-' + aData[i].source);
    297. } else if (aData[i].type === 'node') {
    298. aNodesIds.push(aData[i].id);
    299. }
    300. }
    301.  
    302. // remove all nodes with no links
    303. if (aNodesIds.length > 2) {
    304. for (i = 0; i < aNodesIds.length; i++) {
    305. if (!oNodesLinks[aNodesIds[i]]) {
    306. zingchart.exec(chartId, 'tree.removenode', {
    307. id: aNodesIds[i]
    308. });
    309. }
    310. }
    311. }
    312.  
    313. // from time to time remove oldest leaves
    314. if (sequence % 5 === 0 && aNodesIds.length > 5) {
    315. for (i = 0; i < aNodesIds.length; i++) {
    316. if (oNodesLinks[aNodesIds[i]] === 1) {
    317. zingchart.exec(chartId, 'tree.removenode', {
    318. id: aNodesIds[i]
    319. });
    320. sequence++;
    321. return;
    322. }
    323. }
    324. }
    325.  
    326. // from time to time remove nodes with too many links
    327. if (sequence % 13 === 0 && aNodesIds.length > 5) {
    328. for (i = 0; i < aNodesIds.length; i++) {
    329. if (oNodesLinks[aNodesIds[i]] > 3) {
    330. zingchart.exec(chartId, 'tree.removenode', {
    331. id: aNodesIds[i]
    332. });
    333. sequence++;
    334. return;
    335. }
    336. }
    337. }
    338.  
    339. // from time to time just create a link between existing nodes
    340. if (sequence % 7 === 0 && aNodesIds.length > 3) {
    341. aPairs = [];
    342. for (i = 0; i < aNodesIds.length; i++) {
    343. if (oNodesLinks[aNodesIds[i]] === 1) {
    344. aPairs.push(aNodesIds[i]);
    345. if (aPairs.length === 2) {
    346. oLink = {
    347. source: aPairs[0],
    348. target: aPairs[1],
    349. value: 1 + iCharCode % 2
    350. };
    351. zingchart.exec(chartId, 'tree.addlink', {
    352. data: oLink,
    353. update: true
    354. });
    355. sequence++;
    356. return;
    357. }
    358. }
    359. }
    360. }
    361.  
    362. // otherwise, create a new node
    363. sTarget = 'n' + sequence;
    364. oNode = {
    365. id: sTarget,
    366. text: sTarget,
    367. value: 1,
    368. style: {
    369. backgroundImage: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas' + (sequence % 10) + '.png',
    370. backgroundColor: COLORS[iColorCharCode % COLORS.length]
    371. }
    372. };
    373. colorSequence++;
    374. zingchart.exec(chartId, 'tree.addnode', {
    375. data: oNode,
    376. update: (aNodesIds.length === 0)
    377. });
    378. if (aNodesIds.length > 0) {
    379. sSource = aNodesIds[iCharCode % aNodesIds.length];
    380. oLink = {
    381. source: sSource,
    382. target: sTarget,
    383. value: 1 + iCharCode % 2
    384. };
    385. zingchart.exec(chartId, 'tree.addlink', {
    386. data: oLink,
    387. update: (aNodesIds.length > 0)
    388. });
    389. }
    390. sequence++;
    391. if (sequence > 99) {
    392. window.clearInterval(tick);
    393. renderBtn.removeAttribute('disabled');
    394. }
    395. };
    396. }
    397.  
    398. window.addEventListener('load', function() {
    399. renderChart();
    400. });
    401. </script>
    402. </body>
    403.  
    404. </html>
    1. <!DOCTYPE html>
    2. <html>
    3.  
    4. <head>
    5. <meta charset="utf-8">
    6. <title>ZingChart Demo: Xmas Tree</title>
    7. <script src="https://cdn.zingchart.com/zingchart.min.js"></script>
    8. </head>
    9.  
    10. <body class="zc-body">
    11.  
    12. <div class="zc-info">
    13. <ol>
    14. <li>Enter your full name in the text box and press <strong>Render Tree</strong>.</li>
    15. <li>Based on your name, a unique, force-directed graph will be generated. While the structure will always be the same, the position of the nodes may (slightly) differ every time.</li>
    16. <li>After render, you may make adjustments by dragging nodes around.</li>
    17. <li>Right-click on the tree and choose <strong>View as PNG</strong>.</li>
    18. <li>Right-click again and save your holiday tree.</li>
    19. </ol>
    20. <p>Enjoy! Happy Holidays from ZingChart!</p>
    21. </div>
    22.  
    23. <div class="zc-controls">
    24. <input type="text" id="renderInput" placeholder="Your full name here" value="world">
    25. <button id="renderBtn">Render Tree</button>
    26. </div>
    27.  
    28. <div id="myChart"></div>
    29.  
    30. </body>
    31.  
    32. </html>
    1. .zc-body {
    2. margin: 10px;
    3. padding: 10px;
    4. background: #fbfbfb;
    5. }
    6.  
    7. .zc-info {
    8. margin-bottom: 10px;
    9. border-bottom: 1px solid #ccc;
    10. }
    11.  
    12. .zc-info ol {
    13. margin: 0 0 22px;
    14. padding: 0 0 0 1rem;
    15. font-size: 14px;
    16. }
    17.  
    18. .zc-info p {
    19. color: #dc1257;
    20. }
    21.  
    22. .zc-controls {
    23. padding: 5px 0;
    24. }
    25.  
    26. .zc-controls input {
    27. height: 40px;
    28. border: 1px solid #ebebeb;
    29. border-radius: 4px;
    30. box-sizing: border-box;
    31. font-size: 1rem;
    32. padding: 0 10px;
    33. }
    34.  
    35. .zc-controls input:focus {
    36. font-size: 1rem;
    37. }
    38.  
    39. .zc-controls button {
    40. color: #fff;
    41. background: #073c4e;
    42. border: 1px solid #ebebeb;
    43. border-radius: 4px;
    44. cursor: pointer;
    45. font-size: .8125rem;
    46. padding: 0 10px;
    47. height: 40px;
    48. }
    49.  
    50. .zc-controls button[disabled] {
    51. cursor: not-allowed;
    52. }
    1. // INIT
    2. // -----------------------------
    3. // Define Module Location
    4. zingchart.MODULESDIR = "https://cdn.zingchart.com/modules/";
    5.  
    6. // DEFINE CHART
    7. // -----------------------------
    8. // Main chart render location
    9. let chartId = 'myChart';
    10.  
    11. // DOM ELEMENTS
    12. // -----------------------------
    13. let renderBtn = document.querySelector('#renderBtn');
    14. let renderInput = document.querySelector('#renderInput');
    15.  
    16.  
    17. // RENDER BUTTON EVENTS
    18. // -----------------------------
    19. renderBtn.addEventListener('click', renderChart);
    20.  
    21.  
    22. // HELPER FNS
    23. // -----------------------------
    24.  
    25. // Render Chart
    26. function renderChart() {
    27. // Disable render button
    28. renderBtn.setAttribute('disabled', 'disabled')
    29.  
    30. // Define constants
    31. const COLORS = [
    32. '#99ccff #336699',
    33. '#6CB359 #0F4800',
    34. '#9A5E9A #430443',
    35. '#FFA153 #AC4E00',
    36. '#FF653D #A62300',
    37. '#57B8C6 #095B67',
    38. '#FFE66D #AF930B',
    39. '#EF668F #9D0A36'
    40. ];
    41. const NAME = renderInput.value.trim() || 'Santa Claus';
    42. let width = '100%';
    43. let height = 560;
    44. let colorSequence = 0;
    45. let sequence = 0;
    46. let tick = null;
    47.  
    48. // Define data
    49. let chartConfig = {
    50. type: 'tree',
    51. title: {
    52. text: 'Hello ' + NAME + ', here\'s your holiday tree',
    53. color: '#333333',
    54. fontSize: '17px',
    55. padding: '25px'
    56. },
    57. options: {
    58. aspect: 'graph',
    59. attractionConstant: 0.1,
    60. minSize: '16px',
    61. maxSize: '16px',
    62. minLinkWidth: '1px',
    63. maxLinkWidth: '1px',
    64. repulsionConstant: 400,
    65. repulsionDistanceFactor: 5,
    66. springLength: '35px',
    67. textAttr: 'id',
    68. weightedLinks: 1,
    69. weightedNodes: 1,
    70. link: {
    71. lineColor: '#000000'
    72. },
    73. node: {
    74. backgroundColor: 'none',
    75. backgroundPosition: '45% 45%',
    76. backgroundRepeat: 'no-repeat',
    77. borderWidth: 0,
    78. fillOffsetX: '-5px',
    79. fillOffsetY: '-5px',
    80. fillType: 'radial',
    81. label: {
    82. visible: false
    83. },
    84. tooltip: {
    85. visible: false
    86. }
    87. }
    88. },
    89. plotarea: {
    90. margin: '60px 40px 40px 60px'
    91. },
    92. images: [{
    93. src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas0.png',
    94. visible: false
    95. },
    96. {
    97. src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas1.png',
    98. visible: false
    99. },
    100. {
    101. src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas2.png',
    102. visible: false
    103. },
    104. {
    105. src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas3.png',
    106. visible: false
    107. },
    108. {
    109. src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas4.png',
    110. visible: false
    111. },
    112. {
    113. src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas5.png',
    114. visible: false
    115. },
    116. {
    117. src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas6.png',
    118. visible: false
    119. },
    120. {
    121. src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas7.png',
    122. visible: false
    123. },
    124. {
    125. src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas8.png',
    126. visible: false
    127. },
    128. {
    129. src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas9.png',
    130. visible: false
    131. }
    132. ],
    133. shapes: [],
    134. source: {
    135. fontSize: '12px',
    136. margin: 'auto 25px 25px 25px',
    137. text: 'Happy Holidays from ZingChart!'
    138. },
    139. series: []
    140. };
    141.  
    142. // Build layout
    143. let rows = Math.round(height / 20);
    144. let cols = Math.round(width / 20);
    145. let iCharCode;
    146. for (let row = 0; row < rows; row++) {
    147. iCharCode = NAME.charCodeAt(row % NAME.length);
    148. chartConfig.shapes.push({
    149. type: 'star5',
    150. flat: true,
    151. backgroundColor: COLORS[iCharCode % COLORS.length],
    152. size: 4 + iCharCode % 4,
    153. x: 10,
    154. y: 10 + row * 20
    155. }, {
    156. type: 'star5',
    157. flat: true,
    158. backgroundColor: COLORS[iCharCode % COLORS.length],
    159. size: 4 + iCharCode % 4,
    160. x: width - 10,
    161. y: 10 + row * 20
    162. });
    163. }
    164. for (let col = 1; col < cols - 1; col++) {
    165. iCharCode = NAME.charCodeAt(col % NAME.length);
    166. chartConfig.shapes.push({
    167. type: 'star5',
    168. flat: true,
    169. backgroundColor: COLORS[iCharCode % COLORS.length],
    170. size: 4 + iCharCode % 4,
    171. x: 10 + col * 20,
    172. y: 10
    173. }, {
    174. type: 'star5',
    175. flat: true,
    176. backgroundColor: COLORS[iCharCode % COLORS.length],
    177. size: 4 + iCharCode % 4,
    178. x: 10 + col * 20,
    179. y: height - 10
    180. });
    181. }
    182.  
    183. // Render the chart
    184. zingchart.render({
    185. id: chartId,
    186. width,
    187. height,
    188. output: 'canvas',
    189. data: chartConfig,
    190. events: {
    191. load: function() {
    192. tick = window.setInterval(fnStep, 150);
    193. }
    194. }
    195. });
    196.  
    197. function fnStep() {
    198. let i, sSource, sTarget, aPairs, oLink;
    199. let iCharCode = NAME.charCodeAt((sequence + colorSequence) % NAME.length);
    200. let iColorCharCode = NAME.charCodeAt(colorSequence % NAME.length);
    201. // get data from graph
    202. let aData = zingchart.exec(chartId, 'tree.getdata') || [];
    203. // count links for each node
    204. let oNodesLinks = {},
    205. aNodesIds = [],
    206. aLinksIds = [];
    207. for (i = 0; i < aData.length; i++) {
    208. if (aData[i].type === 'link') {
    209. oNodesLinks[aData[i].source] = ++oNodesLinks[aData[i].source] || 1;
    210. oNodesLinks[aData[i].target] = ++oNodesLinks[aData[i].target] || 1;
    211. aLinksIds.push(aData[i].source + '-' + aData[i].target);
    212. aLinksIds.push(aData[i].target + '-' + aData[i].source);
    213. } else if (aData[i].type === 'node') {
    214. aNodesIds.push(aData[i].id);
    215. }
    216. }
    217.  
    218. // remove all nodes with no links
    219. if (aNodesIds.length > 2) {
    220. for (i = 0; i < aNodesIds.length; i++) {
    221. if (!oNodesLinks[aNodesIds[i]]) {
    222. zingchart.exec(chartId, 'tree.removenode', {
    223. id: aNodesIds[i]
    224. });
    225. }
    226. }
    227. }
    228.  
    229. // from time to time remove oldest leaves
    230. if (sequence % 5 === 0 && aNodesIds.length > 5) {
    231. for (i = 0; i < aNodesIds.length; i++) {
    232. if (oNodesLinks[aNodesIds[i]] === 1) {
    233. zingchart.exec(chartId, 'tree.removenode', {
    234. id: aNodesIds[i]
    235. });
    236. sequence++;
    237. return;
    238. }
    239. }
    240. }
    241.  
    242. // from time to time remove nodes with too many links
    243. if (sequence % 13 === 0 && aNodesIds.length > 5) {
    244. for (i = 0; i < aNodesIds.length; i++) {
    245. if (oNodesLinks[aNodesIds[i]] > 3) {
    246. zingchart.exec(chartId, 'tree.removenode', {
    247. id: aNodesIds[i]
    248. });
    249. sequence++;
    250. return;
    251. }
    252. }
    253. }
    254.  
    255. // from time to time just create a link between existing nodes
    256. if (sequence % 7 === 0 && aNodesIds.length > 3) {
    257. aPairs = [];
    258. for (i = 0; i < aNodesIds.length; i++) {
    259. if (oNodesLinks[aNodesIds[i]] === 1) {
    260. aPairs.push(aNodesIds[i]);
    261. if (aPairs.length === 2) {
    262. oLink = {
    263. source: aPairs[0],
    264. target: aPairs[1],
    265. value: 1 + iCharCode % 2
    266. };
    267. zingchart.exec(chartId, 'tree.addlink', {
    268. data: oLink,
    269. update: true
    270. });
    271. sequence++;
    272. return;
    273. }
    274. }
    275. }
    276. }
    277.  
    278. // otherwise, create a new node
    279. sTarget = 'n' + sequence;
    280. oNode = {
    281. id: sTarget,
    282. text: sTarget,
    283. value: 1,
    284. style: {
    285. backgroundImage: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas' + (sequence % 10) + '.png',
    286. backgroundColor: COLORS[iColorCharCode % COLORS.length]
    287. }
    288. };
    289. colorSequence++;
    290. zingchart.exec(chartId, 'tree.addnode', {
    291. data: oNode,
    292. update: (aNodesIds.length === 0)
    293. });
    294. if (aNodesIds.length > 0) {
    295. sSource = aNodesIds[iCharCode % aNodesIds.length];
    296. oLink = {
    297. source: sSource,
    298. target: sTarget,
    299. value: 1 + iCharCode % 2
    300. };
    301. zingchart.exec(chartId, 'tree.addlink', {
    302. data: oLink,
    303. update: (aNodesIds.length > 0)
    304. });
    305. }
    306. sequence++;
    307. if (sequence > 99) {
    308. window.clearInterval(tick);
    309. renderBtn.removeAttribute('disabled');
    310. }
    311. };
    312. }
    313.  
    314. window.addEventListener('load', function() {
    315. renderChart();
    316. });