Ext.NET icon indicating copy to clipboard operation
Ext.NET copied to clipboard

broken: ext-*series' tooltip inner property

Open fabriciomurta opened this issue 5 years ago • 5 comments

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

  1. Chart > Area > Basic
  2. Chart > Area > Stacked
  3. Chart > Area > Stacked_100
  4. Chart > Bar > 3D
  5. Chart > Bar > Basic
  6. Chart > Bar > Stacked
  7. Chart > Bar > Stacked_100
  8. Chart > Column > Basic
  9. Chart > Column > Stacked
  10. Chart > Column > Stacked_100
  11. Chart > Combination > Binding_Tabs
  12. Chart > Combination > Custom_Theme
  13. Chart > Combination > Pareto
  14. Chart > Line > Basic
  15. Chart > Line > Markers
  16. Chart > Line > Mixed
  17. Chart > Misc > Captions
  18. Chart > Misc > Merge_Two_Charts
  19. Chart > Misc > Reload
  20. Chart > Misc > ToolTips
  21. Chart > Pie > Basic
  22. Chart > Radar > Basic
  23. Chart > Radar > Marked
  24. Combination_Samples > Applications > Word_Wrench

MVC examples matching [A-Za-z]+Series and Tooltip

  1. Chart > Area > Basic
  2. Chart > Area > Stacked
  3. Chart > Area > Stacked_100
  4. Chart > Bar > Basic
  5. Chart > Bar > Basic_3D
  6. Chart > Bar > Stacked
  7. Chart > Bar > Stacked_100
  8. Chart > Column > Basic
  9. Chart > Column > Stacked
  10. Chart > Column > Stacked_100
  11. Chart > Combination > Binding_Tabs
  12. Chart > Combination > Custom_Theme
  13. Chart > Misc > Captions
  14. Chart > Pie > Basic
  15. Desktop > Overview

fabriciomurta avatar Jul 21 '20 19:07 fabriciomurta

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>

AndreyChechel avatar Jul 21 '20 19:07 AndreyChechel

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?

fabriciomurta avatar Jul 21 '20 20:07 fabriciomurta

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.

AndreyChechel avatar Jul 21 '20 20:07 AndreyChechel

Note: the sprite, config, renderData, index function 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"
});

AndreyChechel avatar Jul 21 '20 20:07 AndreyChechel

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!

fabriciomurta avatar Jul 21 '20 21:07 fabriciomurta