qwt: how to add extra text in legend - legend

I have a QwtPlot with a couple of lines in it. It also has a legend.
Now apart from the description of the lines themself, I would like to add extra text describing the graph in general.
E.g. "line a: length of frog, line b: weight of frog" and then as an extra "outside temperature is 12C" (the temperature is then not drawn).

The description of QwtPlot shown in legend is QwtLegendData. Further in the QwtPlotItem doc (which is a superclass of all QwtPlots):
QwtLegendData is basically a list of QVariants that makes it possible to overload and reimplement legendData() to return almost any type of information, that is understood by the receiver that acts as the legend.
So everything that you need is to pull the existing "automated" legend from the plot and add one more QwtLegendData to it. It also needs a QVariant as a "key" to distinguish between Datas for each plot, but it can be really anything expectably different from the keys of real plots. Even default (empty) QVariant() will do, if you don't plan to add any more such extra texts.
QwtLegendData data;
data.setValue(QwtLegendData::Role::TitleRole, QVariant("Outside temperature is 12C"));
QList<QwtLegendData> list;
list << data;
QwtAbstractLegend* existingLegend = frogPlot.legend();
// "update" with a new key really means "insert"
existingLegend->updateLegend(QVariant("Temperature comment extra text"), list);

Related

How to incorporate keys or dataframe column names in plotly express custom hover text?

Lost as I can be on how to control hover text with embedded data.
Non-dataframe scenario
In one case, I am passing a list of dicts to a plotly express (scatter) plot, having the shape:
list[dict[str, float]]
and I would like the hover text for each point to include its key from the dict inside my own domain-specific phrasing for the hover text.
When not tampering with the hover text, the default hover text showing up includes the key following the string "variable", and the x and y values being called "index" and "value" accordingly there in the default hover text. Obviously the x value is just the index of the dict from the list for input shaped as in my input type.
But incorporating these values with names bearing the semantics of the data seems to pose a challenge, as including something like follows does not really plug in (by substitution) anything but the x and y values in the percent prefix bracelets:
fig.update(data=[{'hovertemplate': 'distance: %{y} (class %{variable})'}])
For example, %{variable} will show as just the string as is, it will not substitute this string with the value of what the default hover text calls "variable".
How would I incorporate the "variable" value, as called in the default hover text, in my own hover text specification?
I went through numerous documentation pages where this is accomplished via plotly's non-express api or other ways which didn't seem to work for me. It's in general elusive to adapt any of the dataframe based solutions to my dataframe-sidestepping case. I wonder if there's an idiomatic way.
DataFrame based scenario
In another case, switching to dataframe input, I still battle to get the desired column name be recognized as, I wander in the plurality of ways to handle hover text and data for plotly:
fig = px.scatter(df, x='x', y='distance', color='class')
fig.update(data=[{'hovertemplate': 'distance: %{y} class %{class}'}])
fig.show()
― %{class} in the above dataframe oriented approach, is obviously not the proper way to select the class column's value for the hover data. How would I bring in the value of the desired dataframe column name into the hover text?

Tabulator - formatting print and PDF output

I am a relatively new user of Tabulator so please forgive me if I am asking anything that, perhaps, should be obvious.
I have a Tabulator report that I am able to print and create as a PDF, but the report's formatting (as shown on the screen) is not used in either output.
For printing I have used printAsHtml and printStyled=true, but this doesn't produce a printout that matches what is on the screen. I have formatted number fields (with comma separators) and these are showing correctly, but the number columns should be right-aligned but all of the columns appear as left-aligned.
I am also using Tree View where the tree rows are coloured differently to the main table, but when I print the report with a tree open it colours the whole table with the tree colours and not just the tree.
For the PDF none of the Tabulator formatting is being used. I've looked for anything similar to the printStyled option, but I can't see anything. I've also looked at the autoTable option, but I am struggling to find what to use.
I want to format the print and PDF outputs so that they look as close to the screen representation as possible.
Is there anywhere I could look that would provide examples of how to achieve the above? The Tabulator documentation is very good, but the provided examples don't appear to explain what I am trying to do.
Perhaps there are there CSS classes that I am missing or even mis-using? I have tried including .tabulator-print-table in my CSS, but I am probably not using it correctly. I also couldn't find anything equivalent for producing PDFs. Some examples would help immensely.
Thank you in advance for any advice or assistance.
Formatting is deliberately not included in these, below i will outline why:
Downloaders
Downloaded files do not contain formatted data, only the raw data, this is because a lot of the formatters create visual elements (progress bar, star formatter etc) that cannot be replicated sensibly in downloaded files.
If you want to change the format of data in the download you will need to use an accessor, the accessorDownload option is the one you want to use in this case. The accessors transform the data as it is leaving the table.
For instance we could create an accessor that prepended "Mr " to the front of every name in a column:
var mrAccessor= function(value, data, type, params, column, row){
return "Mr " + value;
}
Assign it to a columns definition:
{title:"Name", field:"name", accessorDownload:mrAccessor}
Printing
Printing also does not include the formatters, this is because when you print a Tabulator table, the whole table is actually rebuilt as a standard HTML table, which allows the printer to work out how to layout everything across multiple pages with column headers etc. The downside of this is that it is only loosely styled like a Tabulator and so formatted contents generated inside Tabulator cells will likely break when added to a normal td element.
For this reason there is also a accessorPrint option that works in the same way as the download accessor but for printing.
If you want to use the same accessor for both occasions, you can assign the function once to the accessor option and it will be applied in both instances.
Checkout the Accessor Documentation for full details.

Blender: split object with a shape

I've got a flat object that I want to split in multiple pieces (background: I want to print it later, but the surface of my printer is not large enough). I've modeled a simple puzzle-shape:
I would like to use this shape to cut through my object, but if I use the boolean modifier, blender generates vertexes where the shape and the object intersects, but it won't cut the object since my shape got a thickness of 0:
I don't want to make my shape thicker, because otherwise it would delete something of my object...
You are able to separate the two sides of the object from each other, and then rejoin them afterwards if you need to. (This does include the use of the boolean modifier)
First, you should add the boolean modifier to the main mesh where you want it, with the 'difference' operation. Then in edit mode, as you explained before, the vertexes are created but there isn't the actual 'cut' that you were looking for.
I recreated the scenario with a plane intersecting a cube:
This is what it looks like in edit mode after having applied the boolean modifier:
Second what you can do is (after applying the boolean modifier) select the faces you want to be separated in edit mode. Then, pressing P (shortcut for separate, you can get to it by right clicking) click on 'selection' and you should have two separate objects. One of the objects will have what looks like a missing face: If you wanted two separate objects, then you just need to add a face on the object with the missing face and you can look no further. If you wanted separate parts of objects that are separate within edit mode (all together one object in object mode) then you can select the two objects and press crtl+j. Hope this helps somehwhat!
I have selected half of the cube that I want cut out (the selection does not include the face in the middle):
There are now two objects, completely seperated from each other:

Enumeration in the dialog box

My tableViewController with a list of items of various types will provide a button to show a modal dialog box. This dialog box (similar to alert view) will provide the user with an exclusive choice from a list of 6 options.
Based on what the user chooses and confirms, the list in the main tableview controller screen will be filtered down to only show items that match the selected type.
At the moment, I have those six types listed in a typedefed enum. So far so good.
However I also need to be able to populate my custom dialog box with six nsstrings whose names will match the types used in the enumeration.
How to reconciliate this enum with my requirement for a source of those strings, but in such a way that I would ensure some level of consistency between the two? I do not want to hardcode anything.
You need a helper method that returns a string for each enum value. This should be written to deal with possible localization. All of your data and event handling should be based on the enum value. The string should be used for display.
The helper method should take an enum value and use a switch statement to return the proper string.
I can think of a few:
Change the enum to a bunch of strings. This makes things a bit tedious if they need to be integers too (-[NSArray indexOfObject:]).
Make a C array of strings. This lets you use C99's handy syntax:
NSString * const names[] = {
[Foo] = #"Foo",
[Bar] = #"Bar",
};
Autogenerated code to do the above.
Caveats:
Both of these will make i18n rather painful. This might not be relevant if it's contract work that will only need to be in one language, but it's Bad Practice.
Using button indexes as keys works until you decide you need to remove buttons in the middle. String keys work much better in the general case (I wrote a UIAlertView/UIActionSheet wrapper that accept (key,title) pairs and returned the key instead of the button index).
I take your remark that you "do not want to hardcode anything" to mean that you don't want any string constants in your code. So:
You could simply assign the strings to your sheet's UI elements (perhaps check boxes, for example) and give those UI elements tag values that match your enumeration (something you could query as your sheet closes). This has the additional benefit that you can easily localize the sheet.
Or:
If you want to keep the strings separate from your sheet, you could create a .strings file (perhaps you could call it Enumeration.strings or some such) formatted something like this:
"001" = "string one";
"002" = "string two";
.
.
"010" = "string ten";
and you could then retrieve the strings using your enumeration values like this:
NSString *myString = NSLocalizedStringFromTable([NSString stringWithFormat:#"%03d", myEnumerationValue], #"Enumeration", #"");
but then you'd have to have a way of plugging the strings into your UI, keeping track of UI elements through IBOutlets. Note that I used three decimal places here; perhaps you could get by with two, or even one. Finally, you get the ability to localize as in the first suggestion.

How to use a single NSValueTransformer subclass to toggle the titles of multiple menu items

I would like to make some bindings that toggle item titles in a popup menu based on a single numerical value in a text field. Let me explain:
This is my UI:
I want my menu items to automatically adjust to singular or plural based on the number in the text field. For example, when I type "1" in the box, I want the menu items to be labeled "minute", "hour" and "day". When I type "4", I want the menu items to be labeled "minutes", "hours" and "days".
What I did to date:
I bound the three menu item's labels to the same key path as the text field's value.
I created an NSValueTransformer subclass to interpret the value in the text field and return singular or plural to be used as item titles.
I applied this value transformer to the three bindings.
The issue:
My value transformer can either return singular or plural but it can't set the appropriate string based on the menu item it's applied to.
It looks to me like a value transformer is generic and can't return different values for different destinations. That would mean that to have the three titles change automatically, I would need to have three different value transformers that return the appropriate string for each menu item. That doesn't seem optimal at all.
Ideally I would be able to combine a string stored in the destination menu item (let's say in the item's tag property) with an "s" in the value transformer when the text field's value is larger than one, or something similar that would enable me to use a single value transformer for all the menu items.
Is there something I missed? What would be an ideal solution?
Okay, this is probably not an ideal solution, but something you could consider: if you set your value transformers from your code (and not in IB), you could instantiate 3 different transformers of the same class. You could give your value transformer an ivar NSString *unit (and add something like [[MyValueTransformer alloc] initWithUnit:]) to allow each to return their own string, but you still have to write the value transformer's code only once.
(Also, if you're ever going to consider making your application localizable, simply appending an "s" to create the plurals is not going to work. You could of course add ivars for both NSString *singular and NSString *plural to do that.)
Edit: Wait, I just realized you can register value transformers! If you register them as MyValueTransformerHours and MyValueTransformerMinutes (by manually allocating and initializing them in your code), you can use them from Interface Builder. See also https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ValueTransformers/Concepts/Registration.html#//apple_ref/doc/uid/20002166-BAJEAIEE.