40

フィールド値の一部が配列であるデータ セットがあり、クロスフィルターと d3.js または dc.js を使用して、これらの値がデータセットに何回存在したかのヒストグラムを表示したいと考えています。

次に例を示します。

var data = [
    {"key":"KEY-1","tags":["tag1", "tag2"]},
    {"key":"KEY-2","tags":["tag2"]},
    {"key":"KEY-3","tags":["tag3", "tag1"]}];

var cf = crossfilter(data);

var tags = cf.dimension(function(d){ return d.tags;});
var tagsGroup = tags.group();


dc.rowChart("#chart")
    .renderLabel(true)
    .dimension(tags)
    .group(tagsGroup)
    .xAxis().ticks(3);

dc.renderAll();

そしてJSFiddle http://jsfiddle.net/uhXf5/2/

そのコードを実行すると、次のようなグラフが生成されます。

グラフ1

しかし、私が欲しいのは次のようなものです:

ここに画像の説明を入力

物事をさらに複雑にするために、任意の行をクリックして、クリックされたタグでデータセットをフィルター処理できるとしたら素晴らしいことです。

それを達成する方法は誰にもありますか?

ありがとう、コスチャ

4

5 に答える 5

15

Jeff と Kostya によってリストされたアプローチの背景を説明したいと思います。

通常のグループ メソッドとは異なり、tagsGroup が groupAll を使用していることに気付くでしょう。Crossfilter は、「返されたオブジェクトは、top または order メソッドがないことを除いて、標準のグループ化に似ています。代わりに、value を使用して、一致するすべてのレコードの reduce 値を取得します。」Kostya は「.value()」メソッドを呼び出して、グループ全体を表す単一のオブジェクトを取得しました。

var tagsGroup = tags.groupAll().reduce(reduceAdd, reduceRemove, reduceInitial).value();

dc.js は group オブジェクトに all メソッドがあることを想定しているため、このオブジェクトは dc.js ではうまく機能しません。Kostya は、そのオブジェクトにパッチを適用して、次のような「all」メソッドを作成しました。

// hack to make dc.js charts work
tagsGroup.all = function() {
  var newObject = [];
  for (var key in this) {
    if (this.hasOwnProperty(key) && key != "all") {
      newObject.push({
        key: key,
        value: this[key]
      });
    }
  }
  return newObject;
}

これは単純な dc.js チャートで機能しますが、すべてのグループ関数が存在するわけではないため、すべての dc.js 機能を使用することはできません。たとえば、cap メソッドはグループ オブジェクトに「top」メソッドがあることを想定しているため、チャートで「cap」メソッドを使用することはできません。次のように top メソッドにパッチを適用することもできます。

topicsGroup.top = function(count) {
    var newObject = this.all();
     newObject.sort(function(a, b){return b.value - a.value});
    return newObject.slice(0, count);
};

これにより、チャートで cap メソッドを使用できるようになります。

barChart
    .renderLabel(true)
    .height(200)
    .dimension(topicsDim)
    .group(topicsGroup)
    .cap(2)
    .ordering(function(d){return -d.value;})
    .xAxis().ticks(3);

更新された例は、http://jsfiddle.net/djmartin_umich/m7V89/#baseで入手できます。

于 2014-07-09T17:18:40.633 に答える
7

ジェフの答えは機能しますが、「見つかった」変数を追跡したり、アイテムが見つかった場合にループを続行したりする必要はありません。X が [X,Y,Z] にある場合、これにより既に反復の量が 1/3 に削減されています。

else
    dimension.filterFunction(function (d) {
        for (var i=0; i < d.length; i++) {
            if (filters.indexOf(d[i]) >= 0) return true;
        }
        return false; 
    });

または、dc.js の filterFunction メソッドにパッチを適用すると、すべてのケースを処理できます。

于 2013-12-03T02:49:07.007 に答える