Disable brush resizing (DC.js, D3.js)

The brush size needs to be changed only from the drop-down list, as shown below: https://jsfiddle.net/dani2011/67jopfj8/3/

You must disable the brush, expanding:

1) Extending an existing brush using the handle area / brush size area

Gray circles are handels:

enter image description here

2) Dragging a new brush, clicking on the background of the brush, where the cursor appears.

Javascript file

Brush pens removed:

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 you use css instead:

 #bitrate-timeSlider-chart g.resize { display:none; visibility:hidden; 

Now it looks like this:

enter image description here .

The rect and path elements inside "resize e", "resize w" have been removed:

enter image description here

However, "resize e", "resize w" to continue the brush still exist:

enter image description here

g.resize.e and g.resize.w dimesions are 0 * 0:

enter image description here

Furthurmore, after deleting "resize e", "resize w" in "developer tools / elements" in chrome, they will appear after moving the brush.

I tried to remove the resizing area in the brush, 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 changing setHandlePaths , resizing HandlePath :

1) Noticed _chart. setHandlePaths (gBrush):

 _chart.renderBrush = function (g) {.... // _chart.setHandlePaths(gBrush); ...} 

2) Changed _chart. setHandlePaths = function (gBrush), for example, by removing gbrush.path :

  // gBrush.selectAll('.resize path').exit().remove(); 

3) Note / modified by _chart. resizeHandlePath = function (d) {...}.

d3.js file

1) Note / resize , for example:

mode: "move" //mode: "resize" ,

 var resize = g.selectAll(".resize").data(resizes[0], d3_identity); 

Using resizes [0] disables the rendering of brushes in the background, but can still re-expand an existing brush

2) Note / change 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(); Now the cursor is a "pointer" instead of "haircross", expanding the brush to full width.

c) d3_svg_brushCursor is disabled , the entire brush disappears

4) Changed the event pointer , as indicated here: https://developer.mozilla.org/en/docs/Web/CSS/pointer-events

5) console.log in different places to track various 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"); ... 

Two changes that seemed to come close to the desired result are in d3.js:

1) Using the dimensions [0] , disables the rendering of brushes on the background, but can still re-expand the existing brush

 var resize = g.selectAll(".resize").data(resizes[0], d3_identity); 

2) Removing the background of the brush changes the cursor to "pointer" instead of "haircross", expanding the brush to full width only when you click on the graph

 `background.exit().remove();` 

Any help would be greatly appreciated!

+5
source share
2 answers

This is from the accepted answer in Disable brush size d3 , as suggested by @altocumulus. I did not see @Dani's answer to this idea in particular, but I thought I would go and try, since I saw other people trying to do this in the past. (Perhaps in the dc.js users group .)

It looks a little twitching because d3.js will paint the brush to a new degree, and then after a moment we reset the degree that we want, but functionally it seems to do what we want.

In dc.js, a function that handles brush rounding, 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; }; 

Note that it follows the same pattern as Lars answer. Well, that sounds like rounding, doesn't it? Let it override.

First save the current number of hours when it will be set in the drop-down list:

 var graphSpan; function addHours(amountHours) { graphSpan = amountHours; // ... 

Then undo 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 installed, we add this amount to the beginning to get the end. If it is not installed, we allow the user to specify the width of the brush - you need to use graphSpan and the selection widget by default if you want this part to work automatically.

Well, let's say: it twitches very much , but it works:

twitchy fixed brush brush https://jsfiddle.net/gordonwoodhull/272xrsat/5/

EDIT: Get rid of the twitching! The problem was that dc.js set the brush size asynchronously after a while (in response to a 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; } 

brush size improvement https://jsfiddle.net/gordonwoodhull/272xrsat/9/

+1
source

What worked for me:

in d3:

disable change d3.selectAll('.brush>.handle').remove();

disable the d3.selectAll('.brush>.overlay').remove();

or in css:

disable the resize knob

 '.handle { pointer-events: none; }' 

disable crosshair

 '.overlay { pointer-events: none; }' 
0
source

Source: https://habr.com/ru/post/1261365/


All Articles