1
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Title here</title>
    <meta charset="UTF-8">
    <link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="../css/dc.css"/>
</head>
<body>

  <div id = "select_box"> </div>
  <div id = "chart"> </div>

<script type="text/javascript" src="../js/d3.js"></script>
<script type="text/javascript" src="../js/crossfilter.js"></script>
<script type="text/javascript" src="../js/reductio.js"></script>
<script type="text/javascript" src="../js/dc.js"></script>

<script type="text/javascript">
var facts = crossfilter([
{Dept: "A", HC: 500, attrition: 100, belongto: "abc", subtract: 23 },
{Dept: "A", HC: 500, attrition: 100, belongto: "pqr", subtract: 5 },
{Dept: "A", HC: 500, attrition: 100, belongto: "xyz", subtract: 25 },
{Dept: "B", HC: 200, attrition: 30, belongto: "abc", subtract: 6 },
{Dept: "B", HC: 200, attrition: 30, belongto: "pqr", subtract: 3 },
{Dept: "B", HC: 200, attrition: 30, belongto: "xyz", subtract: 10 }
]);

// Simplified view of facts //Not used //Just for understanding purpose
var simplifiedfacts = crossfilter([
{Dept: "A", HC: 500, attrition: 100, abc: 23, pqr: 5, xyz: 25},
{Dept: "B", HC: 200, attrition: 30, abc: 6, pqr: 3, xyz: 10}
]);

var catdim = facts.dimension(function(d) { return d.belongto; }); //category
var deptdim = facts.dimension(function(d) { return d.Dept; });

//Here is how I want the group to be
// (min(attrition) - abc - xyz - pqr) / min(HC) <- abc, xyz and pqr are part of checkbox
// So for dept A this will become (100 - 23 - 5 - 25) / 500 <- if all selection are on

// Three function used in dimension reduce.
function addR(p, v) {
  p.att += Math.min(v.attrition);
  p.abc +=  v.subtract; // Needs improvement
  p.hc += Math.min(v.HC);
  p.final = (p.att - p.abc)/p.hc;
  return p
}

function removeR(p, v) {
  p.att -= Math.min(v.attrition);
  p.abc -= v.subtract; // Needs improvement
  p.hc -= Math.min(v.HC);
  p.final = (p.att + p.abc)/p.hc;
  return p
}

function initialR(p, v) {
    return {att:0, hc:0, abc:0}
}

var deptgroup = deptdim.group().reduce(addR, removeR, initialR)

dc.cboxMenu("#select_box")
  .dimension(catdim)
  .title(function(d) { return "Exlude: " + d.key })
  .multiple(true)
  .group(catdim.group());


dc.barChart("#chart")
  .x(d3.scaleBand())
  .xUnits(dc.units.ordinal)
  .elasticY(true)
  .dimension(deptdim)
  .group(deptgroup)
  .valueAccessor(function(p) { return p.value.final; });

dc.renderAll();
</script>

</body>
</html>

JSFiddle

Q:- With the data, I need
(minimum of (attrition) - abc - xyz - pqr) / minimum of (HC), where abc, xyz and pqr are multiselect checkbox options.

When no checkbox is selected result will be:
Dept A: (100-0-0-0) / 500 = 0.2
if abc is checked (excluded): (100-23-0-0)/500 = 0.154
if abc and pqr is checked: (100-23-5-0)/500 = 0.144 if all boxes are checked: (100-23-5-25)/500 = 0.094 and similarly for Dept B.

My Try: I tried to use javascript Math.min function, the result is fine in the first iteration but does not give accurate results from the second iteration.
I tried using reductio functions as well, but was not able to produce required results.

Gordon
  • 19,811
  • 4
  • 36
  • 74
Vasim
  • 3,052
  • 3
  • 35
  • 56
  • I'd suggest getting into the debugger inside of those reduce functions and see what you are dealing with. Each record is passed to the reduce function once when it is added to or removed from a group, so `v.attrition` is just a value, so doing `Math.min(v.attrition)` doesn't really do anything. Instead, you'll need to keep a list of every value you have seen (including duplicates) and then calculate your minimum based on that. You can use reductio to do this as documented here: https://github.com/crossfilter/reductio#aggregations-standard-aggregations-reductio-b-min-b-i-boolean-i-i-value-i- – Ethan Jewett Aug 14 '18 at 15:15
  • Please use the [dc.js] tag for questions about the charting library - [dc] is the classic Unix command "desktop calculator" :-) – Gordon Aug 14 '18 at 22:40
  • FWIW there is a dc.js example that shows [one way to do minimum value](http://dc-js.github.io/dc.js/examples/complex-reduce.html). Using reductio will be easier though. As Ethan says, you need to keep a list of all values. – Gordon Aug 14 '18 at 22:44
  • Thank you Ethan Jewett for the reductio library. After some hours of play and documentation, I was able to solve my requirements. Gordon -Thanks for input will take care next time. – Vasim Aug 15 '18 at 05:04

0 Answers0