broken: ext-*series' tooltip inner property
Found: Ext.NET 7.0.0-preview4_2020-07-21.
Within a chart series block like this:
<ext-areaseries titles="IE,Chrome,Firefox,Safari,Opera" xfield="Date" yfield="IE,Chrome,Firefox,Safari,Opera">
<tooltip trackmouse="true">
<renderer handler="var browser = context.series.getTitle()[Ext.Array.indexOf(context.series.getYField(), context.field)]; toolTip.setHtml(browser + ' for ' + Ext.Date.format(record.get('Date'), 'M d') + ': ' + record.get(context.field) + '%');" />
</tooltip>
</ext-areaseries>
The inner property probably had its meaning different than Ext.NET, to keep the "pattern-of-things" throughout the syntax, and a first attempt to address the syntax would be:
<tooltip>
<ext-seriesTooltip trackMouse="true">
<renderer handler="var browser = context.series.getTitle()[Ext.Array.indexOf(context.series.getYField(), context.field)]; toolTip.setHtml(browser + ' for ' + Ext.Date.format(record.get('Date'), 'M d') + ': ' + record.get(context.field) + '%');" />
</ext-seriesTooltip>
</tooltip>
Which in turn, considering #1738, suggests renderer should be an inline property, like:
<tooltip>
<ext-seriesTooltip trackMouse="true" renderer="function?" />
<renderer handler="var browser = context.series.getTitle()[Ext.Array.indexOf(context.series.getYField(), context.field)]; toolTip.setHtml(browser + ' for ' + Ext.Date.format(record.get('Date'), 'M d') + ': ' + record.get(context.field) + '%');" />
</ext-seriesTooltip>
</tooltip>
It is then uncertain how to provide inline handlers like in the example above.
Note: The examples below will not necessarily have a Tooltip block within an ext-*Series one, and the Tooltip block might not have the Renderer inner tag.
WebForms examples matching [A-Za-z]+Series and Tooltip
- Chart > Area > Basic
- Chart > Area > Stacked
- Chart > Area > Stacked_100
- Chart > Bar > 3D
- Chart > Bar > Basic
- Chart > Bar > Stacked
- Chart > Bar > Stacked_100
- Chart > Column > Basic
- Chart > Column > Stacked
- Chart > Column > Stacked_100
- Chart > Combination > Binding_Tabs
- Chart > Combination > Custom_Theme
- Chart > Combination > Pareto
- Chart > Line > Basic
- Chart > Line > Markers
- Chart > Line > Mixed
- Chart > Misc > Captions
- Chart > Misc > Merge_Two_Charts
- Chart > Misc > Reload
- Chart > Misc > ToolTips
- Chart > Pie > Basic
- Chart > Radar > Basic
- Chart > Radar > Marked
- Combination_Samples > Applications > Word_Wrench
MVC examples matching [A-Za-z]+Series and Tooltip
- Chart > Area > Basic
- Chart > Area > Stacked
- Chart > Area > Stacked_100
- Chart > Bar > Basic
- Chart > Bar > Basic_3D
- Chart > Bar > Stacked
- Chart > Bar > Stacked_100
- Chart > Column > Basic
- Chart > Column > Stacked
- Chart > Column > Stacked_100
- Chart > Combination > Binding_Tabs
- Chart > Combination > Custom_Theme
- Chart > Misc > Captions
- Chart > Pie > Basic
- Desktop > Overview
Is it what was needed?
<tooltip>
<ext-seriesTooltip trackMouse="true" renderer="var browser = context.series.getTitle()[Ext.Array.indexOf(context.series.getYField(), context.field)]; toolTip.setHtml(browser + ' for ' + Ext.Date.format(record.get('Date'), 'M d') + ': ' + record.get(context.field) + '%');" />
</tooltip>
I'd say it would rather have a way to specify if we want to pass a function reference or a function body to be run. In some cases for other components we may even need to pass an inline function!
- Scenario 1:
<script>
var myFunction = function(a, b, c) { return a+b+c; };
</script>
then
<Tooltip trackmouse="true">
<Renderer Fn="myFunction" />
</Tooltip>
Resulting in
Tooltip: {
trackMouse: true,
renderer: myFunction
}
- Scenario 2: (no outside js script)
<Tooltip trackmouse="true">
<Renderer Handler="return a + b + c" />
</Tooltip>
Resulting in
Tooltip: {
trackMouse: true,
renderer: function(sprite, config, renderData, index) { return a + b +c; }
}
Note: the sprite, config, renderData, index function parameters are inferred from the documentation
Bottomline
Is then, by the syntax you suggested, that Ext.NET 7 should infer between function and handler depending on the contents?
It can auto detect. If renderer="myFunction" is specified - it'll recognize it as a Fn. Whereas the renderer="return a + b + c" will be recognized as a Handler, so it'll be wrapped with function() { ... } code.
There is still a way to control it explicitly through rendererModel:
<ext-seriesTooltip rendererModel=@(new JsFunction { Fn="myFunction" }) />
Anyways, I agree that we should consider supporting an inner element for explicit configuration though Tag Helpers.
Note: the
sprite, config, renderData, indexfunction parameters are inferred from the documentation
Function parameters are not currently supported for Properties/Configs. But they are supported for events, e.g. for the markup below:
<ext-button>
<listeners>
<focusEnter handler="alert('focusEnter');" />
</listeners>
</ext-button>
the following javascript will be generated (item, event, eOpts are added automatically):
Ext.create("Ext.button.Button", {
id: "ctl01",
listeners: {
focusenter: {
fn: function (item, event, eOpts) {
alert('focusEnter');
}
}
},
renderTo: "App.ctl01_Container"
});
The versatility of renderer="fn" and renderer="return a + b + c;" is nice, and I can't really think in a case where it would break, maybe if you have a function resolved at render time (renderer=myObject.myFunctionReturner()) which I don't know of actual case exploring it...
So if we have the possibility on the inner property and ability to discern between Fn="" and Handler="", I would go with that.
And the parameter inference for the Handler="" scenario is rather important, as the renderer usually passes the raw value we want to transform to whatever displayed value we want.
You showed great points, thanks for taking the time to clarify them!