D3 Brush Custom Handles null selection visibility - d3.js

I am trying to figure out how to have custom brush handles highlight data in a range equal to a single value, which seems to result in a null selection.
Here the Plunkr I recreated on one of Mike Bostock's examples. It's in Angular 2/ionic, so if that's an issue, please go here to view his example's plain javascript. The primary thing I edited was commenting out where he hides the custom handles with css when there is a null selection.
if (s == null) {
//handle.attr("display", "none");
//circle.classed("active", false);
}
http://plnkr.co/edit/tRyhlJ
https://bl.ocks.org/mbostock/4349545
If you look in the plunkr example, you can see that if you click and let go the brush is still a perfect sphere, with the line where you clicked. Instead if disappearing, I want the brush handles to stay... and not cause errors when you click to expand the handles.
The error I am currently getting, and can't seem to find a workaround, is this:
How do I gracefully ignore this internal d3 error and continue on letting my selection expand?
I've tried all sorts of things like turning pointer-events off when it's in this state, and manually unhiding/resizing the default handles, to no avail. Every time, when I click the handles I get this error.

As far as I can tell, there's no "clean" way to deal with it. The reason is that a single click defines a range whose size is 0, which the brush considers an empty range (see source) and so it purposely nullifies the selection (see source).
That all means that unless you create your own version of d3-brush to do what you want, there's no way to have an empty selection that's not null nor a way to render a brush for an empty selection.
There's one workaround I can think of: when you detect an empty selection (where s == null) use brush.move to set the selection to something. That something would have to be a range whose size is not 0 (because if you make it 0 then d3, again, would consider that an empty selection and nullify it). To make a non-zero selection that looks like a zero-sized selection (which it has to be, because it's being defined by a single click event) you'd have to make it a tiny selection, eg [123, 123.0001]. Instead of 123, you need to know the mouse position of the click, which you can get using d3.mouse. Putting it all together, it looks like this:
if (s == null) {
var mousex = d3.mouse(this)[0]
gBrush.call(brush.move, [mousex, mousex+.001]);
}

Related

Tooltip issue in amchart v4 , not reload on pie chart slice

series.slices.template.events.on("over", function(ev) {
series.slices.template.tooltipHTML=showHtml(ev, series.name);
}, this);
Tooltip issue in amchart4: not reload on pie chart slice.
I am using custom tooltip like generating custom html on mouse hover. Everything is working but when I move cursor from one slice to another, the popup html is not refreshing. When I mouse out and then again mouse over the same slice, the popup html shows correct data.
I think the previous html data is cached somewhere. Please help me.
It could possibly help to see what showHtml is doing. But we'll make do without that.
There are a few problems with this code.
Code-wise, the most obvious is this line:
series.slices.template.tooltipHTML=showHtml(ev, series.name);
You're resetting the template's tooltipHTML instead of the actual slice's tooltipHTML.The template has applyOnClones as true by default so it will propagate to all the other slices, so if this worked it was by accident. If there's any slice-specific settings in showHtml that don't rely on data placeholders this will break tooltipHTML for the next slice that's hovered over.
The real issue, however, is the approach.
So long as tooltipHTML or tooltipText are set, a tooltip will appear on hover.
It's better to use an adapter for tooltipHTML in this case.
As a quick test to see which wins the race condition, the hover event or the tooltipText/HTML adapter, make a handler for each, and hover over a slice:
series.slices.template.events.on("over", function(){
console.log("hover");
});
// override tooltipText so tooltipHTML is actually used
series.slices.template.tooltipHTML = "something...";
series.slices.template.adapter.add("tooltipHTML", function(tooltipHTML) {
console.log("adapter");
return tooltipHTML;
});
// console:
// "adapter"
// "hover"
You'll find that the adapter triggers first, so by the time you hover, the tooltip is already on its way with its HTML and all.
So use an adapter, just be sure to adjust your showHtml function so its first argument takes target itself instead of event (it may not be necessary to have another argument with the tooltipHTML that's being modified because it will always be sent the original tooltipHTML unformatted string, so that could be referred to manually whether as a string or variable).
The adapter can look like this:
var originalTooltipHTML = "<strong>{country}: </strong>"
series.slices.template.tooltipHTML = originalTooltipHTML;
series.slices.template.adapter.add("tooltipHTML", function(tooltipHTML, target) {
// #2: If we had used an event, here you would work on the target itself, event.target, not the template.
// The showHtml might not even be needed, perhaps whatever it does can go in here instead.
return showHtml(target);
});
Here's a demo with all that thrown together:
https://codepen.io/team/amcharts/pen/a0122e572d27cf513a78384345cad3a6

Xamarin Forms - Why Is LineBreakMode TailTruncation Causing Word Wrap

In a Xamarin Forms project (C# code, not XAML), I have a some nested horizontal stacklayouts that look like this:
Notice there's a "Declined:" Label, then a quantity Label (4), and then a reason code Label ("Can't Find"). I have set the reason code Label to a LineBreakMode of LineBreakMode.TailTruncation. I would expect that when the label gets too long to fit on the line, it would truncate it with ellipses. It does. However, it doesn't do it gracefully - it causes things to be squished and to word wrap, like this:
I have set the "Declined:" Label to LineBreakMode.NoWrap, and you'll notice the last "d" in "Declined" is cut off". I haven't set any LineBreakMode on the "Ordered" and "Picked" Labels, and you'll notice those word wrap. Why is this happening, and how can I fix it?
Does it look normal again when you rotate the device or if you call ForceLayout() on the parent element to all of those nested StackLayouts?
I have noticed that sometimes I must do that to force a redraw or layout pass on certain devices (usually is it only needed on one platforms or another as opposed to all platforms).
If that doesn't work, I would suggest using Grid if that is possible in your situation. That is what I tend to do when I run into elements sitting on top of each other like this. I am not sure why it happens but Grid never fails me. Grid seems to be much more strict about spacing and does not let things bleed over like that

Does anyone know why an object would miss a property?

We have a script that export our Indesign documents to HTML and one of the routine is to export tables. In this script we go throught each Tables->Rows->Cells and evaluate some of the properties (i.e. bottomEdgeStrokeType, topEdgeStrokeType, etc...) and transport them to HTML.
Now yesterday we had problem converting one particular document because some cells were missing the "bottomEdgeStrokeType" property entirely. I've discovered this by outputting the properties of each cells and compare the faulty ones with the others.
This line bellow was trowing the error: "Invalid object for this request.".
var cellType = cell["bottomEdgeStrokeType"];
Now, to fix this I've wrapped this around a try catch block to handle the case when it's not there, but now what is puzzling me is how on earth can Extendscript instantiate an object with missing properties?
Indesign version: CS5.5
A property is not only 'undefined' if it cannot exist at all (such as asking for the parent text frame for a character in overset text), but InDesign's Javascript engine also fails to return a reasonably accurate result for multiple values.
If you ask for "the" point size of a paragraph, where this paragraph contains multiple sizes, poor ID does not consider to return something like CONSTANT.Mixed, or the first value only, or (what I might have preferred) an array of the values; it returns undefined instead.
So how can a single table cell have multiple bottom strokes? If the cell underneath it is split into multiple cells, and one has a "top" stroke but the other has not.
It's difficult to recommend an adequate solution. You could first test if the current cell is "merged" (as far as InDesign's internal table model is concerned) with columnSpan; and if so, iterate over the number of columns spanned and test the next row's cells for their top stroke, which in theory should match the bottom stroke of the cell above. (I find myself wondering if this is always true. ID's table model is ... weird. It's not entirely like a HTML table, despite the functional overlaps.)
If columnSpan is greater than 1 and equal to the number of cells immediately below the current one, you could test if all of their "top" values are the same and if so use that value. (I never tested this so ID's table model may simply fail because a cell is merged, regardless of same-values or not.)
One could attempt to flag this cell's next row to output "top" strokes as well -- but alternating top and bottom strokes may not align nicely in CSS, side to side. Perhaps it's best to translate only the first top stroke value to "the" bottom stroke property for your current cell, and fix up manually where needed (how?) or, a reasonable action, hope that no-one will ever notice it.

How to fix overlapping objects on the stage in AS3

I have a flash game where I have a picture designed to be the textbox for a prompt and textbox inside with the relevant text but the textbox is being hidden by the image. Anyone know how to make is so that the textbox is guaranteed to be on top or whatever I need to do to keep this from happening?
The other answer using setChildIndex will definitely work, however, I think a different design approach is really what you should be doing to remove the headache altogether.
For example in a game I might have different layers such as :
backgroundLayer
gameLayer
interfaceLayer
Those 3 Sprite layers would get added to the stage in that order. I would then add display objects to the appropriate layers. So anything I added to the backgroundLayer or gameLayer would ALWAYS be 'behind' my user interface on the interfaceLayer.
That allows you to not have to worry about the layering constantly. The answer with setChildIndex will fix the problem for that moment, but should something else be added to the container it will overlap your textbox, which is something I don't assume you want.
here's an example :
var backgroundLayer:Sprite = new Sprite;
var gameLayer:Sprite = new Sprite;
var interfaceLayer:Sprite = new Sprite;
addChild(backgroundLayer);
addChild(gameLayer);
addChild(interfaceLayer);
now, whatever you add to interfaceLayer, will ALWAYS be on top of objects you add to gameLayer or backgroundLayer.
So in the case of your text box, just add it to your interfaceLayer and any other objects you want behind it, you add to the gameLayer or backgroundLayer.
The order of adding display objects to display object containers effect their z-order, in other words the front to back order. The last added display object becomes the frontmost. So the child index of the children of a display object container is important for drawing of overlapped children.
If you put picture and text on the same DisplayObjectContainer such as a MovieClip:
Lets say your DisplayObjectContainer is mc.
And your textbox is txt
Please try this:
mc.setChildIndex(txt, mc.numChildren-1);

UITableView - setting cell contents based on index path

- (UITableViewCell *)tableView:... cellForRowAtIndexPath:... {
// init and sanity check
if (indexPath.row == 0) {
// make cell look like a section header
// easier and less complex than using a custom header view
NSLog(#"header");
// should prove that only four cells get the bg image
// and yet, almost every time the table is reloaded
// one more cell unexpectedly gets the background
// without putting another line in the debugger
} else {
// normal cells after row 0
// BUG: some of these are getting the row 0 background
NSLog(#"row");
// firing exactly the right number of times --
// once for each row with an index greater than 0
// so why are some of these cells getting the header bg?
// when these cells get the headers' contents
// they behave exactly as one would expect
// except that they should be the normal rows
}
// misc stuff, not causing problems
return cell;
}
Short of forcing the user to completely relaunch the app just to have different data dumped into the table, I can't figure out how to fix the bug.
The problem is less severe if I collapse every section (that is, empty the expandedSections set and reload, leaving only the pseudo-headers visible), but it doesn't go away.
Edit:
Initial load: screenshot
After reloading: screenshot
Links instead of images because it's an iPad app.
Using some dummy content for testing.
Is this any help? I know there needs to be more code for serious help, but I don't know what else to add, short of a link to the code for the entire view.
Have you tried setting a different cell identifier for the first cell and another one for the rest of them?
The tableView reuses the same cell type when creating new cells so it might get them mixed up. By using different cell identifiers for each type, it will know exactly when to use each cell.
It's probably related to the cell cache...something about setting the image for row == 0 and not clearing it otherwise...but with the limited amount of code you're showing it's hard to be more specific.

Resources