Nvd3js项目符号图表:Chart.update不更新图表

时间:2016-06-01 07:21:31

标签: d3.js charts nvd3.js bullet-chart

我已经定制了nvd3子弹图,它的工作正常。 当窗口调整大小时问题开始,chart.update处理程序创建错误 d3.js:8868 Uncaught TypeError:无法读取属性' 1'未定义的 ,因此代码控制不会再次运行图表功能。 请帮忙。



library(ggplot2)
library(gtable)
library(grid)

a.x <- rnorm(20,5,1)
a.y <- rnorm(20,10,2)
b.x <- rnorm(10,20,2)
b.y <- rnorm(10,5,2)
x <- data.frame(x=c(a.x,b.x),y=c(a.y,b.y),col=c(rep("A",20),rep("B",10)))

p1 <- ggplot(x,aes(x=x,y=y))+geom_point(aes(color=col))+stat_smooth(method = "lm",se=F,colour="black",linetype=2,size=0.5)+theme_bw()+theme(legend.position="none")
p2 <- ggplot(x,aes(x=col,y=y,color=col))+geom_boxplot()+theme_bw()+theme(legend.position="none",axis.ticks.y=element_blank(),axis.title.y=element_blank(),axis.text.y=element_blank())
p3 <- ggplot(x,aes(x=col,y=x,color=col))+geom_boxplot()+coord_flip()+theme_bw()+theme(legend.position="none",axis.ticks.x=element_blank(),axis.title.x=element_blank(),axis.text.x=element_blank())

gt1 <- ggplot_gtable(ggplot_build(p1))
gt2 <- ggplot_gtable(ggplot_build(p2))
gt3 <- ggplot_gtable(ggplot_build(p3))

maxWidth <- unit.pmax(gt1$widths[2:3], gt2$widths[2:3])
maxHeight <- unit.pmax(gt1$heights[4:5], gt3$heights[4:5])


gt1$widths[2:3] <- as.list(maxWidth)
gt2$widths[2:3] <- as.list(maxWidth)

gt1$heights[4:5] <- as.list(maxHeight)
gt3$heights[4:5] <- as.list(maxHeight)

gt <- gtable(widths = unit(c(4, 1), "null"), height = unit(c(1, 4), "null"))

gt <- gtable_add_grob(gt, gt1, 2, 1)
gt <- gtable_add_grob(gt, gt2, 2, 2)
gt <- gtable_add_grob(gt, gt3, 1, 1)


grid.newpage()
grid.draw(gt)
&#13;
// expected input data format
var config = {
  title: 'Sample Chart',
  subtitle: 'description subtitle',
  legend: true,
  min: 0,
  max: 500,
  averageText: 'Top Users in Intro Psychology courses nationally',
  data: [{
    label: 'Instructor1',
    marker: 20,
    color: ''
  }, {
    label: 'Instructor2',
    marker: 250,
    color: ''
  }, {
    label: 'Instructor3',
    marker: 150,
    color: ''
  }, {
    label: 'Instructor4',
    marker: 50,
    color: ''
  }]
};

// initializing the colors category
var colors = config.data.map(function(val) {
    return val.color
  }),
  defaultColors = d3.scale.category20().range();

// data initialization
function generateData() {
  var sum = new Number().valueOf();
  config.data.sort(function(val1, val2) {
    return val1.marker <= val2.marker;
  });
  config.data.forEach(function(val, i) {
    sum += Number(val.marker);
  });

  return {
    "ranges": [config.min, sum / config.data.length, config.max],
    "measures": [config.max],
    "markers": config.data.map(function(val) {
      return val.marker
    })
  };
}

// wrap the text within given width
function wrap(text, width) {
  var words = text.text().split(/\s+/),
    line = [],
    dy = parseFloat(text.attr("dy")) || 10,
    lineNumber = 0,
    lineHeight = 3;
  var tspan = text.text(null).append('tspan');
  var offset = 0;
  while (1) {
    if (tspan.node().getComputedTextLength() > width) {
      words.unshift(line.pop());
      tspan.text(line.join(' '));
      offset = (width - tspan.node().getComputedTextLength()) / 2;
      tspan.attr('x', offset);
      tspan = text.append('tspan').attr("dy", lineHeight + dy);
      line = [];
      ++lineNumber;
    } else {
      if (!words.length)
        break;
      line.push(words.shift());
      tspan.text(line.join(' '));
      offset = (width - tspan.node().getComputedTextLength()) / 2;
      tspan.attr('x', offset);
    }
  }
  text.attr('y', -1 * lineNumber * lineHeight * 5);
}

// set the position for markers
function setMarkers(markers) {
    markers.each(function(mark, i) {
      var marker = d3.select(this);
      marker.attr('d', 'M -5 -10 l0 20 l5 5 l5 -5 l0 -20 z')
        .style({
          'fill': colors[i] || defaultColors[i],
          'stroke': 'none'
        });
    });
  }
  //convert r,g,b to hex value

function rgb2hex(rgb) {
  rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
  return (rgb && rgb.length === 4) ? "#" +
    ("0" + parseInt(rgb[1], 10).toString(16)).slice(-2) +
    ("0" + parseInt(rgb[2], 10).toString(16)).slice(-2) +
    ("0" + parseInt(rgb[3], 10).toString(16)).slice(-2) : '';
}

// handle tooltip events
function setTooltipEvents(chart) {
  chart.bullet.dispatch.on('elementMouseover.tooltip', function(evt) {
    if (evt.label === 'Current') {
      return false;
    }
    var thisBullet = config.data.filter(function(val, i) {
      return (rgb2hex(evt.color) == (val.color || defaultColors[i]) && evt.value === val.marker);
    })[0];
    evt['series'] = {
      key: thisBullet.label,
      value: evt.value,
      color: evt.color
    };

    chart.tooltip.data(evt).hidden(false);
  });
  d3.select('#chart #nv-avg').on('mouseover', function(evt) {
    evt['series'] = {
      key: 'Average',
      value: evt.ranges[1],
      color: defaultColors[defaultColors.length - 1]
    };

    chart.tooltip.data(evt).hidden(false);
  });

  d3.select('#chart #nv-avg').on('mousemove', function(evt) {
    chart.tooltip();
  });

  d3.select('#chart #nv-avg').on('mouseleave', function(evt) {
    chart.tooltip.hidden(true);
  });
}

// core graph/chart drawing snippet 
nv.addGraph(function() {
  var chart = nv.models.bulletChart() // initialize the chart
    .margin({
      right: 10,
      left: 10
    })
    .tickFormat(function(d) {
      return d + "%";
    });

  d3.select('#chart svg') //setup chart svg container
    .datum(generateData())
    .transition().duration(1000)
    .style({
      'height': '400px'
    })
    .call(chart);

  var width = nv.utils.availableWidth(null, d3.select('#chart svg'), chart._options.margin);

  var scaleBar = d3.select('.nv-measure') // style for main axis
    .style({
      'fill': '#000',
      'height': '5'
    });
  var parentBox = d3.select(scaleBar.node().parentNode); // wrapper for main axis
  var avgRange = d3.select('.nv-rangeAvg').node(); // average marker node 
  var avgBox = avgRange.getBBox(); // average marker dimensions
  var scaleBarBox = scaleBar.node().getBBox(); // main axis dimensions

  d3.selectAll('.nv-range').remove(); // remove extra elements

  d3.select('.nv-bulletChart').attr('transform', function() {
    var transform = d3.transform(d3.select(this).attr("transform"));
    return 'translate(' + transform.translate[0] + ',' + 185 + ')';
  });
  // set average marker
  var avgRectWidth = 150,
    avgRectHeight = 50;
  var avgMarker = parentBox.append('g').attr({
    'transform': 'translate(' + (avgBox.x + avgBox.width - avgRectWidth / 2) + ',' + (-1 * (avgRectHeight - scaleBarBox.y)) + ')',
    'id': 'nv-avg'
  });

  var avgMarkerRect = avgMarker.append('rect')
    .attr({
      'width': avgRectWidth,
      'height': avgRectHeight,
      'x': 0,
      'y': 0,
      'fill': '#fff',
      'fill-opacity': 0
    });
  var avgMarkerBox = avgMarkerRect.node().getBBox();

  avgMarker.append('path')
    .attr({
      'transform': 'translate(' + (avgMarkerBox.x + avgMarkerBox.width / 2) + ',' + avgMarkerBox.height + ')',
      'd': 'M0 0 l7.5 -5 l0 -25 l-15 0 l0 25 z'
    }).style({
      'fill': defaultColors[defaultColors.length - 1],
      'stroke': 'none'
    });
  avgMarker.append('text').text(config.averageText).attr({
    'x': 0,
    'y': 0
  });

  d3.select('#nv-avg text').call(wrap, avgMarkerBox.width);

  // left end circle
  parentBox.append('circle').attr({
    'cx': scaleBarBox.x,
    'cy': scaleBarBox.y + scaleBarBox.height / 2,
    'r': '10'
  });

  //right end circle
  parentBox.append('circle').attr({
    'cx': scaleBarBox.x + scaleBarBox.width,
    'cy': scaleBarBox.y + scaleBarBox.height / 2,
    'r': '10'
  });

  // set markers for data to be plotted
  d3.select('#chart').selectAll('.nv-markerTriangle')
    .call(setMarkers);

  //optional functionality to format ticks
  d3.selectAll('#chart .nv-tick').each(function(tick, i) {
    var text = d3.select(this).select('text');
    if (i % 2 !== 0)
      text.text('');
  });

  setTooltipEvents(chart);

  nv.utils.windowResize(function() {

    chart.update();
    width = nv.utils.availableWidth(null, d3.select('#chart svg'), chart._options.margin);

  }); // update chart on resize
  return chart;
});
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

我今天遇到了同样的问题,这是NVD3库中的一个错误。