2017-09-21 4 views
0

Ich experimentierte mit Sankey-Diagrammen mit der Javascript-Bibliothek d3. Ich bin vor kurzem auf ein sehr schönes Sankey-Diagramm auf bl.ocks gestoßen.D3.js Sankey-Diagramm mit Partikeln

https://bl.ocks.org/micahstubbs/ae0946f9efe18fc4f67460e7387abc0b

Das erste, was ich, bevor es zu meinem eigenen Sankeydiagramm versucht, die Anwendung wurde Kopieren Sie den gesamten Code auf der bl.ocks Seite und es heraus in meinem eigenen Code-Editor (Dreamweaver) versuchen. Das Problem ist, wenn ich versuche, die sankey ich die folgende Konsole Fehler erhalten zu laden:

SyntaxError: missing = in const declaration 

ich nicht wirklich verstehen, was hier vor sich geht, da es ganz gut auf der bl.ocks Seite scheint zu funktionieren. Das Stück Code, wo soll angeblich sein ist wie folgt zusammen:

for (const x in particles) { 
    if ({}.hasOwnProperty.call(particles, x)) { 
    const currentTime = elapsed - particles[x].time; 
    // var currentPercent = currentTime/1000 * particles[x].path.getTotalLength(); 
    particles[x].current = currentTime * 0.15 * particles[x].speed; 
    const currentPos = particles[x].path.getPointAtLength(particles[x].current); 
    context.beginPath(); 
    context.fillStyle = particles[x].link.particleColor(0); 
    context.arc(currentPos.x, currentPos.y + particles[x].offset, particles[x].link.particleSize, 0, 2 * Math.PI); 
    context.fill(); 
    } 
} 

Es ist an der Unterseite des vis.js Code. Könnte mir jemand helfen, damit dieser Code funktioniert? Ich liebe den visuellen Effekt und möchte lernen, es zu benutzen. Danke.

Antwort

0

Von MDN: Eine Konstante ist ein Wert, der vom Programm während der normalen Ausführung nicht geändert werden kann. Es kann nicht durch Neuzuweisung geändert werden, und es kann nicht neu deklariert werden. In JavaScript werden Konstanten mit dem Schlüsselwort const deklariert. Ein Initialisierer für eine Konstante ist erforderlich; Das heißt, Sie müssen seinen Wert in derselben Anweisung angeben, in der er deklariert ist (was sinnvoll ist, da er später nicht geändert werden kann).

Es ist möglich, dass Daten (Energie) nicht korrekt geladen werden. Ich kann Ihnen nicht sagen, was falsch ist, wenn Sie nicht den ganzen Code posten. Aber ich habe den Code des Diagramms von bl.ocks.org unten kombiniert. Es funktioniert auch auf Codepen.

<html lang='en'> 
 

 
<head> 
 
    <meta charset='utf-8' /> 
 
    <title>Sankey Particles</title> 
 
    <style> 
 
    .node rect { 
 
     cursor: move; 
 
     fill-opacity: .9; 
 
     shape-rendering: crispEdges; 
 
    } 
 
    
 
    .node text { 
 
     pointer-events: none; 
 
     text-shadow: 0 1px 0 #fff; 
 
    } 
 
    
 
    .link { 
 
     fill: none; 
 
     stroke: #000; 
 
     stroke-opacity: .15; 
 
    } 
 
    
 
    .link:hover { 
 
     stroke-opacity: .25; 
 
    } 
 
    
 
    svg { 
 
     position: absolute; 
 
    } 
 
    
 
    canvas { 
 
     position: absolute; 
 
    } 
 
    </style> 
 
</head> 
 

 
<body> 
 
    <canvas width='960' height='960'></canvas> 
 
    <svg width='960' height='960'></svg> 
 
    <script src='https://cdnjs.cloudflare.com/ajax/libs/d3/4.8.0/d3.js' charset='utf-8' type='text/javascript'></script> 
 
    <script src='https://cdnjs.cloudflare.com/ajax/libs/d3-sankey/0.4.2/d3-sankey.js' charset='utf-8' type='text/javascript'></script> 
 
    <script src='https://cdnjs.cloudflare.com/ajax/libs/d3-timer/1.0.5/d3-timer.js' charset='utf-8' type='text/javascript'></script> 
 
    <script src='vis.js'></script> 
 
    <script> 
 
    const margin = { top: 1, right: 1, bottom: 6, left: 1 }; 
 
    const width = 960 - margin.left - margin.right; 
 
    const height = 500 - margin.top - margin.bottom; 
 
    const formatNumber = d3.format(",.0f"); 
 
    const format = d => `${formatNumber(d)} TWh`; 
 
    const color = d3.scaleOrdinal(d3.schemeCategory20); 
 
    
 
    const svg = d3 
 
     .select("svg") 
 
     .attr("width", width + margin.left + margin.right) 
 
     .attr("height", height + margin.top + margin.bottom) 
 
     .append("g") 
 
     .attr("transform", `translate(${margin.left},${margin.top})`); 
 
    
 
    const sankey = d3.sankey().nodeWidth(15).nodePadding(10).size([width, height]); 
 
    
 
    const path = sankey.link(); 
 
    
 
    const freqCounter = 1; 
 
    
 
    var energy = { 
 
     nodes: [ 
 
     { name: "Agricultural 'waste'" }, 
 
     { name: "Bio-conversion" }, 
 
     { name: "Liquid" }, 
 
     { name: "Losses" }, 
 
     { name: "Solid" }, 
 
     { name: "Gas" }, 
 
     { name: "Biofuel imports" }, 
 
     { name: "Biomass imports" }, 
 
     { name: "Coal imports" }, 
 
     { name: "Coal" }, 
 
     { name: "Coal reserves" }, 
 
     { name: "District heating" }, 
 
     { name: "Industry" }, 
 
     { name: "Heating and cooling - commercial" }, 
 
     { name: "Heating and cooling - homes" }, 
 
     { name: "Electricity grid" }, 
 
     { name: "Over generation/exports" }, 
 
     { name: "H2 conversion" }, 
 
     { name: "Road transport" }, 
 
     { name: "Agriculture" }, 
 
     { name: "Rail transport" }, 
 
     { name: "Lighting & appliances - commercial" }, 
 
     { name: "Lighting & appliances - homes" }, 
 
     { name: "Gas imports" }, 
 
     { name: "Ngas" }, 
 
     { name: "Gas reserves" }, 
 
     { name: "Thermal generation" }, 
 
     { name: "Geothermal" }, 
 
     { name: "H2" }, 
 
     { name: "Hydro" }, 
 
     { name: "International shipping" }, 
 
     { name: "Domestic aviation" }, 
 
     { name: "International aviation" }, 
 
     { name: "National navigation" }, 
 
     { name: "Marine algae" }, 
 
     { name: "Nuclear" }, 
 
     { name: "Oil imports" }, 
 
     { name: "Oil" }, 
 
     { name: "Oil reserves" }, 
 
     { name: "Other waste" }, 
 
     { name: "Pumped heat" }, 
 
     { name: "Solar PV" }, 
 
     { name: "Solar Thermal" }, 
 
     { name: "Solar" }, 
 
     { name: "Tidal" }, 
 
     { name: "UK land based bioenergy" }, 
 
     { name: "Wave" }, 
 
     { name: "Wind" } 
 
     ], 
 
     links: [ 
 
     { source: 0, target: 1, value: 124.729 }, 
 
     { source: 1, target: 2, value: 0.597 }, 
 
     { source: 1, target: 3, value: 26.862 }, 
 
     { source: 1, target: 4, value: 280.322 }, 
 
     { source: 1, target: 5, value: 81.144 }, 
 
     { source: 6, target: 2, value: 35 }, 
 
     { source: 7, target: 4, value: 35 }, 
 
     { source: 8, target: 9, value: 11.606 }, 
 
     { source: 10, target: 9, value: 63.965 }, 
 
     { source: 9, target: 4, value: 75.571 }, 
 
     { source: 11, target: 12, value: 10.639 }, 
 
     { source: 11, target: 13, value: 22.505 }, 
 
     { source: 11, target: 14, value: 46.184 }, 
 
     { source: 15, target: 16, value: 104.453 }, 
 
     { source: 15, target: 14, value: 113.726 }, 
 
     { source: 15, target: 17, value: 27.14 }, 
 
     { source: 15, target: 12, value: 342.165 }, 
 
     { source: 15, target: 18, value: 37.797 }, 
 
     { source: 15, target: 19, value: 4.412 }, 
 
     { source: 15, target: 13, value: 40.858 }, 
 
     { source: 15, target: 3, value: 56.691 }, 
 
     { source: 15, target: 20, value: 7.863 }, 
 
     { source: 15, target: 21, value: 90.008 }, 
 
     { source: 15, target: 22, value: 93.494 }, 
 
     { source: 23, target: 24, value: 40.719 }, 
 
     { source: 25, target: 24, value: 82.233 }, 
 
     { source: 5, target: 13, value: 0.129 }, 
 
     { source: 5, target: 3, value: 1.401 }, 
 
     { source: 5, target: 26, value: 151.891 }, 
 
     { source: 5, target: 19, value: 2.096 }, 
 
     { source: 5, target: 12, value: 48.58 }, 
 
     { source: 27, target: 15, value: 7.013 }, 
 
     { source: 17, target: 28, value: 20.897 }, 
 
     { source: 17, target: 3, value: 6.242 }, 
 
     { source: 28, target: 18, value: 20.897 }, 
 
     { source: 29, target: 15, value: 6.995 }, 
 
     { source: 2, target: 12, value: 121.066 }, 
 
     { source: 2, target: 30, value: 128.69 }, 
 
     { source: 2, target: 18, value: 135.835 }, 
 
     { source: 2, target: 31, value: 14.458 }, 
 
     { source: 2, target: 32, value: 206.267 }, 
 
     { source: 2, target: 19, value: 3.64 }, 
 
     { source: 2, target: 33, value: 33.218 }, 
 
     { source: 2, target: 20, value: 4.413 }, 
 
     { source: 34, target: 1, value: 4.375 }, 
 
     { source: 24, target: 5, value: 122.952 }, 
 
     { source: 35, target: 26, value: 839.978 }, 
 
     { source: 36, target: 37, value: 504.287 }, 
 
     { source: 38, target: 37, value: 107.703 }, 
 
     { source: 37, target: 2, value: 611.99 }, 
 
     { source: 39, target: 4, value: 56.587 }, 
 
     { source: 39, target: 1, value: 77.81 }, 
 
     { source: 40, target: 14, value: 193.026 }, 
 
     { source: 40, target: 13, value: 70.672 }, 
 
     { source: 41, target: 15, value: 59.901 }, 
 
     { source: 42, target: 14, value: 19.263 }, 
 
     { source: 43, target: 42, value: 19.263 }, 
 
     { source: 43, target: 41, value: 59.901 }, 
 
     { source: 4, target: 19, value: 0.882 }, 
 
     { source: 4, target: 26, value: 400.12 }, 
 
     { source: 4, target: 12, value: 46.477 }, 
 
     { source: 26, target: 15, value: 525.531 }, 
 
     { source: 26, target: 3, value: 787.129 }, 
 
     { source: 26, target: 11, value: 79.329 }, 
 
     { source: 44, target: 15, value: 9.452 }, 
 
     { source: 45, target: 1, value: 182.01 }, 
 
     { source: 46, target: 15, value: 19.013 }, 
 
     { source: 47, target: 15, value: 289.366 } 
 
     ] 
 
    }; 
 
    
 
    sankey.nodes(energy.nodes).links(energy.links).layout(32); 
 
    
 
    const link = svg 
 
     .append("g") 
 
     .selectAll(".link") 
 
     .data(energy.links) 
 
     .enter() 
 
     .append("path") 
 
     .attr("class", "link") 
 
     .attr("d", path) 
 
     .style("stroke-width", d => Math.max(1, d.dy)) 
 
     .sort((a, b) => b.dy - a.dy); 
 
    
 
    link 
 
     .append("title") 
 
     .text(d => `${d.source.name} → ${d.target.name}\n${format(d.value)}`); 
 
    
 
    const node = svg 
 
     .append("g") 
 
     .selectAll(".node") 
 
     .data(energy.nodes) 
 
     .enter() 
 
     .append("g") 
 
     .attr("class", "node") 
 
     .attr("transform", d => `translate(${d.x},${d.y})`) 
 
     .call(
 
     d3 
 
      .drag() 
 
      .subject(d => d) 
 
      .on("start", function() { 
 
      this.parentNode.appendChild(this); 
 
      }) 
 
      .on("drag", dragmove) 
 
    ); 
 
    
 
    node 
 
     .append("rect") 
 
     .attr("height", d => d.dy) 
 
     .attr("width", sankey.nodeWidth()) 
 
     .style("fill", d => { 
 
     d.color = color(d.name.replace(/ .*/, "")); 
 
     return d.color; 
 
     }) 
 
     .style("stroke", "none") 
 
     .append("title") 
 
     .text(d => `${d.name}\n${format(d.value)}`); 
 
    
 
    node 
 
     .append("text") 
 
     .attr("x", -6) 
 
     .attr("y", d => d.dy/2) 
 
     .attr("dy", ".35em") 
 
     .attr("text-anchor", "end") 
 
     .attr("transform", null) 
 
     .text(d => d.name) 
 
     .filter(d => d.x < width/2) 
 
     .attr("x", 6 + sankey.nodeWidth()) 
 
     .attr("text-anchor", "start"); 
 
    
 
    function dragmove(d) { 
 
     d3 
 
     .select(this) 
 
     .attr(
 
      "transform", 
 
      `translate(${d.x},${(d.y = Math.max(
 
      0, 
 
      Math.min(height - d.dy, d3.event.y) 
 
     ))})` 
 
     ); 
 
     sankey.relayout(); 
 
     link.attr("d", path); 
 
    } 
 
    
 
    const linkExtent = d3.extent(energy.links, d => d.value); 
 
    const frequencyScale = d3.scaleLinear().domain(linkExtent).range([0.05, 1]); 
 
    const particleSize = d3.scaleLinear().domain(linkExtent).range([1, 5]); 
 
    
 
    energy.links.forEach(link => { 
 
     link.freq = frequencyScale(link.value); 
 
     link.particleSize = 2; 
 
     link.particleColor = d3 
 
     .scaleLinear() 
 
     .domain([0, 1]) 
 
     .range([link.source.color, link.target.color]); 
 
    }); 
 
    
 
    const t = d3.timer(tick, 1000); 
 
    let particles = []; 
 
    
 
    function tick(elapsed, time) { 
 
     particles = particles.filter(d => d.current < d.path.getTotalLength()); 
 
    
 
     d3.selectAll("path.link").each(function(d) { 
 
     // if (d.freq < 1) { 
 
     for (let x = 0; x < 2; x += 1) { 
 
      const offset = (Math.random() - 0.5) * (d.dy - 4); 
 
      if (Math.random() < d.freq) { 
 
      const length = this.getTotalLength(); 
 
      particles.push({ 
 
       link: d, 
 
       time: elapsed, 
 
       offset, 
 
       path: this, 
 
       length, 
 
       animateTime: length, 
 
       speed: 0.5 + Math.random() 
 
      }); 
 
      } 
 
     } 
 
     // } 
 
     /*  
 
       else { 
 
        for (var x = 0; x<d.freq; x++) { 
 
        var offset = (Math.random() - .5) * d.dy; 
 
        particles.push({link: d, time: elapsed, offset: offset, path: this}) 
 
        } 
 
       } 
 
      */ 
 
     }); 
 
    
 
     particleEdgeCanvasPath(elapsed); 
 
    } 
 
    
 
    function particleEdgeCanvasPath(elapsed) { 
 
     const context = d3.select("canvas").node().getContext("2d"); 
 
    
 
     context.clearRect(0, 0, 1000, 1000); 
 
    
 
     context.fillStyle = "gray"; 
 
     context.lineWidth = "1px"; 
 
     for (const x in particles) { 
 
     if ({}.hasOwnProperty.call(particles, x)) { 
 
      const currentTime = elapsed - particles[x].time; 
 
      // var currentPercent = currentTime/1000 * particles[x].path.getTotalLength(); 
 
      particles[x].current = currentTime * 0.15 * particles[x].speed; 
 
      const currentPos = particles[x].path.getPointAtLength(
 
      particles[x].current 
 
     ); 
 
      context.beginPath(); 
 
      context.fillStyle = particles[x].link.particleColor(0); 
 
      context.arc(
 
      currentPos.x, 
 
      currentPos.y + particles[x].offset, 
 
      particles[x].link.particleSize, 
 
      0, 
 
      2 * Math.PI 
 
     ); 
 
      context.fill(); 
 
     } 
 
     } 
 
    } 
 
    </script> 
 
</body> 
 

 
</html>

+0

Danke. Es scheint jetzt aus irgendeinem Grund zu funktionieren. Bin dankbar. –