使用 DC.js 和交叉过滤器的复合图(条形图和线形图),当条形值 = 0 时线消失
Composite graph (bar & line) using DC.js and crossfilter, line disappears when bar value = 0
当度量的最后一个值为零时,该线在复合图中消失。我有 code pen here
这是我的示例数据:
var data = [
{ "ID": 1, "TxDate": "2017/12/30", "InstCode": "Loc1", "NTS": 7, "NTS2": 1 },
{ "ID": 2, "TxDate": "2017/12/31", "InstCode": "Loc1", "NTS": 14, "NTS2": 6 },
{ "ID": 3, "TxDate": "2017/12/31", "InstCode": "Loc1", "NTS": 1, "NTS2": 1 },
{ "ID": 4, "TxDate": "2017/12/30", "InstCode": "Loc2", "NTS": 1, "NTS2": 1 },
{ "ID": 5, "TxDate": "2018/01/02", "InstCode": "Loc2", "NTS": 2, "NTS2": 1 },
{ "ID": 6, "TxDate": "2018/01/02", "InstCode": "Loc2", "NTS": 1, "NTS2": 1 },
{ "ID": 7, "TxDate": "2018/01/03", "InstCode": "Loc1", "NTS": 3, "NTS2": 4 },
{ "ID": 8, "TxDate": "2018/01/03", "InstCode": "Loc1", "NTS": 1, "NTS2": 1 },
{ "ID": 9, "TxDate": "2018/01/04", "InstCode": "Loc1", "NTS": 1, "NTS2": 1 },
{ "ID": 10, "TxDate": "2018/01/02", "InstCode": "Loc2", "NTS": 4, "NTS2": 1 },
{ "ID": 11, "TxDate": "2018/01/03", "InstCode": "Loc1", "NTS": 22, "NTS2": 14 },
{ "ID": 12, "TxDate": "2018/01/02", "InstCode": "Loc1", "NTS": 2, "NTS2": 0 },
{ "ID": 13, "TxDate": "2018/01/04", "InstCode": "Loc2", "NTS": 0, "NTS2": 0 },
{ "ID": 14, "TxDate": "2018/01/04", "InstCode": "Loc2", "NTS": 0, "NTS2": 0 },
{ "ID": 15, "TxDate": "2018/02/04", "InstCode": "Loc2", "NTS": 0, "NTS2": 3 }
];
var yearPieChart = dc.pieChart("#year-pie-chart");
var monthBarChart = dc.barChart("#month-bar-chart");
var composite = dc.compositeChart('#compo-bar-line-chart');
问题是"NTS"的最后一个值:1的那一刻,合成图出现了。如果我更改下面的行
{ "ID": 15, "TxDate": "2018/02/04", "InstCode": "Loc2", "NTS": 0, "NTS2": 3 }
到
{ "ID": 15, "TxDate": "2018/02/04", "InstCode": "Loc2", "NTS": 1, "NTS2": 3 }
合成图出现。有没有什么方法可以在值 "NTS": 0 时显示图表 非常感谢您的帮助。
复合条码:
composite
.width(1200).height(450)
.margins({ top: 20, bottom: 90, right: 10, left: 70 })
.x(d3.scale.ordinal().domain(nonEmptytxNTSGroup))
.xUnits(dc.units.ordinal)
//.xAxisLabel('Date')
.yAxisLabel("NTS")
.elasticX(true)
.elasticY(true)
//.rightYAxisLabel('Final Treatments')
.group(nonEmptytxNTSGroup)
.renderLabel(true)
._rangeBandPadding(1)
.compose(
[
dc.barChart(composite)
.gap(1)
.centerBar(true)
.group(nonEmptytxNTSGroup)
.elasticX(true)
.elasticY(true)
.renderLabel(true),
dc.lineChart(composite)
.group(nonEmptytxFinalTxGroup)
.useRightYAxis(false)
.colors('red')
.elasticX(true)
.elasticY(true)
.renderDataPoints({
radius: 10,
fillOpacity: 5.5,
strokeOpacity: 5.8
})
.renderLabel(true)
]
);
composite.renderlet(function (composite) {
composite.selectAll("g.x text")
.attr('dx', '-35')
//.select("g.axis.y")
//.attr("transform", "rotate(-45)");
.attr('transform', "translate(-10,0) rotate(-65)");
});
在复合图表中,所有子图表将共享相同的 X 比例尺。这是由给予父(复合)图表的组决定的。
在您的示例中,您使用条形图组作为复合图表组。如果折线图组有任何不在条形图组中的键,则拒绝绘制。 (具体来说,它在行中以一些 NaN
结束,对于比例中不存在的 X 值,然后完整性检查将其重置为空行。)
解决此问题的最简单方法是不使用 remove_empty_bins
。然后域将始终匹配两个图表。
更复杂但可以说更可靠的方法是使用通常用于堆叠图表的解决方案,其中所有堆叠还必须在其 X 域中匹配。
The FAQ contains combine_groups
:
function combine_groups() { // (groups...)
var groups = Array.prototype.slice.call(arguments);
return {
all: function() {
var alls = groups.map(function(g) { return g.all(); });
var gm = {};
alls.forEach(function(a, i) {
a.forEach(function(b) {
if(!gm[b.key]) {
gm[b.key] = new Array(groups.length);
for(var j=0; j<groups.length; ++j)
gm[b.key][j] = 0;
}
gm[b.key][i] = b.value;
});
});
var ret = [];
for(var k in gm)
ret.push({key: k, value: gm[k]});
return ret;
}
};
}
从非空组中生成一个组合组,如下所示:
var combined = combine_groups(nonEmptytxNTSGroup, nonEmptytxFinalTxGroup);
给复合图表设置公共域:
composite
// ...
.group(combined)
告诉每个子图表从组合值之一中提取其值:
.compose(
[
dc.barChart(composite)
// ...
.group(combined, "1", function(kv) { return kv.value[0]; })
// ...
dc.lineChart(composite)
.group(combined, "2", function(kv) { return kv.value[1]; })
// ...
]
现在您有一个复合图表,它将使用两个非空组的域的 并集。请注意,这也会强制子图表具有相同的域:任何跳过的值现在都将设置为 0:
此处最后一个柱为零,但仍绘制其 0 标签,因为折线图在那里具有非零值。
当度量的最后一个值为零时,该线在复合图中消失。我有 code pen here
这是我的示例数据:
var data = [
{ "ID": 1, "TxDate": "2017/12/30", "InstCode": "Loc1", "NTS": 7, "NTS2": 1 },
{ "ID": 2, "TxDate": "2017/12/31", "InstCode": "Loc1", "NTS": 14, "NTS2": 6 },
{ "ID": 3, "TxDate": "2017/12/31", "InstCode": "Loc1", "NTS": 1, "NTS2": 1 },
{ "ID": 4, "TxDate": "2017/12/30", "InstCode": "Loc2", "NTS": 1, "NTS2": 1 },
{ "ID": 5, "TxDate": "2018/01/02", "InstCode": "Loc2", "NTS": 2, "NTS2": 1 },
{ "ID": 6, "TxDate": "2018/01/02", "InstCode": "Loc2", "NTS": 1, "NTS2": 1 },
{ "ID": 7, "TxDate": "2018/01/03", "InstCode": "Loc1", "NTS": 3, "NTS2": 4 },
{ "ID": 8, "TxDate": "2018/01/03", "InstCode": "Loc1", "NTS": 1, "NTS2": 1 },
{ "ID": 9, "TxDate": "2018/01/04", "InstCode": "Loc1", "NTS": 1, "NTS2": 1 },
{ "ID": 10, "TxDate": "2018/01/02", "InstCode": "Loc2", "NTS": 4, "NTS2": 1 },
{ "ID": 11, "TxDate": "2018/01/03", "InstCode": "Loc1", "NTS": 22, "NTS2": 14 },
{ "ID": 12, "TxDate": "2018/01/02", "InstCode": "Loc1", "NTS": 2, "NTS2": 0 },
{ "ID": 13, "TxDate": "2018/01/04", "InstCode": "Loc2", "NTS": 0, "NTS2": 0 },
{ "ID": 14, "TxDate": "2018/01/04", "InstCode": "Loc2", "NTS": 0, "NTS2": 0 },
{ "ID": 15, "TxDate": "2018/02/04", "InstCode": "Loc2", "NTS": 0, "NTS2": 3 }
];
var yearPieChart = dc.pieChart("#year-pie-chart");
var monthBarChart = dc.barChart("#month-bar-chart");
var composite = dc.compositeChart('#compo-bar-line-chart');
问题是"NTS"的最后一个值:1的那一刻,合成图出现了。如果我更改下面的行
{ "ID": 15, "TxDate": "2018/02/04", "InstCode": "Loc2", "NTS": 0, "NTS2": 3 }
到
{ "ID": 15, "TxDate": "2018/02/04", "InstCode": "Loc2", "NTS": 1, "NTS2": 3 }
合成图出现。有没有什么方法可以在值 "NTS": 0 时显示图表 非常感谢您的帮助。
复合条码:
composite
.width(1200).height(450)
.margins({ top: 20, bottom: 90, right: 10, left: 70 })
.x(d3.scale.ordinal().domain(nonEmptytxNTSGroup))
.xUnits(dc.units.ordinal)
//.xAxisLabel('Date')
.yAxisLabel("NTS")
.elasticX(true)
.elasticY(true)
//.rightYAxisLabel('Final Treatments')
.group(nonEmptytxNTSGroup)
.renderLabel(true)
._rangeBandPadding(1)
.compose(
[
dc.barChart(composite)
.gap(1)
.centerBar(true)
.group(nonEmptytxNTSGroup)
.elasticX(true)
.elasticY(true)
.renderLabel(true),
dc.lineChart(composite)
.group(nonEmptytxFinalTxGroup)
.useRightYAxis(false)
.colors('red')
.elasticX(true)
.elasticY(true)
.renderDataPoints({
radius: 10,
fillOpacity: 5.5,
strokeOpacity: 5.8
})
.renderLabel(true)
]
);
composite.renderlet(function (composite) {
composite.selectAll("g.x text")
.attr('dx', '-35')
//.select("g.axis.y")
//.attr("transform", "rotate(-45)");
.attr('transform', "translate(-10,0) rotate(-65)");
});
在复合图表中,所有子图表将共享相同的 X 比例尺。这是由给予父(复合)图表的组决定的。
在您的示例中,您使用条形图组作为复合图表组。如果折线图组有任何不在条形图组中的键,则拒绝绘制。 (具体来说,它在行中以一些 NaN
结束,对于比例中不存在的 X 值,然后完整性检查将其重置为空行。)
解决此问题的最简单方法是不使用 remove_empty_bins
。然后域将始终匹配两个图表。
更复杂但可以说更可靠的方法是使用通常用于堆叠图表的解决方案,其中所有堆叠还必须在其 X 域中匹配。
The FAQ contains combine_groups
:
function combine_groups() { // (groups...)
var groups = Array.prototype.slice.call(arguments);
return {
all: function() {
var alls = groups.map(function(g) { return g.all(); });
var gm = {};
alls.forEach(function(a, i) {
a.forEach(function(b) {
if(!gm[b.key]) {
gm[b.key] = new Array(groups.length);
for(var j=0; j<groups.length; ++j)
gm[b.key][j] = 0;
}
gm[b.key][i] = b.value;
});
});
var ret = [];
for(var k in gm)
ret.push({key: k, value: gm[k]});
return ret;
}
};
}
从非空组中生成一个组合组,如下所示:
var combined = combine_groups(nonEmptytxNTSGroup, nonEmptytxFinalTxGroup);
给复合图表设置公共域:
composite
// ...
.group(combined)
告诉每个子图表从组合值之一中提取其值:
.compose(
[
dc.barChart(composite)
// ...
.group(combined, "1", function(kv) { return kv.value[0]; })
// ...
dc.lineChart(composite)
.group(combined, "2", function(kv) { return kv.value[1]; })
// ...
]
现在您有一个复合图表,它将使用两个非空组的域的 并集。请注意,这也会强制子图表具有相同的域:任何跳过的值现在都将设置为 0:
此处最后一个柱为零,但仍绘制其 0 标签,因为折线图在那里具有非零值。