Search code examples
d3.jsjsdom

D3.CSV ReferenceError: fetch is not defined


I want to export only the SVG of the "Radial Stacked Barchart" using jsdom.env is not a function exporting svg to image for the "Radial Stacked Barchart" I use the following article: https://bl.ocks.org/KoGor/9f3932d3c7154f8ab3ea2078b2aca113

I created two scripts

ExportToSVG.js script:

const d3 = require("d3");
const fs = require("fs");
const {JSDOM} = require("jsdom");

// init d3 - https://gist.github.com/tomgp/c99a699587b5c5465228
const minHtml = '<html><head></head><body><svg width="960" height="800" font-family="sans-serif" font-size="10"></body></html>'
const dom = new JSDOM(`${minHtml}`, { pretendToBeVisual: true });
const window = dom.window;
window.d3 = d3.select(window.document);

// D3JS CODE * * * * * *  WORKS  * * * * * * * * * * *
var svg = window.d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height"),
    innerRadius = 180,
    outerRadius = Math.min(width, height) / 2.5,
    g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

var xScaleOffset = Math.PI * 75/180;
var x = d3.scaleBand()
    .range([xScaleOffset, 2 * Math.PI + xScaleOffset])
    .align(0);

var y = d3.scaleLinear()
    .range([innerRadius, outerRadius]);

var z = d3.scaleOrdinal()
    .range(["#a1d76a", "#91bfdb"]); 

var zClasses = ['внутренняя сторона', 'внешняя сторона'];

// END (D3JS) * * * * * * * * * * * * * * * * * * * * * * * *


// D3JS CODE * * * * * *  EXPIRIMENT  * * * * * * * * * * *
d3.csv("simple_stat.csv", function(d, i, columns) {
    d.left_lane = (+d.left_lane);
    d.right_lane =  (+d.right_lane);
    return d;
  }, function(error, data) {
    if (error) throw error;
  
    var keys = data.columns.slice(1);
    var meanAccidents = d3.mean(data, function(d) { return d3.sum(keys, function(key) { return d[key]; }); })
  
    x.domain(data.map(function(d) { return d.km; }));
    y.domain([0, d3.max(data, function(d) { return (d.left_lane + d.right_lane); })]);
    z.domain(data.columns.slice(1));
  
    // Accidents
    g.append('g')
        .selectAll("g")
      .data(d3.stack().keys(data.columns.slice(1))(data))
      .enter().append("g")
        .attr("fill", function(d) { return z(d.key); })
      .selectAll("path")
      .data(function(d) { return d; })
      .enter().append("path")
        .attr("d", d3.arc()
            .innerRadius(function(d) { return y(d[0]); })
            .outerRadius(function(d) { return y(d[1]); })
            .startAngle(function(d) { return x(d.data.km); })
            .endAngle(function(d) { return x(d.data.km) + x.bandwidth(); })
            .padAngle(0.01)
            .padRadius(innerRadius));
  
    //yAxis and Mean
  
    var yAxis = g.append("g")
        .attr("text-anchor", "middle");
  
    var yTicksValues = d3.ticks(0, 40, 4);
  
    console.log('Среднее: ', meanAccidents);
  
    // Mean value line
    var yMeanTick = yAxis
      .append("g")
      .datum([meanAccidents]);
  
    yMeanTick.append("circle")
        .attr("fill", "none")
        .attr("stroke", "#C0625E")
        .attr("stroke-dasharray", "5 3")
        .attr("r", y);
  
    var yTick = yAxis
      .selectAll("g")
      .data(yTicksValues)
      .enter().append("g");
  
    yTick.append("circle")
        .attr("fill", "none")
        .attr("stroke", "#ccdcea")
        .attr("r", y);
  
    yTick.append("text")
        .attr("y", function(d) { return -y(d); })
        .attr("dy", "0.35em")
        .attr("fill", "none")
        .attr("stroke", "#fff")
        .attr("stroke-width", 5)
        .text(y.tickFormat(5, "s"));
  
    yTick.append("text")
        .attr("y", function(d) { return -y(d); })
        .attr("dy", "0.35em")
        .text(y.tickFormat(5, "s"));
  
    yAxis.append("text")
        .attr("y", function(d) { return -y(yTicksValues.pop()); })
        .attr("dy", "-2em")
        .text("МКАД, аварийность");
  
    // Labels for xAxis
  
    var label = g.append("g")
      .selectAll("g")
      .data(data)
      .enter().append("g")
        .attr("text-anchor", "middle")
        .attr("transform", function(d) { return "rotate(" + ((x(d.km) + x.bandwidth() / 2) * 180 / Math.PI - 90) + ")translate(" + innerRadius + ",0)"; });
  
    label.append("line")
        .attr("x2", function(d) { return (((d.km % 5) == 0) | (d.km == '1')) ? -7 : -4 })
        .attr("stroke", "#000");
  
    label.append("text")
        .attr("transform", function(d) { return (x(d.km) + x.bandwidth() / 2 + Math.PI / 2) % (2 * Math.PI) < Math.PI ? "rotate(90)translate(0,16)" : "rotate(-90)translate(0,-9)"; })
        .text(function(d) { 
          var xlabel = (((d.km % 5) == 0) | (d.km == '1')) ? d.km : '';
          return xlabel; });
  
  // Legend
    var legend = g.append("g")
      .selectAll("g")
      .data(zClasses)
      .enter().append("g")
        .attr("transform", function(d, i) { return "translate(-50," + (i - (zClasses.length - 1) / 2) * 25+ ")"; });
  
    legend.append("circle")
        .attr("r", 8)
        .attr("fill", z);
  
    legend.append("text")
        .attr("x", 15)
        .attr("y", 0)
        .attr("dy", "0.35em")
        .text(function(d) { return d; });
  
  });

console.log( window.d3.select("body").html() );

For the data I use the same data as what is described in the example in the above url. When I execute the following statement

node ExportToSVG > out.svg 

I get this error:

C:\Users\username\Documents\git\svgcreator.node.js\node_modules\d3-fetch\dist\d3-fetch.js:32
  return fetch(input, init).then(responseText);
ReferenceError: fetch is not defined
    at text (C:\Users\username\Documents\git\svgcreator.node.js\node_modules\?[4md3-fetch?[24m\dist\d3-fetch.js:32:3)
    at Object.<anonymous> (C:\Users\username\Documents\git\svgcreator.node.js\node_modules\?[4md3-fetch?[24m\dist\d3-fetch.js:38:12)
    at Object.<anonymous> (C:\Users\username\Documents\git\svgcreator.node.js\ExportToSVG.js:36:4)
?[90m    at Module._compile (internal/modules/cjs/loader.js:1063:30)?[39m
?[90m    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)?[39m
?[90m    at Module.load (internal/modules/cjs/loader.js:928:32)?[39m
?[90m    at Function.Module._load (internal/modules/cjs/loader.js:769:14)?[39m
?[90m    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)?[39m
?[90m    at internal/main/run_main_module.js:17:47?[39m

Can you please help me

Manny thanks Erik


Solution

  • the following should work for you.

    source

    You need an environment that supports the Fetch API, such as a a web browser. Node does not currently support Fetch, though it may in the future. If you want to load this library in an environment that does not natively support Fetch you will need to load your own polyfill such as node-fetch.