score:2
Accepted answer
as in this example where mr. bostock applies a clip path to the area path, you need to apply one to the bars. the easiest way is to put them in their own g
then apply the clip-path to that:
svg.append("defs").append("clippath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
...
// plot the stacked bars
var focus_bar = focus
.append("g") //<-- g just for the bars to be clipped
.attr("class","barclipper")
.style('clip-path', 'url(#clip)') //<-- apply clipping
.selectall('.g')
.data(data.answer_counts)
.enter().append('g')
.attr('class', 'g bar stack')
.attr('transform', function(d) {
return "translate(" + x(d.date) + ",0)"
});
full code:
<!doctype html>
<html>
<head>
<script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
<style>
#milestones_attempts_combo .context {
/*fill: #efefef; */
}
#milestones_attempts_combo .focus .right,
#milestones_attempts_combo .context .right {
fill: #0064cd;
}
#milestones_attempts_combo .focus .wrong,
#milestones_attempts_combo .context .wrong {
fill: #cd001d;
}
#milestones_attempts_combo .y-axis-label,
#milestones_attempts_combo .y2-axis-label {
fill: #aaa;
font-size: 120%;
}
#milestones_attempts_combo .focus-line,
#milestones_attempts_combo .context-line {
stroke: orange;
stroke-width: 2;
fill-opacity: 0;
}
.brush .extent {
stroke: #efefef;
fill: #666;
fill-opacity: .125;
shape-rendering: crispedges;
}
.stats-container {
width: 700px;
margin: 0 auto;
}
.chart .axis line,
.chart .axis path,
.chart .tick line {
fill: none;
stroke: #aaa;
shape-rendering: crispedges;
}
</style>
</head>
<body>
<div id="milestones_attempts_combo"></div>
<script>
(function() {
var myjsondata = {
"answer_counts": [{
"date": "2012-09-13",
"ys": [{
"y1": 9,
"y0": 0,
"class": "right"
}, {
"y1": 12,
"y0": 9,
"class": "wrong"
}],
"total": 12
}, {
"date": "2012-09-16",
"ys": [{
"y1": 16,
"y0": 0,
"class": "right"
}, {
"y1": 17,
"y0": 16,
"class": "wrong"
}],
"total": 17
}, {
"date": "2012-09-17",
"ys": [{
"y1": 12,
"y0": 0,
"class": "right"
}, {
"y1": 14,
"y0": 12,
"class": "wrong"
}],
"total": 14
}, {
"date": "2012-09-19",
"ys": [{
"y1": 2,
"y0": 0,
"class": "right"
}, {
"y1": 2,
"y0": 2,
"class": "wrong"
}],
"total": 2
}, {
"date": "2012-09-20",
"ys": [{
"y1": 12,
"y0": 0,
"class": "right"
}, {
"y1": 16,
"y0": 12,
"class": "wrong"
}],
"total": 16
}, {
"date": "2012-09-21",
"ys": [{
"y1": 20,
"y0": 0,
"class": "right"
}, {
"y1": 22,
"y0": 20,
"class": "wrong"
}],
"total": 22
}, {
"date": "2012-09-22",
"ys": [{
"y1": 1,
"y0": 0,
"class": "right"
}, {
"y1": 1,
"y0": 1,
"class": "wrong"
}],
"total": 1
}, {
"date": "2012-09-23",
"ys": [{
"y1": 10,
"y0": 0,
"class": "right"
}, {
"y1": 12,
"y0": 10,
"class": "wrong"
}],
"total": 12
}, {
"date": "2012-09-24",
"ys": [{
"y1": 9,
"y0": 0,
"class": "right"
}, {
"y1": 9,
"y0": 9,
"class": "wrong"
}],
"total": 9
}, {
"date": "2012-09-25",
"ys": [{
"y1": 2,
"y0": 0,
"class": "right"
}, {
"y1": 4,
"y0": 2,
"class": "wrong"
}],
"total": 4
}, {
"date": "2012-09-29",
"ys": [{
"y1": 26,
"y0": 0,
"class": "right"
}, {
"y1": 37,
"y0": 26,
"class": "wrong"
}],
"total": 37
}, {
"date": "2012-10-01",
"ys": [{
"y1": 44,
"y0": 0,
"class": "right"
}, {
"y1": 44,
"y0": 44,
"class": "wrong"
}],
"total": 44
}, {
"date": "2012-10-02",
"ys": [{
"y1": 2,
"y0": 0,
"class": "right"
}, {
"y1": 2,
"y0": 2,
"class": "wrong"
}],
"total": 2
}, {
"date": "2012-10-03",
"ys": [{
"y1": 13,
"y0": 0,
"class": "right"
}, {
"y1": 13,
"y0": 13,
"class": "wrong"
}],
"total": 13
}, {
"date": "2012-10-05",
"ys": [{
"y1": 47,
"y0": 0,
"class": "right"
}, {
"y1": 47,
"y0": 47,
"class": "wrong"
}],
"total": 47
}, {
"date": "2012-10-08",
"ys": [{
"y1": 17,
"y0": 0,
"class": "right"
}, {
"y1": 17,
"y0": 17,
"class": "wrong"
}],
"total": 17
}, {
"date": "2012-10-09",
"ys": [{
"y1": 19,
"y0": 0,
"class": "right"
}, {
"y1": 20,
"y0": 19,
"class": "wrong"
}],
"total": 20
}, {
"date": "2012-10-10",
"ys": [{
"y1": 31,
"y0": 0,
"class": "right"
}, {
"y1": 31,
"y0": 31,
"class": "wrong"
}],
"total": 31
}, {
"date": "2012-10-11",
"ys": [{
"y1": 6,
"y0": 0,
"class": "right"
}, {
"y1": 6,
"y0": 6,
"class": "wrong"
}],
"total": 6
}, {
"date": "2012-10-14",
"ys": [{
"y1": 6,
"y0": 0,
"class": "right"
}, {
"y1": 6,
"y0": 6,
"class": "wrong"
}],
"total": 6
}, {
"date": "2012-10-19",
"ys": [{
"y1": 30,
"y0": 0,
"class": "right"
}, {
"y1": 32,
"y0": 30,
"class": "wrong"
}],
"total": 32
}, {
"date": "2012-10-20",
"ys": [{
"y1": 20,
"y0": 0,
"class": "right"
}, {
"y1": 22,
"y0": 20,
"class": "wrong"
}],
"total": 22
}, {
"date": "2012-10-23",
"ys": [{
"y1": 20,
"y0": 0,
"class": "right"
}, {
"y1": 20,
"y0": 20,
"class": "wrong"
}],
"total": 20
}, {
"date": "2012-10-24",
"ys": [{
"y1": 20,
"y0": 0,
"class": "right"
}, {
"y1": 21,
"y0": 20,
"class": "wrong"
}],
"total": 21
}, {
"date": "2012-10-29",
"ys": [{
"y1": 22,
"y0": 0,
"class": "right"
}, {
"y1": 22,
"y0": 22,
"class": "wrong"
}],
"total": 22
}, {
"date": "2012-11-01",
"ys": [{
"y1": 1,
"y0": 0,
"class": "right"
}, {
"y1": 1,
"y0": 1,
"class": "wrong"
}],
"total": 1
}, {
"date": "2012-11-02",
"ys": [{
"y1": 26,
"y0": 0,
"class": "right"
}, {
"y1": 29,
"y0": 26,
"class": "wrong"
}],
"total": 29
}, {
"date": "2012-11-05",
"ys": [{
"y1": 23,
"y0": 0,
"class": "right"
}, {
"y1": 27,
"y0": 23,
"class": "wrong"
}],
"total": 27
}, {
"date": "2012-11-06",
"ys": [{
"y1": 10,
"y0": 0,
"class": "right"
}, {
"y1": 11,
"y0": 10,
"class": "wrong"
}],
"total": 11
}, {
"date": "2012-11-07",
"ys": [{
"y1": 15,
"y0": 0,
"class": "right"
}, {
"y1": 18,
"y0": 15,
"class": "wrong"
}],
"total": 18
}, {
"date": "2012-11-09",
"ys": [{
"y1": 26,
"y0": 0,
"class": "right"
}, {
"y1": 31,
"y0": 26,
"class": "wrong"
}],
"total": 31
}, {
"date": "2012-11-10",
"ys": [{
"y1": 2,
"y0": 0,
"class": "right"
}, {
"y1": 2,
"y0": 2,
"class": "wrong"
}],
"total": 2
}, {
"date": "2012-11-14",
"ys": [{
"y1": 15,
"y0": 0,
"class": "right"
}, {
"y1": 17,
"y0": 15,
"class": "wrong"
}],
"total": 17
}, {
"date": "2012-11-16",
"ys": [{
"y1": 20,
"y0": 0,
"class": "right"
}, {
"y1": 23,
"y0": 20,
"class": "wrong"
}],
"total": 23
}, {
"date": "2012-11-18",
"ys": [{
"y1": 2,
"y0": 0,
"class": "right"
}, {
"y1": 2,
"y0": 2,
"class": "wrong"
}],
"total": 2
}, {
"date": "2012-11-19",
"ys": [{
"y1": 23,
"y0": 0,
"class": "right"
}, {
"y1": 26,
"y0": 23,
"class": "wrong"
}],
"total": 26
}, {
"date": "2012-11-21",
"ys": [{
"y1": 2,
"y0": 0,
"class": "right"
}, {
"y1": 3,
"y0": 2,
"class": "wrong"
}],
"total": 3
}, {
"date": "2012-11-23",
"ys": [{
"y1": 9,
"y0": 0,
"class": "right"
}, {
"y1": 10,
"y0": 9,
"class": "wrong"
}],
"total": 10
}, {
"date": "2012-11-26",
"ys": [{
"y1": 2,
"y0": 0,
"class": "right"
}, {
"y1": 2,
"y0": 2,
"class": "wrong"
}],
"total": 2
}, {
"date": "2012-11-27",
"ys": [{
"y1": 25,
"y0": 0,
"class": "right"
}, {
"y1": 26,
"y0": 25,
"class": "wrong"
}],
"total": 26
}, {
"date": "2012-11-28",
"ys": [{
"y1": 73,
"y0": 0,
"class": "right"
}, {
"y1": 75,
"y0": 73,
"class": "wrong"
}],
"total": 75
}, {
"date": "2012-12-02",
"ys": [{
"y1": 19,
"y0": 0,
"class": "right"
}, {
"y1": 20,
"y0": 19,
"class": "wrong"
}],
"total": 20
}, {
"date": "2012-12-05",
"ys": [{
"y1": 1,
"y0": 0,
"class": "right"
}, {
"y1": 1,
"y0": 1,
"class": "wrong"
}],
"total": 1
}, {
"date": "2013-01-11",
"ys": [{
"y1": 2,
"y0": 0,
"class": "right"
}, {
"y1": 3,
"y0": 2,
"class": "wrong"
}],
"total": 3
}, {
"date": "2013-01-16",
"ys": [{
"y1": 8,
"y0": 0,
"class": "right"
}, {
"y1": 8,
"y0": 8,
"class": "wrong"
}],
"total": 8
}],
"badge_set_reached": [{
"date": "2014-05-24",
"set": 3
}, {
"date": "2014-09-29",
"set": 5
}, {
"date": "2014-11-10",
"set": 6
}, {
"date": "2014-08-29",
"set": 7
}, {
"date": "2015-08-12",
"set": 9
}, {
"date": "2016-01-09",
"set": 9
}]
}
var data = myjsondata;
// preprocess data to get usable date objects
var parse_date = d3.time.format('%y-%m-%d').parse
for (var i in data) {
var myobj = data[i]
for (var j in myobj) {
myobj[j].date = parse_date(myobj[j].date);
}
}
console.log(data);
// set variables
var margin = {
left: 60,
right: 60,
top: 10,
bottom: 140
},
navmargin = {
top: 300,
right: 60,
bottom: 40,
left: 60
},
height = 400 - margin.top - margin.bottom,
width = 800 - margin.left - margin.right,
navwidth = width, // for context band
navheight = 400 - navmargin.top - navmargin.bottom,
max_total_counts = d3.max(data.answer_counts, function(d) {
return d.total;
}),
max_extent_dates = d3.extent(data.answer_counts, function(d) {
return d.date;
});
max_extent_in_days = function(timescale) {
return d3.time.days(timescale.domain()[0], d3.time.day.offset(timescale.domain()[1], 1))
};
// scales
var y = d3.scale.linear().domain([0, max_total_counts]).rangeround([height, 0]),
navy = d3.scale.linear().domain([0, max_total_counts]).rangeround([navheight, 0]),
time = d3.time.scale().domain(max_extent_dates).range([0, width]),
navtime = d3.time.scale().domain(max_extent_dates).range([0, width]),
x = d3.scale.ordinal().domain(max_extent_in_days(time)).rangebands([0, width], 0.1, 0), // used to calculate bar widths
navx = d3.scale.ordinal().domain(max_extent_in_days(navtime)).rangebands([0, width], 0.1, 0),
y2 = d3.scale.linear().domain([0, d3.max(data.badge_set_reached, function(d) {
return d.set
})]).rangeround([height, 0]);
navy2 = d3.scale.linear().domain([0, d3.max(data.badge_set_reached, function(d) {
return d.set
})]).rangeround([navheight, 0]);
// axes
var x_axis = d3.svg.axis().scale(time).orient('bottom') // .tickformat(d3.time.format('%y-%m-%d'))
.outerticksize(0), // at start and end of axis line
nav_x_axis = d3.svg.axis().scale(navtime).orient('bottom') // .tickformat(d3.time.format('%y-%m-%d'))
.outerticksize(0), // at start and end of axis line
y_axis = d3.svg.axis().scale(y).orient('left').tickformat(d3.format('d'));
y2_axis = d3.svg.axis().scale(y2).orient('right').tickformat(d3.format('d'));
// add brush
var brush = d3.svg.brush()
.x(navtime)
.on("brush", brushed);
// svg context
var svg = d3.select("#milestones_attempts_combo")
.append('svg')
.attr('class', 'chart')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
svg.append("defs").append("clippath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
var focus = svg.append('g')
.attr('class', 'focus')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
var context = svg.append('g')
.attr('class', 'context')
.attr('transform', 'translate(' + navmargin.left + ',' + navmargin.top + ')');
// plot the stacked bars
var focus_bar = focus
.append("g")
.attr("class","barclipper")
.style('clip-path', 'url(#clip)')
.selectall('.g')
.data(data.answer_counts)
.enter().append('g')
.attr('class', 'g bar stack')
.attr('transform', function(d) {
return "translate(" + x(d.date) + ",0)"
});
var focus_rects = focus_bar.selectall('rect')
.data(function(d) {
return d.ys;
})
.enter().append('rect')
.attr('width', x.rangeband())
.attr('height', function(d) {
return y(d.y0) - y(d.y1);
})
.attr('y', function(d) {
return y(d.y1);
})
.attr('class', function(d) {
return 'rect ' + d['class'];
});
var context_bar = context.selectall('.g')
.data(data.answer_counts)
.enter().append('g')
.attr('class', 'g')
.attr('transform', function(d) {
return "translate(" + navtime(d.date) + ",0)"
});
var context_rects = context_bar.selectall('rect')
.data(function(d) {
return d.ys;
})
.enter().append('rect')
.attr('width', navx.rangeband())
.attr('height', function(d) {
return navy(d.y0) - navy(d.y1);
})
.attr('y', function(d) {
return navy(d.y1);
})
.attr('class', function(d) {
return 'rect ' + d['class'];
});
// plot lines
var line = d3.svg.line()
.x(function(d) {
return time(d.date)
})
.y(function(d) {
return y2(d.set)
})
.interpolate('step-after');
var focus_line = focus.append('path')
.datum(data.badge_set_reached)
.attr('class', 'line focus-line')
.attr('d', line);
var line2 = d3.svg.line()
.x(function(d) {
return time(d.date)
})
.y(function(d) {
return navy2(d.set)
})
.interpolate('step-after');
var context_line = context.append('path')
.datum(data.badge_set_reached)
.attr('class', 'line context-line')
.attr('d', line2);
// plot axes
focus.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0, ' + height + ')')
.call(x_axis)
.selectall('text')
.style('text-anchor', 'end')
// .attr('transform', 'rotate(-45)')
// .attr('dx', '-.5em')
// .attr('dy', '.5em');
focus.append('g')
.attr('class', 'y axis')
.attr('transform', 'translate(0, 0)')
.call(y_axis);
focus.append('g')
.attr('class', 'y2 axis')
.attr('transform', 'translate(' + width + ', 0)')
.call(y2_axis);
context.append('g')
.attr('class', 'navx axis')
.attr('transform', 'translate(0, ' + navheight + ')')
.call(nav_x_axis);
// label axes
svg.append('text')
.attr('class', 'label y-axis-label')
.attr('transform', 'rotate(-90)')
.attr('x', 0 - ((height + margin.top) / 2))
.attr('y', 0)
.attr('dy', 20)
.style('text-anchor', 'middle')
.text('paths attempted');
svg.append('text')
.attr('class', 'label y2-axis-label')
.attr('transform', 'rotate(+90)')
.attr('y', 0 - (width + margin.left + margin.right))
.attr('x', 0 + ((height + margin.top) / 2))
.attr('dy', '2em')
.style('text-anchor', 'middle')
.text('badge set reached');
// add brush to svg
context.append('g')
.attr('class', 'x brush')
.call(brush)
.selectall("rect")
.attr("y", -6)
.attr("height", navheight + 7);
function brushed() {
time.domain(brush.empty() ? navtime.domain() : brush.extent())
.range([0, (width)]);
x.domain(max_extent_in_days(time))
.rangebands([margin.left, (width)], 0.1, 0);
focus.selectall('.bar.stack')
.attr('transform', function(d) {
return "translate(" + time(d.date) + ",0)";
})
.attr('width', x.rangeband());
focus.selectall('.rect')
.attr('width', x.rangeband());
focus.selectall('.line').attr('d', line);
focus.select(".x.axis").call(x_axis);
};
})();
</script>
</body>
</html>
Source: stackoverflow.com
Related Query
- Content of d3.js chart overflows margins when using brush
- Pie chart not updating properly when using brush in series chart
- D3 js - when using brush line grows beyond chart x-axis
- issue while using d3 brush in a line+bar chart (zoom in line+bar chart)
- dc.js - "TypeError: _x is undefined" when using the brush
- NVD3 Line Chart doesn't display when data passed using ajax - data.map is not a function
- Maintain color mapping for Stacked/Grouped Multi-Bar Chart using NVD3 when the series count fluxuates
- d3 chart update automatically when data change by using vue
- How to show D3 chart using Bootstrap modal popup when click on button and download it as image format
- D3.js line chart using the wrong keys when using general update pattern
- Keeping track of the current number of values selected when the brush is moved, using dc.js/crossfilter.js
- D3js v5 Trying to select multiple bars in bar chart using brush and saving values to variable and table
- D3 v4 Multi line chart Brush Issue NaN when moving brush
- Aw snap in Google Chrome when interactive line chart using nvd3 + angular library
- D3 brush extent disappears from chart when dragged beyond extent
- Using D3, I am trying to add and remove lines from a multi line chart when the legend is clicked
- Horizon chart not visible when using d3.scale.log()
- When using a d3 Reusable Chart pattern how do you implement on drag when Dispatching Events (d3v5 +)?
- d3 using zoom and brush on a bar chart
- Mouseover Line on multiple charts when hover on single chart using D3
- d3 NaN when using javascript Filter (data.filter) on stacked Bar Chart
- Why Chart is getting appended to the existing div when using ng-repeat?
- In d3.js, update main chart to reflect brush state when adding/removing lines
- D3.js - overlapped bar chart when using rangeBands()
- Wrong labels in x-axis when using time-series bar chart
- chart but no database when using d3js
- Why isn't d3 text appearing on bar chart when using new dataset?
- Chart Drawn Incorrectly when using NVD3
- How to have only one brush show on page load when using multiple charts in dc.js/d3.js
- Line not visible in line chart when having same value in the domain() - using D3
More Query from same tag
- Nested SVG selections in D3
- d3 label are overlaping
- Update pie chart data at run time
- LeafletJs only show one country
- Sorting animated GIFs in SVG without stopping the animation using D3/JavaScript
- Looping through a set of images using D3js
- dataset created with d3.nest isn't drawing correctly
- Interactivity with the d3 reusable pattern
- How to align d3.linearScale()in the center of the page?
- pan d3.js graph
- Forect layout graph is re-drawing in D3 when meteor db updates
- nested circles in d3
- D3.js mouseover fails to trigger with an overlapping object
- TypeError: undefined is not an object (evaluating 'M.layout.force')
- d3 sort only applies to select rows
- Understanding and rebuilding overload of a dataframe to d3 format
- Creating an average Y line for D3 visualization?
- How do I modify ticks and format labels on D3 axes?
- Calling two sets of json using D3.json
- Update the angular d3 text onclick
- Add Tooltip on Scatter points, error is generated for D3.js Version 4
- Why is rendering this SVG map crashing my browser?
- Loading JSON FIle in FileMaker for D3 in WebViewer
- How can I draw text on a D3 SVG iff it's bounding box falls within certain criteria?
- Can i show dynamic graphs using d3.js on my pelican website?
- Karma/Jasmine unit test for D3 svg element
- D3 svg paths overlapping
- Set y-axis of d3 chart to fit widest label?
- d3 Uncaught TypeError: n.domain is not a function
- how to detect element drag in d3.js force directed graph