gpt4 book ai didi

dc.js使用三列的最小值,最大值,平均值创建dataTable

转载 作者:行者123 更新时间:2023-12-04 17:31:41 29 4
gpt4 key购买 nike

尝试使用样本数据中3列的最小值,最大值和平均值创建d3/dc/xfilter dataTable。辛苦了几个小时,但无法理解如何将reduceAdd,reduceRemove,reduceInitial函数集成到dataTable中以创建三个必要的行。

所需的输出将如下所示:

------------------------------------------
| Value | Cars | Bikes | Trucks |
------------------------------------------
| Min | 125 | 310 | 189 |
------------------------------------------
| Max | 230 | 445 | 290 |
------------------------------------------
| Avg | 178 | 385 | 245 |
------------------------------------------

也看不到如何添加第一列(标签)。我知道reduceInitial可以返回一个数组(例如 ['min', 'max', 'avg']),但是如何从中引用标签呢?

var myCSV = [	
{"shift":"1","date":"01/01/2016/08/00/00","car":"178","truck":"255","bike":"317","moto":"237"},
{"shift":"2","date":"01/01/2016/17/00/00","car":"125","truck":"189","bike":"445","moto":"273"},
{"shift":"3","date":"02/01/2016/08/00/00","car":"140","truck":"219","bike":"328","moto":"412"},
{"shift":"4","date":"02/01/2016/17/00/00","car":"222","truck":"290","bike":"432","moto":"378"},
{"shift":"5","date":"03/01/2016/08/00/00","car":"200","truck":"250","bike":"420","moto":"319"},
{"shift":"6","date":"03/01/2016/17/00/00","car":"230","truck":"220","bike":"310","moto":"413"},
{"shift":"7","date":"04/01/2016/08/00/00","car":"155","truck":"177","bike":"377","moto":"180"},
{"shift":"8","date":"04/01/2016/17/00/00","car":"179","truck":"203","bike":"405","moto":"222"},
{"shift":"9","date":"05/01/2016/08/00/00","car":"208","truck":"185","bike":"360","moto":"195"},
{"shift":"10","date":"05/01/2016/17/00/00","car":"150","truck":"290","bike":"315","moto":"280"},
{"shift":"11","date":"06/01/2016/08/00/00","car":"200","truck":"220","bike":"350","moto":"205"},
{"shift":"12","date":"06/01/2016/17/00/00","car":"230","truck":"170","bike":"390","moto":"400"},
];


dataTable = dc.dataTable('#dataTable');
lc1 = dc.lineChart("#line1");
lc2 = dc.lineChart("#line2");
lc3 = dc.lineChart("#line3");

var dateFormat = d3.time.format("%d/%m/%Y/%H/%M/%S");

myCSV.forEach(function (d) {
d.date = dateFormat.parse(d.date);
});

myCSV.forEach(function (d) {
d['car'] = +d['car'];
d['bike'] = +d['bike'];
d['moto'] = +d['moto'];
});

//console.log(myCSV);

var facts = crossfilter(myCSV);
var dateDim = facts.dimension(function (d) {return d.date});

var carDim = facts.dimension(function (d) {return d['car']});
var dgCar = dateDim.group().reduceSum(function (d) {return d['car']});

var bikeDim = facts.dimension(function (d) {return d['bike']});
var dgBike = dateDim.group().reduceSum(function (d) {return d['bike']});

var motoDim = facts.dimension(function (d) {return d['moto']});
var dgMoto = dateDim.group().reduceSum(function (d) {return d['moto']});

var minDate = new Date ("2016-01-01T08:00:00.000Z");
var maxDate = new Date ("2016-01-03T17:00:00.000Z");

var maxY = d3.max(myCSV, function(d) {return d['car']});

function reduceAdd(i,d){ return i+1; }
function reduceRemove(i,d){return i-1; }
function reduceInitial(){ return ['min','max','avg'];}


dataTable
.width(jsTablWidth)
.height(400)
.dimension(dateDim)
.group( function(d){return '';} )
.columns([
{
label: 'Value',
format: function(d) { return dateGroup1.reduce(reduceAdd,reduceRemove,reduceInital); }
},
{
label: tSel1.replace(/_/g, " "),
format: function(d) { return //avg cars ; }
},
{
label: tSel2.replace(/_/g, " "),
format: function(d) { return //avg bikes ; }
},
{
label: tSel3.replace(/_/g, " "),
format: function(d) { return //avg moto; }
}
]);


dc.renderAll();
dc.redrawAll();
svg{height:280px;}
<script src="http://cdnjs.cloudflare.com/ajax/libs/d3/3.3.3/d3.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.1/crossfilter.min.js"></script>
<script src="http://dc-js.github.io/dc.js/js/dc.js"></script>
<link href="http://dc-js.github.io/dc.js/css/dc.css" rel="stylesheet"/>

<svg id="dataTable"></svg>
<svg id="line1"></svg>
<svg id="line2"></svg>
<svg id="line3"></svg>

最佳答案

好的,希望您可以将 table 对角线交叉放置,将运输方式设置为行而不是列。如果不弄清楚那部分,这个解决方案已经很古怪了。

sample output

除了跟踪所有值之外,实际上没有其他方法可以计算出最小值和最大值。因此,我们将使用complex reductions example中的减少量。这些实际上根本不会减少,但会维护已过滤行的排序数组。

我们需要一个唯一的键来保留排序后的数组(以便我们删除正确的行。幸运的是,您在shift字段中输入了该键。

因此,这里是那些功能,或者更确切地说,是在给定唯一键访问器的情况下生成还原器的功能。

  function groupArrayAdd(keyfn) {
var bisect = d3.bisector(keyfn);
return function(elements, item) {
var pos = bisect.right(elements, keyfn(item));
elements.splice(pos, 0, item);
return elements;
};
}
function groupArrayRemove(keyfn) {
var bisect = d3.bisector(keyfn);
return function(elements, item) {
var pos = bisect.left(elements, keyfn(item));
if(keyfn(elements[pos])===keyfn(item))
elements.splice(pos, 1);
return elements;
};
}
function groupArrayInit() {
return [];
}

由于这些保留了对整个行的引用,因此我们只需要一组即可。我们在计算以下指标时将使用更具体的访问器。

在这里,我们需要 crossfilter.groupAll,它将所有内容减少到一个bin中。这是因为行没有被任何键分区;每行都有助于所有运输方式:
var filteredRows = facts.groupAll().reduce(
groupArrayAdd(dc.pluck('shift')),
groupArrayRemove(dc.pluck('shift')),
groupArrayInit
);

现在是最荒谬的部分。我们将创建您见过的最假的尺寸对象。重要的是,它是一个带有 .bottom()方法的对象,该方法可以动态计算每一行:
var fakeDim = {
bottom: function() {
return [
{key: 'Car', value: filteredRows.value(), acc: dc.pluck('car')},
{key: 'Truck', value: filteredRows.value(), acc: dc.pluck('car')},
{key: 'Bike', value: filteredRows.value(), acc: dc.pluck('bike')},
{key: 'Moto', value: filteredRows.value(), acc: dc.pluck('moto')}
];
}
};

除了等待,看起来根本没有做任何计算,只是在获取值吗?那奇怪的 acc是什么?

好吧,我们正在精确地生成生成表行所需的源数据,并且我们将使用下面的 format访问器实际计算所有内容。我们将 key用作“标签列”,将原始行保留在 value成员中;并且我们将提供访问器 acc来计算指标。

数据表定义如下所示:
dataTable
.width(400)
.height(400)
.dimension(fakeDim)
.group( function(d){return '';} )
.columns([
{
label: 'Value',
format: function(d) {
return d.key;
}
},
{
label: 'Min',
format: function(d) {
return d3.min(d.value, d.acc);
}
},
{
label: 'Max',
format: function(d) {
return d3.max(d.value, d.acc);
}
},
{
label: 'Avg',
format: function(d) {
return d3.mean(d.value, d.acc);
}
}
]);

这是所有指标最终计算出来的地方。我们将提供所有可用的行,并且每个表行都有一个访问器。 d3-array具有方便的函数,用于计算数组的最小值,最大值和平均值。繁荣,完成。

我把一个堆积的图表放到这个 fiddle 中进行测试。 (我知道堆叠这些值可能没有任何意义,这只会有助于进行过滤。)

http://jsfiddle.net/gordonwoodhull/g4xqvgvL/21/

旋转数据表

对此的额外奖励使我想起了我从来没有解决过表转换问题,所以我想看看一下,因为它很有趣。我仍然认为赏金应该归@SergGr,但这是根据类别,维和列访问器/格式器转置表的解决方案。

首先,我们需要类别列表,因此让我们更好地组织类别和字段名称:
var categories = {  
Car: 'car',
Truck: 'truck',
Bike: 'bike',
Moto: 'moto'
};

现在可以简化伪维,因为它是从以下类别映射生成的:
function fake_dimension(cats) {
return {
bottom: function() {
return Object.keys(cats).map(function(k) {
return {
key: k,
value: filteredRows.value(),
acc: dc.pluck(cats[k])
};
});
}
};
}
var fakeDim = fake_dimension(categories);

我们需要将列定义从图表定义中拉出,因为我们将对其进行转换:
var columns = [
{
label: 'Value',
format: function(d) {
return d.key;
}
},
{
label: 'Min',
format: function(d) {
return d3.min(d.value, d.acc);
}
},
{
label: 'Max',
format: function(d) {
return d3.max(d.value, d.acc);
}
},
{
label: 'Avg',
format: function(d) {
return d3.mean(d.value, d.acc);
}
}
];

最后,我们可以编写转置函数:
function transpose_datatable(cats, dim, cols) {
var cols2 = d3.map(cols, function(col) { // 1
return col.label;
});
return {
dim: { // 2
bottom: function() {
var dall = d3.map(dim.bottom(Infinity), function(row) { // 3
return row.key;
});
return cols.slice(1).map(function(col) { // 4
var row = {
label: col.label
};
Object.keys(cats).forEach(function(k) {
row[k] = dall.get(k);
});
return row;
});
}
},
cols: [ // 5
{
label: cols[0].label,
format: function(d) {
return d.label;
}
}
].concat(Object.keys(cats).map(function(k) { // 6
return {
label: k,
format: function(d) {
return cols2.get(d.label).format(d[k]);
}
}
}))
};
}

var transposed = transpose_datatable(categories, fakeDim, columns)
  • 首先,我们需要原始列与其定义的映射,因为它们将成为行。我们可以在此处使用d3.map,它的行为就像一个行为良好的JavaScript对象。
  • 我们将创建一个新的伪维,以及新的列定义数组。伪维度只有一种.bottom()方法,就像上面的方法一样。
  • .bottom()的定义将需要通过键(类别名称)索引的所有原始数据。因此,我们也将其放入d3.map对象中。
  • 现在,我们可以构建伪造的尺寸数据。第一列只是标题(现在将是列标题),因此我们将跳过它。该行的数据将是新标题(以前的列标签),以及每个类别的字段。这些字段将填充原始维度中的行。
  • 新的列定义需要替换标签,列,其余的从类别名称生成。
  • 每列的标签现在是类别名称,.format()调用原始列的format,使用类别名称获取数据。

  • 新的屏幕截图:

    screenshot with rotated datatable

    关于dc.js使用三列的最小值,最大值,平均值创建dataTable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42475836/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com