-
Notifications
You must be signed in to change notification settings - Fork 9
Custom formatters
Custom formatters are implemented as static methods that accept a single argument of type object
and return a value of the appropriate type - string
for a String formatter, double?
for a Number formatter and Colour?
for a Colour formatter.
In general, code for a string formatter looks like the following:
public static string Format(object attribute)
{
//...
}
The code within the curly braces somehow converts the value of attribute
(which is an object
) into a string
. This can be done in multiple ways; if the attribute is expected to already be a string (e.g. because we are formatting the Name
attribute), converting it is as simple as using the following code:
public static string Format(object attribute)
{
return attribute as string;
}
If attribute
is a string
, this method returns its value; otherwise it returns null
. Alternatively, if the attribute is expected to be a Number (which translates to the double
C# type - such as the Length
attribute), the first step is to unbox it back into a double
:
public static string Format(object attribute)
{
if (attribute is double attributeValue)
{
//...
}
else
{
return null;
}
}
This checks if attribute
is actually a double
: if it is, it stores its value in a variable called attributeValue
; if it is not, it immediately returns null
. Once we have converted the attribute value into a double
, we can manipulate it before finally converting it into a string
:
public static string Format(object attribute)
{
if (attribute is double attributeValue)
{
attributeValue = attributeValue * 100;
return attributeValue.ToString();
}
else
{
return null;
}
}
This code multiplies the attribute value by 100 before returning its string representation. Of course, there are countless variations on this theme; one could check whether the attribute value is a valid number before returning it, or if it is greater than 0, and so on.
To get started in writing a custom formatter, it might be a good idea to try different settings in the formatter window, to see how they affect the generated code. It should then be clear which parts of the code need to be modified to change the results obtained.
Number formatters are similar to String formatters; they are implemented as a method with an argument of type object
and returning a value of type double?
. The ?
is important, because it allows formatters to return null
if the attribute value is invalid. The method signature for a Number formatter is the following:
public static double? Format(object attribute)
{
//...
}
If the attribute is expected to be of type Number (i.e. double
, like the Length
or Support
attributes), we can directly convert it:
public static double? Format(object attribute)
{
return attribute as double;
}
We could also manipulate the value, e.g.:
public static double? Format(object attribute)
{
return (attribute as double) * 4;
}
This code returns the value of the attribute multiplied by 4.
If the attribute is instead a string
, it needs to be unboxed first:
public static double? Format(object attribute)
{
if (attribute is string attributeValue)
{
//...
}
else
{
return null;
}
}
As in the case of the String formatter, this code attempts to unbox the attribute
into a string
variable called attributeValue
; if this does not succeed, the method returns null
. Otherwise, attributeValue
needs to be converted into a double
. This can be achieved e.g. by parsing the string value (which would for example convert the string "1.23"
into the number 1.23
):
public static double? Format(object attribute)
{
if (attribute is string attributeValue)
{
return double.Parse(attributeValue);
}
else
{
return null;
}
}
Again, fiddling with the default settings of the formatter is a good way of understanding which parts of the code need to be changed to achieve different results.
Colour formatters are similar to String and Number formatters; they are implemented as a method with an argument of type object
and returning a value of type Colour?
. The ?
is important, because it allows formatters to return null
if the attribute value is invalid. The method signature for a Colour formatter is the following:
public static Colour? Format(object attribute)
{
//...
}
If the attribute
is expected to be a string
, one approach could be to parse it as a CSS colour string:
public static Colour? Format(object attribute)
{
if (attribute is string colour)
{
return Colour.FromCSSString(colour);
}
else
{
return null;
}
}
This code attempts to convert the attribute
into a string
called colour
. If this succeeds, it interprets the string as a CSS colour and returns the resulting colour; otherwise it returns null
. This makes it possible to directly convert attribute values such as "red"
, "#FF0000"
, or "rgb(255, 0, 0)"
into Colour
s.
An alternative approach would be to return different colours depending on the value of the attribute. For example, the following code associates different colours to the attribute values "large"
, "medium"
and "small"
:
public static Colour? Format(object attribute)
{
if (attribute is string size)
{
switch (size)
{
case "large":
return Colours.Red;
case "medium":
return Colours.Green;
case "small":
return Colours.Blue;
}
}
else
{
return null;
}
}
Colour
objects can be initialised in multiple ways, including the Colour.FromRGB
and Colour.FromRGBA
methods (which create Colour
objects from RGB values), the Colour.FromCSSString
method (which creates the colour from a CSS colour string), and more. All methods to create colours are in the form of Colour.FromXXX
; therefore, if you start to type this in the code editor window, you can use the autocomplete feature to see a list of all the available possibilities.
In addition, the CSS named colours are defined in the Colours
static class and can be obtained (like in the code above) by using a syntax like Colours.Red
or Colours.CornflowerBlue
.
If the attribute is expected to be a double
, there are again multiple ways in which it could be converted into a Colour
; for example, the following code returns a red colour if the attribute value is lower than 0.5
, a yellow colour if it is between 0.5
and 0.95
and a green colour if it is greater than or equal to 0.95
:
public static Colour? Format(object attribute)
{
if (attribute is double support)
{
if (support < 0.5)
{
return Colour.FromRgb(255, 0, 0);
}
else if (support < 0.95)
{
return Colours.Yellow;
}
else // support >= 0.95
{
return Colours.FromCSSString("green");
}
}
else
{
return null;
}
}
You can fiddle with the settings for the default colour formatter to get additional ideas, e.g. on how to convert a number into a colour from a gradient.
- Home
- Introduction
-
Workload examples
- Drawing a tree highlighting support values
- Displaying character states on a tree
- Displaying BLAST scores
- Working with large trees from the command‐line interface
- Drawing taxon images
- Drawing an alignment with the tree
- Plotting the age distributions in a time‐calibrated tree
- Plotting multiple age distributions
- Plotting the results of a stochastic mapping analysis
- Creating a new tree
- Crop regions and output DPI
- Tree statistics
- Comparing trees
- Command‐line interface
- Developer's guide
- Glossary