Brush extent needs to be changed only from a dropdown as shown here: https://jsfiddle.net/dani2011/67jopfj8/3/
Need to disable brush extending by:
1) Extending an existing brush using the handles/resize-area of the brush
Gray circles are the handels:
2) Dragging a new brush by clicking on the brush background, where the haircross cursor appears.
JavaScript file
Removed the handles of the brush:
timeSlider.on('preRedraw',function (chart)
{
var timesliderSVG = d3.select("#bitrate-timeSlider-chart").selectAll("g.brush").selectAll("g.resize").selectAll("*").data(data[0]).exit().remove();})
If using css instead:
#bitrate-timeSlider-chart g.resize {
display:none;
visibility:hidden;
Now it looks like this:
.
The rect and the path elements inside "resize e","resize w" were removed:
However,the "resize e", "resize w" for extanding the brush still exist:
g.resize.e and g.resize.w dimesions are 0*0:
Furthurmore,after deleting "resize e","resize w" in the "developer tools/elements" in chrome,they reappear after moving the brush.
Tried to remove the resize-area in brushstart,brush,brushend:
timeSlider.on('renderlet', function (chart) {
var brushg = d3.select("#bitrate-timeSlider-chart").selectAll("g.brush");
var resizeg = brushg.selectAll("g.resize").selectAll("*").data(data[0]);
var timesliderSVG4 =
brushg.on("brushstart", function () {resizeg.exit().remove()}).on("brush", function () { resizeg.exit().remove() }).on("brushend", function () {resizeg.exit().remove() })
dc.js file
Tried to change setHandlePaths,resizeHandlePath:
1) Remarked the _chart.setHandlePaths(gBrush):
_chart.renderBrush = function (g) {....
// _chart.setHandlePaths(gBrush);
...}
2) Changed _chart.setHandlePaths = function (gBrush) for example by removing the gbrush.path:
// gBrush.selectAll('.resize path').exit().remove();
3) Remarked/changed _chart.resizeHandlePath = function (d) {...}.
d3.js file
1) Remarked/changed resize such as:
mode: "move" //mode: "resize"
,
var resize = g.selectAll(".resize").data(resizes[0], d3_identity);
Using resizes[0] disable the brush rendering on the background but still can re-extend the existing brush
2) Remarked/changed d3_svg_brushResizes
3) In d3.svg.brush = function():
a) Added .style("display","none"):
background.enter().append("rect").attr("class", "background").style("visibility", "hidden").style("display", "none").style("cursor", "none");
b) background.exit().remove();
The cursor now is "pointer" instead of "haircross" extending the brush to a full width
c) d3_svg_brushCursor disabled makes the whole brush disappear
4) Changed the pointer-events as specified here: https://developer.mozilla.org/en/docs/Web/CSS/pointer-events
5) console.log in different places to track the different brush events:
function d3_event_dragSuppress(node) {
console.log("here2 ");
}
if (d3_event_dragSelect) {
console.log("here3 d3_event_dragSelect");
...
}
return function (suppressClick) {
console.log("suppressClick1");
...
var off = function () {
console.log("suppressClick2");
...
w.on(click, function () {
console.log("suppressClick3")
...
function d3_mousePoint(container, e) {
console.log("d3_mousePoint1")
...
if (svg.createSVGPoint) {
console.log("createSVGPoint");
...
if (window.scrollX || window.scrollY) {
console.log("createSVGPoint1");
svg = d3.select("body").append("svg").style({
...
function dragstart(id, position, subject, move, end) {
console.log("dragstart")
...
function moved() {
console.log("moved ");
console.log("transition1");
...
if (d3.event.changedTouches) {
console.log("brushstart1");
...
} else {
console.log("brushstart2");
..
if (dragging) {
console.log("dragging4");
....
if (d3.event.keyCode == 32) {
if (!dragging) {
console.log("notdragging1");
...
function brushmove() {
console.log("brushmove");
...
if (!dragging) {
console.log("brushmove!dragging");
if (d3.event.altKey) {
console.log("brushmove!dragging1");
...
if (resizingX && move1(point, x, 0)) {
console.log("resizeXMove1");
...
if (resizingY && move1(point, y, 1)) {
console.log("resizeYMove1");
...
if (moved) {
console.log("moved");
...
}
function move1(point, scale, i) {
if (dragging) {
console.log("dragging1");
...
if (dragging) {
console.log("dragging2");
...
} else {
console.log("dragging10");
...
if (extent[0] != min || extent[1] != max) {
console.log("dragging11");
if (i) console.log("dragging12"); yExtentDomain = null;
console.log("dragging13");
function brushend() {
console.log("brushend");
...
The two changes that seemed to get closest to the needed result are in d3.js:
1) Using resizes[0] disables the brush rendering on the background but still can re-extend the existing brush
var resize = g.selectAll(".resize").data(resizes[0], d3_identity);
2) Removing the brush's background changes the cursor to "pointer" instead of "haircross",extending the brush to a full width only when clicking on the graph
`background.exit().remove();`
Any help would be very appreciated!
This is from the accepted answer in Disable d3 brush resize, as suggested by @altocumulus. I didn't see a response from @Dani on this idea in particular, but thought I'd go ahead and try it, since I've seen other people try it in the past. (Probably on the dc.js users group.)
It looks a little twitchy, because d3.js will draw the brush at the new extent, and then a moment later we reset the extent to what we want, but functionally it seems to do what we want.
In dc.js the function that handles brush "rounding" is coordinateGridMixin.extendBrush
:
_chart.extendBrush = function () {
var extent = _brush.extent();
if (_chart.round()) {
extent[0] = extent.map(_chart.round())[0];
extent[1] = extent.map(_chart.round())[1];
_g.select('.brush')
.call(_brush.extent(extent));
}
return extent;
};
Notice that it's following the same pattern as Lars' answer. Well, this is sort of like rounding, right? Let's override it.
First, let's store the current number of hours when it's set through the dropdown:
var graphSpan;
function addHours(amountHours) {
graphSpan = amountHours;
// ...
Next let's override coordinateGridMixin.extendBrush
:
timeSlider.extendBrush = function() {
var extent = timeSlider.brush().extent();
if(graphSpan) {
extent[1] = moment(extent[0]).add(graphSpan, 'hours');
}
return extent;
}
We just replace the function. If we needed to reuse the old implementation in our function, we could use dc.override
.
If graphSpan
has been set, we add that amount to the beginning to get the end. If it's not set, we allow the user to specify the brush width - you'd need to default the graphSpan
and the select widget if you wanted that part to work automatically.
Well, let's admit it: it's very twitchy, but it works:
EDIT: Got rid of the twitch! The problem was that dc.js was setting the brush extent asynchronously after a little while (in response to the filter event). If we also set it during extentBrush
then it never shows the wrong extent:
timeSlider.extendBrush = function() {
var extent = timeSlider.brush().extent();
if(graphSpan) {
extent[1] = moment(extent[0]).add(graphSpan, 'hours');
timeSlider.brush().extent(extent);
}
return extent;
}
https://jsfiddle.net/gordonwoodhull/xdo05chk/1/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With