javascript - d3.js:5942 错误:<g> 属性转换的无效值 ="translate(NaN,0)"

标签 javascript d3.js dc.js

使用 d3.js v3.55、crossfilter.js v1.311 和 dc.js v1.73 并尝试构建一个返回平均值而不是总和或计数的 reduce 函数。内置的 reduceSum 工作正常,但是当我尝试添加自己的 reduce 函数时,基于互联网上的许多示例。我收到消息: d3.js:5942 错误:属性 transform="translate(NaN,0)"的值无效 d3.js:8718 错误:属性宽度的无效值=“NaN”

这里是在不删除任何重要信息的情况下尽可能减少的代码:

<script type="text/javascript">
//
// Create the Chart Objects
//
var GeoZoneChart               = dc.rowChart("#chart-geo-zone");
var pdcData = [
{GeoZone: 'New York Metro', PDCLast365: 0.43}, 
{GeoZone: 'New York Metro', PDCLast365: 0.427}, 
{GeoZone: 'New York Metro', PDCLast365: 0.418}, 
{GeoZone: 'Los Angeles Metro', PDCLast365: 0.4085}, 
{GeoZone: 'Los Angeles Metro', PDCLast365: 0.40565}, 
{GeoZone: 'Chicago Metro', PDCLast365: 0.46789457}, 
{GeoZone: 'Chicago Metro', PDCLast365: 0.46366023}, 
{GeoZone: 'Chicago Metro', PDCLast365: 0.447781455}
];
//
// normalize/parse data
//   in this case, turn the decimel into a percentage
pdcData.forEach(function(d) {
    d.PDCLast365 = d.PDCLast365 * 100;
    d.PDCLast365 = d.PDCLast365.toFixed(2);
});

function isNumeric(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

function reduceAddAvg(attr) {
  return function(p,v) {
    if (isNumeric(v[attr]) ){
        ++p.count;
        p.sum += v[attr];
        p.avg = p.sum/p.count;
    }
    return p;
  };
}
function reduceRemoveAvg(attr) {
  return function(p,v) {
    if (isNumeric(v[attr]) ){
        --p.count;
        p.sum -= v[attr];
        p.avg = p.sum/p.count;
    }
    return p;
  };
}
function reduceInitAvg() {
  return {count:0, sum:0, avg:0};
}

//
// set crossfilter
//
var ndx = crossfilter(pdcData),
    GeoZoneDim           = ndx.dimension(function(d) {return d.GeoZone;}),
    PDCLast365PerGeoZone = 
          GeoZoneDim.group().reduce(
            reduceAddAvg('PDCLast365'), 
            reduceRemoveAvg('PDCLast365'), 
            reduceInitAvg);


GeoZoneChart
    .width(400).height(200)
    .dimension(GeoZoneDim)
    .group(PDCLast365PerGeoZone)
    .elasticX(true);

dc.renderAll();
</script>

最佳答案

p.count 降为零时,你需要一个 guard 。所以:

function reduceRemoveAvg(attr) {
  return function(p,v) {
    if (isNumeric(v[attr]) ){
        --p.count;
        p.sum -= v[attr];
        p.avg = p.count ? p.sum/p.count : 0;
    }
    return p;
  };
}

如果您能在 SO 或 dc.js 网站或用户组上指出任何此类不良示例,我们将不胜感激。

编辑:我不确定它在这里会产生什么影响,但是 toFixed()实际上返回一个字符串,而不是一个数字。而你的 isNumeric 测试的是这个值是否可以转换为数字,而不是它是否是数字。所以你最终可能会得到字符串连接而不是加法。

正如我在下面所说的,正确的计算方法是在 reduce 函数中放置断点并查看实际计算的内容。

关于javascript - d3.js:5942 错误:<g> 属性转换的无效值 ="translate(NaN,0)",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29571724/

相关文章:

javascript - 如何将以下 Json 对象转换为字符串,如下所示

javascript - 如何为D3折线图添加背景底纹

javascript - 水平条形图 d3.js 中的 y 轴上未显示文本

d3.js - d3 使用 SVG 轴和 Canvas 图表进行缩放和拖动

d3.js - 按聚合划分聚合 (D3/DC/Crossfilter/Reductio)

d3.js - 在 dc.js 中为条形图跳过 x 轴上的重叠标签

javascript - 表格上的双水平滚动 - JQuery

javascript - 插画填充颜色对象

reactjs - 将 dc.js 转换为 React 有意义吗?

javascript - 使用来自延迟的 JSON 请求的方法和类创建 Javascript 对象