source: main/trunk/ibisph-view/src/main/webapp/xslt/json/Kendo.xslt @ 25122

Last change on this file since 25122 was 25122, checked in by GarthBraithwaite_STG, 2 months ago

view - updated dataviz grid code and css.

File size: 33.1 KB
Line 
1<?xml version="1.0" encoding="ISO-8859-1"?>
2
3<xsl:stylesheet version="3.0" 
4        xmlns:xsl ="http://www.w3.org/1999/XSL/Transform" 
5        xmlns:xs  ="http://www.w3.org/2001/XMLSchema"
6        xmlns:ibis="http://www.ibisph.org"
7
8        exclude-result-prefixes="ibis xs xsl"
9>
10
11        <ibis:doc>
12                <name>json/Kendo</name>
13                <summary>Core Kendo grid, charts, datasource json templates</summary>
14                <description>
15                        Provides an XSLT API of kendo related templates used to instantiate
16                        Kendo javascript widgets.  Code called primarily by DataViz code.
17
18                        1) KENDO DATASOURCE--------------:
19                        - records json data array js variable
20                        - dimensions JSON field names - ser, cat, const DIMENSION NAMEs v3 dims are not
21                                1:1, they're combined so need to standardize their name but have a unique
22                                value to work properly.
23                        - measure(S) JSON field - complete list name, title (formatted value), sort order etc.
24                        - grouping field(s)  - just series.  Constant will be via filtering sorting field(s)
25
26                        2) KENDO GRID--------------:
27                        - kendo data source js variable
28                        - dimension columns: series, cat, constant - column titles (which are CSV if
29                                mult dims for a given column?  Kendo DS field names for all to be displayed.   
30                        - actual hidden series sort order so it's not 100% alpha?  What about category sort order?
31                        - all the assoc measure fields and titles - like LCL, numer, denom, label, notes etc.
32                                also needs the XSLT format patterns.
33
34                        3) KENDO CHART--------------:
35                        - kendo data source js variable
36                        - chart title - main top title
37                        - series title - title that is over the series legend
38                        - category title - x axis title
39                        - value title - y axis title
40                </description>
41        </ibis:doc>
42
43
44        <xsl:param name="Kendo.emptyConfigurationName" select="'_empty'" ibis:doc="name to be used for JSON file when no config name"/>
45
46        <xsl:param name="Kendo.jsonFilePath"          select="ibis:getContentPath('json/kendo/')"/>
47        <xsl:param name="Kendo.baseGridJSONFilename"  select="'_BaseGrid.json'"/>
48        <xsl:param name="Kendo.baseChartJSONFilename" select="'_BaseChart.json'"/>
49
50        <xsl:param name="Kendo.defaultErrorLowFieldName"  select="'LowerConfidenceLimit'"/>
51        <xsl:param name="Kendo.defaultErrorHighFieldName" select="'UpperConfidenceLimit'"/>
52
53        <xsl:param name="Kendo.noteColumnTitle"    select="'Notes'"/>
54        <xsl:param name="Kendo.labelColumnTitle"   select="'Label'"/>
55        <xsl:param name="Kendo.valueAttributeColumnTitle" select="'Footnotes'"/>
56        <xsl:param name="Kendo.gridFooterRowTitle" select="'Overall'"/>
57
58        <xsl:param name="Kendo.missingValueReplacementValue" select="'null'"/>
59
60
61        <xsl:param name="Kendo.gridLockColumns"    select="false"
62                ibis:doc="true = sets the locked of the main cat/series/const/measure
63                        grid colums.  If only set locked on the last main column then that
64                        column is listed first with all other columns scrollable even though
65                        some of those columns are listed before.  As such if true all of the
66                        main columns are locked.  lockable is true by default.
67                "
68        />
69        <xsl:param name="Kendo.gridColumnWidth"    select="150"
70                ibis:doc="Controls the main cat/ser/con/measure/note column size (px).
71                        If ibis option set 0 = auto Kendo size else ibis code will not process
72                        and uses set value.
73                "
74        />   
75        <xsl:param name="Kendo.gridAVColumnWidth"  select="120"
76                ibis:doc="Same as Kendo.gridColumnWidth but applies to ancillary value columms."
77        /> 
78        <!-- GRID COLUMN WIDTH NOTES:
79                - if one column width is not specified then grid widths will be somewhat
80                        set via code and will result in smaller table.  If both set to 0 or
81                        both specified then grid will be full size or larger with expand button. 
82                - Even if setting the width or using the auto size these are still html
83                        tables and subject to the browser.
84        -->
85
86
87        <xsl:template name="Kendo.dataSourceConstructorJSON"
88                ibis:doc="
89                        Template that produces a Kendo Datasource javascript JSON structure.
90                        The datasource consists of defining the data array's 'fields' along
91                        with specifying the fields to be used for grouping and sorting.  This
92                        XSLT code uses dimension and measure NAME type elements as the base
93                        name then combined with hard coded suffixes to generate the associated
94                        field names which include actual dimension name/value, xxxTitle,
95                        xxxSortOrder values, and in the case of the measures numeric value,
96                        formatted value, LCL, UCL, numer, denom, label, and note fields.
97
98                        Server side stuff needs to be turned off (which is the default).
99                        ,serverSorting:   false
100                        ,serverPaging:    false
101                        ,serverFiltering: false
102                        If set then client settings are not used e.g. filtering MUST be false
103                        otherwise the client filtering has no effect.  Can't sort the grid etc.
104
105                        SOME GUYS NOTES:
106                        You can't do the .Sum() or .Select() parts. You need to create a model (class) that does this for you so that
107                        you simply return model.PaymentsSum which has either already been calculated or is calculated in this property
108                        of the model. Don't be discouraged this is the first problem everyone has. Esentially for all the Kendo controls
109                        you need to pass them flat models (except for TreeView). When these flat models are constructed though you have
110                        access to the full object graph of the database object you are referencing. It ends up this is the way you want
111                        to do most all of MVC so you can use DataAnnotations and put your heavy lifting in the models. I hope I have
112                        helped, Kendo has some quirks but I have been very happy with it on some really large high profile projects             
113                "
114        >
115                <xsl:param name="datasetRecordsJSONJavascriptVariableName"
116                        ibis:doc="Actual dataset records JSON array or the name of the js
117                                variable that points to a dataset record JSON array. 
118                        "
119                />
120
121                <xsl:param name="recordDimensionFields"         
122                        ibis:doc="Data records dimensions struct of: RECORD_DIMENSION_FIELD/
123                                NAME, TITLE, DIMENSION_USAGE, DIMENSION_NAMES, and
124                                DIMENSION_VALUES_COUNT elements.  The DIMENSION_USAGE is a
125                                generic value like series, category, constant.  The NAME is
126                                typically the same value as usage but camel cased.  It does
127                                not matter to the Kendo code - it just needs to match the JSON
128                                data array (that was built by the XSLT). 
129
130                                Note that the NAME provides the base of other related field
131                                names.  The record array includes the actual xxx name field,
132                                the xxx'Title', and the xxx'SortOrder' fields that were built
133                                when creating the array. 
134                        "
135                />
136                <xsl:param name="recordAncillaryValueFields" 
137                        ibis:doc="Analogous to the dimension struct - but represents the data
138                                array's other associated value field(s).  The AV struct is of
139                                the form:
140                                RECORD_ANCILLARY_VALUE_FIELD
141                                        NAME - complete data array/datasource fieldname
142                                        TITLE
143                                        XSLT_FORMAT_PATTERN 
144                                        JAVASCRIPT_FORMAT_PATTERN
145       
146                                Note that the NAME element value serves as the base field name
147                                for the assoc formatted value xxxTitle fields etc.
148                                These AV fields are the dependent, related measure field names
149                                like: numer, denom, LCL, UCL, label, and note fields. 
150                        "
151                />
152                <xsl:param name="measureValueType"/>
153
154                <xsl:param name="kendoDatasourceSortOrderFieldNames" 
155                        ibis:doc="Optional, complete/actual Kendo datasource field name(s) to
156                                sort by.  Can be a xxxSortOrder, xxxTitle, dimension field name etc. 
157                                This is used by/defines the grid's/chart's default sorting.  If
158                                the 3 way Kendo sorting is enabled then the user can sort asc/dsc
159                                on any column with the 3rd click cycling the grid's column sorting
160                                to the initial order e.g. reverting to the default sorting field. 
161                                Like the grouping field name(s) this value must be complete/specific.
162                        "
163                />
164<xsl:text>{</xsl:text>
165        "data":  <xsl:value-of select="$datasetRecordsJSONJavascriptVariableName"/>
166
167<!-- GARTH TODO:
168        GeoStats = execute first thing on load before creating chart or map.
169        sets the datasource's PEER GROUP field
170        uses the determinent values to set each PEER GROUP's TITLE e.g. legend value
171       
172        Need to have the map's classes used if map is specified because they likely
173        could have different groupings per map.  NM only has HLS, (2) static Ranks
174       
175        EPHT only has HLS and jenks
176       
177                ,"PERCENTAGE-WORKS": ",##0.0'%'"
178                ,"Garth": "$###,##0"
179-->
180        ,"formatPattern":
181        {
182                "measure": "<xsl:sequence select="$measureValueType/JAVASCRIPT_FORMAT_PATTERN"/>"
183                <xsl:for-each select="$recordAncillaryValueFields/RECORD_ANCILLARY_VALUE_FIELD">
184                ,"<xsl:value-of select="NAME"/>": "<xsl:value-of select="JAVASCRIPT_FORMAT_PATTERN"/>"
185                </xsl:for-each>
186        }
187<!-- probably should do this as a prototype on the data source option?
188 
189        ,"getFormattedNumber": function(number, patternName)
190        {
191                var name    = patternName ? patternName : "measure";
192                var pattern = this.options.formatPattern[name];
193                if(pattern) return(this.toString(number, pattern);
194console.error('~~~~~~~~~kendo .getFormattedValue no pattern match.  number: " +number+ ", patternName: " +patternName+ ", lookup name: " +name);
195                return(number);
196        }
197-->
198
199        ,"schema":
200        {
201                "model":
202                {
203                        "id": "rowID"
204                        ,"fields":
205                        {
206                                "rowID":         { type: "string", editable: false }
207                <xsl:for-each select="$recordDimensionFields/RECORD_DIMENSION_FIELD[DIMENSION_VALUES_COUNT != 0]">
208                                ,"<xsl:value-of select="NAME"/>":          { type: "string" }
209                                ,"<xsl:value-of select="NAME"/>Title":     { type: "string" }
210                                ,"<xsl:value-of select="NAME"/>SortOrder": { type: "number" }
211                </xsl:for-each>
212                                ,"MeasureValue":      { type: "number" }
213                                ,"MeasureValueTitle": { type: "string" }
214                                ,"Label":        { type: "string" }
215                                ,"Note":         { type: "string" }
216                                ,"ValueAttributeName":    { type: "string" }
217                <xsl:for-each select="$recordAncillaryValueFields/RECORD_ANCILLARY_VALUE_FIELD">
218                                ,"<xsl:value-of select="NAME"/>":          { type: "number" }
219                                ,"<xsl:value-of select="NAME"/>Title":     { type: "string" }<xsl:text/>
220                </xsl:for-each><xsl:text/>
221                        }
222                }
223        }<xsl:text/>
224
225        <xsl:if test="1 lt number($recordDimensionFields/RECORD_DIMENSION_FIELD[DIMENSION_USAGE='series']/DIMENSION_VALUES_COUNT)">
226        ,"group":
227        [
228                {field: "<xsl:value-of select="$recordDimensionFields/RECORD_DIMENSION_FIELD[DIMENSION_USAGE='series']/NAME"/>SortOrder"}
229        ]
230        </xsl:if>
231        ,"sort":
232        [
233                {"field": "<xsl:value-of select="$recordDimensionFields/RECORD_DIMENSION_FIELD[DIMENSION_USAGE='category']/NAME"/>SortOrder", dir: "asc"}<xsl:text/>
234        <xsl:if test="0 != $recordDimensionFields/RECORD_DIMENSION_FIELD[DIMENSION_USAGE='constant']/DIMENSION_VALUES_COUNT">
235                ,{"field": "<xsl:value-of select="$recordDimensionFields/RECORD_DIMENSION_FIELD[DIMENSION_USAGE='constant']/NAME"/>SortOrder", dir: "asc"}<xsl:text/>
236        </xsl:if>
237        ]<xsl:text/>
238}<xsl:text/>
239        </xsl:template>
240
241
242
243        <xsl:template name="Kendo.namedConfigurationJSON" ibis:doc="Returns the named grid specific JSON options from the XML config file.">
244                <xsl:param name="configurationName"/>
245                <xsl:variable name="configurationName" select="if(0 = string-length($configurationName)) then $Kendo.emptyConfigurationName else $configurationName"/>
246                <xsl:copy-of select="unparsed-text(concat($Kendo.jsonFilePath, $configurationName, '.json'))"/>
247        </xsl:template>
248        <xsl:template name="Kendo.baseGridJSON" ibis:doc="Returns the base/core grid JSON.">
249                <xsl:copy-of select="unparsed-text(concat($Kendo.jsonFilePath, $Kendo.baseGridJSONFilename))"/>
250        </xsl:template>
251        <xsl:template name="Kendo.baseChartJSON" ibis:doc="Returns the base/core chart JSON.">
252                <xsl:copy-of select="unparsed-text(concat($Kendo.jsonFilePath, $Kendo.baseChartJSONFilename))"/>
253        </xsl:template>
254
255
256
257        <xsl:template name="Kendo.requestGridJSON" 
258                ibis:doc="Builds the request specific Kendo Grid JSON options.  This sets
259                        each column's title field name/template, header/footer/value template,
260                        sort comparison func. and any css attributes for the column formatting.
261
262                        NOTES: Field names are datasource field names.  In some instances
263                        fields like v3 IPVs dimension names are generically named series and
264                        category (due to multiple dataset dims being used for a given ser,
265                        cat, or constant dim).  For QMs names are actual dimension names. 
266                        For the measure fields these are based off the actual measure name.
267
268                        See SVN 7526, 2/2/2015 for template and formatting test code.
269                "
270        >
271                <xsl:param name="kendoDataSourceJavascriptVariableName" select="'kendoDataSource'"/>
272                <xsl:param name="recordDimensionFields"         
273                        ibis:doc="Data records JSON dimensions struct of:
274                                RECORD_DIMENSION_FIELD/NAME, TITLE, DIMENSION_NAMES, DIMENSION_VALUES_COUNT
275                                elements with the NAME value typically being the IBIS-Q dimension
276                                NAMEs or for IPs a generic value like SERIES, CATEGORY, CONSTANT. 
277                                It does not matter to the Kendo code - it just needs to match
278                                the JSON data array (that was built by the XSLT).
279                        "
280                />
281                <xsl:param name="recordAncillaryValueFields" ibis:doc="ancillary values struct."/>
282                <xsl:param name="measure" ibis:doc="measure info - NOT the measure value."/>
283                <xsl:param name="measureTitle" select="$measure/TITLE"/>
284
285                <xsl:param name="datasetRecordTotalValues"  ibis:doc="total values - typically from query result."/>
286
287                <xsl:param name="showNoteColumn"  select="false()"/>
288                <xsl:param name="showLabelColumn" select="false()"/>
289                <xsl:param name="showValueAttributeColumn" select="false()"/>
290                <xsl:param name="showFooterRow"   select="($datasetRecordTotalValues instance of node()) and (0 != count($datasetRecordTotalValues/*))"/>
291
292                <xsl:param name="seriesDimensionField"   select="$recordDimensionFields/RECORD_DIMENSION_FIELD[DIMENSION_USAGE='series']"/>
293                <xsl:param name="categoryDimensionField" select="$recordDimensionFields/RECORD_DIMENSION_FIELD[DIMENSION_USAGE='category']"/>
294                <xsl:param name="constantDimensionField" select="$recordDimensionFields/RECORD_DIMENSION_FIELD[DIMENSION_USAGE='constant']"/>
295
296                <xsl:param name="baseExportFilename" select="'export'"/>
297
298<xsl:text>{</xsl:text>
299    "dataSource": <xsl:value-of select="$kendoDataSourceJavascriptVariableName"/>
300        ,"columns":
301        [<xsl:text/>
302                <xsl:if test="1 lt number($seriesDimensionField/DIMENSION_VALUES_COUNT)">
303                {
304                        "field":  "<xsl:value-of select="$seriesDimensionField/NAME"/>SortOrder"
305                        ,"title": "<xsl:value-of select="$seriesDimensionField/TITLE"/> Sort Order"     
306                        ,"hidden": true
307                        ,"locked": <xsl:value-of select="$Kendo.gridLockColumns"/>
308                        <xsl:if test="0 != $Kendo.gridColumnWidth">,"width": <xsl:value-of select="$Kendo.gridColumnWidth"/></xsl:if>
309                        ,"groupHeaderTemplate": "#=items[0].SeriesTitle#"
310                }
311                ,{
312                        "field":  "<xsl:value-of select="$seriesDimensionField/NAME"/>Title"
313                        ,"title": "<xsl:value-of select="$seriesDimensionField/TITLE"/>"       
314                        ,"attributes": {"class": "SeriesColumn Dimension"}             
315                        ,"sortable": false
316                        ,"locked": <xsl:value-of select="$Kendo.gridLockColumns"/>
317                        <xsl:if test="0 != $Kendo.gridColumnWidth">,"width": <xsl:value-of select="$Kendo.gridColumnWidth"/></xsl:if>
318                        <xsl:if test="$showFooterRow">,"footerTemplate": "<div><xsl:value-of select="$Kendo.gridFooterRowTitle"/></div>"</xsl:if>
319                }
320                ,
321                </xsl:if>
322                {
323                        "field":  "<xsl:value-of select="$categoryDimensionField/NAME"/>Title"
324                        ,"title": "<xsl:value-of select="$categoryDimensionField/TITLE"/>"     
325                        ,"attributes": {"class": "Dimension"}           
326                        ,"locked": <xsl:value-of select="$Kendo.gridLockColumns"/>
327                        <xsl:if test="0 != $Kendo.gridColumnWidth">,"width": <xsl:value-of select="$Kendo.gridColumnWidth"/></xsl:if>
328                        <xsl:if test="$showFooterRow and (2 gt number($seriesDimensionField/DIMENSION_VALUES_COUNT))">,"footerTemplate": "<xsl:value-of select="$Kendo.gridFooterRowTitle"/>"</xsl:if>
329                }<xsl:text/>
330                ,{
331                        "field":  "<xsl:value-of select="$categoryDimensionField/NAME"/>SortOrder"
332                        ,"title": "<xsl:value-of select="$categoryDimensionField/TITLE"/> Sort Order"   
333                        ,"hidden": true
334                        ,"locked": <xsl:value-of select="$Kendo.gridLockColumns"/>
335                        <xsl:if test="0 != $Kendo.gridColumnWidth">,"width": <xsl:value-of select="$Kendo.gridColumnWidth"/></xsl:if>
336                        ,"groupHeaderTemplate": "#=items[0].CategoryTitle#"
337                }
338
339                <xsl:if test="1 lt number($constantDimensionField/DIMENSION_VALUES_COUNT)">
340                ,{
341                        "field":  "<xsl:value-of select="$constantDimensionField/NAME"/>Title"
342                        ,"title": "<xsl:value-of select="$constantDimensionField/TITLE"/>"     
343                        ,"attributes": {"class": "Dimension"}
344                        <xsl:if test="0 != $Kendo.gridColumnWidth">,"width": <xsl:value-of select="$Kendo.gridColumnWidth"/></xsl:if>
345                }
346                </xsl:if>
347                <xsl:text/>
348                ,{
349                        "field": "MeasureValueTitle"
350                        ,"title": "<xsl:value-of select="$measureTitle"/>"
351                        ,"attributes": {"class": "Value"}
352                        ,"locked": <xsl:value-of select="$Kendo.gridLockColumns"/>
353                        <xsl:if test="0 != $Kendo.gridColumnWidth">,"width": <xsl:value-of select="$Kendo.gridColumnWidth"/></xsl:if>
354                        ,"template": "#=MeasureValueTitle#"
355                        ,"sortable":
356                        {
357                                "compare": function (a, b)
358                                {
359                                        var diff = a.MeasureValue - b.MeasureValue;
360                                        return(diff);<xsl:text/>
361                                }
362                        }
363                <xsl:if test="$showFooterRow">
364                        ,"footerTemplate":"<xsl:value-of select="$datasetRecordTotalValues/DATASET_RECORD_TOTAL_VALUE[NAME = 'Measure']/TITLE"/>"</xsl:if>
365                }
366                <xsl:text/>
367
368                <!-- Prior to 5/17/2017, had template and format code for each field
369                        value to be shown in the grid.  However, ALL values are pre formatted
370                        via the JSON data array record "xxxxTitle" field so there's no need.
371                -->
372                <xsl:for-each select="$recordAncillaryValueFields/RECORD_ANCILLARY_VALUE_FIELD">
373                        <xsl:variable name="index" select="1 + position()"/>
374                ,{
375                        "field": "<xsl:value-of select="current()/NAME"/>Title"
376                        ,"title": "<xsl:value-of select="current()/TITLE"/>"
377                        ,"template": "#=<xsl:value-of select="current()/NAME"/>Title#"
378                        ,"attributes": {"class": "Value"}
379                        <xsl:if test="0 != $Kendo.gridColumnAVWidth">,"width": <xsl:value-of select="$Kendo.gridColumnAVWidth"/></xsl:if>
380                        ,"sortable":
381                        {
382                                "compare": function (a, b)
383                                {
384                                        var diff = a.<xsl:value-of select="current()/NAME"/> - b.<xsl:value-of select="current()/NAME"/>;
385                                        return(diff);<xsl:text/>
386                                }
387                        }
388                        <xsl:if test="$showFooterRow">,"footerTemplate":"<xsl:value-of select="$datasetRecordTotalValues/DATASET_RECORD_TOTAL_VALUE[NAME = current()/NAME]/TITLE"/>"</xsl:if>
389                }
390                </xsl:for-each>
391
392                <xsl:if test="$showLabelColumn">
393                ,{
394                        "field": "Label"
395                        ,"title": "<xsl:value-of select="$Kendo.labelColumnTitle"/>"
396                        ,"attributes": {"class": "Notes"}
397                        <xsl:if test="0 != $Kendo.gridColumnAVWidth">,"width": <xsl:value-of select="$Kendo.gridColumnAVWidth"/></xsl:if>
398                }<xsl:text/>
399                </xsl:if>
400
401                <xsl:if test="$showValueAttributeColumn">
402                ,{
403                        "field": "ValueAttributeCode"
404                        ,"title": "<xsl:value-of select="$Kendo.valueAttributeColumnTitle"/>"
405                        ,"attributes": {"class": "Notes"}
406                        <xsl:if test="0 != $Kendo.gridColumnAVWidth">,"width": <xsl:value-of select="$Kendo.gridColumnAVWidth"/></xsl:if>
407                }<xsl:text/>
408                </xsl:if>
409
410                <xsl:if test="$showNoteColumn">
411                ,{
412                        "field": "Note"
413                        ,"title": "<xsl:value-of select="$Kendo.noteColumnTitle"/>"
414                        ,"attributes": {"class": "Notes"}
415                        <xsl:if test="0 != $Kendo.gridColumnWidth">,"width": <xsl:value-of select="$Kendo.gridColumnWidth"/></xsl:if>
416                }<xsl:text/>
417                </xsl:if>
418
419                <!-- hidden category sort order
420                ,{field: "<xsl:value-of select="$categoryDimensionField/NAME"/>", title: "Default Order", hidden: false, groupable: false}
421                -->
422        ]
423
424        ,"excel":
425        {
426                "fileName": "<xsl:value-of select="$baseExportFilename"/>.xlsx"
427        }
428        ,"pdf":
429        {
430                "fileName": "<xsl:value-of select="$baseExportFilename"/>.pdf"
431        }
432
433<!--
434        CONFIG that should be put in a kendo grid type json file.
435        IMPORTANT NOTES: The grid and column resizing is influenced by the
436        column widths that are set via kendo parameters, the config settings
437        below, and the css for the grid and the grid container.  Lots of options
438        and configurations of which some are not optimal.  Also if centering
439        wide grids then need to use the view port.  The footer can either be set
440        to the left or centered without writing script code and attaching...
441        ,"ibis":
442        {
443                // count of non hidden columns that determines if size adjustment should
444                // be made.  If 0 then no size adjustments are made and will depend on
445                // the column width params and the assoc css defined for the dataviz grid.
446                // if wanting size adjust for all then set to 1 which could result in
447                // small column counts limited to actual pixels and not filling the width
448                // of the container.  If column count gt or equal then code checks size,
449                // auto fits, min/max, reduce as configured.
450                "columnCountAdjustSize": 5                             
451                ,"minColumnSize": 100
452                ,"maxColumnSize": 300
453                ,"reduceColumnQualifierSize": 300
454                ,"reduceColumnSizeMultiplier": 0.33
455                ,"addExpandButton": true                                // only shown if total col size > container size.
456                ,"expandContainerClass": "WideOverflow" // if set and if needs expansion then added.
457                ,"forceGridTotalColumnsSize": false             // sets the grid size based on the columns widths.
458        }
459
460captured toolbar configs for future ref
461        ,"toolbar":
462        [
463                {name: "excel"}
464                ,{
465                        name: "expand"
466                        ,text: ""
467//                      ,text: "View Full Width"
468                        ,iconClass: "k-icon k-i-logout"
469//                      ,template: "<a role='button' class='k-button k-grid-expand k-button-icontext k-i-logout' href='javascript:null' title='Click here to expand grid to full width'></a>"
470                }
471-->
472
473        // Expand click handler that adds width auto to the grid
474        ,expandClickHandler: function(e)
475        {
476console.log("e (target = button anch element):", e );
477console.log("parentElement.parentElement.parentElement (figure):", e.target.parentElement.parentElement.parentElement);
478
479                // grid width auto expands then with overflow already set visible it shows.
480                e.target.parentElement.parentElement.style.width = e.target.totalColumnsWidth + "px";
481                if(this.options.ibis.expandContainerClass)
482                {
483                        e.target.parentElement.parentElement.parentElement.classList.add(this.options.ibis.expandContainerClass);
484                }
485
486                // hide button
487                e.target.style.display = "none";
488
489                // stop events just in case, return false to ignore href #
490                e.stopPropagation();
491                e.cancelBubble = true;
492                return(false);
493        }
494
495        ,dataBound: function()
496        {
497        <![CDATA[
498                // NOTES:
499                // - Code is self contained and uses "this", standard js because potential
500                //              of mult grids per page. 
501                // - Grids are assumed the same structure within a figure etc.
502                // - .width returns px suffix.  setting width style needs units suffix.
503                // - gridContainerWidth is based on the current container and its css defs
504                //              i.e. if 100% vw you'll never get the expand button etc.
505                if(!this.options.ibis) return;
506
507                var notHiddenColumnCount = 0;
508                for (var i = 0; i < this.columns.length; i++)
509                {
510                        if(!this.columns[i].hidden) notHiddenColumnCount++;
511                }
512
513                var adjustColumnsSize = (this.options.ibis.columnCountAdjustSize && (notHiddenColumnCount >= this.options.ibis.columnCountAdjustSize));
514                var totalColumnsWidth = 0;
515                for (var i = 0; i < this.columns.length; i++)
516                {
517                        var columnWidth = this.columns[i].width;
518
519                        if(adjustColumnsSize)
520                        {
521                                // if undefined or 0 then use kendo auto fit
522                                if(!columnWidth)
523                                {
524                                        this.autoFitColumn(i);
525                                        columnWidth = this.columns[i].width;
526                                }
527                                else if(this.options.ibis.reduceColumnQualifierSize && (columnWidth > this.options.ibis.reduceColumnQualifierSize))
528                                {
529                                        columnWidth *= this.options.ibis.reduceColumnSizeMultiplier;
530                                        this.resizeColumn(this.columns[i], columnWidth);
531                                }
532
533                                // if min/max set then test and adjust.
534                                if(this.options.ibis.minColumnSize && (columnWidth < this.options.ibis.minColumnSize))
535                                {
536                                        columnWidth = this.options.ibis.minColumnSize;
537                                        this.resizeColumn(this.columns[i], columnWidth);
538                                }
539                                else if(this.options.ibis.maxColumnSize && (columnWidth > this.options.ibis.maxColumnSize))
540                                {
541                                        columnWidth = this.options.ibis.maxColumnSize;
542                                        this.resizeColumn(this.columns[i], columnWidth);
543                                }
544                        }       // end of if adjusting sizing
545
546                        if(columnWidth) totalColumnsWidth += columnWidth;
547                } // end of columns loop
548
549                var gridContainerWidth = parseInt(window.getComputedStyle(this.element[0]).width, 10);
550                var tableWidth         = parseInt(window.getComputedStyle(this.element[0].querySelector("table")).width, 10);
551console.log("gridContainerWidth: ", gridContainerWidth, ", tableWidth: ", tableWidth, "totalColumnsWidth: ", totalColumnsWidth);
552
553                // If the table width is wider than the container width and if the expand
554                // button is wanted then show the button and set the footer table's sizing.
555                // else no button but still wide and force then set the class.
556                if(totalColumnsWidth > gridContainerWidth)
557                {
558                        if(this.options.ibis.addExpandButton)
559                        {
560                                var expandButton = this.element[0].querySelector(".k-grid-expand");
561                                expandButton.style.display = "block";
562                                expandButton.onclick=this.options.expandClickHandler.bind(this);
563                                expandButton.title="Click here to expand grid to full width";
564                                expandButton.totalColumnsWidth = totalColumnsWidth;     
565                                this.element[0].querySelector(".k-grid-footer-wrap table").style.width = "100%";       
566                        }
567                        else if(this.options.ibis.expandContainerClass)
568                        {
569                                this.element[0].parentElement.classList.add(this.options.ibis.expandContainerClass);
570                                this.element[0].style.width = (totalColumnsWidth) + "px";
571                        }
572                }
573
574                // if force size then set the actual grid size
575                if(this.options.ibis.forceGridTotalColumnsSize && totalColumnsWidth)
576                {
577                        this.element[0].style.width = (totalColumnsWidth) + "px";
578                }
579
580                // no matter what sizing is applied need to set the footer width to auto
581                // because kendo code sets: padding-right: 17px; and width to container width.
582                this.element[0].querySelector(".k-grid-footer").style.width = "auto";
583        ]]>
584        }
585}
586        </xsl:template>
587
588
589
590        <xsl:template name="Kendo.requestChartJSON" ibis:doc="Builds the request specific chart JSON options.">
591                <xsl:param name="kendoDataSourceJavascriptVariableName" select="'kendoDataSource'"/>
592
593                <xsl:param name="title"         ibis:doc="top overall title"/>
594                <xsl:param name="categoryTitle" ibis:doc="x axis title"/>
595                <xsl:param name="seriesTitle"   ibis:doc="series legend title"/>
596                <xsl:param name="valueTitle"    ibis:doc="y axis title"/>
597                <xsl:param name="measureValueType"/>
598
599                <xsl:param name="seriesFieldName"/>
600                <xsl:param name="categoryFieldName"/>
601                <xsl:param name="constantFieldName"/>
602                <xsl:param name="errorLowFieldName"     select="$Kendo.defaultErrorLowFieldName"/>
603                <xsl:param name="errorHighFieldName"    select="$Kendo.defaultErrorHighFieldName"/>
604
605                <xsl:param name="recordAncillaryValueFields"/>
606
607                <xsl:param name="includeDatasetSeries" select="false()"/>
608
609                <xsl:param name="includeLimits"        select="false()"/>
610                <xsl:param name="includeNumerator"     select="false()"/>
611                <xsl:param name="includeDenominator"   select="false()"/>
612
613                <xsl:param name="width"  ibis:doc="Forces/sets the chart's width (in pixels).  If not set then uses the container width if container is visible."/>
614
615                <xsl:param name="baseExportFilename" select="'export'"/>
616
617                <!--
618                        Did have code to dynamically craft - too complex and error prone.
619                        PLUS XSLT format pattern is not 100% with the kendo pattern...
620                        Template must be used because axis ticks are dynamically, chart
621                        script generated. 
622                -->
623
624                <xsl:param name="valueAxisTemplate">
625                        <xsl:choose>
626<!--
627        NOTE: no # is acceptable unless escaped because it is part of the template expression.
628        <JAVASCRIPT_FORMAT_PATTERN>,0.0\"%\"</JAVASCRIPT_FORMAT_PATTERN>
629        <JAVASCRIPT_FORMAT_PATTERN>,0.0\\'%\\'</JAVASCRIPT_FORMAT_PATTERN>
630        <JAVASCRIPT_FORMAT_PATTERN>,0.0\\&apos;%\\&apos;</JAVASCRIPT_FORMAT_PATTERN>
631
632        CODE: IF want to use the XSLT format pattern - note removal of #.
633                                                                                                                   #=kendo.toString(value, "<xsl:sequence select="translate(replace($measureValueType/JAVASCRIPT_FORMAT_PATTERN, '#', ''), '''', '\&quot;')")#
634        <xsl:when test="$measureValueType/XSLT_FORMAT_PATTERN">#=kendo.toString(value, '<xsl:sequence select="translate(replace($measureValueType/JAVASCRIPT_FORMAT_PATTERN, '#', ''), '''', '\&quot;\')"/>')#</xsl:when>
635        <xsl:when test="$measureValueType/XSLT_FORMAT_PATTERN">#=kendo.toString(value, '<xsl:sequence select="translate(replace($measureValueType/JAVASCRIPT_FORMAT_PATTERN, '#', ''), '''', '\&quot;\')"/>')#</xsl:when>
636        <xsl:when test="$measureValueType/JAVASCRIPT_FORMAT_PATTERN">#=kendo.toString(value, '<xsl:sequence select="$measureValueType/JAVASCRIPT_FORMAT_PATTERN"/>')#</xsl:when>
637-->
638                                <xsl:when test="$measureValueType/JAVASCRIPT_FORMAT_PATTERN">#=kendo.toString(value, '<xsl:sequence select="$measureValueType/JAVASCRIPT_FORMAT_PATTERN"/>')#</xsl:when>
639                                <xsl:when test="contains($valueTitle, 'Percent')">#=kendo.toString(value, '0.0')#%</xsl:when>
640                                <xsl:when test="contains($valueTitle, 'Number') or contains($valueTitle, 'Count')">#=kendo.toString(value, ',0')#</xsl:when>
641                                <xsl:otherwise>#=kendo.toString(value, ',0.0')#</xsl:otherwise>
642                        </xsl:choose>
643                </xsl:param>
644<!--
645<xsl:message select="'VAT: ', $valueAxisTemplate"/>
646<xsl:message select="'MVT: ', $measureValueType"/>
647<xsl:message select="'VT: ', $ValueTypes"/>
648-->
649
650<xsl:text>{</xsl:text>
651    "dataSource": <xsl:value-of select="$kendoDataSourceJavascriptVariableName"/>
652        ,"title":
653        {
654                "text": "<xsl:value-of select="$title"/>"
655        }<xsl:text/>
656        <!-- Kendo seems to handle automatically e.g. pie shows it multi series charts
657        show it and single series charts do not.
658        ,legend: { visible: <xsl:value-of select="$includeDatasetSeries"/> }
659        -->
660
661        <!-- Use series.categoryField instead of categoryAxis.field. This merges
662                categories from all series data.  Also, should NOT use field: "YearAllTitle
663                this field will override seriesDefaults.field: "value" and will bind the
664                chart to category strings which is not correct - from kendo.
665        -->
666        <xsl:text/>
667        ,"seriesDefaults":
668        {
669                "field":           "MeasureValue"
670                ,"errorLowField":  "<xsl:value-of select="$errorLowFieldName"/>"
671                ,"errorHighField": "<xsl:value-of select="$errorHighFieldName"/>"
672        }
673        ,"series":
674        [
675                {       <!-- kendo said can't set field: - can only set the  categoryField: -->
676                        "categoryField": "<xsl:value-of select="$categoryFieldName"/>Title"<xsl:text/>
677                        ,"colorField": "valueColor"
678//,"noteTextField": "Label"
679                        <!-- group by sort order but title via series name - kendo ticket 946525 -->
680                <xsl:if test="$includeDatasetSeries">
681                        ,"name": "#:group.items[0].<xsl:value-of select="$seriesFieldName"/>Title#"
682                </xsl:if>
683                }
684        ]
685
686        ,"categoryAxis":
687        [
688                {
689                        "name": "defaultCategoryAxis"   // used to test if sorting on category column - special missing values sorting. 
690                        ,"title":
691                        {
692                                "text": "<xsl:value-of select="$categoryTitle"/>"
693                        }
694                }
695        ]
696
697        ,"valueAxis":
698        [
699                {
700                        "title":
701                        {
702                                "text": "<xsl:value-of select="$valueTitle"/>"
703                        }
704                        ,"labels":
705                        {
706                                <!--
707GARTH TODO: CHECK INTO THESE FORMAT PATTERNS???  Maybe we have a js format pattern instead of
708JAVA_FP.  Ticket keeps it generic so could be used with js international FP or kendo's.
709                                //format: "XXX {0:n00}" //Custom Formatter like '00##' "<xsl:value-of select="$valueTitle"/>"
710                                // template: kendo.template("Year: #: value #") //Custom Formatter like '00##' "<xsl:value-of select="$valueTitle"/>"
711                                //template: "Garth: #=value# End"
712                                //,format: "p"
713                                //template: "GGG {kendo.toString(value, '#')}"
714                                // works: template: '#= kendo.toString(value, "n0") #'
715                                // # doesn't appear to work.
716                                // works: template: '#= kendo.toString(value, ",0.0")#%'
717                                // doesn't error but doesn't do anything either: format: 'C'
718                                // <XSLT_FORMAT_PATTERN>#0.00</XSLT_FORMAT_PATTERN>
719                                // this works but again any "#" breaks it.    template: '${kendo.toString(value,",0")}'
720                                // % inside mults by 100 and adds the %:      template: '${kendo.toString(value,",0%")}'
721                                http://docs.telerik.com/kendo-ui/framework/globalization/numberformatting       
722                                        Kendo docs say that # works but it blows things up no matter
723                                        how quoted.  The format config doesn't do anything.
724                                -->
725                                "template": "<xsl:value-of select="$valueAxisTemplate"/>"
726                        }
727                }
728        ]
729        ,"tooltip":
730        {
731                "template": ""
732                <xsl:if test="$includeDatasetSeries">
733                        + "${dataItem.<xsl:value-of select="$seriesFieldName"/>Title}, "
734                </xsl:if>
735                        + "${dataItem.<xsl:value-of select="$categoryFieldName"/>Title}: "
736                        + "${dataItem.MeasureValueTitle} "
737                <xsl:for-each select="$recordAncillaryValueFields/RECORD_ANCILLARY_VALUE_FIELD">
738                        + "<br/> <xsl:value-of select="current()/TITLE"/>: ${dataItem.<xsl:value-of select="current()/NAME"/>Title}"<xsl:text/>
739                </xsl:for-each>
740        }
741        <xsl:if test="0 != string-length($width)">
742        ,"chartArea": {"width": <xsl:value-of select="$width"/>}
743        </xsl:if>
744<!--
745        ,"jpg":
746        {
747                "fileName": "<xsl:value-of select="$baseExportFilename"/>.jpg"
748        }
749config settings for the saveAsPDF call.  DNA for saveAs callback...
750        ,"pdf":
751        {
752                "fileName": "<xsl:value-of select="$baseExportFilename"/>.pdf"
753                ,"proxyURL": "https://demos.telerik.com/kendo-ui/service/export"
754                ,"paperSize": "auto"
755                ,"margin": { left: "1cm", top: "1cm", right: "1cm", bottom: "1cm" }
756        }
757-->
758<xsl:text>}</xsl:text>
759        </xsl:template>
760
761</xsl:stylesheet>
762<!-- ============================= End of File ============================= -->
Note: See TracBrowser for help on using the repository browser.