【问题标题】:D3 chart giving error Cannot read property 'length' of undefined in zoomD3 图表给出错误无法读取缩放中未定义的属性“长度”
【发布时间】:2017-09-14 07:16:34
【问题描述】:

我正在使用 d3.v4 图表。缩放时出现错误无法读取行 'grp.select(".area").attr("d", area.x(function(d) {return xt(d);} 处未定义的属性 'length' ));'。在浏览器控制台上显示为

**Uncaught TypeError: Cannot read property 'length' of undefined
    at SVGPathElement.t (d3.v4.min.js:2)
    at SVGPathElement.<anonymous> (d3.v4.min.js:2)
    at pt.each (d3.v4.min.js:2)
    at pt.attr (d3.v4.min.js:2)
    at SVGSVGElement.zoomed (pen.js:69)
    at p.apply (d3.v4.min.js:2)
    at N (d3.v4.min.js:2)
    at c.emit (d3.v4.min.js:2)
    at c.zoom (d3.v4.min.js:2)
    at d3.v4.min.js:2**

请帮我解决这个错误。 请参阅以下链接以获取 codepen 示例https://codepen.io/rohitbagde/pen/ZXEVRp

var dataArray=[11,14,27,30,43,47,60,69,77,100];
var dataMonths=[1,2,3,4,5,6,7,8,9,10];
var dataDate=[1,2,3,4,5,6,7,8,9,10];

var height=150;
var width=1000;
var parseMonth= d3.timeParse('%m');
var area = d3.area().x(function(d,i){return x(parseMonth(dataMonths[i]));} )
            .y0(height)
            .y1(function(d){return y(d);});


var svg = d3.select("body").append("svg").attr("height","100%").attr("width","100%");

var grp=svg.append('g').attr('transform','translate(40,0)').attr("class", "charts");

// Domain is referred to data i.e. x-axis
//This for y scale
var y=d3.scaleLinear().domain([0,200]).range([150,0]);
var x=d3.scaleTime()
.domain([d3.min(dataMonths,function(d){ return parseMonth(d);}),
        d3.max(dataMonths,function(d){ return parseMonth(d);})])
.range([0,1000]);

//This is for yaxis
var yAxis=d3.axisLeft(y).ticks(5).tickPadding(10);
var xAxis=d3.axisBottom(x);

grp.append('g').attr('class','axis y').call(yAxis);
grp.append('g').attr('class','axis x').attr('transform','translate(0,150)').call(xAxis);

//for plotting lines
grp.append("path")
  .attr("fill","none")
.attr("stroke","black")
.attr("stroke-width","2")
.attr("class", "area")
  .attr("d",area(dataArray));

//For plotting points
grp.selectAll("circle.grpcircle")
.data(dataArray)
.enter().append("circle")
.attr("class","circle")
.attr("cx",function(d,i){return x(parseMonth(dataMonths[i]));})
.attr("cy",function(d){return y(d);})
.attr("r",'4') 



 //For zooming
var zoom = d3.zoom()
    .scaleExtent([1, 32])
    .translateExtent([[0, 0], [width, height]])
    .extent([[0, 0], [width, height]])
    .on("zoom", zoomed);

var d0=parseMonth(1);
var d1=parseMonth(12);
 svg.call(zoom).transition()
      .duration(1500)
      .call(zoom.transform, d3.zoomIdentity
          .scale(width / (x(d1) - x(d0)))
          .translate(-x(d0), 0)); 

function zoomed() {
  var t = d3.event.transform, xt = t.rescaleX(x);
  area.x(function(d) {alert("Hi");return xt(d);});

  grp.select(".area").attr("d", area.x(function(d) {return xt(d);}));
  grp.select(".x").call(xAxis.scale(xt));
} 

【问题讨论】:

    标签: javascript angularjs d3.js


    【解决方案1】:

    您必须首先将数据数组绑定到 SVG 路径才能使其正常工作。

    //for plotting lines
    grp.append("path")
      .datum(dataArray)
      .attr("fill","none")
      .attr("stroke","black")
      .attr("stroke-width","2")
      .attr("class", "area")
      .attr("d",area);
    

    var dataArray = [11, 14, 27, 30, 43, 47, 60, 69, 77, 100];
    var dataMonths = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    var dataDate = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    
    var height = 150;
    var width = 1000;
    var parseMonth = d3.timeParse('%m');
    var area = d3.area().x(function(d, i) {
        return x(parseMonth(dataMonths[i]));
      })
      .y0(height)
      .y1(function(d) {
        return y(d);
      });
    
    
    var svg = d3.select("body").append("svg").attr("height", "100%").attr("width", "100%");
    
    
    svg.append("defs").append("clipPath")
      .attr("id", "clip")
      .append("rect")
      .attr("width", width)
      .attr("height", height);
    
    var grp = svg.append('g').attr('transform', 'translate(40,0)').attr("class", "charts");
    
    // Domain is referred to data i.e. x-axis
    //This for y scale
    var y = d3.scaleLinear().domain([0, 200]).range([150, 0]);
    var x = d3.scaleTime()
      .domain([d3.min(dataMonths, function(d) {
          return parseMonth(d);
        }),
        d3.max(dataMonths, function(d) {
          return parseMonth(d);
        })
      ])
      .range([0, 1000]);
    
    //This is for yaxis
    var yAxis = d3.axisLeft(y).ticks(5).tickPadding(10);
    var xAxis = d3.axisBottom(x);
    
    grp.append('g').attr('class', 'axis y').call(yAxis);
    grp.append('g').attr('class', 'axis x').attr('transform', 'translate(0,150)').call(xAxis);
    
    //for plotting lines
    grp.append("path")
      .datum(dataArray)
      .attr("fill", "none")
      .attr("stroke", "black")
      .attr("stroke-width", "2")
      .attr("class", "area1")
      .attr("d", area);
    
    grp.selectAll("circle.grpcircle")
      .data(dataArray)
      .enter().append("circle")
      .attr("class", "circle")
      .attr("cx", function(d, i) {
        return x(parseMonth(dataMonths[i]));
      })
      .attr("cy", function(d) {
        return y(d);
      })
      .attr("r", '4')
    
    //For zooming
    var zoom = d3.zoom()
      .scaleExtent([1, 32])
      .translateExtent([
        [0, 0],
        [width, height]
      ])
      .extent([
        [0, 0],
        [width, height]
      ])
      .on("zoom", zoomed);
    
    var d0 = parseMonth(1);
    var d1 = parseMonth(12);
    svg.call(zoom).transition()
      .duration(1500)
      .call(zoom.transform, d3.zoomIdentity
        .scale(width / (x(d1) - x(d0)))
        .translate(-x(d0), 0));
    
    function zoomed() {
      var t = d3.event.transform,
        xt = t.rescaleX(x);
      grp.select(".area1").attr("d", area.x(function(d, i) {
        return xt(parseMonth(dataMonths[i]));
      }));
      grp.select(".x").call(xAxis.scale(xt));
      grp.selectAll("circle")
        .attr("cx", function(d, i) {
          return xt(parseMonth(dataMonths[i]));
        });
    }
    html,
    body {
      height: 100%;
    }
    
    .area1 {
      clip-path: url(#clip);
    }
    <body>
    
      <script src="https://d3js.org/d3.v4.min.js"></script>
    </body>

    【讨论】:

    • 试过这个解决方案。但它显示相同的错误,现在所有点和路径都不可见。
    • 谢谢。这个解决方案对我有用。我想做的另一件事是用类'circle'缩放我的代码sn-p中显示的点。怎么做?现在点没有被放大。只有路径被放大。请帮忙。我是 D3 图表的新手。
    • 找到了解决方案。必须使用 grp.selectAll("circle").attr("cx", function(d,i){return xt(parseMonth(dataMonths[i]));});谢谢。
    • 我有点忙。很高兴你自己解决了。
    猜你喜欢
    • 2016-11-27
    • 2016-03-10
    • 1970-01-01
    • 1970-01-01
    • 2015-05-08
    • 2020-06-02
    • 2021-03-15
    • 2015-08-22
    • 2015-02-05
    相关资源
    最近更新 更多