-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
brush resets to covering entire domain when zooming is enabled, after upgrade to D3 v6 #1772
Comments
Hi @ewaldman, thanks for the report! Brushing works okay in the main page as well as this example. Are you using any custom event handlers in your application? D3 changed the signature for event handlers so that the event is passed as the first argument instead of using a global, so pretty much all event handlers need to be changed. Otherwise, if you can provide a reproducible example, I'd be glad to look into it. |
Thank you for responding. However, I have another question. The event I am using is renderlet. Based on your answer above I added event , and this is the new function: this.timeLineChart.on('renderlet', (event, chart) => { However, google chrome is giving errors. Uncaught TypeError: Cannot read property 'select' of undefined Any tips ? Thank you. |
On further investigation , it seems that my first way of the function was right. this.timeLineChart.on('renderlet', ( chart) => { 'renderlet' is the event name, and the listener function is the second param. However, doing it that way, the brushes do not work in the time line. Could it be that using the latest D3 the brushes only work in bar chart and not in line chart? The examples you pointed me to (above) are both bar charts. Please advise. Thank you. |
Thanks for following up, @ewaldman. It is only DOM events that have the signature changed, like brush events, mouse events, keyboard, etc. dc.js chart events are unaffected and still take the arguments documented in the BaseMixin.on examples. The brush is working in the range series example. I also tried changing the fluctuation chart on the main page to a line chart and that worked. (I just needed to disable some of the bar-specific options.) I guess I would need a running example (like a jsfiddle, codepen, observable, or bl.ock - whatever you are comfortable with) in order to see what is going wrong with your code. |
Hi. this.timeLineChart.on('renderlet', (chart) => { When that code is there , the brushes don't filter properly. When I take out that code - and leave the rest - the brushes do work. Any tips? Do we even need that preserveAspectRatio code for our purpose? Thank you. |
Hmm, I guess you must be doing some kind of automatic resizing when the container resizes. Are you using the built-in useViewBoxResizing or is this something homemade? Personally I don't like Here is the latest explainer of this technique. Since I don't like |
Yesterday we thought that the issue is a 'rendlet' problem. However, today we noticed that even when commenting out rendlet code the brushes don't work in a timeline. (Don't know why I thought it did work yesterday). The package.json file we are using has this config "dependencies": { You mentioned earlier that the brushes did work in your code. Can you please check using the above configuration? Thank you |
Hi. Here is the code we are using (obfuscated a bit to protect the innocent....). Perhaps you can tell what we need to do to fix it so that brushes should work. let data = [
{name: "joe", timeObserved: 1596819575959},
{ name: "jack", timeObserved: 1596819575959},
{ name: "jim", timeObserved: 1596819576000},
{ name: "tom", timeObserved: 1596819576000},
{ name: "john", timeObserved: 1596819576000},
{ name: "jill", timeObserved: 1596819575949},
{ name: "craig", timeObserved: 1596819580801},
{ name: "norbert", timeObserved: 1596819575959},
{ name: "donald", timeObserved: 1596819575949}
];
let cf = crossfilter(data);
this.timeLineChart = dc.lineChart('#timeLine');
this.dateDim = cf.dimension((d) => {
return d3.timeSecond(new Date(d.timeObserved));
});
this.group = this.dateDim.group().reduceSum((d) => 1);
let minDate = d3.min(this.group.all(), (kv) => {
return kv.key;
});
let maxDate = d3.max(this.group.all(), (kv) => {
return kv.key;
});
let min = 0;
let max = 20;
this.timeLineChart
.width(470).height(300)
.dimension(this.dateDim)
.group(this.group)
.curve(d3.curveMonotoneX)
.renderArea(true)
.mouseZoomable(true)
.elasticY(true)
.yAxisPadding(.1)
.elasticX(true)
.x(d3.scaleTime().domain([minDate, maxDate]))
.xUnits(d3.timeWeek.range)
.yAxis()
.tickValues(d3.range(min > 0 ? min - 1 : min, max + 1));
this.timeLineChart.yAxisMin = function() {
return 0;
};
dc.renderAll(); |
Thanks for the reproducible example! I should have picked up earlier that you are using a time scale. I had not tested that, and it doesn't look like we currently have an example covering brushing a time-scaled line chart. I will look into it. |
I did some testing and there is an erroneous zoom event sent after brushing is done, the next time the mouse is moved. A temporary workaround could be to disable You could say that there is an inherent incompatibility between That said, it seems strange that we should get a zoom event when we haven't zoomed, so it's still a bug. |
I can reproduce this on the fluctuation chart as well if |
We took out mouseZoomable and now the brush does indeed work. Thank you so much for all your help. |
Sure, you are subscribed to this ticket, so you will see when we close it. However, as I pointed out above, The behavior is awkward and I don't recommend using these features together. |
We have a follow up question. We ripped out our home grown 'renderlet' code and started using useViewBoxResizing .
The code for sizeSvg is in base-mixin.js. It seems to be failing in selection in D3 when calling this._svg.attr('viewBox') sizeSvg () {
if (this._svg) {
if (!this._useViewBoxResizing) {
this._svg
.attr('width', this.width())
.attr('height', this.height());
} else if (!this._svg.attr('viewBox')) {
this._svg
.attr('viewBox', `0 0 ${this.width()} ${this.height()}`);
}
}
} What can we do for this? |
The error indicates that A couple of conditions could cause this:
Often dc.js will just do nothing in these cases, but it's not guaranteed and sometimes it will crash. |
Our test case runs in a "headless chrome". This probably causes it to call redraw before rendering. As an aside, just a suggestion: The code above in sizeSvg is:
Why not add another part to the "if" statement: Thank you |
I don’t see why headless chrome would cause this. We use headless chrome for testing, and it still renders everything okay. It’s a fully functional browser; it just isn’t connected to any display. The error indicates that something in your code is not doing what you expect. So, sure, we could work around the error, but it’s very likely that you have a bug. I don’t see a lot of profit in making sure that operations succeed when the chart is in an inconsistent state. The most likely issue is the selector being wrong. Please check that Another common error is constructing the chart but never initializing it. |
Regarding the crash when we do testing - see above: To recap, dc.renderAll does lots of work, and part of it is a call to sizeSvg. In there the code calls
The code in attr.js does the following:
Following the code we see that the arguments dc passes in is indded less than 2 , - Question: What can we do about that? When running the code in real time, the code works well. But by jasmin testing it crashes as above. Our code merely calls dc.renderAll. That call causes this entire domino effect. Any tips, ideas? Thank you |
Thanks @ewaldman. As I said above, your charts are in an inconsistent state. There is no reason in normal operation why In particular, your selector is probably wrong when you initialize the chart. Take a look at Lines 525 to 542 in df993a6
See how Most likely, the selector passed to the chart contructor was wrong, so I reproduced the error in this fiddle. Note the typo in the selector passed to the chart constructor, var chart = new dc.BarChart("#testf"); when My guess is that you have a selector which is not selecting anything, so your test was previously "running in a vacuum" and is now crashing. |
Hi.
I am using DC version 4.2.0. I upgraded my D3 to 6.2.0 and now the brush on my LineChart does not work.
When dragging the brush it does indeed filter out the other charts, however when releasing the brush it snaps back and nothing is filtered out. Also, after releasing the brush, the chart continuously redraws itself. When I moved back to D3 version 5.16.0 it works like a charm.
The text was updated successfully, but these errors were encountered: