### Flatten Tree Structure Source: https://github.com/puppeteer/examples/blob/master/html/d3tree_images.html Recursively traverses the D3 tree structure starting from the root node and collects all nodes into a flat array. Assigns unique IDs to nodes if they don't already exist. ```javascript /** * Returns a list of all nodes under the root. */ function flatten(root) { var nodes = []; var i = 0; function recurse(node) { if (node.children) node.children.forEach(recurse); if (!node.id) node.id = ++i; nodes.push(node); } recurse(root); return nodes; } ``` -------------------------------- ### Initialize D3 Force Layout and SVG Source: https://github.com/puppeteer/examples/blob/master/html/d3tree_images.html Sets up the SVG canvas and initializes the D3 force layout with basic parameters. Loads JSON data to build the tree structure. ```javascript var w = 960, h = 800, maxNodeSize = 100, x_browser = 20, y_browser = 25, root; var vis; var force = d3.layout.force(); vis = d3.select("#vis").append("svg").attr("width", w).attr("height", h); d3.json("./output/https___santatracker.google.com_/crawl.json", function(json) { root = json; root.fixed = true; root.x = w / 2; root.y = h / 2; // Build the path var defs = vis.insert("svg:defs").data(["end"]); defs.enter().append("svg:path") .attr("d", "M0,-5L10,0L0,5"); update(); }); ``` -------------------------------- ### Alternative Initialization for Lazy Loading Source: https://github.com/puppeteer/examples/blob/master/html/lazyload.html This demonstrates an alternative way to initialize lazy loading by calling loadIOPolyfillIfNeeded and then chaining the lazyLoadWhenVisible function using .then(). ```javascript loadIOPolyfillIfNeeded().then(lazyLoadWhenVisible); ``` -------------------------------- ### Initialize D3 Tree Layout and SVG Canvas Source: https://github.com/puppeteer/examples/blob/master/html/d3tree.html Sets up the D3 tree layout, diagonal projection, and the main SVG canvas. It also defines margins, dimensions, and appends a group element for the tree structure. This code is essential for any D3-based tree visualization. ```javascript var margin = {top: 20, right: 120, bottom: 20, left: 160}, width = window.innerWidth - margin.right - margin.left, height = window.innerHeight - margin.top - margin.bottom; var i = 0, duration = 250, root; var tree = d3.layout.tree() .size([height, width]); var diagonal = d3.svg.diagonal() .projection(function(d) { return [d.y, d.x]; }); var svg = d3.select("body").append("svg") .attr("width", width + margin.right + margin.left) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); ``` -------------------------------- ### Speak Text using Speech Synthesis API Source: https://github.com/puppeteer/examples/blob/master/html/speech_synth.html Use this function to convert text to speech. It asynchronously fetches available voices and selects a specific one. Ensure the browser supports the Speech Synthesis API. ```javascript async function speak(text) { const msg = new SpeechSynthesisUtterance(); msg.text = text; // msg.volume = 1; // 0 to 1 // msg.rate = 1; // 0.1 to 10 // msg.pitch = 1; //0 to 2 // msg.lang = this.DEST_LANG; msg.voice = await new Promise(resolve => { // Voice are populated, async. speechSynthesis.onvoiceschanged = (e) => { const voices = window.speechSynthesis.getVoices(); // for (const voice of voices) { // console.log(voice.name, voice.localService) // } const name = 'Google UK English Male'; // Note: only works in Google Chrome. resolve(voices.find(voice => voice.name === name)); }; }); msg.onend = e => console.log('SPEECH_DONE'); speechSynthesis.speak(msg); } ``` -------------------------------- ### Update Tree Layout and Render Nodes/Links Source: https://github.com/puppeteer/examples/blob/master/html/d3tree_images.html Updates the force layout with nodes and links, then renders or updates SVG paths for links and groups for nodes. Handles node appearance and interactions. ```javascript function update() { var nodes = flatten(root), links = d3.layout.tree().links(nodes); // Restart the force layout. force.nodes(nodes) .links(links) .gravity(0.05) .charge(-1500) .linkDistance(150) .friction(0.5) .linkStrength(function(l, i) { return 1; }) .size([w, h]) .on("tick", tick) .start(); var path = vis.selectAll("path.link") .data(links, function(d) { return d.target.id; }); path.enter().insert("svg:path") .attr("class", "link") // .attr("marker-end", "url(#end)") .style("stroke", "#eee"); // Exit any old paths. path.exit().remove(); // Update the nodes… var node = vis.selectAll("g.node") .data(nodes, function(d) { return d.id; }); // Enter any new nodes. var nodeEnter = node.enter().append("svg:g") .attr("class", "node") .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }) .on("click", click) .call(force.drag); // Append a circle nodeEnter.append("svg:circle") .attr("r", function(d) { return Math.sqrt(d.size) / 10 || 4.5; }) .style("fill", "#eee"); // Append images var images = nodeEnter.append("svg:image") .attr("xlink:href", function(d) { return d.img;}) .attr("x", function(d) { return -25;}) .attr("y", function(d) { return -25;}) .attr("height", 50) .attr("width", 50); // make the image grow a little on mouse over and add the text details on click var setEvents = images // Append hero text .on( 'click', function (d) { // d3.select("h1").html(d.url); d3.select("h2").html(d.name); d3.select("h3").html ( `Take me to ${d.link || d.name} ⇢` ); }) .on( 'mouseenter', function() { // select element in current context this.parentNode.parentNode.appendChild(this.parentNode); d3.select( this ) .transition() .attr("x", function(d) { return -60;}) .attr("y", function(d) { return -60;}) .attr("height", 400) .attr("width", 400); }) // set back .on( 'mouseleave', function() { d3.select( this ) .transition() .attr("x", function(d) { return -25;}) .attr("y", function(d) { return -25;}) .attr("height", 50) .attr("width", 50); }); // Append hero name on roll over next to the node as well nodeEnter.append("text") .attr("class", "nodetext") .attr("x", x_browser) .attr("y", y_browser +15) .attr("fill", tcBlack) .text(function(d) { return d.title; }); // Exit any old nodes. node.exit().remove(); // Re-select for update. path = vis.selectAll("path.link"); node = vis.selectAll("g.node"); function tick() { path.attr("d", function(d) { var dx = d.target.x - d.source.x, dy = d.target.y - d.source.y, dr = Math.sqrt(dx * dx + dy * dy); return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y; }); node.attr("transform", nodeTransform); } } ``` -------------------------------- ### Load and Process Tree Data Source: https://github.com/puppeteer/examples/blob/master/html/d3tree.html Loads hierarchical data from a specified URL using d3.json and initializes the tree structure. It collapses initial children and prepares the root node for rendering. Ensure the URL points to a valid JSON file with a hierarchical structure. ```javascript const url = new URLSearchParams(location.search).get('url') || '../output/https\_\_news.polymer-project.org/_crawl.json'; console.log(url) d3.json(url, function(error, flare) { if (error) { throw error; } root = flare; root.x0 = height / 2; root.y0 = 0; function collapse(d) { if (d.children) { d._children = d.children; d._children.forEach(collapse); d.children = null; } } root.children.forEach(collapse); update(root); }); ``` -------------------------------- ### Initialize Lazy Loading Source: https://github.com/puppeteer/examples/blob/master/html/lazyload.html This asynchronous IIFE (Immediately Invoked Function Expression) ensures the Intersection Observer polyfill is loaded if necessary, and then calls the function to set up lazy loading for images and iframes. ```javascript (async () => { await loadIOPolyfillIfNeeded(); lazyLoadWhenVisible(); })(); ``` -------------------------------- ### Trigger Speech Synthesis on Button Click Source: https://github.com/puppeteer/examples/blob/master/html/speech_synth.html Attaches an event listener to a button to call the 'speak' function when clicked. Make sure the 'TEXT2SPEECH' variable is defined and contains the text to be spoken. ```javascript const button = document.querySelector('button'); button.addEventListener('click', e => speak(TEXT2SPEECH)); ``` -------------------------------- ### Load Intersection Observer Polyfill Source: https://github.com/puppeteer/examples/blob/master/html/lazyload.html This function checks if the IntersectionObserver API is available in the browser. If not, it dynamically loads a polyfill script from a CDN to ensure compatibility. ```javascript function loadIOPolyfillIfNeeded() { if ('IntersectionObserver' in window) { return Promise.resolve(); } // Note: chrome 41 doesn't support arrow functions return new Promise(function(resolve, reject) { const s = document.createElement('script'); s.async = true; s.src = 'https://cdn.polyfill.io/v2/polyfill.js?features=IntersectionObserver'; ///https://unpkg.com/intersection-observer/intersection-observer.js s.onload = resolve; s.onerror = reject; document.body.appendChild(s); // await import('../node_modules/intersection-observer/intersection-observer.js'); }); } ``` -------------------------------- ### Lazy Load Images/Iframes with Intersection Observer Source: https://github.com/puppeteer/examples/blob/master/html/lazyload.html This function sets up an Intersection Observer to detect when elements with a 'data-src' attribute enter the viewport. Once visible, it sets the 'src' attribute from 'data-src' and unobserves the element. ```javascript window.lazySizesConfig = window.lazySizesConfig || {}; // window.lazySizesConfig.lazyClass = 'lazy'; lazySizesConfig.srcAttr = 'data-original'; function lazyLoadWhenVisible() { const observer = new IntersectionObserver(function(records, observer) { records.forEach(function(record) { const el = record.target; if (!el.src && record.isIntersecting) { el.src = el.dataset.src; delete el.dataset.src; observer.unobserve(el); } }); }, { // rootMargin: '100px', }); const els = document.querySelectorAll('img[data-src],iframe[data-src]'); [].forEach.call(els, function(el) { observer.observe(el); }); } ``` -------------------------------- ### Update Tree Nodes and Links Source: https://github.com/puppeteer/examples/blob/master/html/d3tree.html This function updates the visual representation of the tree, handling node and link transitions. It computes new positions, enters, updates, and exits nodes and links, managing their visual states. Call this function whenever the tree data changes or a node is expanded/collapsed. ```javascript function update(source) { // Compute the new tree layout. var nodes = tree.nodes(root).reverse(), links = tree.links(nodes); // Normalize for fixed-depth. nodes.forEach(function(d) { d.y = d.depth * 180; }); // Update the nodes… var node = svg.selectAll("g.node") .data(nodes, function(d) { return d.id || (d.id = ++i); }); // Enter any new nodes at the parent's previous position. var nodeEnter = node.enter().append("g") .attr("class", "node") .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; }) .on("click", click); nodeEnter.append("circle") .attr("r", 1e-6) .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; }); const text = nodeEnter.append("text") .attr("x", function(d) { return d.children || d._children ? -10 : 10; }) // .attr("x", function(d) { return 10; }) .attr("dy", ".35em") .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; }) // .attr("text-anchor", function(d) { return d.children || d._children ? "start" : "start"; }) .text(function(d) { const url = new URL(d.url); //return url.href.replace(`${url.protocol}//`, ''); // return url.pathname; let title = d.title && d.title.replace('- NEWS', ''); const trunc = 30; if (title && title.length > trunc) title = title.slice(0, trunc).trim() + '...'; return title || d.url; }) .style("fill-opacity", 1e-6); var images = nodeEnter.append("svg:image") .attr("xlink:href", function(d) { return d.img;}) .attr("x", function(d) { return 25;}) .attr("y", function(d) { return -60;}) .attr("height", 100) .attr("width", 100); // nodeEnter.append("text") // .attr("x", function(d) { return d.children || d._children ? -10 : 10; }) // .attr("dy", "2em") // .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; }) // .text(function(d) { return d.url; }) // .style("fill-opacity", 1e-6); // Transition nodes to their new position. var nodeUpdate = node.transition() .duration(duration) .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; }); nodeUpdate.select("circle") .attr("r", 4.5) .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; }); nodeUpdate.selectAll("text") .style("fill-opacity", 1); // Transition exiting nodes to the parent's new position. var nodeExit = node.exit().transition() .duration(duration) .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; }) .remove(); nodeExit.select("circle") .attr("r", 1e-6); nodeExit.select("text") .style("fill-opacity", 1e-6); // Update the links… var link = svg.selectAll("path.link") .data(links, function(d) { return d.target.id; }); // Enter any new links at the parent's previous position. link.enter().insert("path", "g") .attr("class", "link") .attr("d", function(d) { var o = {x: source.x0, y: source.y0}; return diagonal({source: o, target: o}); }); // Transition links to their new position. link.transition() .duration(duration) .attr("d", diagonal); // Transition exiting nodes to the parent's new position. link.exit().transition() .duration(duration) .attr("d", function(d) { var o = {x: source.x, y: source.y}; return diagonal({source: o, target: o}); }) .remove(); // Stash the old positions for transition. nodes.forEach(function(d) { d.x0 = d.x; d.y0 = d.y; }); } ``` -------------------------------- ### Toggle Node Children on Click Source: https://github.com/puppeteer/examples/blob/master/html/d3tree.html Handles the click event on a node to toggle its children between visible and hidden states. This function is crucial for the interactive expansion and collapse behavior of the tree. It modifies the `children` and `_children` properties of the node data. ```javascript function click(d) { if (d.children) { d._children = d.children; d.children = null; } else { d.children = d._children; d._children = null; } update(d); } ``` -------------------------------- ### Constrain Node Position within Bounds Source: https://github.com/puppeteer/examples/blob/master/html/d3tree_images.html Ensures that nodes remain within the SVG canvas boundaries during force-directed layout updates. Adjusts node positions if they exceed the defined limits. ```javascript /** * Gives the coordinates of the border for keeping the nodes inside a frame * http://bl.ocks.org/mbostock/1129492 */ function nodeTransform(d) { d.x = Math.max(maxNodeSize, Math.min(w - (d.imgwidth/2 || 16), d.x)); d.y = Math.max(maxNodeSize, Math.min(h - (d.imgheight/2 || 16), d.y)); return "translate(" + d.x + "," + d.y + ")"; } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.