novus / nvd3

A reusable charting library written in d3.js
http://nvd3.org/
Other
7.22k stars 2.15k forks source link

Error creating discrete bar charts with jsdom in NodeJS #1756

Open isaiahtaylor opened 8 years ago

isaiahtaylor commented 8 years ago
Debug: internal, implementation, error
    TypeError: Uncaught error: Cannot read property 'createElementNS' of undefined
    at Object.d3.transform (/Users/Isaiah/Desktop/Coding/pdp/repo/pdp/node_modules/d3/d3.js:5946:24)
    at d3_interpolateTransform (/Users/Isaiah/Desktop/Coding/pdp/repo/pdp/node_modules/d3/d3.js:6050:12)
    at HTMLUnknownElement.<anonymous> (/Users/Isaiah/Desktop/Coding/pdp/repo/pdp/node_modules/d3/d3.js:8755:32)
    at d3_Map.<anonymous> (/Users/Isaiah/Desktop/Coding/pdp/repo/pdp/node_modules/d3/d3.js:8946:27)
    at d3_Map.d3_class.forEach (/Users/Isaiah/Desktop/Coding/pdp/repo/pdp/node_modules/d3/d3.js:341:33)
    at start (/Users/Isaiah/Desktop/Coding/pdp/repo/pdp/node_modules/d3/d3.js:8945:24)
    at Object.schedule (/Users/Isaiah/Desktop/Coding/pdp/repo/pdp/node_modules/d3/d3.js:8913:36)
    at d3_timer_mark (/Users/Isaiah/Desktop/Coding/pdp/repo/pdp/node_modules/d3/d3.js:2166:35)
    at Timeout.d3_timer_step [as _onTimeout] (/Users/Isaiah/Desktop/Coding/pdp/repo/pdp/node_modules/d3/d3.js:2147:15)
    at tryOnTimeout (timers.js:224:11)
    at Timer.listOnTimeout (timers.js:198:5)

On nv 1.8.4, d3 1.5.7.

The exact same code is used to make pie charts (except for the discrete-specific names), but pies work and discrete fails.

Specifically:

Pie:

jsdom.env({
    features: {
      QuerySelector: true
    },
    html: htmlStub,
    done: function (errors, window) {

      //making chart
      nv.addGraph(function () {
        var chart = nv.models.pieChart()
          .x(function (d) { return d.key })
          .y(function (d) { return d.y })
          .width(width)
          .height(height)
          .showTooltipPercent(false)
          .showLegend(false)
          .labelsOutside(true)
          .donut(donut)
          .donutRatio(ratio)
          .labelThreshold(.01);

        let newEl = window.document.querySelector('#test1');

        var svg = d3.select(newEl)
          .datum(data)
          .attr('width', width)
          .attr('height', height)
          .attr('viewbox', '0 0 ' + viewX + ' ' + viewY)
          .call(chart);

        chart.update();
      }, function () {
        let newEl = window.document.querySelector('#test1');
        setTimeout(function () {
          callback(newEl.outerHTML);
          // const match = newEl.outerHTML.match(/ *\<style\>[^]*\<\/style\> */g, "");
          // callback(match + newEl.outerHTML.replace(/ *\<style\>[^]*\<\/style\> */g, ""));
        }, 0);
      })
    }
  })

^ this works.

Discrete:

jsdom.env({
    features: {
      QuerySelector: true
    },
    html: htmlStub,
    done: function (errors, window) {

      nv.addGraph(function () {
        var chart = nv.models.discreteBarChart()
          .x(function (d) { return d.label })    //Specify the data accessors.
          .y(function (d) { return d.value })
          .staggerLabels(true)    //Too many bars and not enough room? Try staggering labels.
          //.tooltips(false)        //Don't show tooltips
          .showValues(true)       //...instead, show the bar value right on top of each bar.

        let newEl = window.document.querySelector('#test1');

        d3.select(newEl)
          .datum(exampleData())
          .call(chart);

        // nv.utils.windowResize(chart.update);

        return chart;
      });

      //Each bar represents a single discrete quantity.
      function exampleData() {
        return [
          {
            key: "Cumulative Return",
            values: [
              {
                "label": "A Label",
                "value": -29.765957771107
              },
              {
                "label": "B Label",
                "value": 0
              },
              {
                "label": "C Label",
                "value": 32.807804682612
              },
              {
                "label": "D Label",
                "value": 196.45946739256
              },
              {
                "label": "E Label",
                "value": 0.19434030906893
              },
              {
                "label": "F Label",
                "value": -98.079782601442
              },
              {
                "label": "G Label",
                "value": -13.925743130903
              },
              {
                "label": "H Label",
                "value": -5.1387322875705
              }
            ]
          }
        ]

      }
    }, function() {
      let newEl = window.document.querySelector('#test1');
      setTimeout(function () {
        callback(newEl.outerHTML);
      }, 0);
    }
  })

^ this does not, and throws the above error.

liquidpele commented 8 years ago

please create a jsfiddle showing the issue and using the latest master branch builds via rawgit.com, thanks!