score:0

Accepted answer

I was able to find two issues in your code.

  1. The clipPath rectangle used in svg defs is also getting updated within xBrushed function. The problem is with the selector you used.

    You should have used

    main.selectAll(".rect") //which selects all elements with class rect in main selection.
    

    instead of

    main.selectAll("rect") //which selects all rect elements in main selection which includes clipPath rect also.
    

    within the xBrushed function.

  2. You will need to apply the clip-path attribute to the group element which holds the rectangle bar elements.

Working code snippet:

var margin = {
    top: 20,
    right: 20,
    bottom: 30,
    left: 40
  },
  width = 860 - margin.left - margin.right,
  height = 500 - margin.top - margin.bottom;

var min_margin = {
    top: height,
    right: margin.right + 10,
    bottom: margin.bottom,
    left: margin.left + 10
  },
  min_height = 10,
  min_width = 860 - min_margin.left - min_margin.right;




var x = d3.scale.ordinal()
  .rangeRoundBands([0, width], .2);

var min_x = d3.scale.ordinal().rangeRoundBands([0, width], .2);


var y = d3.scale.linear()
  .range([height, 0]);

var xAxis = d3.svg.axis()
  .scale(x)
  .orient("bottom");

var min_xAxis = d3.svg.axis()
  .scale(min_x)
  .orient("bottom");



var main_xZoom = d3.scale.linear()
  .range([0, width])
  .domain([0, width]);

var yAxis = d3.svg.axis()
  .scale(y)
  .orient("left")
  .ticks(10, "%");

var svg = d3.select("body").append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom);

var main = svg.append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

main.append("defs").append("clipPath")
  .attr("id", "clip")
  .append("rect")
  .attr("width", width)
  .attr("height", height + min_height + margin.bottom);


var mini_x_append = svg.append("g")
  .attr("transform", "translate(" + min_margin.left + "," + (margin.top + height) + ")")
  .attr("width", min_width);


var data = [{
  "letter": "A~q112",
  "frequency": 0.08167
}, {
  "letter": "B~12",
  "frequency": 0.01492
}, {
  "letter": "C~c",
  "frequency": 0.02782
}, {
  "letter": "D~1a",
  "frequency": 0.04253
}, {
  "letter": "E~d",
  "frequency": 0.12702
}, {
  "letter": "F~x",
  "frequency": 0.02288
}, {
  "letter": "G~v",
  "frequency": 0.02015
}, {
  "letter": "H~xs",
  "frequency": 0.06094
}, {
  "letter": "I~za",
  "frequency": 0.06966
}, {
  "letter": "J~mj",
  "frequency": 0.00153
}, {
  "letter": "K~th",
  "frequency": 0.00772
}, {
  "letter": "L~ws",
  "frequency": 0.04025
}, {
  "letter": "M~qjl",
  "frequency": 0.02406
}, {
  "letter": "N~i",
  "frequency": 0.06749
}, {
  "letter": "O~p",
  "frequency": 0.07507
}, {
  "letter": "P~zs",
  "frequency": 0.01929
}, {
  "letter": "Q~rip",
  "frequency": 0.00095
}, {
  "letter": "R~hi",
  "frequency": 0.05987
}, {
  "letter": "S~eop",
  "frequency": 0.06327
}, {
  "letter": "T~tl",
  "frequency": 0.09056
}, {
  "letter": "U~se",
  "frequency": 0.02758
}, {
  "letter": "V~wh",
  "frequency": 0.00978
}, {
  "letter": "W~jl",
  "frequency": 0.0236
}, {
  "letter": "X~y",
  "frequency": 0.0015
}, {
  "letter": "Y~ty",
  "frequency": 0.01974
}, {
  "letter": "Z~o",
  "frequency": 0.00074
}, {
  "letter": "A~q12",
  "frequency": 0.08167
}, {
  "letter": "B~122",
  "frequency": 0.01492
}, {
  "letter": "C~c2",
  "frequency": 0.02782
}, {
  "letter": "D~1a2",
  "frequency": 0.04253
}, {
  "letter": "E~d2",
  "frequency": 0.12702
}, {
  "letter": "F~x2",
  "frequency": 0.02288
}, {
  "letter": "G~v2",
  "frequency": 0.02015
}, {
  "letter": "H~xs2",
  "frequency": 0.06094
}, {
  "letter": "I~za2",
  "frequency": 0.06966
}, {
  "letter": "J~mj2",
  "frequency": 0.00153
}, {
  "letter": "K~th2",
  "frequency": 0.00772
}, {
  "letter": "L~ws2",
  "frequency": 0.04025
}, {
  "letter": "M~qjl2",
  "frequency": 0.02406
}, {
  "letter": "N~i2",
  "frequency": 0.06749
}, {
  "letter": "O~p2",
  "frequency": 0.07507
}, {
  "letter": "P~zs2",
  "frequency": 0.01929
}, {
  "letter": "Q~rip2",
  "frequency": 0.00095
}, {
  "letter": "R~hi2",
  "frequency": 0.05987
}, {
  "letter": "S~eo2p",
  "frequency": 0.06327
}, {
  "letter": "T~tl2",
  "frequency": 0.09056
}, {
  "letter": "U~se2",
  "frequency": 0.02758
}, {
  "letter": "V~wh2",
  "frequency": 0.00978
}, {
  "letter": "W~jl2",
  "frequency": 0.0236
}, {
  "letter": "X~y2",
  "frequency": 0.0015
}, {
  "letter": "Y~ty2",
  "frequency": 0.01974
}, {
  "letter": "Z~o2",
  "frequency": 0.00074
}];





x.domain(data.map(function(d) {
  return d.letter;
}));
min_x.domain(data.map(function(d) {
  return d.letter;
}));
y.domain([0, d3.max(data, function(d) {
  return d.frequency;
})]);


var xBrush = d3.svg.brush().x(min_x).on("brush", xBrushed);

// Add the x axis


main.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + (height + min_height) + ")")
  .attr("clip-path", "url(#clip)")
  .call(xAxis)
  .selectAll(".tick text")
  .call(wrap, x.rangeBand());


var x_arc = d3.svg.arc()
  .outerRadius(min_height / 2)
  .startAngle(0)
  .endAngle(function(d, i) {
    return i ? -Math.PI : Math.PI;
  });

var brush_x_grab = mini_x_append.append("g")
  .attr("class", "x brush")
  .call(xBrush);

brush_x_grab.selectAll(".resize").append("path")
  .attr("transform", "translate(0," + min_height / 2 + ")")
  .attr("d", x_arc);

brush_x_grab.selectAll("rect").attr("height", min_height);





main.append("g")
  .attr("class", "y axis")
  .call(yAxis);


var bar = main.append("g")
  .attr("clip-path", "url(#clip)")
  .selectAll(".rect")
  .data(data)
  .enter().append("rect")
  .attr("class", "rect")
  .attr("x", function(d) {
    return x(d.letter);
  })
  .attr("width", x.rangeBand())
  .attr("y", function(d) {
    return y(d.frequency);
  })
  .attr("height", function(d) {
    return height - y(d.frequency);
  });



// Called to re-draw the bars on the main chart when the brush on the x axis
// has been altered.
function xBrushed() {
  var originalRange = main_xZoom.range();
  
  main_xZoom.domain(xBrush.empty() ? originalRange : xBrush.extent());
  
  x.rangeRoundBands([main_xZoom(originalRange[0]), main_xZoom(originalRange[1])], .2);

 // min_x.rangeRoundBands([0, x.rangeBand()], 0);

  main.selectAll(".rect")
    .data(data)
    .attr("width", function(d) {

      return x.rangeBand();
    })
  
    .attr("x", function(d) {
      //   alert("d is"+JSON.stringify(d));


      return x(d.letter);

    
    }); 

  main.select("g.x.axis").call(xAxis).selectAll(".tick text").call(wrap, x.rangeBand());
};

// This comes from the example at http://bl.ocks.org/mbostock/7555321
// for wrapping long axis tick labels
function wrap(text, width) {
  text.each(function() {
    var text = d3.select(this),
      words = text.text().split(/\s+/).reverse(),
      word,
      line = [],
      lineNumber = 0,
      lineHeight = 1.1, // ems
      y = text.attr("y"),
      dy = parseFloat(text.attr("dy")),
      tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
    while (word = words.pop()) {
      //   console.log("wrap is"+JSON.stringify(word));
      line.push(word);
      tspan.text(line.join(" "));
      if (tspan.node().getComputedTextLength() > width) {
        line.pop();
        tspan.text(line.join(" "));
        line = [word];
        tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
      }
    }
  });
};



// Set the initial brush selections.
// svg.select(".x.brush").call(xBrush.extent(main_xZoom.domain()));
svg.select(".x.brush").call(xBrush.extent([0, 110]));
//svg.select(".y.brush").call(yBrush.extent(mini_y0.domain()));

// Forces a refresh of the brushes and main chart based
// on the selected extents.
xBrushed();
//yBrushed();


function type(d) {
  d.frequency = +d.frequency;
  return d;
}
g.axis path,
g.axis line {
  fill: none;
  stroke: black;
  shape-rendering: crispEdges;
}
g.brush rect.extent {
  fill-opacity: 0.2;
}
.resize path {
  fill-opacity: 0.2;
}
.bar {
  fill: steelblue;
}
.axis {
  font: 10px sans-serif;
}
.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}
.x.axis path {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

EDIT:

I found it is more easy to implement this functionality by converting the json data you have to the same format used at this link.

var nestedData;

var main_margin = {
    top: 25,
    right: 80,
    bottom: 60,
    left: 70
  },

  width = 900 - main_margin.left - main_margin.right,
  mini_x_height = 10;
main_height = 525 - main_margin.top - main_margin.bottom,

  mini_x_margin = {
    top: main_height,
    right: main_margin.right + 10,
    bottom: main_margin.bottom,
    left: main_margin.left + 10
  },

  mini_x_width = 900 - mini_x_margin.left - mini_x_margin.right,

  mini_y_margin = {
    top: main_margin.top + 10,
    right: 0,
    bottom: main_margin.bottom + 10,
    left: 0
  },
  mini_y_width = 10,
  mini_y_height = 525 - mini_y_margin.top - mini_y_margin.bottom;


var color = d3.scale.category10();

// x0 is the groups scale on the x axis.
var main_x0 = d3.scale.ordinal().rangeRoundBands([0, width], 0.2);
var mini_x0 = d3.scale.ordinal().rangeRoundBands([0, width], 0.2);

var main_xZoom = d3.scale.linear()
  .range([0, width])
  .domain([0, width]);

// x1 is the series scale on the x axis.
var main_x1 = d3.scale.ordinal();
var mini_x1 = d3.scale.ordinal();

// y is the value scale on the y axis.
var main_y0 = d3.scale.linear().range([main_height, 0]);

var mini_y0 = d3.scale.linear().range([mini_y_height, 0]);

var main_xAxis = d3.svg.axis()
  .scale(main_x0)
  .orient("bottom");

var mini_xAxis = d3.svg.axis()
  .scale(mini_x0)
  .orient("bottom");

var main_yAxis = d3.svg.axis()
  .scale(main_y0)
  .orient("left");

var mini_yAxis = d3.svg.axis()
  .scale(mini_y0)
  .orient("left");

var svg = d3.select("#chart").append("svg")
  .attr("width", width + main_margin.left + main_margin.right)
  .attr("height", main_height + main_margin.top + main_margin.bottom);

var main = svg.append("g")
  .attr("transform", "translate(" + main_margin.left + "," + main_margin.top + ")");

main.append("defs").append("clipPath")
  .attr("id", "clip")
  .append("rect")
  .attr("width", width)
  .attr("height", main_height + mini_x_height + main_margin.bottom);

var mini_x = svg.append("g")
  .attr("transform", "translate(" + mini_x_margin.left + "," + (main_margin.top + main_height) + ")")
  .attr("width", mini_x_width);

var mini_y = svg.append("g")
  .attr("width", mini_y_width)
  .attr("transform", "translate(" + (main_margin.left - mini_y_width) + ", " + mini_y_margin.top + ")")
  .attr("height", mini_y_height);

var data = [{
  key: 'Mechanical',
  values: [{
    key: 'Gear',
    value: 11
}, {
    key: 'Bearing',
    value: 8
  }, {
    key: 'Motor',
    value: 3
  }, {
    key: 'Bearing',
    value: 8
  }, {
    key: 'Motor',
    value: 3
  }, {
    key: 'Bearing',
    value: 8
  }, {
    key: 'Motor',
    value: 3
  }]
}, {
  key: 'Electrical',
  values: [{
    key: 'Switch',
    value: 19
  }, {
    key: 'Plug',
    value: 12
  }, {
    key: 'Cord',
    value: 11
  }, {
    key: 'Fuse',
    value: 3
  }, {
    key: 'Bulb',
    value: 2
  }]
}, {
  key: 'Hydraulic',
  values: [{
    key: 'Pump',
    value: 4
  }, {
    key: 'Leak',
    value: 3
  }, {
    key: 'Seals',
    value: 1
  },{
    key: 'Switch',
    value: 19
  }, {
    key: 'Plug',
    value: 12
  }, {
    key: 'Cord',
    value: 11
  }, {
    key: 'Fuse',
    value: 3
  }, {
    key: 'Bulb',
    value: 2
  }]
}];


var res = [];

data.forEach(function(d){ 
  res.push(d.values.map(function(o){
    o.item=o.key; 
    o.subject = d.key; return o; }));
});

data = [].concat.apply([], res);
res.sort(function(a,b){ return a.subject<b.subject });

//console.log(data);

  var seriesValues = d3.set(data.map(function(x) {
    return x.item;
  })).values().sort(d3.ascending);

  nestedData = d3.nest()
    .key(function(d) {
      return d.subject;
    })
    .sortKeys(d3.ascending)
    .sortValues(function(a, b) {
      return a.item - b.item;
    })
    .entries(data);

  var groupValues = d3.set(data.map(function(x) {
    return x.subject;
  })).values();

  // Define the axis domains
  main_x0.domain(groupValues);
  mini_x0.domain(groupValues);

  main_x1.domain(seriesValues).rangeRoundBands([0, main_x0.rangeBand()], 0);
  mini_x1.domain(seriesValues).rangeRoundBands([0, main_x0.rangeBand()], 0);

  main_y0.domain([0, d3.max(nestedData, function(d) {
    return d3.max(d.values, function(d) {
      return d.value;
    });
  })]);
  mini_y0.domain(main_y0.domain());

  var xBrush = d3.svg.brush().x(mini_x0).on("brush", xBrushed);
  var yBrush = d3.svg.brush().y(mini_y0).on("brush", yBrushed);

  // Add the x axis
  main.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + (main_height + mini_x_height) + ")")
    .attr("clip-path", "url(#clip)")
    .call(main_xAxis)
    .selectAll(".tick text")
    .call(wrap, main_x0.rangeBand());

  // Add the y axis
  main.append("g")
    .attr("class", "y axis")
    .attr("transform", "translate(" + (-mini_y_width) + ", 0)")
    .call(main_yAxis)
    .append("text")
    .attr("transform", "rotate(-90), translate(" + -(main_height / 2) + ", " + -(mini_y_width + main_margin.left - 20) + ")")
    .attr("dy", ".71em")
    .style("text-anchor", "middle")
    .text("value");

  var x_arc = d3.svg.arc()
    .outerRadius(mini_x_height / 2)
    .startAngle(0)
    .endAngle(function(d, i) {
      return i ? -Math.PI : Math.PI;
    });

  var brush_x_grab = mini_x.append("g")
    .attr("class", "x brush")
    .call(xBrush);

  brush_x_grab.selectAll(".resize").append("path")
    .attr("transform", "translate(0," + mini_x_height / 2 + ")")
    .attr("d", x_arc);

  brush_x_grab.selectAll("rect").attr("height", mini_x_height);

  var y_arc = d3.svg.arc()
    .outerRadius(mini_y_width / 2)
    .startAngle(-(Math.PI / 2))
    .endAngle(function(d, i) {
      return i ? -((3 * Math.PI) / 2) : ((Math.PI) / 2);
    });

  var brush_y_grab = mini_y.append("g")
    .attr("class", "y brush")
    .call(yBrush);

  brush_y_grab.selectAll(".resize").append("path")
    .attr("transform", "translate(" + (mini_y_width / 2) + ", 0)")
    .attr("d", y_arc);

  brush_y_grab.selectAll("rect").attr("width", mini_y_width);

  // Create the main bars
  var bar = main.selectAll(".bars")
    .data(nestedData)
    .enter().append("g")
    .attr("clip-path", "url(#clip)")
    .attr("class", function(d) {
      return d.key + "-group bar";
    });

  bar.selectAll("rect")
    .data(function(d) {
      return d.values;
    })
    .enter().append("rect")
    .attr("class", function(d) {
      return d.item;
    })
    .attr("transform", function(d) {
      return "translate(" + main_x0(d.subject) + ",0)";
    })
    .attr("width", function(d) {
      return main_x1.rangeBand();
    })
    .attr("x", function(d) {
      return main_x1(d.item);
    })
    .attr("y", function(d) {
      return main_y0(d.value);
    })
    .attr("height", function(d) {
      return main_height - main_y0(d.value);
    })
    .style("fill", function(d) {
      return color(d.item);
    });


  // Draws the series items onto a legend
  var legend = svg.selectAll(".legend")
    .data(seriesValues.slice())
    .enter().append("g")
    .attr("class", "legend")
    .attr("transform", function(d, i) {
      return "translate(50," + (main_margin.top + (i * 20)) + ")";
    });

  legend.append("rect")
    .attr("x", width - 18)
    .attr("width", 18)
    .attr("height", 18)
    .style("fill", color);

  legend.append("text")
    .attr("x", width - 24)
    .attr("y", 9)
    .attr("dy", ".35em")
    .style("text-anchor", "end")
    .text(function(d) {
      return d;
    });

  // Called to re-draw the bars on the main chart when the brush on the x axis
  // has been altered.
  function xBrushed() {
    var originalRange = main_xZoom.range();
    main_xZoom.domain(xBrush.empty() ? originalRange : xBrush.extent());
    main_x0.rangeRoundBands([main_xZoom(originalRange[0]), main_xZoom(originalRange[1])], .1);

    main_x1.rangeRoundBands([0, main_x0.rangeBand()], 0);

    bar.selectAll("rect")
      .attr("transform", function(d) {
        return "translate(" + main_x0(d.subject) + ",0)";
      })
      .attr("width", function(d) {
        return main_x1.rangeBand();
      })
      .attr("x", function(d) {
        return main_x1(d.item);
      });

    main.select("g.x.axis").call(main_xAxis).selectAll(".tick text").call(wrap, main_x0.rangeBand());
  };

  // Called to re-draw the bars on the main chart when the
  // brush on the y axis has been altered.
  function yBrushed() {
    main_y0.domain(yBrush.empty() ? mini_y0.domain() : yBrush.extent());

    bar.selectAll("rect")
      .attr("y", function(d) {
        return main_y0(d.value);
      })
      .attr("height", function(d) {
        return main_height - main_y0(d.value);
      });

    main.select("g.y.axis").call(main_yAxis);
  };

  // This comes from the example at http://bl.ocks.org/mbostock/7555321
  // for wrapping long axis tick labels
  function wrap(text, width) {
    text.each(function() {
      var text = d3.select(this),
        words = text.text().split(/\s+/).reverse(),
        word,
        line = [],
        lineNumber = 0,
        lineHeight = 1.1, // ems
        y = text.attr("y"),
        dy = parseFloat(text.attr("dy")),
        tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
      while (word = words.pop()) {
        line.push(word);
        tspan.text(line.join(" "));
        if (tspan.node().getComputedTextLength() > width) {
          line.pop();
          tspan.text(line.join(" "));
          line = [word];
          tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
        }
      }
    });
  };

  // Set the initial brush selections.
  // svg.select(".x.brush").call(xBrush.extent(main_xZoom.domain()));
  svg.select(".x.brush").call(xBrush.extent([0, 610]));
  svg.select(".y.brush").call(yBrush.extent(mini_y0.domain()));

  // Forces a refresh of the brushes and main chart based
  // on the selected extents.
  xBrushed();
  yBrushed();

//});
g.axis path,
g.axis line {
  fill: none;
  stroke: black;
  shape-rendering: crispEdges;
}
g.brush rect.extent {
  fill-opacity: 0.2;
}
.resize path {
  fill-opacity: 0.2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="chart"></div>


Related Query

More Query from same tag