Difference between revisions of "Formulas"
(No difference)
|
Revision as of 06:36, 6 October 2010
Formulas will be a new feature in the upcoming Freeplane 1.3 (and in current testversions). Formulas are very similar to formulas in spreadsheet processors like Excel or OpenOffice Calc:
=2 + 3
Formulas, which are identified by the leading '=', are expressions that are evaluated for display. That is their result is displayed instead of the formula text. In case of =2 + 3 this would be 5. The formula itself (=2 + 3) is only visible in the editor.
Contents
Overview
Formulas can be defined in
- node texts
- attribute values
- notes
Formulas are evaluated as Groovy scripts. This fact defines the basic syntax of formulas. But although Groovy is a full-blown programming language simple things are very simple in Groovy like this:
= 3 * 2
gives 6,
= (3 * 2) + " times"
gives 6 times. Note that the space after the '=' is optional.
Now something more complex:
= children.sum{ it.text }
gives the concatenation of all child node texts and
= children.sum(0){ it.to.num }
sums over the numerical values of the child nodes.
Formulas have access to a read-only variant of the Scripting API, i.e. formulas may not change anything in a map. There are some minor extensions to the Groovy language for formulas to improve the ease of use, e.g. for simpler data type conversion.
References
Formulas have access to all nodes in the map by
- navigating the hierarchy for instance via =node.children, =node.parent or =node.map.root
- searching the map via find, e.g. =node.find{ it.text == 'sum'}.
- direct references to a specific node by id like ID_172581364.to.num. (This requires special editor support.)
Note that like in Excel you can easily create circular references if a node references itself (either directly or indirectly).
= parent.children.sum{ it.to.text }
The circular reference is obviously due to navigating back and forth in the hierarchy. Now an Example that more likely may occur to you (paste the next lines into a map):
= "count nodes above 10: " + node.find { it.to.num > 10 }.size() = 10 = 11
The result should be count nodes above 10: 1 but the find tries to evaluate itself (in it.to.num). This leads to this error:
Circular reference: The formula in node '= count nodes....' references itself.
To prevent that you should avoid formula evaluation in the argument to find like this:
= "count nodes matching '11': " + node.find { it.text == '11' }.size()
Note that many problems with circular references arise from using find. So my advice is: Avoid find if you don't need it.
When the map is changed...
Formulas are immediately updated when necessary. To reduce the overhead of formula evaluation care is taken not to evaluate more formulas than necessary. But Groovy as formula evaluation engine gives you very powerful tools that may break the formula depencency tracking in some rare cases. I can't give you an example currently but it must be possible.
Just in case the formula processor got confused somehow there's a function Tools > Formulas > Evaluate all that re-evaluate the whole map.
Note that properties and methods of a formula node (like children or text) are directly available to the formula, i.e. the leading "node." can be left out.
Editor support for formulas
In general every standard node text editor can be used for editing formulas. However these editors provide no special support for editing formulas. The following features will be available:
- Syntax highlighting
- GUI-Support for referencing other nodes
- GUI-Support for visualization of node references
Formatting
There will be predefined display formats, e.g. to round numbers or to make colors value-dependent. These won't be formula specific.
Security
Formulas will have very strict security limitations that can not be disabled via configuration.
Miscelleneous
Richtext nodes (in node texts and notes) are supported by stripping all HTML clutter from the text before evaluation but using plaintext is definitely preferable for formulas.
Borders: Formula nodes are marked with a green border. To remove it select the option Preferences... > Plugins > Don't mark formulas with a border.
Open issues
Please help to fix some open issues. Please leave your opinion on the discussion page or in the discussion forum.
= Plus operator for nodes
Given the following map:
= children.sum() 1 2
What should be the result of the formula? (Currently you'll get the error "no ... method ... NodeProxy.plus(NodeProxy) ... found")
- Should it be an error (like now)?
- Should it be "3"? (In this case NodeProxy.plus(NodeProxy) would be implemented as NodeProxy.to.object + NodeProxy.to.object)
- Should it be "12"? (In this case NodeProxy.plus(NodeProxy) would be implemented as NodeProxy.text + NodeProxy.text)
Implementation of functions available in spreadsheet processors?
Spreadsheet processors have a large number of functions that are not directly supported by Freeplane (see [ODF specification]). Of course many of these functions are not easily translatable from tabulars to mindmaps but one might strive to provide as many as possible to increase portability of existing formulas to Freeplane.
What do you think, do we need implementations for functions like NOW(), SECOND(), PPMT(), RRI(), COLUMNS(), etc., even if Groovy equivalents exist?
Limitations
The whole functionality as described above is not yet available. This is the roadmap for missing features.
To be implemented before/in 1.3
The following features will be added before 1.3 release:
- Formulas in attribute values
- Formulas in notes
- Strict security limitations for formulas that can not be disabled via configuration.
To be implemented after 1.3
Most of the following features will probably be implemented only after the 1.2 release:
- Readonly API. Note that formulas that change the state of the script, e.g. by invoking a setter method on nodes, attributes etc. will stop working without further notice. Please stick to the public, official API.
- Special editor support for editing formulas and references.
- Predefined display formats, e.g. to round numbers or to make colors value-dependent.
- References to nodes in other maps.