【问题标题】:DC.js Graphing TagsDC.js 图形标签
【发布时间】:2015-02-14 21:09:31
【问题描述】:

附上示例数据

var data = [
    {Name: 'Mr A', Spent: 40, Year: 2011, tags: ['a', 'b', 'c']},
    {Name: 'Mr B', Spent: 10, Year: 2011, tags: ['c']},
    {Name: 'Mr C', Spent: 40, Year: 2011, tags: ['a']},
    {Name: 'Mr A', Spent: 70, Year: 2012, tags: ['c', 'b']},
    {Name: 'Mr B', Spent: 20, Year: 2012, tags: ['b']},
    {Name: 'Mr B', Spent: 50, Year: 2013, tags: ['a', 'b', 'c']},
    {Name: 'Mr C', Spent: 30, Year: 2013, tags: ['a', 'b']}
];

我正在尝试创建一个 dc.js 行图,该图表将显示每个唯一标签并允许我减少每个标签绘制的值。到目前为止,我有这段代码可以让我将标签减少到他们花费的总和:

function reduceAdd(p, v) {
  v.tags.forEach (function(val, idx) {
     p[val] = (p[val] || 0) + v.Spent;
  });
  return p;
}

function reduceRemove(p, v) {
   v.tags.forEach (function(val, idx) {
     p[val] -= v.Spent;
  });
  return p;
}

function reduceInitial() {
  return {};  
}
var tagsDim = ndx.dimension(function(d)  {return d.tags; } );
tagsGroup = tagsDim.groupAll().reduce(reduceAdd, reduceRemove, reduceInitial);
console.log(tagsGroup.value())
'{ a: 160, b: 210, c: 170 }'

这正确地给出了减少的总和。但是,因为这是一个 groupAll 对象 dc.js 无法绘制它,所以我不太确定从这里去哪里。 dc.js 甚至可以访问数组中的标签吗?以不同的方式计算总和会更好吗?

【问题讨论】:

  • 这样你会得到不相交的组——因为一行可以属于与标签一样多的组,所以行将被计算多次。此外,任何其他跨行进行普通总和的图表都会得到不同的总数。这是你想要的吗?
  • 很确定 crossfilter 不支持这个,所以你必须自己实现它。很容易适应您作为fake group 获得的组;棘手的部分是写filter function
  • 谢谢@Gordon,我会试试的。

标签: javascript dc.js crossfilter


【解决方案1】:

如果有帮助,这里是我用来创建具有多个标签的行图的代码。它应该适用于您的数据。

你可以在这里试试:http://jsfiddle.net/ewm76uru/30/

var data = [
{id:1, author:'foo', tags: ['tag1','tag2','tag3']},
{id:2, author:'foo', tags: ['tag3']},
{id:3, author:'foo', tags: ['tag1']},
{id:4, author:'bar', tags: ['tag2','tag3']},
{id:5, author:'bar', tags: ['tag3']},
{id:6, author:'bar', tags: ['tag2','tag3']},
{id:7, author:'bar', tags: ['tag1','tag2']}
]; 

    var content=crossfilter(data);

    // table
    var idDimension = content.dimension(function (d) { return d.id; });
    var table = dc.dataTable("#idtable");
    table.dimension(idDimension)
        .group(function(d){ return "ITEMS" })
        .columns([
            function(d){return d.id+" : "; },
    function(d){return d.author+" "},
            function(d){return d.tags;},
        ])

    // author chart
    var authorDimension = content.dimension(function (d) { return d.author; });
    var authorgroup = authorDimension.group().reduceSum(function(d) { return 1; })
    authorChart = dc.rowChart('#idauthor');
    authorChart
        .width(300)
        .renderLabel(true)
        .gap(2)
        .margins({top: 10, left: 10, right: 20, bottom: 40})
        .group(authorgroup)
        .dimension(authorDimension)
        .elasticX(true)
        .transitionDuration(1000)
        .colors(d3.scale.category10())
        .label(function (d) { return d.key })
        .xAxis().ticks(5);

    // tags chart
    function reduceAdd(p, v) {
        v.tags.forEach (function(val, idx) {
            p[val] = (p[val] || 0) + 1; //increment counts
        });
        return p;
    }

    function reduceRemove(p, v) {
        v.tags.forEach (function(val, idx) {
            p[val] = (p[val] || 0) - 1; //decrement counts
        });
        return p;
    }

    function reduceInitial() {
        return [];
    }


    var tags = content.dimension(function (d) { return d.tags });
    var tags2 = content.dimension(function (d) { return d.tags });
    var groupall = tags.groupAll();
    var tagsGroup = groupall.reduce(reduceAdd, reduceRemove, reduceInitial).value();
    tagsGroup.all = function() {
        var newObject = [];
        for (var key in this) {
            if (this[key] && key != "all") {
                newObject.push({
                    key: key,
                    value: this[key]
                });
            }
        }
        return newObject;
    }

    var tagsChart = dc.rowChart("#idtags")
    tagsChart
        .width(400)
        .height(200)
        .renderLabel(true)
        .labelOffsetY(10)
        .gap(2)
        .group(tagsGroup)
        .dimension(tags2)
        .elasticX(true)
        .transitionDuration(1000)
        .colors(d3.scale.category10())
        .label(function (d) { return d.key })
        .on("filtered", function(c,f) {
            //tags2.filter(f)
        })
        .filterHandler (function (dimension, filters) {
            dimension.filter(null);
            dimension.filterFunction(function (d) {
                for (var i=0; i < filters.length; i++) {
                    if (d.indexOf(filters[i]) <0) return false;
                }
                return true;
            });



            return filters;
        })
    .xAxis().ticks(5);

    dc.renderAll();

【讨论】:

  • 我已经编辑了我的答案以解释如何通过多个标签进行过滤,并更新了标签过滤器
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-13
  • 1970-01-01
  • 1970-01-01
  • 2018-06-12
相关资源
最近更新 更多