- <!DOCTYPE html>
- <html>
-
- <head>
- <meta charset="utf-8">
- <title>ZingChart Demo: Xmas Tree</title>
- <script nonce="undefined" src="https://cdn.zingchart.com/zingchart.min.js"></script>
- <style>
- .zc-body {
- margin: 10px;
- padding: 10px;
- background: #fbfbfb;
- }
-
- .zc-info {
- margin-bottom: 10px;
- border-bottom: 1px solid #ccc;
- }
-
- .zc-info ol {
- margin: 0 0 22px;
- padding: 0 0 0 1rem;
- font-size: 14px;
- }
-
- .zc-info p {
- color: #dc1257;
- }
-
- .zc-controls {
- padding: 5px 0;
- }
-
- .zc-controls input {
- height: 40px;
- border: 1px solid #ebebeb;
- border-radius: 4px;
- box-sizing: border-box;
- font-size: 1rem;
- padding: 0 10px;
- }
-
- .zc-controls input:focus {
- font-size: 1rem;
- }
-
- .zc-controls button {
- color: #fff;
- background: #073c4e;
- border: 1px solid #ebebeb;
- border-radius: 4px;
- cursor: pointer;
- font-size: .8125rem;
- padding: 0 10px;
- height: 40px;
- }
-
- .zc-controls button[disabled] {
- cursor: not-allowed;
- }
- </style>
- </head>
-
- <body class="zc-body">
-
- <div class="zc-info">
- <ol>
- <li>Enter your full name in the text box and press <strong>Render Tree</strong>.</li>
- <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>
- <li>After render, you may make adjustments by dragging nodes around.</li>
- <li>Right-click on the tree and choose <strong>View as PNG</strong>.</li>
- <li>Right-click again and save your holiday tree.</li>
- </ol>
- <p>Enjoy! Happy Holidays from ZingChart!</p>
- </div>
-
- <div class="zc-controls">
- <input type="text" id="renderInput" placeholder="Your full name here" value="world">
- <button id="renderBtn">Render Tree</button>
- </div>
-
- <div id="myChart"></div>
-
- <script>
- ZC.LICENSE = ["569d52cefae586f634c54f86dc99e6a9", "b55b025e438fa8a98e32482b5f768ff5"]; // INIT
- // -----------------------------
- // Define Module Location
- zingchart.MODULESDIR = "https://cdn.zingchart.com/modules/";
-
- // DEFINE CHART
- // -----------------------------
- // Main chart render location
- let chartId = 'myChart';
-
- // DOM ELEMENTS
- // -----------------------------
- let renderBtn = document.querySelector('#renderBtn');
- let renderInput = document.querySelector('#renderInput');
-
-
- // RENDER BUTTON EVENTS
- // -----------------------------
- renderBtn.addEventListener('click', renderChart);
-
-
- // HELPER FNS
- // -----------------------------
-
- // Render Chart
- function renderChart() {
- // Disable render button
- renderBtn.setAttribute('disabled', 'disabled')
-
- // Define constants
- const COLORS = [
- '#99ccff #336699',
- '#6CB359 #0F4800',
- '#9A5E9A #430443',
- '#FFA153 #AC4E00',
- '#FF653D #A62300',
- '#57B8C6 #095B67',
- '#FFE66D #AF930B',
- '#EF668F #9D0A36'
- ];
- const NAME = renderInput.value.trim() || 'Santa Claus';
- let width = '100%';
- let height = 560;
- let colorSequence = 0;
- let sequence = 0;
- let tick = null;
-
- // Define data
- let chartConfig = {
- type: 'tree',
- title: {
- text: 'Hello ' + NAME + ', here\'s your holiday tree',
- color: '#333333',
- fontSize: '17px',
- padding: '25px'
- },
- options: {
- aspect: 'graph',
- attractionConstant: 0.1,
- minSize: '16px',
- maxSize: '16px',
- minLinkWidth: '1px',
- maxLinkWidth: '1px',
- repulsionConstant: 400,
- repulsionDistanceFactor: 5,
- springLength: '35px',
- textAttr: 'id',
- weightedLinks: 1,
- weightedNodes: 1,
- link: {
- lineColor: '#000000'
- },
- node: {
- backgroundColor: 'none',
- backgroundPosition: '45% 45%',
- backgroundRepeat: 'no-repeat',
- borderWidth: 0,
- fillOffsetX: '-5px',
- fillOffsetY: '-5px',
- fillType: 'radial',
- label: {
- visible: false
- },
- tooltip: {
- visible: false
- }
- }
- },
- plotarea: {
- margin: '60px 40px 40px 60px'
- },
- images: [{
- src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas0.png',
- visible: false
- },
- {
- src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas1.png',
- visible: false
- },
- {
- src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas2.png',
- visible: false
- },
- {
- src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas3.png',
- visible: false
- },
- {
- src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas4.png',
- visible: false
- },
- {
- src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas5.png',
- visible: false
- },
- {
- src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas6.png',
- visible: false
- },
- {
- src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas7.png',
- visible: false
- },
- {
- src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas8.png',
- visible: false
- },
- {
- src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas9.png',
- visible: false
- }
- ],
- shapes: [],
- source: {
- fontSize: '12px',
- margin: 'auto 25px 25px 25px',
- text: 'Happy Holidays from ZingChart!'
- },
- series: []
- };
-
- // Build layout
- let rows = Math.round(height / 20);
- let cols = Math.round(width / 20);
- let iCharCode;
- for (let row = 0; row < rows; row++) {
- iCharCode = NAME.charCodeAt(row % NAME.length);
- chartConfig.shapes.push({
- type: 'star5',
- flat: true,
- backgroundColor: COLORS[iCharCode % COLORS.length],
- size: 4 + iCharCode % 4,
- x: 10,
- y: 10 + row * 20
- }, {
- type: 'star5',
- flat: true,
- backgroundColor: COLORS[iCharCode % COLORS.length],
- size: 4 + iCharCode % 4,
- x: width - 10,
- y: 10 + row * 20
- });
- }
- for (let col = 1; col < cols - 1; col++) {
- iCharCode = NAME.charCodeAt(col % NAME.length);
- chartConfig.shapes.push({
- type: 'star5',
- flat: true,
- backgroundColor: COLORS[iCharCode % COLORS.length],
- size: 4 + iCharCode % 4,
- x: 10 + col * 20,
- y: 10
- }, {
- type: 'star5',
- flat: true,
- backgroundColor: COLORS[iCharCode % COLORS.length],
- size: 4 + iCharCode % 4,
- x: 10 + col * 20,
- y: height - 10
- });
- }
-
- // Render the chart
- zingchart.render({
- id: chartId,
- width,
- height,
- output: 'canvas',
- data: chartConfig,
- events: {
- load: function() {
- tick = window.setInterval(fnStep, 150);
- }
- }
- });
-
- function fnStep() {
- let i, sSource, sTarget, aPairs, oLink;
- let iCharCode = NAME.charCodeAt((sequence + colorSequence) % NAME.length);
- let iColorCharCode = NAME.charCodeAt(colorSequence % NAME.length);
- // get data from graph
- let aData = zingchart.exec(chartId, 'tree.getdata') || [];
- // count links for each node
- let oNodesLinks = {},
- aNodesIds = [],
- aLinksIds = [];
- for (i = 0; i < aData.length; i++) {
- if (aData[i].type === 'link') {
- oNodesLinks[aData[i].source] = ++oNodesLinks[aData[i].source] || 1;
- oNodesLinks[aData[i].target] = ++oNodesLinks[aData[i].target] || 1;
- aLinksIds.push(aData[i].source + '-' + aData[i].target);
- aLinksIds.push(aData[i].target + '-' + aData[i].source);
- } else if (aData[i].type === 'node') {
- aNodesIds.push(aData[i].id);
- }
- }
-
- // remove all nodes with no links
- if (aNodesIds.length > 2) {
- for (i = 0; i < aNodesIds.length; i++) {
- if (!oNodesLinks[aNodesIds[i]]) {
- zingchart.exec(chartId, 'tree.removenode', {
- id: aNodesIds[i]
- });
- }
- }
- }
-
- // from time to time remove oldest leaves
- if (sequence % 5 === 0 && aNodesIds.length > 5) {
- for (i = 0; i < aNodesIds.length; i++) {
- if (oNodesLinks[aNodesIds[i]] === 1) {
- zingchart.exec(chartId, 'tree.removenode', {
- id: aNodesIds[i]
- });
- sequence++;
- return;
- }
- }
- }
-
- // from time to time remove nodes with too many links
- if (sequence % 13 === 0 && aNodesIds.length > 5) {
- for (i = 0; i < aNodesIds.length; i++) {
- if (oNodesLinks[aNodesIds[i]] > 3) {
- zingchart.exec(chartId, 'tree.removenode', {
- id: aNodesIds[i]
- });
- sequence++;
- return;
- }
- }
- }
-
- // from time to time just create a link between existing nodes
- if (sequence % 7 === 0 && aNodesIds.length > 3) {
- aPairs = [];
- for (i = 0; i < aNodesIds.length; i++) {
- if (oNodesLinks[aNodesIds[i]] === 1) {
- aPairs.push(aNodesIds[i]);
- if (aPairs.length === 2) {
- oLink = {
- source: aPairs[0],
- target: aPairs[1],
- value: 1 + iCharCode % 2
- };
- zingchart.exec(chartId, 'tree.addlink', {
- data: oLink,
- update: true
- });
- sequence++;
- return;
- }
- }
- }
- }
-
- // otherwise, create a new node
- sTarget = 'n' + sequence;
- oNode = {
- id: sTarget,
- text: sTarget,
- value: 1,
- style: {
- backgroundImage: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas' + (sequence % 10) + '.png',
- backgroundColor: COLORS[iColorCharCode % COLORS.length]
- }
- };
- colorSequence++;
- zingchart.exec(chartId, 'tree.addnode', {
- data: oNode,
- update: (aNodesIds.length === 0)
- });
- if (aNodesIds.length > 0) {
- sSource = aNodesIds[iCharCode % aNodesIds.length];
- oLink = {
- source: sSource,
- target: sTarget,
- value: 1 + iCharCode % 2
- };
- zingchart.exec(chartId, 'tree.addlink', {
- data: oLink,
- update: (aNodesIds.length > 0)
- });
- }
- sequence++;
- if (sequence > 99) {
- window.clearInterval(tick);
- renderBtn.removeAttribute('disabled');
- }
- };
- }
-
- window.addEventListener('load', function() {
- renderChart();
- });
- </script>
- </body>
-
- </html>
- <!DOCTYPE html>
- <html>
-
- <head>
- <meta charset="utf-8">
- <title>ZingChart Demo: Xmas Tree</title>
- <script src="https://cdn.zingchart.com/zingchart.min.js"></script>
- </head>
-
- <body class="zc-body">
-
- <div class="zc-info">
- <ol>
- <li>Enter your full name in the text box and press <strong>Render Tree</strong>.</li>
- <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>
- <li>After render, you may make adjustments by dragging nodes around.</li>
- <li>Right-click on the tree and choose <strong>View as PNG</strong>.</li>
- <li>Right-click again and save your holiday tree.</li>
- </ol>
- <p>Enjoy! Happy Holidays from ZingChart!</p>
- </div>
-
- <div class="zc-controls">
- <input type="text" id="renderInput" placeholder="Your full name here" value="world">
- <button id="renderBtn">Render Tree</button>
- </div>
-
- <div id="myChart"></div>
-
- </body>
-
- </html>
- .zc-body {
- margin: 10px;
- padding: 10px;
- background: #fbfbfb;
- }
-
- .zc-info {
- margin-bottom: 10px;
- border-bottom: 1px solid #ccc;
- }
-
- .zc-info ol {
- margin: 0 0 22px;
- padding: 0 0 0 1rem;
- font-size: 14px;
- }
-
- .zc-info p {
- color: #dc1257;
- }
-
- .zc-controls {
- padding: 5px 0;
- }
-
- .zc-controls input {
- height: 40px;
- border: 1px solid #ebebeb;
- border-radius: 4px;
- box-sizing: border-box;
- font-size: 1rem;
- padding: 0 10px;
- }
-
- .zc-controls input:focus {
- font-size: 1rem;
- }
-
- .zc-controls button {
- color: #fff;
- background: #073c4e;
- border: 1px solid #ebebeb;
- border-radius: 4px;
- cursor: pointer;
- font-size: .8125rem;
- padding: 0 10px;
- height: 40px;
- }
-
- .zc-controls button[disabled] {
- cursor: not-allowed;
- }
- // INIT
- // -----------------------------
- // Define Module Location
- zingchart.MODULESDIR = "https://cdn.zingchart.com/modules/";
-
- // DEFINE CHART
- // -----------------------------
- // Main chart render location
- let chartId = 'myChart';
-
- // DOM ELEMENTS
- // -----------------------------
- let renderBtn = document.querySelector('#renderBtn');
- let renderInput = document.querySelector('#renderInput');
-
-
- // RENDER BUTTON EVENTS
- // -----------------------------
- renderBtn.addEventListener('click', renderChart);
-
-
- // HELPER FNS
- // -----------------------------
-
- // Render Chart
- function renderChart() {
- // Disable render button
- renderBtn.setAttribute('disabled', 'disabled')
-
- // Define constants
- const COLORS = [
- '#99ccff #336699',
- '#6CB359 #0F4800',
- '#9A5E9A #430443',
- '#FFA153 #AC4E00',
- '#FF653D #A62300',
- '#57B8C6 #095B67',
- '#FFE66D #AF930B',
- '#EF668F #9D0A36'
- ];
- const NAME = renderInput.value.trim() || 'Santa Claus';
- let width = '100%';
- let height = 560;
- let colorSequence = 0;
- let sequence = 0;
- let tick = null;
-
- // Define data
- let chartConfig = {
- type: 'tree',
- title: {
- text: 'Hello ' + NAME + ', here\'s your holiday tree',
- color: '#333333',
- fontSize: '17px',
- padding: '25px'
- },
- options: {
- aspect: 'graph',
- attractionConstant: 0.1,
- minSize: '16px',
- maxSize: '16px',
- minLinkWidth: '1px',
- maxLinkWidth: '1px',
- repulsionConstant: 400,
- repulsionDistanceFactor: 5,
- springLength: '35px',
- textAttr: 'id',
- weightedLinks: 1,
- weightedNodes: 1,
- link: {
- lineColor: '#000000'
- },
- node: {
- backgroundColor: 'none',
- backgroundPosition: '45% 45%',
- backgroundRepeat: 'no-repeat',
- borderWidth: 0,
- fillOffsetX: '-5px',
- fillOffsetY: '-5px',
- fillType: 'radial',
- label: {
- visible: false
- },
- tooltip: {
- visible: false
- }
- }
- },
- plotarea: {
- margin: '60px 40px 40px 60px'
- },
- images: [{
- src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas0.png',
- visible: false
- },
- {
- src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas1.png',
- visible: false
- },
- {
- src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas2.png',
- visible: false
- },
- {
- src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas3.png',
- visible: false
- },
- {
- src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas4.png',
- visible: false
- },
- {
- src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas5.png',
- visible: false
- },
- {
- src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas6.png',
- visible: false
- },
- {
- src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas7.png',
- visible: false
- },
- {
- src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas8.png',
- visible: false
- },
- {
- src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas9.png',
- visible: false
- }
- ],
- shapes: [],
- source: {
- fontSize: '12px',
- margin: 'auto 25px 25px 25px',
- text: 'Happy Holidays from ZingChart!'
- },
- series: []
- };
-
- // Build layout
- let rows = Math.round(height / 20);
- let cols = Math.round(width / 20);
- let iCharCode;
- for (let row = 0; row < rows; row++) {
- iCharCode = NAME.charCodeAt(row % NAME.length);
- chartConfig.shapes.push({
- type: 'star5',
- flat: true,
- backgroundColor: COLORS[iCharCode % COLORS.length],
- size: 4 + iCharCode % 4,
- x: 10,
- y: 10 + row * 20
- }, {
- type: 'star5',
- flat: true,
- backgroundColor: COLORS[iCharCode % COLORS.length],
- size: 4 + iCharCode % 4,
- x: width - 10,
- y: 10 + row * 20
- });
- }
- for (let col = 1; col < cols - 1; col++) {
- iCharCode = NAME.charCodeAt(col % NAME.length);
- chartConfig.shapes.push({
- type: 'star5',
- flat: true,
- backgroundColor: COLORS[iCharCode % COLORS.length],
- size: 4 + iCharCode % 4,
- x: 10 + col * 20,
- y: 10
- }, {
- type: 'star5',
- flat: true,
- backgroundColor: COLORS[iCharCode % COLORS.length],
- size: 4 + iCharCode % 4,
- x: 10 + col * 20,
- y: height - 10
- });
- }
-
- // Render the chart
- zingchart.render({
- id: chartId,
- width,
- height,
- output: 'canvas',
- data: chartConfig,
- events: {
- load: function() {
- tick = window.setInterval(fnStep, 150);
- }
- }
- });
-
- function fnStep() {
- let i, sSource, sTarget, aPairs, oLink;
- let iCharCode = NAME.charCodeAt((sequence + colorSequence) % NAME.length);
- let iColorCharCode = NAME.charCodeAt(colorSequence % NAME.length);
- // get data from graph
- let aData = zingchart.exec(chartId, 'tree.getdata') || [];
- // count links for each node
- let oNodesLinks = {},
- aNodesIds = [],
- aLinksIds = [];
- for (i = 0; i < aData.length; i++) {
- if (aData[i].type === 'link') {
- oNodesLinks[aData[i].source] = ++oNodesLinks[aData[i].source] || 1;
- oNodesLinks[aData[i].target] = ++oNodesLinks[aData[i].target] || 1;
- aLinksIds.push(aData[i].source + '-' + aData[i].target);
- aLinksIds.push(aData[i].target + '-' + aData[i].source);
- } else if (aData[i].type === 'node') {
- aNodesIds.push(aData[i].id);
- }
- }
-
- // remove all nodes with no links
- if (aNodesIds.length > 2) {
- for (i = 0; i < aNodesIds.length; i++) {
- if (!oNodesLinks[aNodesIds[i]]) {
- zingchart.exec(chartId, 'tree.removenode', {
- id: aNodesIds[i]
- });
- }
- }
- }
-
- // from time to time remove oldest leaves
- if (sequence % 5 === 0 && aNodesIds.length > 5) {
- for (i = 0; i < aNodesIds.length; i++) {
- if (oNodesLinks[aNodesIds[i]] === 1) {
- zingchart.exec(chartId, 'tree.removenode', {
- id: aNodesIds[i]
- });
- sequence++;
- return;
- }
- }
- }
-
- // from time to time remove nodes with too many links
- if (sequence % 13 === 0 && aNodesIds.length > 5) {
- for (i = 0; i < aNodesIds.length; i++) {
- if (oNodesLinks[aNodesIds[i]] > 3) {
- zingchart.exec(chartId, 'tree.removenode', {
- id: aNodesIds[i]
- });
- sequence++;
- return;
- }
- }
- }
-
- // from time to time just create a link between existing nodes
- if (sequence % 7 === 0 && aNodesIds.length > 3) {
- aPairs = [];
- for (i = 0; i < aNodesIds.length; i++) {
- if (oNodesLinks[aNodesIds[i]] === 1) {
- aPairs.push(aNodesIds[i]);
- if (aPairs.length === 2) {
- oLink = {
- source: aPairs[0],
- target: aPairs[1],
- value: 1 + iCharCode % 2
- };
- zingchart.exec(chartId, 'tree.addlink', {
- data: oLink,
- update: true
- });
- sequence++;
- return;
- }
- }
- }
- }
-
- // otherwise, create a new node
- sTarget = 'n' + sequence;
- oNode = {
- id: sTarget,
- text: sTarget,
- value: 1,
- style: {
- backgroundImage: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/374756/xmas' + (sequence % 10) + '.png',
- backgroundColor: COLORS[iColorCharCode % COLORS.length]
- }
- };
- colorSequence++;
- zingchart.exec(chartId, 'tree.addnode', {
- data: oNode,
- update: (aNodesIds.length === 0)
- });
- if (aNodesIds.length > 0) {
- sSource = aNodesIds[iCharCode % aNodesIds.length];
- oLink = {
- source: sSource,
- target: sTarget,
- value: 1 + iCharCode % 2
- };
- zingchart.exec(chartId, 'tree.addlink', {
- data: oLink,
- update: (aNodesIds.length > 0)
- });
- }
- sequence++;
- if (sequence > 99) {
- window.clearInterval(tick);
- renderBtn.removeAttribute('disabled');
- }
- };
- }
-
- window.addEventListener('load', function() {
- renderChart();
- });