datavis-glide 4.0.0-PRE.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/LICENSE +45 -0
  2. package/README.md +129 -0
  3. package/datavis.js +101 -0
  4. package/dist/wcdatavis.css +1957 -0
  5. package/dist/wcdatavis.min.js +1 -0
  6. package/global-jquery.js +4 -0
  7. package/ie-fixes.js +13 -0
  8. package/index.js +70 -0
  9. package/meteor.js +1 -0
  10. package/package.json +102 -0
  11. package/src/flags.js +6 -0
  12. package/src/graph.js +1079 -0
  13. package/src/graph_renderer.js +85 -0
  14. package/src/grid.js +2777 -0
  15. package/src/grid_control.js +1957 -0
  16. package/src/grid_filter.js +1073 -0
  17. package/src/grid_renderer.js +276 -0
  18. package/src/group_fun_win.js +121 -0
  19. package/src/lang/en-US.js +188 -0
  20. package/src/lang/es-MX.js +188 -0
  21. package/src/lang/fr-FR.js +188 -0
  22. package/src/lang/id-ID.js +188 -0
  23. package/src/lang/nl-NL.js +188 -0
  24. package/src/lang/pt-BR.js +188 -0
  25. package/src/lang/ru-RU.js +188 -0
  26. package/src/lang/th-TH.js +188 -0
  27. package/src/lang/vi-VN.js +188 -0
  28. package/src/lang/zh-Hans-CN.js +188 -0
  29. package/src/operations_palette.js +176 -0
  30. package/src/prefs_modules.js +132 -0
  31. package/src/reg/graph_renderer.js +17 -0
  32. package/src/renderers/graph/chartjs.js +457 -0
  33. package/src/renderers/graph/google.js +584 -0
  34. package/src/renderers/graph/jit.js +61 -0
  35. package/src/renderers/graph/svelte-gantt.js +168 -0
  36. package/src/renderers/grid/dummy.js +79 -0
  37. package/src/renderers/grid/handlebars.js +217 -0
  38. package/src/renderers/grid/squirrelly.js +215 -0
  39. package/src/renderers/grid/table/group_detail.js +1404 -0
  40. package/src/renderers/grid/table/group_summary.js +380 -0
  41. package/src/renderers/grid/table/pivot.js +915 -0
  42. package/src/renderers/grid/table/plain.js +1592 -0
  43. package/src/renderers/grid/table.js +2510 -0
  44. package/src/trans.js +101 -0
  45. package/src/ui/collapsible.js +234 -0
  46. package/src/ui/filters/date.js +283 -0
  47. package/src/ui/grid_filter.js +398 -0
  48. package/src/ui/popup_menu.js +224 -0
  49. package/src/ui/popup_window.js +572 -0
  50. package/src/ui/slider.js +156 -0
  51. package/src/ui/tabs.js +202 -0
  52. package/src/ui/templates.js +131 -0
  53. package/src/ui/toolbar.js +63 -0
  54. package/src/ui/toolbars/grid.js +873 -0
  55. package/src/ui/windows/col_config.js +341 -0
  56. package/src/ui/windows/debug.js +164 -0
  57. package/src/ui/windows/grid_table_opts.js +139 -0
  58. package/src/util/handlebars.js +158 -0
  59. package/src/util/jquery.js +630 -0
  60. package/src/util/misc.js +1058 -0
  61. package/src/util/squirrelly.js +155 -0
  62. package/wcdatavis.css +1601 -0
@@ -0,0 +1,276 @@
1
+ import _ from 'underscore';
2
+
3
+ import {
4
+ deepCopy,
5
+ getPropDef,
6
+ makeSubclass,
7
+ mixinEventHandling,
8
+ } from './util/misc.js';
9
+
10
+ import { OrdMap, Lock, ComputedView } from 'datavis-ace';
11
+
12
+ // GridRenderer {{{1
13
+
14
+ // Constructor {{{2
15
+
16
+ /**
17
+ * @param {Grid} grid
18
+ *
19
+ * @param {object} defn
20
+ *
21
+ * @param {ComputedView} view
22
+ *
23
+ * @param {object} features
24
+ *
25
+ * @param {object} opts
26
+ *
27
+ * @param {Timing} timing
28
+ *
29
+ * @param {string} id
30
+ *
31
+ * @class
32
+ */
33
+
34
+ var GridRenderer = (function () {
35
+ var UNIQUE_ID = 0;
36
+
37
+ return makeSubclass('GridRenderer', Object, function (grid, defn, view, features, opts, timing, id, colConfig) {
38
+ var self = this;
39
+
40
+ self.UNIQUE_ID = UNIQUE_ID++;
41
+
42
+ self.id = id;
43
+ self.grid = grid;
44
+ self.defn = defn;
45
+ self.view = view;
46
+ self.features = deepCopy(features);
47
+ self.opts = opts;
48
+ self.timing = timing;
49
+ self.colConfig = colConfig;
50
+ self.hasRendered = false;
51
+ self._destroyed = false;
52
+
53
+ self._validateFeatures();
54
+
55
+ self.drawLock = new Lock('GridRenderer/draw');
56
+
57
+ self.grid.on('colConfigUpdate', function (newColConfig, initColConfig, shouldRedraw) {
58
+ if (self._destroyed) { return; }
59
+ self.logDebug(self.makeLogTag() + ' Received new colConfig: %O', newColConfig);
60
+ self.colConfig = newColConfig;
61
+ if (self.hasRendered && shouldRedraw) {
62
+ self.logDebug(self.makeLogTag() + ' Redrawing with new colConfig');
63
+ self.draw(self.root, self.drawOpts);
64
+ }
65
+ }, { who: self });
66
+ });
67
+ })();
68
+
69
+ // FIXME: We don't need all these, we only need "unableToRender." However, mixinEventHandling()
70
+ // can't traverse the class hierarchy, so trying to subscribe to "unableToRender" from a GridTable
71
+ // will not work (because "unableToRender" isn't in the GridTable subclass' event list). So for a
72
+ // quick workaround, we just put all the events that any subclass may use here. But the real fix
73
+ // should be to make mixinEventHandling() traverse up the superclass chain.
74
+
75
+ mixinEventHandling(GridRenderer, [
76
+ 'columnResize' // A column is resized.
77
+ , 'unableToRender' // A grid renderer can't render the data in the view it's bound to.
78
+ , 'limited' // The grid table isn't rendering all possible rows.
79
+ , 'unlimited' // The grid table is rendering all possible rows.
80
+ , 'csvReady' // CSV data has been generated.
81
+ , 'generateCsvProgress' // CSV generation progress.
82
+ , 'renderBegin'
83
+ , 'renderEnd'
84
+ , 'selectionChange'
85
+ ]);
86
+
87
+ // #canRender {{{2
88
+
89
+ GridRenderer.prototype.canRender = function () {
90
+ throw new Error('ABSTRACT');
91
+ };
92
+
93
+ // #draw {{{2
94
+
95
+ GridRenderer.prototype.draw = function (root, opts, cont1) {
96
+ var self = this;
97
+ var args = Array.prototype.slice.call(arguments);
98
+
99
+ if (self._destroyed) { return; }
100
+
101
+ self.logDebug(self.makeLogTag() + ' Beginning draw operation; opts = %O', opts);
102
+
103
+ opts = opts || {};
104
+
105
+ self.root = root;
106
+ self.drawOpts = opts;
107
+
108
+ if (self.drawLock.isLocked()) {
109
+ return self.drawLock.onUnlock(function () {
110
+ if (self._destroyed) { return; }
111
+ GridRenderer.prototype.draw.apply(self, args);
112
+ });
113
+ }
114
+
115
+ self.drawLock.lock();
116
+
117
+ self.clear();
118
+
119
+ return self.view.getData(function (ok, data) {
120
+ if (self._destroyed) { return; }
121
+ if (!ok) {
122
+ return cont1(false);
123
+ }
124
+
125
+ self.logDebug(self.makeLogTag() + ' Data = %O', data);
126
+
127
+ return self.view.getTypeInfo(function (ok, typeInfo) {
128
+ if (!ok) {
129
+ return cont1(false);
130
+ }
131
+
132
+ if (data == null || typeInfo == null) {
133
+ self.logError(self.makeLogTag() + ' Provided data or typeInfo is null');
134
+ return cont1(false);
135
+ }
136
+
137
+ self.logDebug(self.makeLogTag() + ' TypeInfo = %O', typeInfo.asMap());
138
+
139
+ if ((data.isPlain && !self.canRender('plain'))
140
+ || (data.isGroup && !self.canRender('group'))
141
+ || (data.isPivot && !self.canRender('pivot'))) {
142
+
143
+ self.logDebug(self.makeLogTag() + ' Unable to render data using current grid table: { isPlain = %s ; isGroup = %s ; isPivot = %s }', data.isPlain, data.isGroup, data.isPivot);
144
+
145
+ return self.fire('unableToRender');
146
+ }
147
+
148
+ self.hasRendered = true;
149
+ self.fire('renderBegin');
150
+
151
+ self.data = data;
152
+ self.typeInfo = typeInfo;
153
+
154
+ self.timing.start(['Grid Renderer', 'Draw']);
155
+
156
+ return cont1(true, data, typeInfo, function (cont2) {
157
+ self.fire('renderEnd');
158
+ if (self.drawLock._lockCount > 0) {
159
+ self.drawLock.unlock();
160
+ }
161
+
162
+ if (typeof cont2 === 'function') {
163
+ return cont2();
164
+ }
165
+ });
166
+ });
167
+ });
168
+ };
169
+
170
+ // #clear {{{2
171
+
172
+ /**
173
+ * Remove the table from page.
174
+ */
175
+
176
+ GridRenderer.prototype.clear = function () {
177
+ var self = this;
178
+
179
+ self.root.children().remove();
180
+ };
181
+
182
+ // #destroy {{{2
183
+
184
+ GridRenderer.prototype.destroy = function () {
185
+ var self = this;
186
+
187
+ self._destroyed = true;
188
+ self.clear();
189
+ self.grid.off('*', self);
190
+ };
191
+
192
+ // #toString {{{2
193
+
194
+ GridRenderer.prototype.toString = function () {
195
+ var self = this;
196
+
197
+ return 'GridRenderer(' + self.UNIQUE_ID + ')';
198
+ };
199
+
200
+ // #_validateFeatures {{{2
201
+
202
+ GridRenderer.prototype._validateFeatures = function () {
203
+ return true;
204
+ };
205
+
206
+ // #hasOperations {{{2
207
+
208
+ /**
209
+ * Indicates if there are operations registered for the requested situation.
210
+ *
211
+ * @param {string} type
212
+ * What type of operations we're checking for: "cell", "row", "all", "group", or "pivot".
213
+ *
214
+ * @param {string} [field]
215
+ * When `type` is "cell", this is the field we want to know about.
216
+ *
217
+ * @example
218
+ * hasOperations('all')
219
+ * hasOperations('cell', 'Employee')
220
+ */
221
+
222
+ GridRenderer.prototype.hasOperations = function (type, field) {
223
+ var self = this;
224
+
225
+ if (!self.features.operations) {
226
+ return false;
227
+ }
228
+
229
+ switch (type) {
230
+ case 'all':
231
+ return getPropDef(0, self.defn, 'operations', 'all', 'length') > 0;
232
+ case 'row':
233
+ return getPropDef(0, self.defn, 'operations', 'row', 'length') > 0;
234
+ case 'cell':
235
+ return getPropDef(0, self.defn, 'operations', 'cell', field, 'length') > 0;
236
+ default:
237
+ return false;
238
+ }
239
+ };
240
+
241
+ GridRenderer.prototype.clearRenderCache = function (cols) {
242
+ var self = this;
243
+
244
+ if (self.data != null) {
245
+ if (self.data.isPlain) {
246
+ _.each(self.data.data, function (row) {
247
+ if (cols != null) {
248
+ _.each(cols, function (c) {
249
+ row.rowData[c].cachedRender = null;
250
+ });
251
+ }
252
+ else {
253
+ _.each(row.rowData, function (c) {
254
+ c.cachedRender = null;
255
+ });
256
+ }
257
+ });
258
+ }
259
+ else if (self.data.isGroup) {
260
+ // do nothing
261
+ }
262
+ else if (self.data.isPivot) {
263
+ // do nothing
264
+ }
265
+ }
266
+ };
267
+
268
+ // Registry {{{1
269
+
270
+ GridRenderer.registry = new OrdMap();
271
+
272
+ // Exports {{{1
273
+
274
+ export {
275
+ GridRenderer
276
+ };
@@ -0,0 +1,121 @@
1
+ import { OrdMap } from 'datavis-ace';
2
+
3
+ import jQuery from 'jquery';
4
+
5
+ import { trans } from './trans.js';
6
+ import {
7
+ makeSubclass,
8
+ } from './util/misc.js';
9
+ import { PopupWindow } from './ui/popup_window.js';
10
+
11
+ // GroupFunWin {{{1
12
+
13
+ var GroupFunWin = makeSubclass('GroupFunWin', Object, function (title, groupFuns) {
14
+ var self = this;
15
+
16
+ var selected = null;
17
+
18
+ self.win = new PopupWindow({
19
+ title: title,
20
+ width: 600
21
+ });
22
+
23
+ self.win.on('open', function () {
24
+ selected = null;
25
+ });
26
+
27
+ self.win.on('close', function () {
28
+ self.cb(selected);
29
+ });
30
+
31
+ var contentDiv = jQuery('<div>');
32
+
33
+ var root = jQuery('<div>').css({
34
+ 'display': 'flex'
35
+ }).appendTo(contentDiv);
36
+
37
+ // These are the columns that contain related group function buttons.
38
+
39
+ var categories = new OrdMap();
40
+ categories.set('repeating', { display: trans('GRID.GROUP_FUN.DIALOG.REPEATING') });
41
+ categories.set('date', { display: trans('GRID.GROUP_FUN.DIALOG.DATE') });
42
+ categories.set('datetime', { display: trans('GRID.GROUP_FUN.DIALOG.DATE_TIME') });
43
+ categories.set('time', { display: trans('GRID.GROUP_FUN.DIALOG.TIME') });
44
+ categories.set('other', { display: trans('GRID.GROUP_FUN.DIALOG.OTHER') });
45
+
46
+ // Create the UI for each category.
47
+
48
+ categories.each(function (c) {
49
+ c.div = jQuery('<div>', {'class': 'wcdv_groupfun_buttons'});
50
+ c.root = jQuery('<div>').css({ 'flex': '1 1 auto' });
51
+ c.root.append(jQuery('<h1>', {'class': 'wcdv_groupfun_header'}).text(c.display));
52
+ c.root.append(c.div);
53
+ c.members = 0;
54
+ });
55
+
56
+ self.buttons = {};
57
+
58
+ // Go through each group function and create the UI for it, plus add it to the appropriate column.
59
+
60
+ groupFuns.each(function (gf, gfName) {
61
+ self.buttons[gfName] = jQuery('<button>', {
62
+ 'type': 'button',
63
+ 'class': 'wcdv_option',
64
+ 'data-wcdv-groupfunname': gfName,
65
+ 'title': gf.getTransName()
66
+ })
67
+ .text(gf.getTransName())
68
+ .on('click', function () {
69
+ selected = gfName;
70
+ self.win.close();
71
+ });
72
+
73
+ var c = categories.get(gf.category) || categories.get('other');
74
+ c.div.append(self.buttons[gfName]);
75
+ c.members += 1;
76
+ });
77
+
78
+ // Only show categories that have group functions inside them. Mostly, this prevents showing the
79
+ // "Other" column unless someone has made their own group functions.
80
+
81
+ categories.each(function (c) {
82
+ if (c.members > 0) {
83
+ root.append(c.root);
84
+ }
85
+ });
86
+
87
+ // Add the "None" button to use no function.
88
+
89
+ self.buttons['none'] = jQuery('<button>', {
90
+ 'type': 'button',
91
+ 'class': 'wcdv_option',
92
+ 'data-wcdv-groupfunname': 'none',
93
+ 'title': trans('GRID.GROUP_FUN.NONE')
94
+ })
95
+ .text(trans('GRID.GROUP_FUN.NONE'))
96
+ .on('click', function () {
97
+ selected = 'none';
98
+ self.win.close();
99
+ });
100
+
101
+ contentDiv.append(jQuery('<div>').append(self.buttons['none']));
102
+
103
+ self.win.setContent(contentDiv);
104
+ });
105
+
106
+ // #show {{{2
107
+
108
+ GroupFunWin.prototype.show = function (gfName, cb) {
109
+ var self = this;
110
+ self.cb = cb;
111
+
112
+ self.win.open();
113
+
114
+ if (gfName != null && self.buttons[gfName] != null) {
115
+ self.buttons[gfName].focus();
116
+ }
117
+ };
118
+
119
+ export {
120
+ GroupFunWin
121
+ };
@@ -0,0 +1,188 @@
1
+ export default {
2
+ 'AGGREGATE.FIELD.DENOMINATOR': 'Denom',
3
+ 'AGGREGATE.FIELD.NUMERATOR': 'Num',
4
+ 'AGGREGATE.HEADER_DISPLAY': '%s of %s',
5
+ 'AGGREGATE.NAME.AVERAGE': 'Average',
6
+ 'AGGREGATE.NAME.COUNT': 'Count',
7
+ 'AGGREGATE.NAME.COUNT_DISTINCT': 'Count Distinct',
8
+ 'AGGREGATE.NAME.COUNT_OVER_COUNT': 'Count/Count',
9
+ 'AGGREGATE.NAME.DISTINCT_VALUES': 'Distinct Values',
10
+ 'AGGREGATE.NAME.FIRST': 'First',
11
+ 'AGGREGATE.NAME.LAST': 'Last',
12
+ 'AGGREGATE.NAME.MAX': 'Max',
13
+ 'AGGREGATE.NAME.MIN': 'Min',
14
+ 'AGGREGATE.NAME.NTH': 'Nth',
15
+ 'AGGREGATE.NAME.SUM': 'Sum',
16
+ 'AGGREGATE.NAME.SUM_OVER_SUM': 'Sum/Sum',
17
+ 'AGGREGATE.NAME.VALUES': 'Values',
18
+ 'AGGREGATE.NAME.VALUES_WITH_COUNTS': 'Values w/ Counts',
19
+ 'CALENDAR.DATE': 'date',
20
+ 'CALENDAR.DAY': 'day',
21
+ 'CALENDAR.DAY.FRIDAY': 'Friday',
22
+ 'CALENDAR.DAY.MONDAY': 'Monday',
23
+ 'CALENDAR.DAY.SATURDAY': 'Saturday',
24
+ 'CALENDAR.DAY.SUNDAY': 'Sunday',
25
+ 'CALENDAR.DAY.THURSDAY': 'Thursday',
26
+ 'CALENDAR.DAY.TUESDAY': 'Tuesday',
27
+ 'CALENDAR.DAY.WEDNESDAY': 'Wednesday',
28
+ 'CALENDAR.MONTH': 'month',
29
+ 'CALENDAR.MONTH.APRIL': 'April',
30
+ 'CALENDAR.MONTH.AUGUST': 'August',
31
+ 'CALENDAR.MONTH.DECEMBER': 'December',
32
+ 'CALENDAR.MONTH.FEBRUARY': 'February',
33
+ 'CALENDAR.MONTH.JANUARY': 'January',
34
+ 'CALENDAR.MONTH.JULY': 'July',
35
+ 'CALENDAR.MONTH.JUNE': 'June',
36
+ 'CALENDAR.MONTH.MARCH': 'March',
37
+ 'CALENDAR.MONTH.MAY': 'May',
38
+ 'CALENDAR.MONTH.NOVEMBER': 'November',
39
+ 'CALENDAR.MONTH.OCTOBER': 'October',
40
+ 'CALENDAR.MONTH.SEPTEMBER': 'September',
41
+ 'CALENDAR.QUARTER': 'quarter',
42
+ 'CALENDAR.WEEK': 'week',
43
+ 'CALENDAR.YEAR': 'year',
44
+ 'DATA.NOTHING_TO_GRAPH': 'Nothing to Graph',
45
+ 'DATA.NO_DATA': 'No Data',
46
+ 'DIALOG.CANCEL': 'Cancel',
47
+ 'DIALOG.OK': 'OK',
48
+ 'FILTER.DATE.OPERATOR.AFTER': 'after',
49
+ 'FILTER.DATE.OPERATOR.AND': 'and',
50
+ 'FILTER.DATE.OPERATOR.BEFORE': 'before',
51
+ 'FILTER.DATE.OPERATOR.BETWEEN': 'between',
52
+ 'FILTER.DATE.OPERATOR.CURRENT': 'current',
53
+ 'FILTER.DATE.OPERATOR.EVERY': 'every',
54
+ 'FILTER.DATE.OPERATOR.LAST': 'last',
55
+ 'FILTER.DATE.OPERATOR.ON': 'on',
56
+ 'FILTER.STRING.OPERATOR.BLANK': 'blank',
57
+ 'FILTER.STRING.OPERATOR.IN': 'in',
58
+ 'FILTER.STRING.OPERATOR.NOT_BLANK': 'not blank',
59
+ 'FILTER.STRING.OPERATOR.NOT_IN': 'not in',
60
+ 'GRAPH.TITLEBAR.SHOW_HIDE': 'Show/Hide Graph',
61
+ 'GRAPH.TITLEBAR.SHOW_HIDE_CONTROLS': 'Show/Hide Graph Controls',
62
+ 'GRID.COLCONFIG_WIN.ALLOW_FORMATTING': 'Allow embedded DataVis formatting?',
63
+ 'GRID.COLCONFIG_WIN.ALLOW_HTML': 'Allow HTML to be rendered?',
64
+ 'GRID.COLCONFIG_WIN.HIDE_COL': 'Hide column?',
65
+ 'GRID.COLCONFIG_WIN.MOVE_COL_TO_BOTTOM': 'Move to bottom of column list',
66
+ 'GRID.COLCONFIG_WIN.MOVE_COL_TO_TOP': 'Move to top of column list',
67
+ 'GRID.COLCONFIG_WIN.PINNED_COL_WARNING': 'Pinned columns always appear before any others in plain (non-grouped) output, in the relative order shown above.',
68
+ 'GRID.COLCONFIG_WIN.PIN_COL': 'Pin column to left side of table?',
69
+ 'GRID.COLCONFIG_WIN.RENAME_COL': 'Rename column in table.',
70
+ 'GRID.COLCONFIG_WIN.RENAME_COL.PROMPT': 'Rename field "%s" to what?',
71
+ 'GRID.COLCONFIG_WIN.REORDER_COLS': 'Click and drag to reorder columns',
72
+ 'GRID.COLCONFIG_WIN.RESET_COL_ORDER': 'Reset Column Order',
73
+ 'GRID.COLCONFIG_WIN.TBL.DISPLAY': 'Display',
74
+ 'GRID.COLCONFIG_WIN.TBL.FIELD': 'Field',
75
+ 'GRID.COLCONFIG_WIN.TBL.OPTIONS': 'Options',
76
+ 'GRID.COLCONFIG_WIN.TITLE': 'Columns',
77
+ 'GRID.GROUP_FUN.DATE.FULL_DATE': 'Full Date (No Time)',
78
+ 'GRID.GROUP_FUN.DATE.YEAR': 'Year',
79
+ 'GRID.GROUP_FUN.DATE.YEAR_AND_MONTH': 'Year & Month',
80
+ 'GRID.GROUP_FUN.DATE.YEAR_AND_QUARTER': 'Year & Quarter',
81
+ 'GRID.GROUP_FUN.DATE.YEAR_AND_WEEK': 'Year & Week (ISO)',
82
+ 'GRID.GROUP_FUN.DATE_TIME.SLICE.15MIN': 'Date & Time: 15 min slices',
83
+ 'GRID.GROUP_FUN.DATE_TIME.SLICE.1HR': 'Date & Time: 1 hr slices',
84
+ 'GRID.GROUP_FUN.DIALOG.DATE': 'Date',
85
+ 'GRID.GROUP_FUN.DIALOG.DATE_TIME': 'Date & Time',
86
+ 'GRID.GROUP_FUN.DIALOG.OTHER': 'Other',
87
+ 'GRID.GROUP_FUN.DIALOG.REPEATING': 'Repeating',
88
+ 'GRID.GROUP_FUN.DIALOG.TIME': 'Time',
89
+ 'GRID.GROUP_FUN.DIALOG.TITLE': 'Apply Function to %s',
90
+ 'GRID.GROUP_FUN.NONE': 'None',
91
+ 'GRID.GROUP_FUN.REPEATING.DAY_OF_WEEK': 'Day of Week',
92
+ 'GRID.GROUP_FUN.REPEATING.MONTH': 'Month',
93
+ 'GRID.GROUP_FUN.REPEATING.QUARTER': 'Quarter',
94
+ 'GRID.GROUP_FUN.REPEATING.WEEK': 'Week (ISO)',
95
+ 'GRID.GROUP_FUN.TIME.SLICE.15MIN': 'Time: 15 min slices',
96
+ 'GRID.GROUP_FUN.TIME.SLICE.1HR': 'Time: 1 hr slices',
97
+ 'GRID.OMNIFILTER.ARIA_LABEL': 'Filter all rows by text',
98
+ 'GRID.OMNIFILTER.CLEAR': 'Clear filter',
99
+ 'GRID.OMNIFILTER.PLACEHOLDER': 'Type to filter rows...',
100
+ 'GRID.OMNIFILTER.TOGGLE': 'Toggle search filter',
101
+ 'GRID.PAGINATION.ARIA_LABEL': 'Page navigation',
102
+ 'GRID.PAGINATION.GO_TO_PAGE': 'Go to page %s',
103
+ 'GRID.PERSPECTIVE_WIN.TEMP_PERSPECTIVE_WARNING': 'This perspective is temporary; the configuration below does not reflect the current state of any bound prefs modules.',
104
+ 'GRID.PERSPECTIVE_WIN.TITLE': 'Perspective',
105
+ 'GRID.TABLE.ADD_FILTER_HELP': 'Click to add a filter for "%s"',
106
+ 'GRID.TABLE.DRAGGABLE_FIELD_HELP': 'You can drag & drop this field into the grid controls above to filter, group or pivot.',
107
+ 'GRID.TABLE.REORDER_COLUMN': 'Drag to reorder column',
108
+ 'GRID.TABLE.RESIZE_COLUMN': 'Drag to resize column',
109
+ 'GRID.TABLE.SORT_MENU.ASCENDING': '%s, Ascending',
110
+ 'GRID.TABLE.SORT_MENU.DESCENDING': '%s, Descending',
111
+ 'GRID.TABLE.SORT_MENU.RESET_SORT': 'Reset Sort',
112
+ 'GRID.TEMPLATE_EDITOR.CONFIG.AFTER': 'After',
113
+ 'GRID.TEMPLATE_EDITOR.CONFIG.AFTER_GROUP': 'After Group',
114
+ 'GRID.TEMPLATE_EDITOR.CONFIG.BEFORE': 'Before',
115
+ 'GRID.TEMPLATE_EDITOR.CONFIG.BEFORE_GROUP': 'Before Group',
116
+ 'GRID.TEMPLATE_EDITOR.CONFIG.EMPTY': 'Empty',
117
+ 'GRID.TEMPLATE_EDITOR.CONFIG.ITEM': 'Item',
118
+ 'GRID.TEMPLATE_EDITOR.GROUPED': 'Grouped',
119
+ 'GRID.TEMPLATE_EDITOR.PIVOTTED': 'Pivotted',
120
+ 'GRID.TEMPLATE_EDITOR.PLAIN': 'Plain',
121
+ 'GRID.TEMPLATE_EDITOR.TITLE': 'Template Editor',
122
+ 'GRID.TITLEBAR.CANCEL': 'Cancel',
123
+ 'GRID.TITLEBAR.CLEAR_FILTER': 'clear filter',
124
+ 'GRID.TITLEBAR.DATA_LIMITED_WARNING': 'To save time, not all records were retrieved. As a result, some functionality is reduced. Click to fetch all data (this may take some time).',
125
+ 'GRID.TITLEBAR.DOWNLOAD_CSV': 'Download CSV',
126
+ 'GRID.TITLEBAR.GENERATE_CSV': 'Generate CSV',
127
+ 'GRID.TITLEBAR.GROUP_COUNT_PLURAL': '%d groups',
128
+ 'GRID.TITLEBAR.GROUP_COUNT_SINGULAR': '%d group',
129
+ 'GRID.TITLEBAR.LOADED': 'Loaded',
130
+ 'GRID.TITLEBAR.LOADING': 'Loading...',
131
+ 'GRID.TITLEBAR.NOT_LOADED': 'Not Loaded',
132
+ 'GRID.TITLEBAR.RECORD_COUNT_PLURAL': '%d records',
133
+ 'GRID.TITLEBAR.RECORD_COUNT_SINGULAR': '%d record',
134
+ 'GRID.TITLEBAR.REFRESH': 'Refresh',
135
+ 'GRID.TITLEBAR.SELECTED_COUNT_PLURAL': '%d records selected',
136
+ 'GRID.TITLEBAR.SELECTED_COUNT_SINGULAR': '%d record selected',
137
+ 'GRID.TITLEBAR.SHOW_DEBUG_INFO': 'Show Grid Debug Info',
138
+ 'GRID.TITLEBAR.SHOW_HIDE': 'Show/Hide Grid',
139
+ 'GRID.TITLEBAR.SHOW_HIDE_CONTROLS': 'Show/Hide Grid Controls',
140
+ 'GRID.TITLEBAR.WORKING': 'Working...',
141
+ 'GRID_CONTROL.AGGREGATE.EDIT_OPTIONS': 'Edit options',
142
+ 'GRID_CONTROL.AGGREGATE.OPTIONS_DIALOG.TITLE': 'Options for %s',
143
+ 'GRID_CONTROL.AGGREGATE.TITLE': 'Aggregate',
144
+ 'GRID_CONTROL.FIELD': 'Field',
145
+ 'GRID_CONTROL.FIELD.REMOVE': 'Remove',
146
+ 'GRID_CONTROL.FIELD.SHOW_FUNCTIONS': 'Show functions available for this field',
147
+ 'GRID_CONTROL.FILTER.TITLE': 'Filters',
148
+ 'GRID_CONTROL.GROUP.TITLE': 'Group Fields',
149
+ 'GRID_CONTROL.OPERATIONS.TITLE': 'Operations',
150
+ 'GRID_CONTROL.PIVOT.TITLE': 'Pivot Fields',
151
+ 'GRID_CONTROL.SELECT_AGGREGATE': 'Select Aggregate',
152
+ 'GRID_CONTROL.SELECT_FIELD': 'Select Field',
153
+ 'GRID_TOOLBAR.GROUP.EXPAND_ALL': 'Expand All Groups',
154
+ 'GRID_TOOLBAR.GROUP.MODE.DETAIL': 'Detail',
155
+ 'GRID_TOOLBAR.GROUP.MODE.SUMMARY': 'Summary',
156
+ 'GRID_TOOLBAR.GROUP.PIN_GROUPS': 'Pin Groups',
157
+ 'GRID_TOOLBAR.GROUP.TOTAL_ROW': 'Total Row',
158
+ 'GRID_TOOLBAR.MIRAGE.STORE_DISPLAYED_DATA': 'Store Displayed Data',
159
+ 'GRID_TOOLBAR.PIVOT.HIDE_ZERO_VALUES': 'Hide Zero Values',
160
+ 'GRID_TOOLBAR.PIVOT.TOTAL_ROW_COLUMN': 'Total Row/Column',
161
+ 'GRID_TOOLBAR.PLAIN.AUTO_RESIZE_COLUMNS': 'Auto-resize Columns',
162
+ 'GRID_TOOLBAR.PLAIN.COLUMNS': 'Columns',
163
+ 'GRID_TOOLBAR.PLAIN.ROW_MODE': 'Row Mode',
164
+ 'GRID_TOOLBAR.PLAIN.ROW_MODE.CLIPPED': 'Clipped',
165
+ 'GRID_TOOLBAR.PLAIN.ROW_MODE.WRAPPED': 'Wrapped',
166
+ 'GRID_TOOLBAR.PLAIN.SHOW_ALL_ROWS': 'Show All Rows',
167
+ 'GRID_TOOLBAR.PLAIN.SHOW_MORE_ON_SCROLL': 'Show More on Scroll',
168
+ 'GRID_TOOLBAR.PLAIN.TEMPLATES_EDITOR': 'Templates Editor',
169
+ 'GRID_TOOLBAR.PREFS.BACK.TOOLTIP': 'Back',
170
+ 'GRID_TOOLBAR.PREFS.BACKEND_DOES_NOT_SAVE': 'The preferences system is not configured to permanently save perspectives.',
171
+ 'GRID_TOOLBAR.PREFS.DELETE.TOOLTIP': 'Delete',
172
+ 'GRID_TOOLBAR.PREFS.DELETE_PERSPECTIVE.CONFIRM': 'Are you sure you want to delete this perspective?',
173
+ 'GRID_TOOLBAR.PREFS.FORWARD.TOOLTIP': 'Forward',
174
+ 'GRID_TOOLBAR.PREFS.INFO.TOOLTIP': 'Info',
175
+ 'GRID_TOOLBAR.PREFS.NEW_PERSPECTIVE': 'New Perspective...',
176
+ 'GRID_TOOLBAR.PREFS.NEW_PERSPECTIVE.PROMPT': 'Enter new perspective name',
177
+ 'GRID_TOOLBAR.PREFS.RENAME.TOOLTIP': 'Rename',
178
+ 'GRID_TOOLBAR.PREFS.RENAME_PERSPECTIVE.PROMPT': 'Rename perspective "%s" to what?',
179
+ 'GRID_TOOLBAR.PREFS.RESET.CONFIRM': 'Are you sure you want to reset all configuration, delete all perspectives, and start over?',
180
+ 'GRID_TOOLBAR.PREFS.RESET.TOOLTIP': 'Reset',
181
+ 'GRID_TOOLBAR.PREFS.SAVE.HELP': 'Click to save the current configuration. The next time this grid is visited, the previously saved configuration will automatically be used.',
182
+ 'GRID_TOOLBAR.PREFS.SAVE.TOOLTIP': 'Save',
183
+ 'GRID_TOOLBAR.PREFS.SAVE_AS.HELP': 'This pre-defined perspective cannot be saved with this name. Click to save with a new name. After that, any changes will be saved under the new name.',
184
+ 'GRID_TOOLBAR.PREFS.SAVE_AS.TOOLTIP': 'Save As...',
185
+ 'GRID_TOOLBAR.RENDERER.DISPLAY_OPTIONS': 'Display Options',
186
+ 'POPUP_WINDOW.CLOSE': 'Close',
187
+ 'PREFS.MAIN_PERSPECTIVE': 'Main Perspective',
188
+ };