Display original (conditional) brushed unbrushed crossfilter bars with dc.js with different colors The Next CEO of Stack OverflowSum by category in Piechart (Dc.js & Crossfilter)Crossfilter and dc.js mean valueDifferent filters for different charts using dc.js and crossfilterdc.js brush not aligned with cursordc.js / crossfilter dimensions (year / week)Crossfilter with DC.js Choropleth mapDc.js lineChart not displaying crossfiltered dataPercentage Change in dc.js/crossfilterAverage in Crossfilter and DC.jsCrossfilter DC.JS Chart on Sub Elements
Why does standard notation not preserve intervals (visually)
Some questions about different axiomatic systems for neighbourhoods
Can we say or write : "No, it'sn't"?
Would be okay to drive on this tire?
Is there a difference between "Fahrstuhl" and "Aufzug"
is it ok to reduce charging current for li ion 18650 battery?
Math-accent symbol over parentheses enclosing accented symbol (amsmath)
Easy to read palindrome checker
How to invert MapIndexed on a ragged structure? How to construct a tree from rules?
Why does the flight controls check come before arming the autobrake on the A320?
Why don't programming languages automatically manage the synchronous/asynchronous problem?
Method for adding error messages to a dictionary given a key
Is micro rebar a better way to reinforce concrete than rebar?
Why this way of making earth uninhabitable in Interstellar?
Why is information "lost" when it got into a black hole?
Is a distribution that is normal, but highly skewed considered Gaussian?
Does Germany produce more waste than the US?
No sign flipping while figuring out the emf of voltaic cell?
Running a General Election and the European Elections together
Is it professional to write unrelated content in an almost-empty email?
What does "Its cash flow is deeply negative" mean?
A Man With a Stainless Steel Endoskeleton (like The Terminator) Fighting Cloaked Aliens Only He Can See
Proper way to express "He disappeared them"
Reference request: Grassmannian and Plucker coordinates in type B, C, D
Display original (conditional) brushed unbrushed crossfilter bars with dc.js with different colors
The Next CEO of Stack OverflowSum by category in Piechart (Dc.js & Crossfilter)Crossfilter and dc.js mean valueDifferent filters for different charts using dc.js and crossfilterdc.js brush not aligned with cursordc.js / crossfilter dimensions (year / week)Crossfilter with DC.js Choropleth mapDc.js lineChart not displaying crossfiltered dataPercentage Change in dc.js/crossfilterAverage in Crossfilter and DC.jsCrossfilter DC.JS Chart on Sub Elements
Say we have the following crossfilter / dc.js app:

While this is nice, the user loses "reference" the population when brushing. I would like for charts x, y, z, and a to keep the "underlying" bars when other charts are brushed. Perhaps in a different color like so:

I believe this may require updating the dc.renderAll() function, but I am not sure even how to start.
Here is all the code to reproduce this app with the .csv data hosted as a gist.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Data Exploration Tool MVP</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="http://unpkg.com/dc@3/dc.css"/>
<style>
#data-count
margin-top: 0;
text-align: left;
float: none;
table
table-layout: fixed;
td
width: 1%;
</style>
</head>
<body>
<div class="container-fluid" style="margin: 10px;">
<div class="row">
<h2>Data Exploration Tool</h2>
<div class="col-md-3 well well-sm">
<div class="dc-data-count" id="data-count">
<span class="filter-count"></span>
selected out of
<span class="total-count"></span>
points |
<a href="javascript:dc.filterAll(); dc.renderAll();">Reset All</a><br>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<!-- First row of charts -->
<div class="row">
<div class="col-md-3">
<div id="chart-11" style="width:100%;">
<div id="chart-11-title"></div>
<div class="reset" style="visibility: hidden;">range: <span class="filter"></span>
<a href="javascript:chart_11.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-12" style="width:100%;">
<div id="chart-12-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_12.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-13" style="width:100%;">
<div id="chart-13-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_13.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-14" style="width:100%;">
<div id="chart-14-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_14.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
</div>
<!-- Second row of chart -->
<div class="row">
<div class="col-md-3">
<div id="chart-21" style="width:100%;">
<div id="chart-21-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_21.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-22" style="width:100%;">
<div id="chart-22-title"></div>
<div class="reset" style="visibility: hidden;">range: <span class="filter"></span>
<a href="javascript:chart_22.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-23"style="width:100%;">
<div id="chart-23-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_23.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-24"style="width:100%;">
<div id="chart-24-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_24.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.9.1/d3.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.js"></script>
<script src="http://unpkg.com/dc@3/dc.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<script type="text/javascript">
'use strict';
dc.config.defaultColors(d3.schemeSet1);
var
chart_11 = dc.barChart("#chart-11"),
chart_12 = dc.barChart("#chart-12"),
chart_13 = dc.barChart("#chart-13"),
chart_21 = dc.barChart("#chart-21"),
chart_22 = dc.barChart("#chart-22"),
chart_23 = dc.barChart("#chart-23"),
data_count = dc.dataCount(".dc-data-count");
d3.csv("https://gist.githubusercontent.com/JasonAizkalns/32ece5c815f9ac5d540c41dc0825bbab/raw/362050300ddcb99f195044c00d9f26b0d7d489ca/data.csv").then(function(data)
var var_names = ["x", "y", "z", "a", "b", "c"];
$("#chart-11-title").append(["<h5>", var_names[0], "<br>Subtitle</h5>"].join(""));
$("#chart-12-title").append(["<h5>", var_names[1], "<br>Subtitle</h5>"].join(""));
$("#chart-13-title").append(["<h5>", var_names[2], "<br>Subtitle</h5>"].join(""));
$("#chart-21-title").append(["<h5>", var_names[3], "<br>Subtitle</h5>"].join(""));
$("#chart-22-title").append(["<h5>", var_names[4], "<br>Subtitle</h5>"].join(""));
$("#chart-23-title").append(["<h5>", var_names[5], "<br>Subtitle</h5>"].join(""));
var c11_bin = 10,
c12_bin = 10,
c13_bin = 500,
c21_bin = 100,
c22_bin = 20,
c23_bin = 1000;
var ndx = crossfilter(data),
chart_11_dim = ndx.dimension(function(d) return +d[var_names[0]]; ),
chart_12_dim = ndx.dimension(function(d) return +d[var_names[1]]; ),
chart_13_dim = ndx.dimension(function(d) return +d[var_names[2]]; ),
chart_21_dim = ndx.dimension(function(d) return +d[var_names[3]]; ),
chart_22_dim = ndx.dimension(function(d) return +d[var_names[4]]; ),
chart_23_dim = ndx.dimension(function(d) return +d[var_names[5]]; ),
chart_11_grp = chart_11_dim.group(function(d) return Math.floor(d / c11_bin) * c11_bin ).reduceCount(),
chart_12_grp = chart_12_dim.group(function(d) return Math.floor(d / c12_bin) * c12_bin ).reduceCount(),
chart_13_grp = chart_13_dim.group(function(d) return Math.floor(d / c13_bin) * c13_bin ).reduceCount(),
chart_21_grp = chart_21_dim.group(function(d) return Math.floor(d / c21_bin) * c21_bin ).reduceCount(),
chart_22_grp = chart_22_dim.group(function(d) return Math.floor(d / c22_bin) * c22_bin ).reduceCount(),
chart_23_grp = chart_23_dim.group(function(d) return Math.floor(d / c23_bin) * c23_bin ).reduceCount();
var all = ndx.groupAll();
data_count.dimension(ndx)
.group(all);
var chart_11_min = +chart_11_dim.bottom(1)[0][var_names[0]],
chart_11_max = +chart_11_dim.top(1)[0][var_names[0]],
chart_12_min = +chart_12_dim.bottom(1)[0][var_names[1]],
chart_12_max = +chart_12_dim.top(1)[0][var_names[1]],
chart_13_min = +chart_13_dim.bottom(1)[0][var_names[2]],
chart_13_max = +chart_13_dim.top(1)[0][var_names[2]],
chart_21_min = +chart_21_dim.bottom(1)[0][var_names[3]],
chart_21_max = +chart_21_dim.top(1)[0][var_names[3]],
chart_22_min = +chart_22_dim.bottom(1)[0][var_names[4]],
chart_22_max = +chart_22_dim.top(1)[0][var_names[4]],
chart_23_min = +chart_23_dim.bottom(1)[0][var_names[5]],
chart_23_max = +chart_23_dim.top(1)[0][var_names[5]];
var breathing_room = 0.05;
chart_11
.dimension(chart_11_dim)
.group(chart_11_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_11_min - ((chart_11_max - chart_11_min) * breathing_room), chart_11_max + ((chart_11_max - chart_11_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c11_bin; )
.controlsUseVisibility(true);
chart_12
.dimension(chart_12_dim)
.group(chart_12_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_12_min - ((chart_12_max - chart_12_min) * breathing_room), chart_12_max + ((chart_12_max - chart_12_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c12_bin; )
.controlsUseVisibility(true);
chart_13
.dimension(chart_13_dim)
.group(chart_13_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_13_min - ((chart_13_max - chart_13_min) * breathing_room), chart_13_max + ((chart_13_max - chart_13_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c13_bin; )
.controlsUseVisibility(true);
chart_21
.dimension(chart_21_dim)
.group(chart_21_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_21_min - ((chart_21_max - chart_21_min) * breathing_room), chart_21_max + ((chart_21_max - chart_21_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c21_bin; )
.controlsUseVisibility(true);
chart_22
.dimension(chart_22_dim)
.group(chart_22_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_22_min - ((chart_22_max - chart_22_min) * breathing_room), chart_22_max + ((chart_22_max - chart_22_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c22_bin; )
.controlsUseVisibility(true);
chart_23
.dimension(chart_23_dim)
.group(chart_23_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_23_min - ((chart_23_max - chart_23_min) * breathing_room), chart_23_max + ((chart_23_max - chart_23_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c23_bin; )
.controlsUseVisibility(true);
dc.renderAll();
);
</script>
</div>
</body>
</html>
d3.js dc.js crossfilter
add a comment |
Say we have the following crossfilter / dc.js app:

While this is nice, the user loses "reference" the population when brushing. I would like for charts x, y, z, and a to keep the "underlying" bars when other charts are brushed. Perhaps in a different color like so:

I believe this may require updating the dc.renderAll() function, but I am not sure even how to start.
Here is all the code to reproduce this app with the .csv data hosted as a gist.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Data Exploration Tool MVP</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="http://unpkg.com/dc@3/dc.css"/>
<style>
#data-count
margin-top: 0;
text-align: left;
float: none;
table
table-layout: fixed;
td
width: 1%;
</style>
</head>
<body>
<div class="container-fluid" style="margin: 10px;">
<div class="row">
<h2>Data Exploration Tool</h2>
<div class="col-md-3 well well-sm">
<div class="dc-data-count" id="data-count">
<span class="filter-count"></span>
selected out of
<span class="total-count"></span>
points |
<a href="javascript:dc.filterAll(); dc.renderAll();">Reset All</a><br>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<!-- First row of charts -->
<div class="row">
<div class="col-md-3">
<div id="chart-11" style="width:100%;">
<div id="chart-11-title"></div>
<div class="reset" style="visibility: hidden;">range: <span class="filter"></span>
<a href="javascript:chart_11.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-12" style="width:100%;">
<div id="chart-12-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_12.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-13" style="width:100%;">
<div id="chart-13-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_13.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-14" style="width:100%;">
<div id="chart-14-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_14.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
</div>
<!-- Second row of chart -->
<div class="row">
<div class="col-md-3">
<div id="chart-21" style="width:100%;">
<div id="chart-21-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_21.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-22" style="width:100%;">
<div id="chart-22-title"></div>
<div class="reset" style="visibility: hidden;">range: <span class="filter"></span>
<a href="javascript:chart_22.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-23"style="width:100%;">
<div id="chart-23-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_23.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-24"style="width:100%;">
<div id="chart-24-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_24.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.9.1/d3.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.js"></script>
<script src="http://unpkg.com/dc@3/dc.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<script type="text/javascript">
'use strict';
dc.config.defaultColors(d3.schemeSet1);
var
chart_11 = dc.barChart("#chart-11"),
chart_12 = dc.barChart("#chart-12"),
chart_13 = dc.barChart("#chart-13"),
chart_21 = dc.barChart("#chart-21"),
chart_22 = dc.barChart("#chart-22"),
chart_23 = dc.barChart("#chart-23"),
data_count = dc.dataCount(".dc-data-count");
d3.csv("https://gist.githubusercontent.com/JasonAizkalns/32ece5c815f9ac5d540c41dc0825bbab/raw/362050300ddcb99f195044c00d9f26b0d7d489ca/data.csv").then(function(data)
var var_names = ["x", "y", "z", "a", "b", "c"];
$("#chart-11-title").append(["<h5>", var_names[0], "<br>Subtitle</h5>"].join(""));
$("#chart-12-title").append(["<h5>", var_names[1], "<br>Subtitle</h5>"].join(""));
$("#chart-13-title").append(["<h5>", var_names[2], "<br>Subtitle</h5>"].join(""));
$("#chart-21-title").append(["<h5>", var_names[3], "<br>Subtitle</h5>"].join(""));
$("#chart-22-title").append(["<h5>", var_names[4], "<br>Subtitle</h5>"].join(""));
$("#chart-23-title").append(["<h5>", var_names[5], "<br>Subtitle</h5>"].join(""));
var c11_bin = 10,
c12_bin = 10,
c13_bin = 500,
c21_bin = 100,
c22_bin = 20,
c23_bin = 1000;
var ndx = crossfilter(data),
chart_11_dim = ndx.dimension(function(d) return +d[var_names[0]]; ),
chart_12_dim = ndx.dimension(function(d) return +d[var_names[1]]; ),
chart_13_dim = ndx.dimension(function(d) return +d[var_names[2]]; ),
chart_21_dim = ndx.dimension(function(d) return +d[var_names[3]]; ),
chart_22_dim = ndx.dimension(function(d) return +d[var_names[4]]; ),
chart_23_dim = ndx.dimension(function(d) return +d[var_names[5]]; ),
chart_11_grp = chart_11_dim.group(function(d) return Math.floor(d / c11_bin) * c11_bin ).reduceCount(),
chart_12_grp = chart_12_dim.group(function(d) return Math.floor(d / c12_bin) * c12_bin ).reduceCount(),
chart_13_grp = chart_13_dim.group(function(d) return Math.floor(d / c13_bin) * c13_bin ).reduceCount(),
chart_21_grp = chart_21_dim.group(function(d) return Math.floor(d / c21_bin) * c21_bin ).reduceCount(),
chart_22_grp = chart_22_dim.group(function(d) return Math.floor(d / c22_bin) * c22_bin ).reduceCount(),
chart_23_grp = chart_23_dim.group(function(d) return Math.floor(d / c23_bin) * c23_bin ).reduceCount();
var all = ndx.groupAll();
data_count.dimension(ndx)
.group(all);
var chart_11_min = +chart_11_dim.bottom(1)[0][var_names[0]],
chart_11_max = +chart_11_dim.top(1)[0][var_names[0]],
chart_12_min = +chart_12_dim.bottom(1)[0][var_names[1]],
chart_12_max = +chart_12_dim.top(1)[0][var_names[1]],
chart_13_min = +chart_13_dim.bottom(1)[0][var_names[2]],
chart_13_max = +chart_13_dim.top(1)[0][var_names[2]],
chart_21_min = +chart_21_dim.bottom(1)[0][var_names[3]],
chart_21_max = +chart_21_dim.top(1)[0][var_names[3]],
chart_22_min = +chart_22_dim.bottom(1)[0][var_names[4]],
chart_22_max = +chart_22_dim.top(1)[0][var_names[4]],
chart_23_min = +chart_23_dim.bottom(1)[0][var_names[5]],
chart_23_max = +chart_23_dim.top(1)[0][var_names[5]];
var breathing_room = 0.05;
chart_11
.dimension(chart_11_dim)
.group(chart_11_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_11_min - ((chart_11_max - chart_11_min) * breathing_room), chart_11_max + ((chart_11_max - chart_11_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c11_bin; )
.controlsUseVisibility(true);
chart_12
.dimension(chart_12_dim)
.group(chart_12_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_12_min - ((chart_12_max - chart_12_min) * breathing_room), chart_12_max + ((chart_12_max - chart_12_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c12_bin; )
.controlsUseVisibility(true);
chart_13
.dimension(chart_13_dim)
.group(chart_13_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_13_min - ((chart_13_max - chart_13_min) * breathing_room), chart_13_max + ((chart_13_max - chart_13_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c13_bin; )
.controlsUseVisibility(true);
chart_21
.dimension(chart_21_dim)
.group(chart_21_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_21_min - ((chart_21_max - chart_21_min) * breathing_room), chart_21_max + ((chart_21_max - chart_21_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c21_bin; )
.controlsUseVisibility(true);
chart_22
.dimension(chart_22_dim)
.group(chart_22_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_22_min - ((chart_22_max - chart_22_min) * breathing_room), chart_22_max + ((chart_22_max - chart_22_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c22_bin; )
.controlsUseVisibility(true);
chart_23
.dimension(chart_23_dim)
.group(chart_23_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_23_min - ((chart_23_max - chart_23_min) * breathing_room), chart_23_max + ((chart_23_max - chart_23_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c23_bin; )
.controlsUseVisibility(true);
dc.renderAll();
);
</script>
</div>
</body>
</html>
d3.js dc.js crossfilter
add a comment |
Say we have the following crossfilter / dc.js app:

While this is nice, the user loses "reference" the population when brushing. I would like for charts x, y, z, and a to keep the "underlying" bars when other charts are brushed. Perhaps in a different color like so:

I believe this may require updating the dc.renderAll() function, but I am not sure even how to start.
Here is all the code to reproduce this app with the .csv data hosted as a gist.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Data Exploration Tool MVP</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="http://unpkg.com/dc@3/dc.css"/>
<style>
#data-count
margin-top: 0;
text-align: left;
float: none;
table
table-layout: fixed;
td
width: 1%;
</style>
</head>
<body>
<div class="container-fluid" style="margin: 10px;">
<div class="row">
<h2>Data Exploration Tool</h2>
<div class="col-md-3 well well-sm">
<div class="dc-data-count" id="data-count">
<span class="filter-count"></span>
selected out of
<span class="total-count"></span>
points |
<a href="javascript:dc.filterAll(); dc.renderAll();">Reset All</a><br>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<!-- First row of charts -->
<div class="row">
<div class="col-md-3">
<div id="chart-11" style="width:100%;">
<div id="chart-11-title"></div>
<div class="reset" style="visibility: hidden;">range: <span class="filter"></span>
<a href="javascript:chart_11.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-12" style="width:100%;">
<div id="chart-12-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_12.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-13" style="width:100%;">
<div id="chart-13-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_13.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-14" style="width:100%;">
<div id="chart-14-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_14.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
</div>
<!-- Second row of chart -->
<div class="row">
<div class="col-md-3">
<div id="chart-21" style="width:100%;">
<div id="chart-21-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_21.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-22" style="width:100%;">
<div id="chart-22-title"></div>
<div class="reset" style="visibility: hidden;">range: <span class="filter"></span>
<a href="javascript:chart_22.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-23"style="width:100%;">
<div id="chart-23-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_23.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-24"style="width:100%;">
<div id="chart-24-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_24.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.9.1/d3.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.js"></script>
<script src="http://unpkg.com/dc@3/dc.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<script type="text/javascript">
'use strict';
dc.config.defaultColors(d3.schemeSet1);
var
chart_11 = dc.barChart("#chart-11"),
chart_12 = dc.barChart("#chart-12"),
chart_13 = dc.barChart("#chart-13"),
chart_21 = dc.barChart("#chart-21"),
chart_22 = dc.barChart("#chart-22"),
chart_23 = dc.barChart("#chart-23"),
data_count = dc.dataCount(".dc-data-count");
d3.csv("https://gist.githubusercontent.com/JasonAizkalns/32ece5c815f9ac5d540c41dc0825bbab/raw/362050300ddcb99f195044c00d9f26b0d7d489ca/data.csv").then(function(data)
var var_names = ["x", "y", "z", "a", "b", "c"];
$("#chart-11-title").append(["<h5>", var_names[0], "<br>Subtitle</h5>"].join(""));
$("#chart-12-title").append(["<h5>", var_names[1], "<br>Subtitle</h5>"].join(""));
$("#chart-13-title").append(["<h5>", var_names[2], "<br>Subtitle</h5>"].join(""));
$("#chart-21-title").append(["<h5>", var_names[3], "<br>Subtitle</h5>"].join(""));
$("#chart-22-title").append(["<h5>", var_names[4], "<br>Subtitle</h5>"].join(""));
$("#chart-23-title").append(["<h5>", var_names[5], "<br>Subtitle</h5>"].join(""));
var c11_bin = 10,
c12_bin = 10,
c13_bin = 500,
c21_bin = 100,
c22_bin = 20,
c23_bin = 1000;
var ndx = crossfilter(data),
chart_11_dim = ndx.dimension(function(d) return +d[var_names[0]]; ),
chart_12_dim = ndx.dimension(function(d) return +d[var_names[1]]; ),
chart_13_dim = ndx.dimension(function(d) return +d[var_names[2]]; ),
chart_21_dim = ndx.dimension(function(d) return +d[var_names[3]]; ),
chart_22_dim = ndx.dimension(function(d) return +d[var_names[4]]; ),
chart_23_dim = ndx.dimension(function(d) return +d[var_names[5]]; ),
chart_11_grp = chart_11_dim.group(function(d) return Math.floor(d / c11_bin) * c11_bin ).reduceCount(),
chart_12_grp = chart_12_dim.group(function(d) return Math.floor(d / c12_bin) * c12_bin ).reduceCount(),
chart_13_grp = chart_13_dim.group(function(d) return Math.floor(d / c13_bin) * c13_bin ).reduceCount(),
chart_21_grp = chart_21_dim.group(function(d) return Math.floor(d / c21_bin) * c21_bin ).reduceCount(),
chart_22_grp = chart_22_dim.group(function(d) return Math.floor(d / c22_bin) * c22_bin ).reduceCount(),
chart_23_grp = chart_23_dim.group(function(d) return Math.floor(d / c23_bin) * c23_bin ).reduceCount();
var all = ndx.groupAll();
data_count.dimension(ndx)
.group(all);
var chart_11_min = +chart_11_dim.bottom(1)[0][var_names[0]],
chart_11_max = +chart_11_dim.top(1)[0][var_names[0]],
chart_12_min = +chart_12_dim.bottom(1)[0][var_names[1]],
chart_12_max = +chart_12_dim.top(1)[0][var_names[1]],
chart_13_min = +chart_13_dim.bottom(1)[0][var_names[2]],
chart_13_max = +chart_13_dim.top(1)[0][var_names[2]],
chart_21_min = +chart_21_dim.bottom(1)[0][var_names[3]],
chart_21_max = +chart_21_dim.top(1)[0][var_names[3]],
chart_22_min = +chart_22_dim.bottom(1)[0][var_names[4]],
chart_22_max = +chart_22_dim.top(1)[0][var_names[4]],
chart_23_min = +chart_23_dim.bottom(1)[0][var_names[5]],
chart_23_max = +chart_23_dim.top(1)[0][var_names[5]];
var breathing_room = 0.05;
chart_11
.dimension(chart_11_dim)
.group(chart_11_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_11_min - ((chart_11_max - chart_11_min) * breathing_room), chart_11_max + ((chart_11_max - chart_11_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c11_bin; )
.controlsUseVisibility(true);
chart_12
.dimension(chart_12_dim)
.group(chart_12_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_12_min - ((chart_12_max - chart_12_min) * breathing_room), chart_12_max + ((chart_12_max - chart_12_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c12_bin; )
.controlsUseVisibility(true);
chart_13
.dimension(chart_13_dim)
.group(chart_13_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_13_min - ((chart_13_max - chart_13_min) * breathing_room), chart_13_max + ((chart_13_max - chart_13_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c13_bin; )
.controlsUseVisibility(true);
chart_21
.dimension(chart_21_dim)
.group(chart_21_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_21_min - ((chart_21_max - chart_21_min) * breathing_room), chart_21_max + ((chart_21_max - chart_21_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c21_bin; )
.controlsUseVisibility(true);
chart_22
.dimension(chart_22_dim)
.group(chart_22_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_22_min - ((chart_22_max - chart_22_min) * breathing_room), chart_22_max + ((chart_22_max - chart_22_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c22_bin; )
.controlsUseVisibility(true);
chart_23
.dimension(chart_23_dim)
.group(chart_23_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_23_min - ((chart_23_max - chart_23_min) * breathing_room), chart_23_max + ((chart_23_max - chart_23_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c23_bin; )
.controlsUseVisibility(true);
dc.renderAll();
);
</script>
</div>
</body>
</html>
d3.js dc.js crossfilter
Say we have the following crossfilter / dc.js app:

While this is nice, the user loses "reference" the population when brushing. I would like for charts x, y, z, and a to keep the "underlying" bars when other charts are brushed. Perhaps in a different color like so:

I believe this may require updating the dc.renderAll() function, but I am not sure even how to start.
Here is all the code to reproduce this app with the .csv data hosted as a gist.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Data Exploration Tool MVP</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="http://unpkg.com/dc@3/dc.css"/>
<style>
#data-count
margin-top: 0;
text-align: left;
float: none;
table
table-layout: fixed;
td
width: 1%;
</style>
</head>
<body>
<div class="container-fluid" style="margin: 10px;">
<div class="row">
<h2>Data Exploration Tool</h2>
<div class="col-md-3 well well-sm">
<div class="dc-data-count" id="data-count">
<span class="filter-count"></span>
selected out of
<span class="total-count"></span>
points |
<a href="javascript:dc.filterAll(); dc.renderAll();">Reset All</a><br>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<!-- First row of charts -->
<div class="row">
<div class="col-md-3">
<div id="chart-11" style="width:100%;">
<div id="chart-11-title"></div>
<div class="reset" style="visibility: hidden;">range: <span class="filter"></span>
<a href="javascript:chart_11.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-12" style="width:100%;">
<div id="chart-12-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_12.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-13" style="width:100%;">
<div id="chart-13-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_13.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-14" style="width:100%;">
<div id="chart-14-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_14.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
</div>
<!-- Second row of chart -->
<div class="row">
<div class="col-md-3">
<div id="chart-21" style="width:100%;">
<div id="chart-21-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_21.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-22" style="width:100%;">
<div id="chart-22-title"></div>
<div class="reset" style="visibility: hidden;">range: <span class="filter"></span>
<a href="javascript:chart_22.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-23"style="width:100%;">
<div id="chart-23-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_23.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-24"style="width:100%;">
<div id="chart-24-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
<a href="javascript:chart_24.filterAll();dc.redrawAll();">reset</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.9.1/d3.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.js"></script>
<script src="http://unpkg.com/dc@3/dc.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<script type="text/javascript">
'use strict';
dc.config.defaultColors(d3.schemeSet1);
var
chart_11 = dc.barChart("#chart-11"),
chart_12 = dc.barChart("#chart-12"),
chart_13 = dc.barChart("#chart-13"),
chart_21 = dc.barChart("#chart-21"),
chart_22 = dc.barChart("#chart-22"),
chart_23 = dc.barChart("#chart-23"),
data_count = dc.dataCount(".dc-data-count");
d3.csv("https://gist.githubusercontent.com/JasonAizkalns/32ece5c815f9ac5d540c41dc0825bbab/raw/362050300ddcb99f195044c00d9f26b0d7d489ca/data.csv").then(function(data)
var var_names = ["x", "y", "z", "a", "b", "c"];
$("#chart-11-title").append(["<h5>", var_names[0], "<br>Subtitle</h5>"].join(""));
$("#chart-12-title").append(["<h5>", var_names[1], "<br>Subtitle</h5>"].join(""));
$("#chart-13-title").append(["<h5>", var_names[2], "<br>Subtitle</h5>"].join(""));
$("#chart-21-title").append(["<h5>", var_names[3], "<br>Subtitle</h5>"].join(""));
$("#chart-22-title").append(["<h5>", var_names[4], "<br>Subtitle</h5>"].join(""));
$("#chart-23-title").append(["<h5>", var_names[5], "<br>Subtitle</h5>"].join(""));
var c11_bin = 10,
c12_bin = 10,
c13_bin = 500,
c21_bin = 100,
c22_bin = 20,
c23_bin = 1000;
var ndx = crossfilter(data),
chart_11_dim = ndx.dimension(function(d) return +d[var_names[0]]; ),
chart_12_dim = ndx.dimension(function(d) return +d[var_names[1]]; ),
chart_13_dim = ndx.dimension(function(d) return +d[var_names[2]]; ),
chart_21_dim = ndx.dimension(function(d) return +d[var_names[3]]; ),
chart_22_dim = ndx.dimension(function(d) return +d[var_names[4]]; ),
chart_23_dim = ndx.dimension(function(d) return +d[var_names[5]]; ),
chart_11_grp = chart_11_dim.group(function(d) return Math.floor(d / c11_bin) * c11_bin ).reduceCount(),
chart_12_grp = chart_12_dim.group(function(d) return Math.floor(d / c12_bin) * c12_bin ).reduceCount(),
chart_13_grp = chart_13_dim.group(function(d) return Math.floor(d / c13_bin) * c13_bin ).reduceCount(),
chart_21_grp = chart_21_dim.group(function(d) return Math.floor(d / c21_bin) * c21_bin ).reduceCount(),
chart_22_grp = chart_22_dim.group(function(d) return Math.floor(d / c22_bin) * c22_bin ).reduceCount(),
chart_23_grp = chart_23_dim.group(function(d) return Math.floor(d / c23_bin) * c23_bin ).reduceCount();
var all = ndx.groupAll();
data_count.dimension(ndx)
.group(all);
var chart_11_min = +chart_11_dim.bottom(1)[0][var_names[0]],
chart_11_max = +chart_11_dim.top(1)[0][var_names[0]],
chart_12_min = +chart_12_dim.bottom(1)[0][var_names[1]],
chart_12_max = +chart_12_dim.top(1)[0][var_names[1]],
chart_13_min = +chart_13_dim.bottom(1)[0][var_names[2]],
chart_13_max = +chart_13_dim.top(1)[0][var_names[2]],
chart_21_min = +chart_21_dim.bottom(1)[0][var_names[3]],
chart_21_max = +chart_21_dim.top(1)[0][var_names[3]],
chart_22_min = +chart_22_dim.bottom(1)[0][var_names[4]],
chart_22_max = +chart_22_dim.top(1)[0][var_names[4]],
chart_23_min = +chart_23_dim.bottom(1)[0][var_names[5]],
chart_23_max = +chart_23_dim.top(1)[0][var_names[5]];
var breathing_room = 0.05;
chart_11
.dimension(chart_11_dim)
.group(chart_11_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_11_min - ((chart_11_max - chart_11_min) * breathing_room), chart_11_max + ((chart_11_max - chart_11_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c11_bin; )
.controlsUseVisibility(true);
chart_12
.dimension(chart_12_dim)
.group(chart_12_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_12_min - ((chart_12_max - chart_12_min) * breathing_room), chart_12_max + ((chart_12_max - chart_12_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c12_bin; )
.controlsUseVisibility(true);
chart_13
.dimension(chart_13_dim)
.group(chart_13_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_13_min - ((chart_13_max - chart_13_min) * breathing_room), chart_13_max + ((chart_13_max - chart_13_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c13_bin; )
.controlsUseVisibility(true);
chart_21
.dimension(chart_21_dim)
.group(chart_21_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_21_min - ((chart_21_max - chart_21_min) * breathing_room), chart_21_max + ((chart_21_max - chart_21_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c21_bin; )
.controlsUseVisibility(true);
chart_22
.dimension(chart_22_dim)
.group(chart_22_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_22_min - ((chart_22_max - chart_22_min) * breathing_room), chart_22_max + ((chart_22_max - chart_22_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c22_bin; )
.controlsUseVisibility(true);
chart_23
.dimension(chart_23_dim)
.group(chart_23_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_23_min - ((chart_23_max - chart_23_min) * breathing_room), chart_23_max + ((chart_23_max - chart_23_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) return (end - start) / c23_bin; )
.controlsUseVisibility(true);
dc.renderAll();
);
</script>
</div>
</body>
</html>
d3.js dc.js crossfilter
d3.js dc.js crossfilter
asked Mar 8 at 15:33
JasonAizkalnsJasonAizkalns
12.5k43083
12.5k43083
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
So yeah, neither dc.js nor crossfilter directly supports this use case, not that people don't want it.
Crossfilter only supports one active filter and gives you no way to find out what the totals were when no filters were applied.
Thanks for the reproducible example to start with. I put your original code in a fiddle.
It's a little tedious, but one way to get the affect you are after is to change each chart into a composite of two bar charts. We'll make the second subchart red and hide it until something is filtered. (More precisely, we'll hide it whenever there is nothing filtered.)
And we'll make the first (blue) subchart always show the initial values, not affected by any filters.
Creating a composite chart looks like this:
var chart_11 = dc.compositeChart("#chart-11"),
chart_12 = dc.compositeChart("#chart-12"),
chart_13 = dc.compositeChart("#chart-13"),
chart_21 = dc.compositeChart("#chart-21"),
chart_22 = dc.compositeChart("#chart-22"),
chart_23 = dc.compositeChart("#chart-23");
chart_11
.compose([
dc.barChart(chart_11)
.dimension(chart_11_dim)
.group(chart_11_grp_copy)
.controlsUseVisibility(true)
,
dc.barChart(chart_11)
.dimension(chart_11_dim)
.group(chart_11_grp)
.colors('red')
.controlsUseVisibility(true)
.brushOn(false)
]);
(Yes it seems you have to apply controlsUseVisibility to every child chart - looks like a bug.)
The heart of the problem is how to make the underlying blue chart not change. We can use a
fake group for this. The idea is this object acts like a group except it just returns what the group had on page load:
function static_copy_group(group)
var all = group.all().map(kv => (key: kv.key, value: kv.value));
return
all: function()
return all;
var chart_11_grp_copy = static_copy_group(chart_11_grp),
chart_12_grp_copy = static_copy_group(chart_12_grp),
chart_13_grp_copy = static_copy_group(chart_13_grp),
chart_21_grp_copy = static_copy_group(chart_21_grp),
chart_22_grp_copy = static_copy_group(chart_22_grp),
chart_23_grp_copy = static_copy_group(chart_23_grp);
Yes, that's a deep copy of group.all() because crossfilter updates everything in place.
Finally, here's the code to hide the second chart when nothing is filtered:
function any_filters()
return [chart_11, chart_12, chart_13, chart_21, chart_22, chart_23]
.some(chart => chart.filters().length);
function hide_second_chart(chart)
chart.select('.sub._1')
.attr('visibility', any_filters() ? 'visible' : 'hidden')
[chart_11, chart_12, chart_13, chart_21, chart_22, chart_23].forEach(function(chart)
chart.on('pretransition', hide_second_chart)
)

Example fiddle.
Thank you -- I am assuming when you say Crossfilter does not support this that your comment extends to Reductio and Universe? FYI: I also have this posted onCode Reviewfor function / code clean-up -- feels like a nice example that others (especially those less comfortable with JS) could leverage -- crosstalking between visualizations is still a sore spot in other languages, especially analysis-centric languages such as R.
– JasonAizkalns
Mar 8 at 20:25
Not sure why, but I'm receiving(index):213 Uncaught (in promise) TypeError: chart_11.compose is not a functionwhen trying to run locally. I haved3loaded via:<script src="https://d3js.org/d3.v5.min.js"></script>
– JasonAizkalns
Mar 8 at 20:38
Whoops, I missed another change - yes you needcompositeCharts notbarCharts - the composite chart overlays a bunch of ordinary charts on top of each other.
– Gordon
Mar 8 at 20:48
Would you be cool with making this into an example for the dc.js examples page? And right, I don't know of anything in reductio or universe that will help with this. (I originally got involved with dc.js in order to bring these charts to R via RCloud. Sadly, no htmlwidget version yet, and no integration with crosstalk... stuff I'd love to do if I find time.)
– Gordon
Mar 8 at 20:54
of course, this has always been on the backburner for me -- something that crosstalk doesn't do well nor is plotly ready to scale quite as fast yet. I think it should be cleaned up before an example page, (maybe wait a few days for someone to chime in on Code Review) but let me know.
– JasonAizkalns
Mar 8 at 21:02
|
show 2 more comments
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55066391%2fdisplay-original-conditional-brushed-unbrushed-crossfilter-bars-with-dc-js-wit%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
So yeah, neither dc.js nor crossfilter directly supports this use case, not that people don't want it.
Crossfilter only supports one active filter and gives you no way to find out what the totals were when no filters were applied.
Thanks for the reproducible example to start with. I put your original code in a fiddle.
It's a little tedious, but one way to get the affect you are after is to change each chart into a composite of two bar charts. We'll make the second subchart red and hide it until something is filtered. (More precisely, we'll hide it whenever there is nothing filtered.)
And we'll make the first (blue) subchart always show the initial values, not affected by any filters.
Creating a composite chart looks like this:
var chart_11 = dc.compositeChart("#chart-11"),
chart_12 = dc.compositeChart("#chart-12"),
chart_13 = dc.compositeChart("#chart-13"),
chart_21 = dc.compositeChart("#chart-21"),
chart_22 = dc.compositeChart("#chart-22"),
chart_23 = dc.compositeChart("#chart-23");
chart_11
.compose([
dc.barChart(chart_11)
.dimension(chart_11_dim)
.group(chart_11_grp_copy)
.controlsUseVisibility(true)
,
dc.barChart(chart_11)
.dimension(chart_11_dim)
.group(chart_11_grp)
.colors('red')
.controlsUseVisibility(true)
.brushOn(false)
]);
(Yes it seems you have to apply controlsUseVisibility to every child chart - looks like a bug.)
The heart of the problem is how to make the underlying blue chart not change. We can use a
fake group for this. The idea is this object acts like a group except it just returns what the group had on page load:
function static_copy_group(group)
var all = group.all().map(kv => (key: kv.key, value: kv.value));
return
all: function()
return all;
var chart_11_grp_copy = static_copy_group(chart_11_grp),
chart_12_grp_copy = static_copy_group(chart_12_grp),
chart_13_grp_copy = static_copy_group(chart_13_grp),
chart_21_grp_copy = static_copy_group(chart_21_grp),
chart_22_grp_copy = static_copy_group(chart_22_grp),
chart_23_grp_copy = static_copy_group(chart_23_grp);
Yes, that's a deep copy of group.all() because crossfilter updates everything in place.
Finally, here's the code to hide the second chart when nothing is filtered:
function any_filters()
return [chart_11, chart_12, chart_13, chart_21, chart_22, chart_23]
.some(chart => chart.filters().length);
function hide_second_chart(chart)
chart.select('.sub._1')
.attr('visibility', any_filters() ? 'visible' : 'hidden')
[chart_11, chart_12, chart_13, chart_21, chart_22, chart_23].forEach(function(chart)
chart.on('pretransition', hide_second_chart)
)

Example fiddle.
Thank you -- I am assuming when you say Crossfilter does not support this that your comment extends to Reductio and Universe? FYI: I also have this posted onCode Reviewfor function / code clean-up -- feels like a nice example that others (especially those less comfortable with JS) could leverage -- crosstalking between visualizations is still a sore spot in other languages, especially analysis-centric languages such as R.
– JasonAizkalns
Mar 8 at 20:25
Not sure why, but I'm receiving(index):213 Uncaught (in promise) TypeError: chart_11.compose is not a functionwhen trying to run locally. I haved3loaded via:<script src="https://d3js.org/d3.v5.min.js"></script>
– JasonAizkalns
Mar 8 at 20:38
Whoops, I missed another change - yes you needcompositeCharts notbarCharts - the composite chart overlays a bunch of ordinary charts on top of each other.
– Gordon
Mar 8 at 20:48
Would you be cool with making this into an example for the dc.js examples page? And right, I don't know of anything in reductio or universe that will help with this. (I originally got involved with dc.js in order to bring these charts to R via RCloud. Sadly, no htmlwidget version yet, and no integration with crosstalk... stuff I'd love to do if I find time.)
– Gordon
Mar 8 at 20:54
of course, this has always been on the backburner for me -- something that crosstalk doesn't do well nor is plotly ready to scale quite as fast yet. I think it should be cleaned up before an example page, (maybe wait a few days for someone to chime in on Code Review) but let me know.
– JasonAizkalns
Mar 8 at 21:02
|
show 2 more comments
So yeah, neither dc.js nor crossfilter directly supports this use case, not that people don't want it.
Crossfilter only supports one active filter and gives you no way to find out what the totals were when no filters were applied.
Thanks for the reproducible example to start with. I put your original code in a fiddle.
It's a little tedious, but one way to get the affect you are after is to change each chart into a composite of two bar charts. We'll make the second subchart red and hide it until something is filtered. (More precisely, we'll hide it whenever there is nothing filtered.)
And we'll make the first (blue) subchart always show the initial values, not affected by any filters.
Creating a composite chart looks like this:
var chart_11 = dc.compositeChart("#chart-11"),
chart_12 = dc.compositeChart("#chart-12"),
chart_13 = dc.compositeChart("#chart-13"),
chart_21 = dc.compositeChart("#chart-21"),
chart_22 = dc.compositeChart("#chart-22"),
chart_23 = dc.compositeChart("#chart-23");
chart_11
.compose([
dc.barChart(chart_11)
.dimension(chart_11_dim)
.group(chart_11_grp_copy)
.controlsUseVisibility(true)
,
dc.barChart(chart_11)
.dimension(chart_11_dim)
.group(chart_11_grp)
.colors('red')
.controlsUseVisibility(true)
.brushOn(false)
]);
(Yes it seems you have to apply controlsUseVisibility to every child chart - looks like a bug.)
The heart of the problem is how to make the underlying blue chart not change. We can use a
fake group for this. The idea is this object acts like a group except it just returns what the group had on page load:
function static_copy_group(group)
var all = group.all().map(kv => (key: kv.key, value: kv.value));
return
all: function()
return all;
var chart_11_grp_copy = static_copy_group(chart_11_grp),
chart_12_grp_copy = static_copy_group(chart_12_grp),
chart_13_grp_copy = static_copy_group(chart_13_grp),
chart_21_grp_copy = static_copy_group(chart_21_grp),
chart_22_grp_copy = static_copy_group(chart_22_grp),
chart_23_grp_copy = static_copy_group(chart_23_grp);
Yes, that's a deep copy of group.all() because crossfilter updates everything in place.
Finally, here's the code to hide the second chart when nothing is filtered:
function any_filters()
return [chart_11, chart_12, chart_13, chart_21, chart_22, chart_23]
.some(chart => chart.filters().length);
function hide_second_chart(chart)
chart.select('.sub._1')
.attr('visibility', any_filters() ? 'visible' : 'hidden')
[chart_11, chart_12, chart_13, chart_21, chart_22, chart_23].forEach(function(chart)
chart.on('pretransition', hide_second_chart)
)

Example fiddle.
Thank you -- I am assuming when you say Crossfilter does not support this that your comment extends to Reductio and Universe? FYI: I also have this posted onCode Reviewfor function / code clean-up -- feels like a nice example that others (especially those less comfortable with JS) could leverage -- crosstalking between visualizations is still a sore spot in other languages, especially analysis-centric languages such as R.
– JasonAizkalns
Mar 8 at 20:25
Not sure why, but I'm receiving(index):213 Uncaught (in promise) TypeError: chart_11.compose is not a functionwhen trying to run locally. I haved3loaded via:<script src="https://d3js.org/d3.v5.min.js"></script>
– JasonAizkalns
Mar 8 at 20:38
Whoops, I missed another change - yes you needcompositeCharts notbarCharts - the composite chart overlays a bunch of ordinary charts on top of each other.
– Gordon
Mar 8 at 20:48
Would you be cool with making this into an example for the dc.js examples page? And right, I don't know of anything in reductio or universe that will help with this. (I originally got involved with dc.js in order to bring these charts to R via RCloud. Sadly, no htmlwidget version yet, and no integration with crosstalk... stuff I'd love to do if I find time.)
– Gordon
Mar 8 at 20:54
of course, this has always been on the backburner for me -- something that crosstalk doesn't do well nor is plotly ready to scale quite as fast yet. I think it should be cleaned up before an example page, (maybe wait a few days for someone to chime in on Code Review) but let me know.
– JasonAizkalns
Mar 8 at 21:02
|
show 2 more comments
So yeah, neither dc.js nor crossfilter directly supports this use case, not that people don't want it.
Crossfilter only supports one active filter and gives you no way to find out what the totals were when no filters were applied.
Thanks for the reproducible example to start with. I put your original code in a fiddle.
It's a little tedious, but one way to get the affect you are after is to change each chart into a composite of two bar charts. We'll make the second subchart red and hide it until something is filtered. (More precisely, we'll hide it whenever there is nothing filtered.)
And we'll make the first (blue) subchart always show the initial values, not affected by any filters.
Creating a composite chart looks like this:
var chart_11 = dc.compositeChart("#chart-11"),
chart_12 = dc.compositeChart("#chart-12"),
chart_13 = dc.compositeChart("#chart-13"),
chart_21 = dc.compositeChart("#chart-21"),
chart_22 = dc.compositeChart("#chart-22"),
chart_23 = dc.compositeChart("#chart-23");
chart_11
.compose([
dc.barChart(chart_11)
.dimension(chart_11_dim)
.group(chart_11_grp_copy)
.controlsUseVisibility(true)
,
dc.barChart(chart_11)
.dimension(chart_11_dim)
.group(chart_11_grp)
.colors('red')
.controlsUseVisibility(true)
.brushOn(false)
]);
(Yes it seems you have to apply controlsUseVisibility to every child chart - looks like a bug.)
The heart of the problem is how to make the underlying blue chart not change. We can use a
fake group for this. The idea is this object acts like a group except it just returns what the group had on page load:
function static_copy_group(group)
var all = group.all().map(kv => (key: kv.key, value: kv.value));
return
all: function()
return all;
var chart_11_grp_copy = static_copy_group(chart_11_grp),
chart_12_grp_copy = static_copy_group(chart_12_grp),
chart_13_grp_copy = static_copy_group(chart_13_grp),
chart_21_grp_copy = static_copy_group(chart_21_grp),
chart_22_grp_copy = static_copy_group(chart_22_grp),
chart_23_grp_copy = static_copy_group(chart_23_grp);
Yes, that's a deep copy of group.all() because crossfilter updates everything in place.
Finally, here's the code to hide the second chart when nothing is filtered:
function any_filters()
return [chart_11, chart_12, chart_13, chart_21, chart_22, chart_23]
.some(chart => chart.filters().length);
function hide_second_chart(chart)
chart.select('.sub._1')
.attr('visibility', any_filters() ? 'visible' : 'hidden')
[chart_11, chart_12, chart_13, chart_21, chart_22, chart_23].forEach(function(chart)
chart.on('pretransition', hide_second_chart)
)

Example fiddle.
So yeah, neither dc.js nor crossfilter directly supports this use case, not that people don't want it.
Crossfilter only supports one active filter and gives you no way to find out what the totals were when no filters were applied.
Thanks for the reproducible example to start with. I put your original code in a fiddle.
It's a little tedious, but one way to get the affect you are after is to change each chart into a composite of two bar charts. We'll make the second subchart red and hide it until something is filtered. (More precisely, we'll hide it whenever there is nothing filtered.)
And we'll make the first (blue) subchart always show the initial values, not affected by any filters.
Creating a composite chart looks like this:
var chart_11 = dc.compositeChart("#chart-11"),
chart_12 = dc.compositeChart("#chart-12"),
chart_13 = dc.compositeChart("#chart-13"),
chart_21 = dc.compositeChart("#chart-21"),
chart_22 = dc.compositeChart("#chart-22"),
chart_23 = dc.compositeChart("#chart-23");
chart_11
.compose([
dc.barChart(chart_11)
.dimension(chart_11_dim)
.group(chart_11_grp_copy)
.controlsUseVisibility(true)
,
dc.barChart(chart_11)
.dimension(chart_11_dim)
.group(chart_11_grp)
.colors('red')
.controlsUseVisibility(true)
.brushOn(false)
]);
(Yes it seems you have to apply controlsUseVisibility to every child chart - looks like a bug.)
The heart of the problem is how to make the underlying blue chart not change. We can use a
fake group for this. The idea is this object acts like a group except it just returns what the group had on page load:
function static_copy_group(group)
var all = group.all().map(kv => (key: kv.key, value: kv.value));
return
all: function()
return all;
var chart_11_grp_copy = static_copy_group(chart_11_grp),
chart_12_grp_copy = static_copy_group(chart_12_grp),
chart_13_grp_copy = static_copy_group(chart_13_grp),
chart_21_grp_copy = static_copy_group(chart_21_grp),
chart_22_grp_copy = static_copy_group(chart_22_grp),
chart_23_grp_copy = static_copy_group(chart_23_grp);
Yes, that's a deep copy of group.all() because crossfilter updates everything in place.
Finally, here's the code to hide the second chart when nothing is filtered:
function any_filters()
return [chart_11, chart_12, chart_13, chart_21, chart_22, chart_23]
.some(chart => chart.filters().length);
function hide_second_chart(chart)
chart.select('.sub._1')
.attr('visibility', any_filters() ? 'visible' : 'hidden')
[chart_11, chart_12, chart_13, chart_21, chart_22, chart_23].forEach(function(chart)
chart.on('pretransition', hide_second_chart)
)

Example fiddle.
edited Mar 8 at 20:46
answered Mar 8 at 19:52
GordonGordon
13.5k32362
13.5k32362
Thank you -- I am assuming when you say Crossfilter does not support this that your comment extends to Reductio and Universe? FYI: I also have this posted onCode Reviewfor function / code clean-up -- feels like a nice example that others (especially those less comfortable with JS) could leverage -- crosstalking between visualizations is still a sore spot in other languages, especially analysis-centric languages such as R.
– JasonAizkalns
Mar 8 at 20:25
Not sure why, but I'm receiving(index):213 Uncaught (in promise) TypeError: chart_11.compose is not a functionwhen trying to run locally. I haved3loaded via:<script src="https://d3js.org/d3.v5.min.js"></script>
– JasonAizkalns
Mar 8 at 20:38
Whoops, I missed another change - yes you needcompositeCharts notbarCharts - the composite chart overlays a bunch of ordinary charts on top of each other.
– Gordon
Mar 8 at 20:48
Would you be cool with making this into an example for the dc.js examples page? And right, I don't know of anything in reductio or universe that will help with this. (I originally got involved with dc.js in order to bring these charts to R via RCloud. Sadly, no htmlwidget version yet, and no integration with crosstalk... stuff I'd love to do if I find time.)
– Gordon
Mar 8 at 20:54
of course, this has always been on the backburner for me -- something that crosstalk doesn't do well nor is plotly ready to scale quite as fast yet. I think it should be cleaned up before an example page, (maybe wait a few days for someone to chime in on Code Review) but let me know.
– JasonAizkalns
Mar 8 at 21:02
|
show 2 more comments
Thank you -- I am assuming when you say Crossfilter does not support this that your comment extends to Reductio and Universe? FYI: I also have this posted onCode Reviewfor function / code clean-up -- feels like a nice example that others (especially those less comfortable with JS) could leverage -- crosstalking between visualizations is still a sore spot in other languages, especially analysis-centric languages such as R.
– JasonAizkalns
Mar 8 at 20:25
Not sure why, but I'm receiving(index):213 Uncaught (in promise) TypeError: chart_11.compose is not a functionwhen trying to run locally. I haved3loaded via:<script src="https://d3js.org/d3.v5.min.js"></script>
– JasonAizkalns
Mar 8 at 20:38
Whoops, I missed another change - yes you needcompositeCharts notbarCharts - the composite chart overlays a bunch of ordinary charts on top of each other.
– Gordon
Mar 8 at 20:48
Would you be cool with making this into an example for the dc.js examples page? And right, I don't know of anything in reductio or universe that will help with this. (I originally got involved with dc.js in order to bring these charts to R via RCloud. Sadly, no htmlwidget version yet, and no integration with crosstalk... stuff I'd love to do if I find time.)
– Gordon
Mar 8 at 20:54
of course, this has always been on the backburner for me -- something that crosstalk doesn't do well nor is plotly ready to scale quite as fast yet. I think it should be cleaned up before an example page, (maybe wait a few days for someone to chime in on Code Review) but let me know.
– JasonAizkalns
Mar 8 at 21:02
Thank you -- I am assuming when you say Crossfilter does not support this that your comment extends to Reductio and Universe? FYI: I also have this posted on
Code Review for function / code clean-up -- feels like a nice example that others (especially those less comfortable with JS) could leverage -- crosstalking between visualizations is still a sore spot in other languages, especially analysis-centric languages such as R.– JasonAizkalns
Mar 8 at 20:25
Thank you -- I am assuming when you say Crossfilter does not support this that your comment extends to Reductio and Universe? FYI: I also have this posted on
Code Review for function / code clean-up -- feels like a nice example that others (especially those less comfortable with JS) could leverage -- crosstalking between visualizations is still a sore spot in other languages, especially analysis-centric languages such as R.– JasonAizkalns
Mar 8 at 20:25
Not sure why, but I'm receiving
(index):213 Uncaught (in promise) TypeError: chart_11.compose is not a function when trying to run locally. I have d3 loaded via: <script src="https://d3js.org/d3.v5.min.js"></script>– JasonAizkalns
Mar 8 at 20:38
Not sure why, but I'm receiving
(index):213 Uncaught (in promise) TypeError: chart_11.compose is not a function when trying to run locally. I have d3 loaded via: <script src="https://d3js.org/d3.v5.min.js"></script>– JasonAizkalns
Mar 8 at 20:38
Whoops, I missed another change - yes you need
compositeCharts not barCharts - the composite chart overlays a bunch of ordinary charts on top of each other.– Gordon
Mar 8 at 20:48
Whoops, I missed another change - yes you need
compositeCharts not barCharts - the composite chart overlays a bunch of ordinary charts on top of each other.– Gordon
Mar 8 at 20:48
Would you be cool with making this into an example for the dc.js examples page? And right, I don't know of anything in reductio or universe that will help with this. (I originally got involved with dc.js in order to bring these charts to R via RCloud. Sadly, no htmlwidget version yet, and no integration with crosstalk... stuff I'd love to do if I find time.)
– Gordon
Mar 8 at 20:54
Would you be cool with making this into an example for the dc.js examples page? And right, I don't know of anything in reductio or universe that will help with this. (I originally got involved with dc.js in order to bring these charts to R via RCloud. Sadly, no htmlwidget version yet, and no integration with crosstalk... stuff I'd love to do if I find time.)
– Gordon
Mar 8 at 20:54
of course, this has always been on the backburner for me -- something that crosstalk doesn't do well nor is plotly ready to scale quite as fast yet. I think it should be cleaned up before an example page, (maybe wait a few days for someone to chime in on Code Review) but let me know.
– JasonAizkalns
Mar 8 at 21:02
of course, this has always been on the backburner for me -- something that crosstalk doesn't do well nor is plotly ready to scale quite as fast yet. I think it should be cleaned up before an example page, (maybe wait a few days for someone to chime in on Code Review) but let me know.
– JasonAizkalns
Mar 8 at 21:02
|
show 2 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55066391%2fdisplay-original-conditional-brushed-unbrushed-crossfilter-bars-with-dc-js-wit%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown