survey-analytics 1.12.53 → 1.12.55
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.
- package/fesm/shared.mjs +479 -15
- package/fesm/shared.mjs.map +1 -1
- package/fesm/shared2.mjs +783 -247
- package/fesm/shared2.mjs.map +1 -1
- package/fesm/survey.analytics.core.mjs +2 -2
- package/fesm/survey.analytics.mjs +27 -8
- package/fesm/survey.analytics.mjs.map +1 -1
- package/fesm/survey.analytics.mongo.mjs +221 -0
- package/fesm/survey.analytics.mongo.mjs.map +1 -0
- package/fesm/survey.analytics.tabulator.mjs +68 -26
- package/fesm/survey.analytics.tabulator.mjs.map +1 -1
- package/package.json +2 -2
- package/survey-analytics-tabulator.types/analytics-localization/finnish.d.ts +16 -0
- package/survey-analytics-tabulator.types/analytics-localization/swedish.d.ts +16 -0
- package/survey-analytics.types/analytics-localization/finnish.d.ts +16 -0
- package/survey-analytics.types/analytics-localization/swedish.d.ts +16 -0
- package/survey-analytics.types/entries/mongo.d.ts +1 -0
- package/survey-analytics.types/entries/summary.core.d.ts +1 -0
- package/survey-analytics.types/mongo/index.d.ts +16 -0
- package/survey-analytics.types/mongo/pipelines.d.ts +1 -0
- package/survey-analytics.types/mongo/result-transformers.d.ts +35 -0
- package/survey-analytics.types/statisticCalculators.d.ts +12 -2
- package/survey-analytics.types/visualizationComposite.d.ts +8 -0
- package/survey.analytics.core.css +1 -1
- package/survey.analytics.core.d.ts +1 -0
- package/survey.analytics.core.js +1365 -271
- package/survey.analytics.core.js.map +1 -1
- package/survey.analytics.core.min.css +1 -1
- package/survey.analytics.core.min.js +1 -1
- package/survey.analytics.core.min.js.LICENSE.txt +1 -1
- package/survey.analytics.css +1 -1
- package/survey.analytics.datatables.css +1 -1
- package/survey.analytics.datatables.js +1 -1
- package/survey.analytics.datatables.min.css +1 -1
- package/survey.analytics.datatables.min.js.LICENSE.txt +1 -1
- package/survey.analytics.js +1 -1
- package/survey.analytics.min.css +1 -1
- package/survey.analytics.min.js.LICENSE.txt +1 -1
- package/survey.analytics.mongo.d.ts +1 -0
- package/survey.analytics.mongo.js +359 -0
- package/survey.analytics.mongo.js.map +1 -0
- package/survey.analytics.mongo.min.js +2 -0
- package/survey.analytics.mongo.min.js.LICENSE.txt +5 -0
- package/survey.analytics.tabulator.css +1 -1
- package/survey.analytics.tabulator.js +1 -1
- package/survey.analytics.tabulator.min.css +1 -1
- package/survey.analytics.tabulator.min.js.LICENSE.txt +1 -1
package/fesm/shared2.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* surveyjs - SurveyJS Dashboard library v2.3.
|
|
2
|
+
* surveyjs - SurveyJS Dashboard library v2.3.11
|
|
3
3
|
* Copyright (c) 2015-2025 Devsoft Baltic OÜ - http://surveyjs.io/
|
|
4
4
|
* License: MIT (http://www.opensource.org/licenses/mit-license.php)
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { D as DocumentHelper, l as localization, g as createLoadingIndicator, b as DataHelper, e as createCommercialLicenseLink, f as svgTemplate, t as toPrecision } from './shared.mjs';
|
|
8
|
-
import { Event, hasLicense, QuestionCommentModel, settings, ItemValue, surveyLocalization, IsTouch } from 'survey-core';
|
|
8
|
+
import { Event, QuestionCustomModel, QuestionCompositeModel, hasLicense, QuestionCommentModel, settings, ItemValue, QuestionRatingModel, surveyLocalization, IsTouch } from 'survey-core';
|
|
9
9
|
|
|
10
10
|
/******************************************************************************
|
|
11
11
|
Copyright (c) Microsoft Corporation.
|
|
@@ -43,6 +43,10 @@ class DataProvider {
|
|
|
43
43
|
constructor(_data = []) {
|
|
44
44
|
this._data = _data;
|
|
45
45
|
this.filterValues = {};
|
|
46
|
+
/**
|
|
47
|
+
* Fires when data has been changed.
|
|
48
|
+
*/
|
|
49
|
+
this.onFilterChanged = new Event();
|
|
46
50
|
/**
|
|
47
51
|
* Fires when data has been changed.
|
|
48
52
|
*/
|
|
@@ -79,13 +83,17 @@ class DataProvider {
|
|
|
79
83
|
const filterValueType = typeof filterValue;
|
|
80
84
|
const questionValue = item[key];
|
|
81
85
|
if (Array.isArray(questionValue)) {
|
|
82
|
-
if (filterValueType
|
|
86
|
+
if (filterValueType === "object") {
|
|
87
|
+
return !questionArrayValueContainsValue(questionValue, filterValue);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
83
90
|
return questionValue.indexOf(filterValue) == -1;
|
|
91
|
+
}
|
|
84
92
|
}
|
|
85
93
|
if (typeof questionValue === "object") {
|
|
86
94
|
if (filterValueType !== "object")
|
|
87
95
|
return true;
|
|
88
|
-
return !
|
|
96
|
+
return !questionValueContainsValue(questionValue, filterValue);
|
|
89
97
|
}
|
|
90
98
|
const seriesValue = item[DataProvider.seriesMarkerKey];
|
|
91
99
|
if (!!seriesValue && filterValueType === "object") {
|
|
@@ -118,16 +126,37 @@ class DataProvider {
|
|
|
118
126
|
var filterChanged = true;
|
|
119
127
|
if (selectedValue !== undefined) {
|
|
120
128
|
filterChanged = this.filterValues[questionName] !== selectedValue;
|
|
121
|
-
|
|
129
|
+
if (filterChanged) {
|
|
130
|
+
this.filterValues[questionName] = selectedValue;
|
|
131
|
+
}
|
|
122
132
|
}
|
|
123
133
|
else {
|
|
124
134
|
filterChanged = this.filterValues[questionName] !== undefined;
|
|
125
|
-
|
|
135
|
+
if (filterChanged) {
|
|
136
|
+
delete this.filterValues[questionName];
|
|
137
|
+
}
|
|
126
138
|
}
|
|
127
139
|
if (filterChanged) {
|
|
140
|
+
this.raiseFilterChanged(questionName, selectedValue);
|
|
128
141
|
this.raiseDataChanged();
|
|
129
142
|
}
|
|
130
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* Resets filter.
|
|
146
|
+
*/
|
|
147
|
+
resetFilter() {
|
|
148
|
+
if (Object.keys(this.filterValues).length === 0) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
Object.keys(this.filterValues).forEach(key => delete this.filterValues[key]);
|
|
152
|
+
this.raiseFilterChanged();
|
|
153
|
+
this.raiseDataChanged();
|
|
154
|
+
}
|
|
155
|
+
raiseFilterChanged(questionName, selectedValue) {
|
|
156
|
+
if (!this.onFilterChanged.isEmpty) {
|
|
157
|
+
this.onFilterChanged.fire(this, { questionName, selectedValue });
|
|
158
|
+
}
|
|
159
|
+
}
|
|
131
160
|
raiseDataChanged(questionName) {
|
|
132
161
|
this._filteredData = undefined;
|
|
133
162
|
if (!this.onDataChanged.isEmpty) {
|
|
@@ -137,9 +166,31 @@ class DataProvider {
|
|
|
137
166
|
getFilters() {
|
|
138
167
|
return Object.keys(this.filterValues).map(key => ({ field: key, type: "=", value: this.filterValues[key] }));
|
|
139
168
|
}
|
|
169
|
+
fixDropdownData(dataNames) {
|
|
170
|
+
(this.data || []).forEach((dataItem) => {
|
|
171
|
+
let rawDataItem = dataItem[dataNames[0]];
|
|
172
|
+
if (!!rawDataItem && typeof rawDataItem === "object" && !Array.isArray(rawDataItem)) {
|
|
173
|
+
const arrayData = [];
|
|
174
|
+
Object.keys(rawDataItem).forEach((key) => {
|
|
175
|
+
var nestedDataItem = Object.assign({}, rawDataItem[key]);
|
|
176
|
+
nestedDataItem[DataProvider.seriesMarkerKey] = key;
|
|
177
|
+
arrayData.push(nestedDataItem);
|
|
178
|
+
});
|
|
179
|
+
dataItem[dataNames[0]] = arrayData;
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
140
183
|
}
|
|
141
184
|
DataProvider.seriesMarkerKey = "__sa_series_name";
|
|
142
|
-
function
|
|
185
|
+
function questionArrayValueContainsValue(questionValues, filterValue) {
|
|
186
|
+
for (let i = 0; i < questionValues.length; i++) {
|
|
187
|
+
if (questionValueContainsValue(questionValues[i], filterValue)) {
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
function questionValueContainsValue(questionValue, filterValue) {
|
|
143
194
|
const questionValueKeys = Object.keys(questionValue);
|
|
144
195
|
const filterValueKeys = Object.keys(filterValue);
|
|
145
196
|
if (filterValueKeys.length > questionValueKeys.length)
|
|
@@ -282,16 +333,26 @@ class VisualizerFactory {
|
|
|
282
333
|
static createVisualizer(question, data, options) {
|
|
283
334
|
let type = question.getType();
|
|
284
335
|
let creators = [];
|
|
336
|
+
let questionForCreator = question;
|
|
337
|
+
let optionsForCreator = Object.assign({}, options);
|
|
285
338
|
if (type === "text" && question.inputType) {
|
|
286
339
|
creators = VisualizationManager.getVisualizersByType(question.inputType, type);
|
|
287
340
|
}
|
|
288
341
|
else {
|
|
289
|
-
|
|
342
|
+
let fallbackType = undefined;
|
|
343
|
+
if (question instanceof QuestionCustomModel) {
|
|
344
|
+
fallbackType = question.getDynamicType();
|
|
345
|
+
// questionForCreator = question.contentQuestion;
|
|
346
|
+
}
|
|
347
|
+
else if (question instanceof QuestionCompositeModel) {
|
|
348
|
+
fallbackType = "composite";
|
|
349
|
+
}
|
|
350
|
+
creators = VisualizationManager.getVisualizersByType(type, fallbackType);
|
|
290
351
|
}
|
|
291
|
-
var visualizers = creators.map((creator) => new creator(
|
|
352
|
+
var visualizers = creators.map((creator) => new creator(questionForCreator, data, optionsForCreator));
|
|
292
353
|
if (visualizers.length > 1) {
|
|
293
354
|
const alternativesVisualizerConstructor = VisualizationManager.getAltVisualizerSelector();
|
|
294
|
-
let visualizer = new alternativesVisualizerConstructor(visualizers,
|
|
355
|
+
let visualizer = new alternativesVisualizerConstructor(visualizers, questionForCreator, data, optionsForCreator);
|
|
295
356
|
return visualizer;
|
|
296
357
|
}
|
|
297
358
|
return visualizers[0];
|
|
@@ -325,51 +386,58 @@ function defaultStatisticsCalculator(data, dataInfo) {
|
|
|
325
386
|
return valuesIndex[val.value];
|
|
326
387
|
return valuesIndex[val];
|
|
327
388
|
};
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
});
|
|
342
|
-
}
|
|
343
|
-
else {
|
|
344
|
-
// Series are the keys in question value (matrix question)
|
|
345
|
-
// TODO: think about the de-normalization and combine with the previous case
|
|
346
|
-
rowValues.forEach((val) => {
|
|
347
|
-
series.forEach((seriesName) => {
|
|
348
|
-
if (val[seriesName] !== undefined) {
|
|
349
|
-
const seriesNo = seriesIndex[seriesName] || 0;
|
|
350
|
-
const values = Array.isArray(val[seriesName]) ? val[seriesName] : [val[seriesName]];
|
|
351
|
-
values.forEach(value => {
|
|
352
|
-
const valIndex = getValueIndex(value);
|
|
353
|
-
statistics[index][seriesNo][valIndex]++;
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
});
|
|
357
|
-
});
|
|
358
|
-
}
|
|
389
|
+
const processDataRow = (dataRow, dataName, index) => {
|
|
390
|
+
const rowValue = dataRow[dataName];
|
|
391
|
+
if (rowValue !== undefined || processMissingAnswers) {
|
|
392
|
+
const rowValues = Array.isArray(rowValue) ? rowValue : [rowValue];
|
|
393
|
+
if (series.length > 0) {
|
|
394
|
+
const rowName = dataRow[DataProvider.seriesMarkerKey];
|
|
395
|
+
if (rowName !== undefined) {
|
|
396
|
+
// Series are labelled by seriesMarkerKey in row data
|
|
397
|
+
const seriesNo = seriesIndex[rowName] || 0;
|
|
398
|
+
rowValues.forEach((val) => {
|
|
399
|
+
const valIndex = getValueIndex(val);
|
|
400
|
+
statistics[index][seriesNo][valIndex]++;
|
|
401
|
+
});
|
|
359
402
|
}
|
|
360
403
|
else {
|
|
361
|
-
//
|
|
404
|
+
// Series are the keys in question value (matrix question)
|
|
405
|
+
// TODO: think about the de-normalization and combine with the previous case
|
|
362
406
|
rowValues.forEach((val) => {
|
|
363
|
-
|
|
364
|
-
|
|
407
|
+
series.forEach((seriesName) => {
|
|
408
|
+
if (val[seriesName] !== undefined) {
|
|
409
|
+
const seriesNo = seriesIndex[seriesName] || 0;
|
|
410
|
+
const values = Array.isArray(val[seriesName]) ? val[seriesName] : [val[seriesName]];
|
|
411
|
+
values.forEach(value => {
|
|
412
|
+
const valIndex = getValueIndex(value);
|
|
413
|
+
statistics[index][seriesNo][valIndex]++;
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
});
|
|
365
417
|
});
|
|
366
418
|
}
|
|
367
419
|
}
|
|
420
|
+
else {
|
|
421
|
+
// No series
|
|
422
|
+
rowValues.forEach((val) => {
|
|
423
|
+
const valIndex = getValueIndex(val);
|
|
424
|
+
statistics[0][0][valIndex]++;
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
data.forEach((dataRow) => {
|
|
430
|
+
const nestedDataRows = getNestedDataRows(dataRow, dataInfo);
|
|
431
|
+
nestedDataRows.forEach(nestedDataRow => {
|
|
432
|
+
dataNames.forEach((dataName, index) => {
|
|
433
|
+
processDataRow(nestedDataRow, dataName, index);
|
|
434
|
+
});
|
|
368
435
|
});
|
|
369
436
|
});
|
|
370
437
|
return dataInfo.dataNames.length > 1 ? statistics : statistics[0];
|
|
371
438
|
}
|
|
372
|
-
function histogramStatisticsCalculator(data, intervals,
|
|
439
|
+
function histogramStatisticsCalculator(data, intervals, dataInfo, aggregateDataNames = []) {
|
|
440
|
+
const seriesValues = dataInfo.getSeriesValues();
|
|
373
441
|
const statistics = [];
|
|
374
442
|
if (seriesValues.length === 0) {
|
|
375
443
|
seriesValues.push("");
|
|
@@ -378,8 +446,19 @@ function histogramStatisticsCalculator(data, intervals, seriesValues) {
|
|
|
378
446
|
statistics.push(intervals.map(i => 0));
|
|
379
447
|
data[seriesValues[i]].forEach(dataValue => {
|
|
380
448
|
for (let j = 0; j < intervals.length; ++j) {
|
|
381
|
-
if (intervals[j].start <= dataValue && (dataValue < intervals[j].end || j == intervals.length - 1)) {
|
|
382
|
-
|
|
449
|
+
if (intervals[j].start <= dataValue.continuous && (dataValue.continuous < intervals[j].end || j == intervals.length - 1)) {
|
|
450
|
+
if (aggregateDataNames.length > 0) {
|
|
451
|
+
aggregateDataNames.forEach(aggregateDataName => {
|
|
452
|
+
const aggregateDataValue = dataValue.row[aggregateDataName];
|
|
453
|
+
const numberValue = parseFloat(aggregateDataValue);
|
|
454
|
+
if (aggregateDataValue !== undefined && !isNaN(numberValue)) {
|
|
455
|
+
statistics[i][j] += numberValue;
|
|
456
|
+
}
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
else {
|
|
460
|
+
statistics[i][j]++;
|
|
461
|
+
}
|
|
383
462
|
break;
|
|
384
463
|
}
|
|
385
464
|
}
|
|
@@ -387,21 +466,25 @@ function histogramStatisticsCalculator(data, intervals, seriesValues) {
|
|
|
387
466
|
}
|
|
388
467
|
return statistics;
|
|
389
468
|
}
|
|
390
|
-
function mathStatisticsCalculator(data,
|
|
469
|
+
function mathStatisticsCalculator(data, dataInfo) {
|
|
391
470
|
let resultMin = Number.MAX_VALUE, resultMax = -Number.MAX_VALUE, resultAverage = 0;
|
|
392
471
|
let actualAnswerCount = 0;
|
|
393
|
-
data.forEach((
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
472
|
+
data.forEach((dataRow) => {
|
|
473
|
+
const nestedDataRows = getNestedDataRows(dataRow, dataInfo);
|
|
474
|
+
nestedDataRows.forEach(nestedDataRow => {
|
|
475
|
+
const answerData = nestedDataRow[dataInfo.dataNames[0]];
|
|
476
|
+
if (answerData !== undefined) {
|
|
477
|
+
const questionValue = +answerData;
|
|
478
|
+
actualAnswerCount++;
|
|
479
|
+
resultAverage += questionValue;
|
|
480
|
+
if (resultMin > questionValue) {
|
|
481
|
+
resultMin = questionValue;
|
|
482
|
+
}
|
|
483
|
+
if (resultMax < questionValue) {
|
|
484
|
+
resultMax = questionValue;
|
|
485
|
+
}
|
|
403
486
|
}
|
|
404
|
-
}
|
|
487
|
+
});
|
|
405
488
|
});
|
|
406
489
|
if (actualAnswerCount > 0) {
|
|
407
490
|
resultAverage = resultAverage / actualAnswerCount;
|
|
@@ -409,6 +492,25 @@ function mathStatisticsCalculator(data, dataName) {
|
|
|
409
492
|
resultAverage = Math.ceil(resultAverage * 100) / 100;
|
|
410
493
|
return [resultAverage, resultMin, resultMax];
|
|
411
494
|
}
|
|
495
|
+
function getNestedDataRows(dataRow, dataInfo) {
|
|
496
|
+
let nestedDataRows = [];
|
|
497
|
+
if (!dataInfo.dataPath) {
|
|
498
|
+
nestedDataRows = [dataRow];
|
|
499
|
+
}
|
|
500
|
+
else {
|
|
501
|
+
if (dataRow[dataInfo.dataPath] === undefined)
|
|
502
|
+
return [];
|
|
503
|
+
if (typeof dataRow[dataInfo.dataPath] !== "object")
|
|
504
|
+
return [];
|
|
505
|
+
if (Array.isArray(dataRow[dataInfo.dataPath])) {
|
|
506
|
+
nestedDataRows = dataRow[dataInfo.dataPath];
|
|
507
|
+
}
|
|
508
|
+
else {
|
|
509
|
+
nestedDataRows = [dataRow[dataInfo.dataPath]];
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
return nestedDataRows;
|
|
513
|
+
}
|
|
412
514
|
|
|
413
515
|
class PostponeHelper {
|
|
414
516
|
static postpone(fn, timeout) {
|
|
@@ -563,6 +665,9 @@ class VisualizerBase {
|
|
|
563
665
|
get dataNames() {
|
|
564
666
|
return [this.name];
|
|
565
667
|
}
|
|
668
|
+
get dataPath() {
|
|
669
|
+
return this.options.dataPath;
|
|
670
|
+
}
|
|
566
671
|
/**
|
|
567
672
|
* Indicates whether the visualizer displays a header. This property is `true` when a visualized question has a correct answer.
|
|
568
673
|
* @see hasFooter
|
|
@@ -689,6 +794,18 @@ class VisualizerBase {
|
|
|
689
794
|
}
|
|
690
795
|
return undefined;
|
|
691
796
|
}
|
|
797
|
+
/**
|
|
798
|
+
* Returns the visualizer's title.
|
|
799
|
+
*/
|
|
800
|
+
get title() {
|
|
801
|
+
return this.getTitle(this.question);
|
|
802
|
+
}
|
|
803
|
+
getTitle(question) {
|
|
804
|
+
var _a;
|
|
805
|
+
if (question === undefined)
|
|
806
|
+
return "";
|
|
807
|
+
return this.processText(((_a = question.locTitle) === null || _a === void 0 ? void 0 : _a.renderedHtml) ? question.locTitle.renderedHtml : question.title);
|
|
808
|
+
}
|
|
692
809
|
/**
|
|
693
810
|
* Returns the visualizer's type.
|
|
694
811
|
*/
|
|
@@ -717,9 +834,7 @@ class VisualizerBase {
|
|
|
717
834
|
* @param data A data array with survey results to be visualized.
|
|
718
835
|
*/
|
|
719
836
|
updateData(data) {
|
|
720
|
-
|
|
721
|
-
this.dataProvider.data = data;
|
|
722
|
-
}
|
|
837
|
+
this.dataProvider.data = data;
|
|
723
838
|
if (this.hasFooter) {
|
|
724
839
|
this.footerVisualizer.updateData(data);
|
|
725
840
|
}
|
|
@@ -1172,19 +1287,21 @@ class NumberModel extends VisualizerBase {
|
|
|
1172
1287
|
this.chartTypes = this._chartAdapter.getChartTypes();
|
|
1173
1288
|
this.chartType = this.chartTypes[0];
|
|
1174
1289
|
}
|
|
1175
|
-
this.
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
return {
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
this.
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1290
|
+
if (this.options.allowChangeVisualizerType !== false) {
|
|
1291
|
+
this.registerToolbarItem("changeChartType", () => {
|
|
1292
|
+
if (this.chartTypes.length > 1) {
|
|
1293
|
+
return DocumentHelper.createSelector(this.chartTypes.map((chartType) => {
|
|
1294
|
+
return {
|
|
1295
|
+
value: chartType,
|
|
1296
|
+
text: localization.getString("chartType_" + chartType),
|
|
1297
|
+
};
|
|
1298
|
+
}), (option) => this.chartType === option.value, (e) => {
|
|
1299
|
+
this.setChartType(e.target.value);
|
|
1300
|
+
});
|
|
1301
|
+
}
|
|
1302
|
+
return null;
|
|
1303
|
+
});
|
|
1304
|
+
}
|
|
1188
1305
|
}
|
|
1189
1306
|
onDataChanged() {
|
|
1190
1307
|
this._resultAverage = undefined;
|
|
@@ -1258,7 +1375,7 @@ class NumberModel extends VisualizerBase {
|
|
|
1258
1375
|
if (this._resultAverage === undefined ||
|
|
1259
1376
|
this._resultMin === undefined ||
|
|
1260
1377
|
this._resultMax === undefined) {
|
|
1261
|
-
[this._resultAverage, this._resultMin, this._resultMax] = mathStatisticsCalculator(this.surveyData, this
|
|
1378
|
+
[this._resultAverage, this._resultMin, this._resultMax] = mathStatisticsCalculator(this.surveyData, this);
|
|
1262
1379
|
}
|
|
1263
1380
|
return [this._resultAverage, this._resultMin, this._resultMax];
|
|
1264
1381
|
}
|
|
@@ -1383,19 +1500,21 @@ class SelectBase extends VisualizerBase {
|
|
|
1383
1500
|
this._chartType = this.options.defaultChartType;
|
|
1384
1501
|
}
|
|
1385
1502
|
}
|
|
1386
|
-
this.
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
return {
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
this.
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1503
|
+
if (this.options.allowChangeVisualizerType !== false) {
|
|
1504
|
+
this.registerToolbarItem("changeChartType", () => {
|
|
1505
|
+
if (this.chartTypes.length > 1) {
|
|
1506
|
+
return DocumentHelper.createSelector(this.chartTypes.map((chartType) => {
|
|
1507
|
+
return {
|
|
1508
|
+
value: chartType,
|
|
1509
|
+
text: localization.getString("chartType_" + chartType),
|
|
1510
|
+
};
|
|
1511
|
+
}), (option) => this.chartType === option.value, (e) => {
|
|
1512
|
+
this.setChartType(e.target.value);
|
|
1513
|
+
});
|
|
1514
|
+
}
|
|
1515
|
+
return null;
|
|
1516
|
+
});
|
|
1517
|
+
}
|
|
1399
1518
|
this.registerToolbarItem("changeAnswersOrder", () => {
|
|
1400
1519
|
if (this.isSupportAnswersOrder()) {
|
|
1401
1520
|
this.choicesOrderSelector = DocumentHelper.createSelector([
|
|
@@ -1571,6 +1690,11 @@ class SelectBase extends VisualizerBase {
|
|
|
1571
1690
|
}
|
|
1572
1691
|
}
|
|
1573
1692
|
getSelectedItemByText(itemText) {
|
|
1693
|
+
var _a;
|
|
1694
|
+
if (this.question instanceof QuestionRatingModel) {
|
|
1695
|
+
const rateValues = this.question.rateValues;
|
|
1696
|
+
return (_a = rateValues === null || rateValues === void 0 ? void 0 : rateValues.filter((choice) => choice.text === itemText)[0]) !== null && _a !== void 0 ? _a : new ItemValue(parseFloat(itemText), itemText);
|
|
1697
|
+
}
|
|
1574
1698
|
const selBase = this.question;
|
|
1575
1699
|
if (this.question.hasOther && itemText == selBase.otherText) {
|
|
1576
1700
|
return selBase.otherItem;
|
|
@@ -1579,14 +1703,17 @@ class SelectBase extends VisualizerBase {
|
|
|
1579
1703
|
return selBase.choices.filter((choice) => choice.text === itemText)[0];
|
|
1580
1704
|
}
|
|
1581
1705
|
}
|
|
1582
|
-
|
|
1706
|
+
onSelectionChanged(item) {
|
|
1583
1707
|
var _a;
|
|
1708
|
+
if (this.onDataItemSelected !== undefined) {
|
|
1709
|
+
this.onDataItemSelected(item !== undefined ? item.value : undefined, item !== undefined ? item.text : "");
|
|
1710
|
+
}
|
|
1711
|
+
this.stateChanged("filter", (_a = this.selectedItem) === null || _a === void 0 ? void 0 : _a.value);
|
|
1712
|
+
}
|
|
1713
|
+
setSelection(item) {
|
|
1584
1714
|
if (this.selectedItem !== item) {
|
|
1585
1715
|
this.selectedItem = item;
|
|
1586
|
-
|
|
1587
|
-
this.onDataItemSelected(item !== undefined ? item.value : undefined, item !== undefined ? item.text : "");
|
|
1588
|
-
}
|
|
1589
|
-
this.stateChanged("filter", (_a = this.selectedItem) === null || _a === void 0 ? void 0 : _a.value);
|
|
1716
|
+
this.onSelectionChanged(item);
|
|
1590
1717
|
}
|
|
1591
1718
|
}
|
|
1592
1719
|
get selection() {
|
|
@@ -1772,22 +1899,6 @@ class SelectBase extends VisualizerBase {
|
|
|
1772
1899
|
}
|
|
1773
1900
|
return percentages;
|
|
1774
1901
|
}
|
|
1775
|
-
answersDataReady(answersData) {
|
|
1776
|
-
let result = {};
|
|
1777
|
-
if (this.hideEmptyAnswers) {
|
|
1778
|
-
result = hideEmptyAnswersInData(answersData);
|
|
1779
|
-
}
|
|
1780
|
-
else {
|
|
1781
|
-
result = answersData;
|
|
1782
|
-
}
|
|
1783
|
-
if (this.topN > 0) {
|
|
1784
|
-
result.datasets[0] = result.datasets[0].slice(-this.topN);
|
|
1785
|
-
result.labels = result.labels.slice(-this.topN);
|
|
1786
|
-
result.colors = result.colors.slice(-this.topN);
|
|
1787
|
-
result.texts[0] = result.texts[0].slice(-this.topN);
|
|
1788
|
-
}
|
|
1789
|
-
return result;
|
|
1790
|
-
}
|
|
1791
1902
|
/**
|
|
1792
1903
|
* Returns object with all infotmation for data visualization: datasets, labels, colors, additional texts (percentage).
|
|
1793
1904
|
*/
|
|
@@ -1823,7 +1934,15 @@ class SelectBase extends VisualizerBase {
|
|
|
1823
1934
|
texts,
|
|
1824
1935
|
seriesLabels,
|
|
1825
1936
|
};
|
|
1826
|
-
|
|
1937
|
+
if (this.hideEmptyAnswers) {
|
|
1938
|
+
answersData = hideEmptyAnswersInData(answersData);
|
|
1939
|
+
}
|
|
1940
|
+
if (this.topN > 0) {
|
|
1941
|
+
answersData.datasets[0] = answersData.datasets[0].slice(-this.topN);
|
|
1942
|
+
answersData.labels = answersData.labels.slice(-this.topN);
|
|
1943
|
+
answersData.colors = answersData.colors.slice(-this.topN);
|
|
1944
|
+
answersData.texts[0] = answersData.texts[0].slice(-this.topN);
|
|
1945
|
+
}
|
|
1827
1946
|
this.onAnswersDataReady.fire(this, answersData);
|
|
1828
1947
|
return answersData;
|
|
1829
1948
|
});
|
|
@@ -1961,6 +2080,144 @@ BooleanModel.trueColor = "";
|
|
|
1961
2080
|
BooleanModel.falseColor = "";
|
|
1962
2081
|
VisualizationManager.registerVisualizer("boolean", BooleanModel);
|
|
1963
2082
|
|
|
2083
|
+
function getQuarter(date) {
|
|
2084
|
+
switch (Math.floor(date.getMonth() / 3) + 1) {
|
|
2085
|
+
case 1: return "I";
|
|
2086
|
+
case 2: return "II";
|
|
2087
|
+
case 3: return "III";
|
|
2088
|
+
case 4: return "IV";
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
function getBestIntervalMode(min, max) {
|
|
2092
|
+
const start = new Date(min);
|
|
2093
|
+
const end = new Date(max);
|
|
2094
|
+
const totalMonths = (end.getFullYear() - start.getFullYear()) * 12 + (end.getMonth() - start.getMonth());
|
|
2095
|
+
if (totalMonths > 10 * 12)
|
|
2096
|
+
return "decades";
|
|
2097
|
+
if (totalMonths > 2 * 12)
|
|
2098
|
+
return "years";
|
|
2099
|
+
if (totalMonths > 1 * 12)
|
|
2100
|
+
return "quarters";
|
|
2101
|
+
if (totalMonths > 4)
|
|
2102
|
+
return "months";
|
|
2103
|
+
return "days";
|
|
2104
|
+
}
|
|
2105
|
+
const intervalCalculators = {
|
|
2106
|
+
decades: (min, max) => {
|
|
2107
|
+
const intervals = [];
|
|
2108
|
+
let start = new Date(min);
|
|
2109
|
+
start.setFullYear(Math.floor(start.getFullYear() / 10) * 10);
|
|
2110
|
+
start.setMonth(0);
|
|
2111
|
+
start.setDate(1);
|
|
2112
|
+
start.setHours(0, 0, 0, 0);
|
|
2113
|
+
let startYear = start.getFullYear();
|
|
2114
|
+
const end = new Date(max);
|
|
2115
|
+
const endYear = end.getFullYear();
|
|
2116
|
+
while (startYear <= endYear) {
|
|
2117
|
+
const intervalStart = new Date(startYear, 0, 1);
|
|
2118
|
+
const intervalEnd = new Date(startYear + 10, 0, 1);
|
|
2119
|
+
intervals.push({
|
|
2120
|
+
start: intervalStart.getTime(),
|
|
2121
|
+
end: intervalEnd.getTime(),
|
|
2122
|
+
label: "" + startYear + "s"
|
|
2123
|
+
});
|
|
2124
|
+
startYear += 10;
|
|
2125
|
+
}
|
|
2126
|
+
return intervals;
|
|
2127
|
+
},
|
|
2128
|
+
years: (min, max) => {
|
|
2129
|
+
const intervals = [];
|
|
2130
|
+
let start = new Date(min);
|
|
2131
|
+
start.setMonth(0);
|
|
2132
|
+
start.setDate(1);
|
|
2133
|
+
start.setHours(0, 0, 0, 0);
|
|
2134
|
+
let startYear = start.getFullYear();
|
|
2135
|
+
const end = new Date(max);
|
|
2136
|
+
const endYear = end.getFullYear();
|
|
2137
|
+
while (startYear <= endYear) {
|
|
2138
|
+
const intervalStart = new Date(startYear, 0, 1);
|
|
2139
|
+
const intervalEnd = new Date(startYear + 1, 0, 1);
|
|
2140
|
+
intervals.push({
|
|
2141
|
+
start: intervalStart.getTime(),
|
|
2142
|
+
end: intervalEnd.getTime(),
|
|
2143
|
+
label: "" + startYear
|
|
2144
|
+
});
|
|
2145
|
+
startYear++;
|
|
2146
|
+
}
|
|
2147
|
+
return intervals;
|
|
2148
|
+
},
|
|
2149
|
+
months: (min, max) => {
|
|
2150
|
+
const intervals = [];
|
|
2151
|
+
let start = new Date(min);
|
|
2152
|
+
start.setDate(1);
|
|
2153
|
+
start.setHours(0, 0, 0, 0);
|
|
2154
|
+
let startYear = start.getFullYear();
|
|
2155
|
+
let startMonth = start.getMonth();
|
|
2156
|
+
const end = new Date(max);
|
|
2157
|
+
const endYear = end.getFullYear();
|
|
2158
|
+
const endMonth = end.getMonth();
|
|
2159
|
+
while (startYear < endYear || (startYear === endYear && startMonth <= endMonth)) {
|
|
2160
|
+
const intervalStart = new Date(startYear, startMonth, 1);
|
|
2161
|
+
const intervalEnd = new Date(startYear, startMonth + 1, 1);
|
|
2162
|
+
intervals.push({
|
|
2163
|
+
start: intervalStart.getTime(),
|
|
2164
|
+
end: intervalEnd.getTime(),
|
|
2165
|
+
label: intervalStart.toLocaleDateString(undefined, { year: "numeric", month: "short" })
|
|
2166
|
+
});
|
|
2167
|
+
startMonth++;
|
|
2168
|
+
if (startMonth >= 12) {
|
|
2169
|
+
startMonth = 0;
|
|
2170
|
+
startYear++;
|
|
2171
|
+
}
|
|
2172
|
+
}
|
|
2173
|
+
return intervals;
|
|
2174
|
+
},
|
|
2175
|
+
quarters: (min, max) => {
|
|
2176
|
+
const intervals = [];
|
|
2177
|
+
let start = new Date(min);
|
|
2178
|
+
start.setDate(1);
|
|
2179
|
+
start.setHours(0, 0, 0, 0);
|
|
2180
|
+
let startYear = start.getFullYear();
|
|
2181
|
+
let startMonth = start.getMonth();
|
|
2182
|
+
const end = new Date(max);
|
|
2183
|
+
const endYear = end.getFullYear();
|
|
2184
|
+
const endMonth = end.getMonth();
|
|
2185
|
+
while (startYear < endYear || (startYear === endYear && startMonth <= endMonth)) {
|
|
2186
|
+
const intervalStart = new Date(startYear, startMonth, 1);
|
|
2187
|
+
const intervalEnd = new Date(startYear, startMonth + 3, 1);
|
|
2188
|
+
intervals.push({
|
|
2189
|
+
start: intervalStart.getTime(),
|
|
2190
|
+
end: intervalEnd.getTime(),
|
|
2191
|
+
label: getQuarter(intervalStart) + " " + intervalStart.getFullYear().toString()
|
|
2192
|
+
});
|
|
2193
|
+
startMonth += 3;
|
|
2194
|
+
if (startMonth >= 12) {
|
|
2195
|
+
startMonth = startMonth % 12;
|
|
2196
|
+
startYear++;
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
return intervals;
|
|
2200
|
+
},
|
|
2201
|
+
days: (min, max) => {
|
|
2202
|
+
const intervals = [];
|
|
2203
|
+
let start = new Date(min);
|
|
2204
|
+
start.setHours(0, 0, 0, 0);
|
|
2205
|
+
const end = new Date(max);
|
|
2206
|
+
end.setHours(0, 0, 0, 0);
|
|
2207
|
+
while (start <= end) {
|
|
2208
|
+
const intervalStart = new Date(start);
|
|
2209
|
+
const intervalEnd = new Date(start);
|
|
2210
|
+
intervalEnd.setDate(intervalEnd.getDate() + 1);
|
|
2211
|
+
intervals.push({
|
|
2212
|
+
start: intervalStart.getTime(),
|
|
2213
|
+
end: intervalEnd.getTime(),
|
|
2214
|
+
label: intervalStart.toLocaleDateString()
|
|
2215
|
+
});
|
|
2216
|
+
start.setDate(start.getDate() + 1);
|
|
2217
|
+
}
|
|
2218
|
+
return intervals;
|
|
2219
|
+
}
|
|
2220
|
+
};
|
|
1964
2221
|
class HistogramModel extends SelectBase {
|
|
1965
2222
|
constructor(question, data, options, name) {
|
|
1966
2223
|
super(question, data, options, name || "histogram");
|
|
@@ -1969,6 +2226,14 @@ class HistogramModel extends SelectBase {
|
|
|
1969
2226
|
this._continuousData = undefined;
|
|
1970
2227
|
this._cachedIntervals = undefined;
|
|
1971
2228
|
this._intervalPrecision = 2;
|
|
2229
|
+
this.showRunningTotalsBtn = undefined;
|
|
2230
|
+
this.showGroupedBtn = undefined;
|
|
2231
|
+
this.changeIntervalsModeSelector = undefined;
|
|
2232
|
+
this.aggregateDataNameSelector = undefined;
|
|
2233
|
+
this.intervalModes = ["auto", "decades", "years", "quarters", "months", "days"];
|
|
2234
|
+
this._showRunningTotals = false;
|
|
2235
|
+
this._showGrouped = false;
|
|
2236
|
+
this._aggregateDataName = "";
|
|
1972
2237
|
this._transposeData = false;
|
|
1973
2238
|
if (this.options.intervalPrecision !== undefined) {
|
|
1974
2239
|
this._intervalPrecision = this.options.intervalPrecision;
|
|
@@ -1980,6 +2245,61 @@ class HistogramModel extends SelectBase {
|
|
|
1980
2245
|
else {
|
|
1981
2246
|
this.valueType = "number";
|
|
1982
2247
|
}
|
|
2248
|
+
this._intervalsMode = this.valueType === "date" ? "auto" : "default";
|
|
2249
|
+
if (this.allowChangeIntervals) {
|
|
2250
|
+
this.registerToolbarItem("changeIntervalsMode", () => {
|
|
2251
|
+
this.changeIntervalsModeSelector = DocumentHelper.createSelector(this.intervalModes.map((intervalModeValue) => {
|
|
2252
|
+
return {
|
|
2253
|
+
value: intervalModeValue,
|
|
2254
|
+
text: localization.getString("intervalMode_" + intervalModeValue),
|
|
2255
|
+
};
|
|
2256
|
+
}), (option) => this.intervalsMode === option.value, (e) => {
|
|
2257
|
+
this.intervalsMode = e.target.value;
|
|
2258
|
+
}, localization.getString("intervalModeTitle"));
|
|
2259
|
+
return this.changeIntervalsModeSelector;
|
|
2260
|
+
});
|
|
2261
|
+
}
|
|
2262
|
+
if (this.possibleAggregateDataNames.length > 0) {
|
|
2263
|
+
this.registerToolbarItem("aggregateDataName", () => {
|
|
2264
|
+
const choices = this.possibleAggregateDataNames.map((dataName) => {
|
|
2265
|
+
return typeof dataName === "string" ? { value: dataName, text: dataName } : dataName;
|
|
2266
|
+
});
|
|
2267
|
+
choices.unshift({ value: "", text: localization.getString("noneAggregateText") }),
|
|
2268
|
+
this.aggregateDataNameSelector = DocumentHelper.createSelector(choices, (option) => this.aggregateDataName === option.value, (e) => {
|
|
2269
|
+
this.aggregateDataName = e.target.value;
|
|
2270
|
+
}, localization.getString("selectAggregateText"));
|
|
2271
|
+
this.updateAggregateDataNameSelector();
|
|
2272
|
+
return this.aggregateDataNameSelector;
|
|
2273
|
+
});
|
|
2274
|
+
}
|
|
2275
|
+
if (this.allowChangeIntervals && this.options.allowRunningTotals) {
|
|
2276
|
+
this.registerToolbarItem("showRunningTotals", () => {
|
|
2277
|
+
this.showRunningTotalsBtn = DocumentHelper.createButton(() => {
|
|
2278
|
+
this.showRunningTotals = !this.showRunningTotals;
|
|
2279
|
+
});
|
|
2280
|
+
this.updateShowRunningTotalsBtn();
|
|
2281
|
+
return this.showRunningTotalsBtn;
|
|
2282
|
+
});
|
|
2283
|
+
}
|
|
2284
|
+
if (this.allowChangeIntervals && this.options.allowCompareDatePeriods) {
|
|
2285
|
+
this.registerToolbarItem("showGrouped", () => {
|
|
2286
|
+
this.showGroupedBtn = DocumentHelper.createButton(() => {
|
|
2287
|
+
this.showGrouped = !this.showGrouped;
|
|
2288
|
+
});
|
|
2289
|
+
this.updateShowGroupedBtn();
|
|
2290
|
+
return this.showGroupedBtn;
|
|
2291
|
+
});
|
|
2292
|
+
}
|
|
2293
|
+
}
|
|
2294
|
+
updateIntervalsModeSelector() {
|
|
2295
|
+
if (!!this.changeIntervalsModeSelector) {
|
|
2296
|
+
this.changeIntervalsModeSelector.getElementsByTagName("select")[0].value = this.intervalsMode;
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2299
|
+
updateAggregateDataNameSelector() {
|
|
2300
|
+
if (!!this.aggregateDataNameSelector) {
|
|
2301
|
+
this.aggregateDataNameSelector.getElementsByTagName("select")[0].value = this.aggregateDataName;
|
|
2302
|
+
}
|
|
1983
2303
|
}
|
|
1984
2304
|
reset() {
|
|
1985
2305
|
this._continuousData = undefined;
|
|
@@ -2022,6 +2342,17 @@ class HistogramModel extends SelectBase {
|
|
|
2022
2342
|
this.reset();
|
|
2023
2343
|
super.onDataChanged();
|
|
2024
2344
|
}
|
|
2345
|
+
onSelectionChanged(item) {
|
|
2346
|
+
if (item !== undefined && this.onDataItemSelected !== undefined) {
|
|
2347
|
+
if (this.valueType === "date") {
|
|
2348
|
+
const currIntervalCalueIndex = this.intervalModes.indexOf(this.intervalsMode);
|
|
2349
|
+
if (currIntervalCalueIndex > 0 && currIntervalCalueIndex < this.intervalModes.length - 1) {
|
|
2350
|
+
this.intervalsMode = this.intervalModes[currIntervalCalueIndex + 1];
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
}
|
|
2354
|
+
super.onSelectionChanged(item);
|
|
2355
|
+
}
|
|
2025
2356
|
getContinuousValues() {
|
|
2026
2357
|
if (this._cachedValues === undefined) {
|
|
2027
2358
|
const series = this.getSeriesValues();
|
|
@@ -2031,20 +2362,26 @@ class HistogramModel extends SelectBase {
|
|
|
2031
2362
|
this._continuousData = {};
|
|
2032
2363
|
series.forEach(seriesValue => this._continuousData[seriesValue] = []);
|
|
2033
2364
|
const hash = {};
|
|
2034
|
-
this.data.forEach(
|
|
2035
|
-
const
|
|
2036
|
-
|
|
2037
|
-
const
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2365
|
+
this.data.forEach(dataRow => {
|
|
2366
|
+
const nestedDataRows = getNestedDataRows(dataRow, this);
|
|
2367
|
+
nestedDataRows.forEach(nestedDataRow => {
|
|
2368
|
+
const answerData = nestedDataRow[this.dataNames[0]];
|
|
2369
|
+
if (answerData !== undefined) {
|
|
2370
|
+
const seriesValue = nestedDataRow[DataProvider.seriesMarkerKey] || "";
|
|
2371
|
+
// TODO: _continuousData should be sorted in order to speed-up statistics calculation in the getData function
|
|
2372
|
+
this._continuousData[seriesValue].push({ continuous: this.getContinuousValue(answerData), row: nestedDataRow });
|
|
2373
|
+
hash[answerData] = answerData;
|
|
2374
|
+
}
|
|
2375
|
+
});
|
|
2042
2376
|
});
|
|
2043
|
-
this._cachedValues = Object.keys(hash).map(key => ({ original: hash[key], continuous: this.getContinuousValue(key) }));
|
|
2377
|
+
this._cachedValues = Object.keys(hash).map(key => ({ original: hash[key], continuous: this.getContinuousValue(key), row: hash[key].row }));
|
|
2044
2378
|
this._cachedValues.sort((a, b) => a.continuous - b.continuous);
|
|
2045
2379
|
}
|
|
2046
2380
|
return this._cachedValues;
|
|
2047
2381
|
}
|
|
2382
|
+
isSupportSoftUpdateContent() {
|
|
2383
|
+
return false;
|
|
2384
|
+
}
|
|
2048
2385
|
isSupportMissingAnswers() {
|
|
2049
2386
|
return false;
|
|
2050
2387
|
}
|
|
@@ -2092,29 +2429,220 @@ class HistogramModel extends SelectBase {
|
|
|
2092
2429
|
if (continuousValues.length) {
|
|
2093
2430
|
let start = continuousValues[0].continuous;
|
|
2094
2431
|
const end = continuousValues[continuousValues.length - 1].continuous;
|
|
2095
|
-
const
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
const
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2432
|
+
const intervalsMode = this.intervalsMode === "auto" ? getBestIntervalMode(start, end) : this.intervalsMode;
|
|
2433
|
+
if (intervalCalculators[intervalsMode] !== undefined) {
|
|
2434
|
+
this._cachedIntervals = intervalCalculators[intervalsMode](start, end);
|
|
2435
|
+
}
|
|
2436
|
+
else {
|
|
2437
|
+
const intervalsCount = HistogramModel.IntervalsCount;
|
|
2438
|
+
const delta = (end - start) / intervalsCount;
|
|
2439
|
+
for (let i = 0; i < intervalsCount; ++i) {
|
|
2440
|
+
const next = start + delta;
|
|
2441
|
+
const istart = this.toPrecision(start);
|
|
2442
|
+
const inext = this.toPrecision(next);
|
|
2443
|
+
this._cachedIntervals.push({
|
|
2444
|
+
start: istart,
|
|
2445
|
+
end: i < intervalsCount - 1 ? inext : inext + delta / 100,
|
|
2446
|
+
label: "" + this.getString(istart) + "-" + this.getString(inext)
|
|
2447
|
+
});
|
|
2448
|
+
start = next;
|
|
2449
|
+
}
|
|
2107
2450
|
}
|
|
2108
2451
|
}
|
|
2109
2452
|
}
|
|
2110
2453
|
return this._cachedIntervals;
|
|
2111
2454
|
}
|
|
2455
|
+
get intervalsMode() {
|
|
2456
|
+
if (this.hasCustomIntervals)
|
|
2457
|
+
return "custom";
|
|
2458
|
+
return this._intervalsMode;
|
|
2459
|
+
}
|
|
2460
|
+
set intervalsMode(val) {
|
|
2461
|
+
if (this.allowChangeIntervals && this._intervalsMode !== val) {
|
|
2462
|
+
this._intervalsMode = val;
|
|
2463
|
+
if (!this.canShowGroupedDateSeries) {
|
|
2464
|
+
this._showGrouped = false;
|
|
2465
|
+
}
|
|
2466
|
+
this.updateIntervalsModeSelector();
|
|
2467
|
+
this.updateShowGroupedBtn();
|
|
2468
|
+
this.onDataChanged();
|
|
2469
|
+
}
|
|
2470
|
+
}
|
|
2471
|
+
get allowChangeIntervals() {
|
|
2472
|
+
return this.valueType === "date" && !this.hasCustomIntervals && this.options.allowChangeIntervals === true;
|
|
2473
|
+
}
|
|
2474
|
+
get showRunningTotals() {
|
|
2475
|
+
return this._showRunningTotals;
|
|
2476
|
+
}
|
|
2477
|
+
set showRunningTotals(val) {
|
|
2478
|
+
this._showRunningTotals = val;
|
|
2479
|
+
this.updateShowRunningTotalsBtn();
|
|
2480
|
+
this.stateChanged("showRunningTotals", val);
|
|
2481
|
+
this.refreshContent();
|
|
2482
|
+
}
|
|
2483
|
+
updateShowRunningTotalsBtn() {
|
|
2484
|
+
if (!!this.showRunningTotalsBtn) {
|
|
2485
|
+
this.showRunningTotalsBtn.innerText = this.showRunningTotals
|
|
2486
|
+
? localization.getString("noRunningTotals")
|
|
2487
|
+
: localization.getString("runningTotals");
|
|
2488
|
+
}
|
|
2489
|
+
}
|
|
2490
|
+
get showGrouped() {
|
|
2491
|
+
return this._showGrouped;
|
|
2492
|
+
}
|
|
2493
|
+
set showGrouped(val) {
|
|
2494
|
+
this._showGrouped = val;
|
|
2495
|
+
this.updateShowGroupedBtn();
|
|
2496
|
+
this.stateChanged("showGrouped", val);
|
|
2497
|
+
this.refreshContent();
|
|
2498
|
+
}
|
|
2499
|
+
updateShowGroupedBtn() {
|
|
2500
|
+
if (!!this.showGroupedBtn) {
|
|
2501
|
+
this.showGroupedBtn.innerText = this.showGrouped
|
|
2502
|
+
? localization.getString("ungroupDateSeries")
|
|
2503
|
+
: localization.getString("groupDateSeries");
|
|
2504
|
+
this.showGroupedBtn.style.display = this.canShowGroupedDateSeries ? "inline" : "none";
|
|
2505
|
+
}
|
|
2506
|
+
}
|
|
2507
|
+
get canShowGroupedDateSeries() {
|
|
2508
|
+
return ["years", "quarters", "months"].indexOf(this.intervalsMode) !== -1;
|
|
2509
|
+
}
|
|
2510
|
+
get aggregateDataName() {
|
|
2511
|
+
return this._aggregateDataName;
|
|
2512
|
+
}
|
|
2513
|
+
set aggregateDataName(val) {
|
|
2514
|
+
if (this._aggregateDataName !== val) {
|
|
2515
|
+
this._aggregateDataName = val;
|
|
2516
|
+
this.onDataChanged();
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2519
|
+
get possibleAggregateDataNames() {
|
|
2520
|
+
var _a, _b;
|
|
2521
|
+
return (_b = (_a = this.questionOptions) === null || _a === void 0 ? void 0 : _a.aggregateDataNames) !== null && _b !== void 0 ? _b : [];
|
|
2522
|
+
}
|
|
2112
2523
|
convertFromExternalData(externalCalculatedData) {
|
|
2113
2524
|
return [externalCalculatedData];
|
|
2114
2525
|
}
|
|
2115
2526
|
getCalculatedValuesCore() {
|
|
2116
2527
|
this.getContinuousValues();
|
|
2117
|
-
return histogramStatisticsCalculator(this._continuousData, this.intervals, this.
|
|
2528
|
+
return histogramStatisticsCalculator(this._continuousData, this.intervals, this, [this.aggregateDataName].filter(name => !!name));
|
|
2529
|
+
}
|
|
2530
|
+
getCalculatedValues() {
|
|
2531
|
+
const _super = Object.create(null, {
|
|
2532
|
+
getCalculatedValues: { get: () => super.getCalculatedValues }
|
|
2533
|
+
});
|
|
2534
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2535
|
+
const values = yield _super.getCalculatedValues.call(this);
|
|
2536
|
+
const result = JSON.parse(JSON.stringify(values));
|
|
2537
|
+
if (this.showRunningTotals) {
|
|
2538
|
+
for (let i = 0; i < result.length; i++) {
|
|
2539
|
+
for (let j = 1; j < result[i].length; j++) {
|
|
2540
|
+
result[i][j] += result[i][j - 1];
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
}
|
|
2544
|
+
return result;
|
|
2545
|
+
});
|
|
2546
|
+
}
|
|
2547
|
+
getGroupedDateAnswersData() {
|
|
2548
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2549
|
+
let datasets = (yield this.getCalculatedValues());
|
|
2550
|
+
let colors = this.getColors();
|
|
2551
|
+
let labels = this.getLabels();
|
|
2552
|
+
let seriesLabels = this.getSeriesLabels();
|
|
2553
|
+
const intervals = [].concat(this.intervals);
|
|
2554
|
+
const start = new Date(intervals[0].start);
|
|
2555
|
+
const end = new Date(intervals[intervals.length - 1].end);
|
|
2556
|
+
const startYear = start.getFullYear();
|
|
2557
|
+
const endYear = end.getFullYear();
|
|
2558
|
+
if (this.intervalsMode === "years") {
|
|
2559
|
+
seriesLabels = [];
|
|
2560
|
+
const groupedDatasets = [];
|
|
2561
|
+
for (let year = Math.floor(startYear / 10) * 10; year <= endYear; year += 10) {
|
|
2562
|
+
seriesLabels.push(year.toString() + "s");
|
|
2563
|
+
groupedDatasets.push(new Array(10).fill(0));
|
|
2564
|
+
}
|
|
2565
|
+
for (let i = 0; i < intervals.length; i++) {
|
|
2566
|
+
const interval = intervals[i];
|
|
2567
|
+
const intervalDate = new Date(interval.start);
|
|
2568
|
+
const decade = Math.floor(intervalDate.getFullYear() / 10) * 10;
|
|
2569
|
+
const yearInDecade = intervalDate.getFullYear() - decade;
|
|
2570
|
+
const decadeIndex = Math.floor((decade - Math.floor(startYear / 10) * 10) / 10);
|
|
2571
|
+
groupedDatasets[decadeIndex][yearInDecade] = datasets[0][i];
|
|
2572
|
+
}
|
|
2573
|
+
datasets = groupedDatasets;
|
|
2574
|
+
labels = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
|
|
2575
|
+
}
|
|
2576
|
+
else if (this.intervalsMode === "quarters") {
|
|
2577
|
+
seriesLabels = [];
|
|
2578
|
+
const groupedDatasets = [];
|
|
2579
|
+
for (let year = startYear; year <= endYear; year++) {
|
|
2580
|
+
seriesLabels.push(year.toString());
|
|
2581
|
+
groupedDatasets.push(new Array(4).fill(0));
|
|
2582
|
+
}
|
|
2583
|
+
for (let i = 0; i < intervals.length; i++) {
|
|
2584
|
+
const interval = intervals[i];
|
|
2585
|
+
const intervalDate = new Date(interval.start);
|
|
2586
|
+
const quarter = Math.floor(intervalDate.getMonth() / 3);
|
|
2587
|
+
const year = intervalDate.getFullYear();
|
|
2588
|
+
const yearIndex = year - startYear;
|
|
2589
|
+
groupedDatasets[yearIndex][quarter] = datasets[0][i];
|
|
2590
|
+
}
|
|
2591
|
+
datasets = groupedDatasets;
|
|
2592
|
+
labels = ["I", "II", "III", "IV"];
|
|
2593
|
+
}
|
|
2594
|
+
else if (this.intervalsMode === "months") {
|
|
2595
|
+
seriesLabels = [];
|
|
2596
|
+
const groupedDatasets = [];
|
|
2597
|
+
for (let year = startYear; year <= endYear; year++) {
|
|
2598
|
+
seriesLabels.push(year.toString());
|
|
2599
|
+
groupedDatasets.push(new Array(12).fill(0));
|
|
2600
|
+
}
|
|
2601
|
+
for (let i = 0; i < intervals.length; i++) {
|
|
2602
|
+
const interval = intervals[i];
|
|
2603
|
+
const intervalDate = new Date(interval.start);
|
|
2604
|
+
const month = intervalDate.getMonth();
|
|
2605
|
+
const year = intervalDate.getFullYear();
|
|
2606
|
+
const yearIndex = year - startYear;
|
|
2607
|
+
groupedDatasets[yearIndex][month] = datasets[0][i];
|
|
2608
|
+
}
|
|
2609
|
+
datasets = groupedDatasets;
|
|
2610
|
+
labels = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
2611
|
+
}
|
|
2612
|
+
let texts = datasets;
|
|
2613
|
+
return {
|
|
2614
|
+
datasets,
|
|
2615
|
+
labels,
|
|
2616
|
+
colors,
|
|
2617
|
+
texts,
|
|
2618
|
+
seriesLabels,
|
|
2619
|
+
};
|
|
2620
|
+
});
|
|
2621
|
+
}
|
|
2622
|
+
/**
|
|
2623
|
+
* Returns object with all infotmation for data visualization: datasets, labels, colors, additional texts (percentage).
|
|
2624
|
+
*/
|
|
2625
|
+
getAnswersData() {
|
|
2626
|
+
const _super = Object.create(null, {
|
|
2627
|
+
getAnswersData: { get: () => super.getAnswersData }
|
|
2628
|
+
});
|
|
2629
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2630
|
+
if (!this.showGrouped) {
|
|
2631
|
+
return _super.getAnswersData.call(this);
|
|
2632
|
+
}
|
|
2633
|
+
const answersData = yield this.getGroupedDateAnswersData();
|
|
2634
|
+
const continuousValues = this.getContinuousValues();
|
|
2635
|
+
if (continuousValues.length) {
|
|
2636
|
+
let start = continuousValues[0].continuous;
|
|
2637
|
+
const end = continuousValues[continuousValues.length - 1].continuous;
|
|
2638
|
+
const intervalsMode = this.intervalsMode === "auto" ? getBestIntervalMode(start, end) : this.intervalsMode;
|
|
2639
|
+
if (intervalsMode === "years" && this.showGrouped) {
|
|
2640
|
+
answersData.labelsTitle = localization.getString("groupedYearsAxisTitle");
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
this.onAnswersDataReady.fire(this, answersData);
|
|
2644
|
+
return answersData;
|
|
2645
|
+
});
|
|
2118
2646
|
}
|
|
2119
2647
|
getValueType() {
|
|
2120
2648
|
return this.valueType;
|
|
@@ -2664,7 +3192,7 @@ class AlternativeVisualizersWrapper extends VisualizerBase {
|
|
|
2664
3192
|
}
|
|
2665
3193
|
}
|
|
2666
3194
|
constructor(visualizers, question, data, options) {
|
|
2667
|
-
super(question, data, options);
|
|
3195
|
+
super(question, data, options, "alternative");
|
|
2668
3196
|
this.visualizers = visualizers;
|
|
2669
3197
|
this.visualizersWithSelection = [];
|
|
2670
3198
|
this.onAfterVisualizerRenderCallback = () => {
|
|
@@ -2690,12 +3218,14 @@ class AlternativeVisualizersWrapper extends VisualizerBase {
|
|
|
2690
3218
|
this.visualizersWithSelection.push(visualizer);
|
|
2691
3219
|
}
|
|
2692
3220
|
});
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
3221
|
+
if (this.options.allowChangeVisualizerType !== false) {
|
|
3222
|
+
this.registerToolbarItem("changeVisualizer", () => this.visualizerSelector = DocumentHelper.createSelector(this.visualizers.map((visualizer) => {
|
|
3223
|
+
return {
|
|
3224
|
+
value: visualizer.type,
|
|
3225
|
+
text: localization.getString("visualizer_" + visualizer.type),
|
|
3226
|
+
};
|
|
3227
|
+
}), (option) => this.visualizer.type === option.value, (e) => this.setVisualizer(e.target.value)), 0);
|
|
3228
|
+
}
|
|
2699
3229
|
this.visualizer = visualizers[0];
|
|
2700
3230
|
this.visualizer.onAfterRender.add(this.onAfterVisualizerRenderCallback);
|
|
2701
3231
|
this.visualizer.onStateChanged.add(this.onVisualizerStateChangedCallback);
|
|
@@ -9775,6 +10305,50 @@ class MuuriLayoutEngine extends LayoutEngine {
|
|
|
9775
10305
|
}
|
|
9776
10306
|
}
|
|
9777
10307
|
|
|
10308
|
+
class VisualizationPanelDynamic extends VisualizerBase {
|
|
10309
|
+
constructor(question, data, options = {}, name) {
|
|
10310
|
+
super(question, data, options, name || "panelDynamic");
|
|
10311
|
+
this._contentVisualizer = undefined;
|
|
10312
|
+
this.onAfterRenderPanelCallback = () => {
|
|
10313
|
+
this.afterRender(this.contentContainer);
|
|
10314
|
+
};
|
|
10315
|
+
this.loadingData = false;
|
|
10316
|
+
var options = Object.assign({}, options);
|
|
10317
|
+
options.allowHideQuestions = false;
|
|
10318
|
+
options.allowDynamicLayout = false;
|
|
10319
|
+
options.dataProvider = this.dataProvider;
|
|
10320
|
+
options.dataPath = this.dataNames[0];
|
|
10321
|
+
this._contentVisualizer = new VisualizationPanel(this.getQuestions(), [], options, undefined, false);
|
|
10322
|
+
this._contentVisualizer.onAfterRender.add(this.onAfterRenderPanelCallback);
|
|
10323
|
+
}
|
|
10324
|
+
get contentVisualizer() {
|
|
10325
|
+
return this._contentVisualizer;
|
|
10326
|
+
}
|
|
10327
|
+
setLocale(newLocale) {
|
|
10328
|
+
super.setLocale(newLocale);
|
|
10329
|
+
this._contentVisualizer.locale = newLocale;
|
|
10330
|
+
}
|
|
10331
|
+
resetFilter() {
|
|
10332
|
+
this.contentVisualizer.resetFilter();
|
|
10333
|
+
}
|
|
10334
|
+
getQuestions() {
|
|
10335
|
+
const paneldynamic = this.question;
|
|
10336
|
+
return paneldynamic.template.questions;
|
|
10337
|
+
}
|
|
10338
|
+
destroyContent(container) {
|
|
10339
|
+
this._contentVisualizer.clear();
|
|
10340
|
+
super.destroyContent(this.contentContainer);
|
|
10341
|
+
}
|
|
10342
|
+
renderContent(container) {
|
|
10343
|
+
this._contentVisualizer.render(container);
|
|
10344
|
+
}
|
|
10345
|
+
destroy() {
|
|
10346
|
+
super.destroy();
|
|
10347
|
+
this._contentVisualizer.onAfterRender.remove(this.onAfterRenderPanelCallback);
|
|
10348
|
+
}
|
|
10349
|
+
}
|
|
10350
|
+
VisualizationManager.registerVisualizer("paneldynamic", VisualizationPanelDynamic);
|
|
10351
|
+
|
|
9778
10352
|
const questionElementClassName = "sa-question";
|
|
9779
10353
|
const questionLayoutedElementClassName = "sa-question-layouted";
|
|
9780
10354
|
if (!!document) {
|
|
@@ -9807,7 +10381,7 @@ class VisualizationPanel extends VisualizerBase {
|
|
|
9807
10381
|
this.renderedQuestionsCount = 0;
|
|
9808
10382
|
this.onAfterRenderQuestionCallback = (sender, options) => {
|
|
9809
10383
|
this.renderedQuestionsCount++;
|
|
9810
|
-
if (this.renderedQuestionsCount == this.
|
|
10384
|
+
if (this.renderedQuestionsCount == this.visibleElements.length) {
|
|
9811
10385
|
this.renderedQuestionsCount = 0;
|
|
9812
10386
|
this.layoutEngine.update();
|
|
9813
10387
|
this.afterRender(this.contentContainer);
|
|
@@ -9886,7 +10460,7 @@ class VisualizationPanel extends VisualizerBase {
|
|
|
9886
10460
|
options.layoutEngine ||
|
|
9887
10461
|
new MuuriLayoutEngine(this.allowDynamicLayout, "." + questionLayoutedElementClassName, this.allowDragDrop);
|
|
9888
10462
|
this._layoutEngine.onMoveCallback = (order) => this.reorderVisibleElements(order);
|
|
9889
|
-
this.showToolbar =
|
|
10463
|
+
this.showToolbar = isRoot;
|
|
9890
10464
|
if (this.options.survey) {
|
|
9891
10465
|
localization.currentLocale = this.options.survey.locale;
|
|
9892
10466
|
}
|
|
@@ -9903,11 +10477,7 @@ class VisualizationPanel extends VisualizerBase {
|
|
|
9903
10477
|
if (this.supportSelection !== false) {
|
|
9904
10478
|
this.registerToolbarItem("resetFilter", () => {
|
|
9905
10479
|
return DocumentHelper.createButton(() => {
|
|
9906
|
-
this.
|
|
9907
|
-
if (visualizer instanceof SelectBase || visualizer instanceof AlternativeVisualizersWrapper) {
|
|
9908
|
-
visualizer.setSelection(undefined);
|
|
9909
|
-
}
|
|
9910
|
-
});
|
|
10480
|
+
this.resetFilter();
|
|
9911
10481
|
}, localization.getString("resetFilter"));
|
|
9912
10482
|
}, 900);
|
|
9913
10483
|
}
|
|
@@ -9967,6 +10537,18 @@ class VisualizationPanel extends VisualizerBase {
|
|
|
9967
10537
|
});
|
|
9968
10538
|
}
|
|
9969
10539
|
}
|
|
10540
|
+
resetFilter() {
|
|
10541
|
+
var _a;
|
|
10542
|
+
(_a = this.dataProvider) === null || _a === void 0 ? void 0 : _a.resetFilter();
|
|
10543
|
+
this.visualizers.forEach((visualizer) => {
|
|
10544
|
+
if (visualizer instanceof SelectBase || visualizer instanceof AlternativeVisualizersWrapper) {
|
|
10545
|
+
visualizer.setSelection(undefined);
|
|
10546
|
+
}
|
|
10547
|
+
if (visualizer instanceof VisualizationPanelDynamic) {
|
|
10548
|
+
visualizer.resetFilter();
|
|
10549
|
+
}
|
|
10550
|
+
});
|
|
10551
|
+
}
|
|
9970
10552
|
reorderVisibleElements(order) {
|
|
9971
10553
|
const newElements = [];
|
|
9972
10554
|
order.forEach(name => {
|
|
@@ -10068,13 +10650,15 @@ class VisualizationPanel extends VisualizerBase {
|
|
|
10068
10650
|
buildVisualizers(questions) {
|
|
10069
10651
|
questions.forEach((question) => {
|
|
10070
10652
|
let visualizerOptions = Object.assign({}, this.options);
|
|
10071
|
-
|
|
10653
|
+
if (visualizerOptions.dataProvider === undefined) {
|
|
10654
|
+
visualizerOptions.dataProvider = this.dataProvider;
|
|
10655
|
+
}
|
|
10072
10656
|
let visualizer;
|
|
10073
10657
|
if (Array.isArray(question)) {
|
|
10074
|
-
visualizer = new (VisualizationManager.getPivotVisualizerConstructor())(question,
|
|
10658
|
+
visualizer = new (VisualizationManager.getPivotVisualizerConstructor())(question, [], visualizerOptions, undefined, false);
|
|
10075
10659
|
}
|
|
10076
10660
|
else {
|
|
10077
|
-
visualizer = this.createVisualizer(question, visualizerOptions,
|
|
10661
|
+
visualizer = this.createVisualizer(question, visualizerOptions, []);
|
|
10078
10662
|
}
|
|
10079
10663
|
if (!visualizer) {
|
|
10080
10664
|
return;
|
|
@@ -10145,7 +10729,7 @@ class VisualizationPanel extends VisualizerBase {
|
|
|
10145
10729
|
question = Array.isArray(question) ? question[0] : question;
|
|
10146
10730
|
const element = this.getElement(question.name);
|
|
10147
10731
|
if (!!element) {
|
|
10148
|
-
element.displayName = this.
|
|
10732
|
+
element.displayName = this.getTitle(question);
|
|
10149
10733
|
}
|
|
10150
10734
|
});
|
|
10151
10735
|
this.visualizers.forEach(v => {
|
|
@@ -10192,7 +10776,7 @@ class VisualizationPanel extends VisualizerBase {
|
|
|
10192
10776
|
question = Array.isArray(question) ? question[0] : question;
|
|
10193
10777
|
return {
|
|
10194
10778
|
name: question.name,
|
|
10195
|
-
displayName: this.
|
|
10779
|
+
displayName: this.getTitle(question),
|
|
10196
10780
|
isVisible: true,
|
|
10197
10781
|
isPublic: true,
|
|
10198
10782
|
};
|
|
@@ -10360,7 +10944,23 @@ class VisualizationPanel extends VisualizerBase {
|
|
|
10360
10944
|
* @see IVisualizationPanelOptions.allowSelection
|
|
10361
10945
|
*/
|
|
10362
10946
|
setFilter(questionName, selectedValue) {
|
|
10363
|
-
this.
|
|
10947
|
+
if (!this.dataPath) {
|
|
10948
|
+
this.dataProvider.setFilter(questionName, selectedValue);
|
|
10949
|
+
}
|
|
10950
|
+
else {
|
|
10951
|
+
if (selectedValue !== undefined && selectedValue !== null) {
|
|
10952
|
+
if (typeof selectedValue === "object" && Object.keys(selectedValue)[0]) {
|
|
10953
|
+
const seriesValue = Object.keys(selectedValue)[0];
|
|
10954
|
+
this.dataProvider.setFilter(this.dataPath, { [questionName]: selectedValue[seriesValue], [DataProvider.seriesMarkerKey]: seriesValue });
|
|
10955
|
+
}
|
|
10956
|
+
else {
|
|
10957
|
+
this.dataProvider.setFilter(this.dataPath, { [questionName]: selectedValue });
|
|
10958
|
+
}
|
|
10959
|
+
}
|
|
10960
|
+
else {
|
|
10961
|
+
this.dataProvider.setFilter(this.dataPath, undefined);
|
|
10962
|
+
}
|
|
10963
|
+
}
|
|
10364
10964
|
}
|
|
10365
10965
|
getState() {
|
|
10366
10966
|
return {
|
|
@@ -10449,69 +11049,9 @@ class VisualizationPanel extends VisualizerBase {
|
|
|
10449
11049
|
}
|
|
10450
11050
|
}
|
|
10451
11051
|
|
|
10452
|
-
class VisualizationPanelDynamic extends VisualizerBase {
|
|
10453
|
-
constructor(question, data, options = {}, name) {
|
|
10454
|
-
super(question, data, options, name || "panelDynamic");
|
|
10455
|
-
this._panelVisualizer = undefined;
|
|
10456
|
-
this.onAfterRenderPanelCallback = () => {
|
|
10457
|
-
this.afterRender(this.contentContainer);
|
|
10458
|
-
};
|
|
10459
|
-
this.loadingData = false;
|
|
10460
|
-
var options = Object.assign({}, options);
|
|
10461
|
-
options.allowDynamicLayout = false;
|
|
10462
|
-
options.dataProvider = undefined;
|
|
10463
|
-
this._panelVisualizer = new VisualizationPanel(this.getQuestions(), [], options, undefined, false);
|
|
10464
|
-
this._panelVisualizer.onAfterRender.add(this.onAfterRenderPanelCallback);
|
|
10465
|
-
this.updateData(data);
|
|
10466
|
-
}
|
|
10467
|
-
setLocale(newLocale) {
|
|
10468
|
-
super.setLocale(newLocale);
|
|
10469
|
-
this._panelVisualizer.locale = newLocale;
|
|
10470
|
-
}
|
|
10471
|
-
get type() {
|
|
10472
|
-
return "panelDynamic";
|
|
10473
|
-
}
|
|
10474
|
-
updatePanelVisualizerData() {
|
|
10475
|
-
let panelData = [];
|
|
10476
|
-
this.data.forEach((dataItem) => {
|
|
10477
|
-
if (dataItem[this.question.name] !== undefined) {
|
|
10478
|
-
panelData = panelData.concat(dataItem[this.question.name]);
|
|
10479
|
-
}
|
|
10480
|
-
});
|
|
10481
|
-
this._panelVisualizer.updateData(panelData);
|
|
10482
|
-
}
|
|
10483
|
-
updateData(data) {
|
|
10484
|
-
super.updateData(data);
|
|
10485
|
-
this.updatePanelVisualizerData();
|
|
10486
|
-
}
|
|
10487
|
-
onDataChanged() {
|
|
10488
|
-
this.updatePanelVisualizerData();
|
|
10489
|
-
super.onDataChanged();
|
|
10490
|
-
}
|
|
10491
|
-
getQuestions() {
|
|
10492
|
-
const paneldynamic = this.question;
|
|
10493
|
-
return paneldynamic.template.questions;
|
|
10494
|
-
}
|
|
10495
|
-
destroyContent(container) {
|
|
10496
|
-
this._panelVisualizer.clear();
|
|
10497
|
-
super.destroyContent(this.contentContainer);
|
|
10498
|
-
}
|
|
10499
|
-
renderContent(container) {
|
|
10500
|
-
this._panelVisualizer.render(container);
|
|
10501
|
-
}
|
|
10502
|
-
destroy() {
|
|
10503
|
-
super.destroy();
|
|
10504
|
-
this._panelVisualizer.onAfterRender.remove(this.onAfterRenderPanelCallback);
|
|
10505
|
-
}
|
|
10506
|
-
}
|
|
10507
|
-
VisualizationManager.registerVisualizer("paneldynamic", VisualizationPanelDynamic);
|
|
10508
|
-
|
|
10509
11052
|
class VisualizationMatrixDynamic extends VisualizationPanelDynamic {
|
|
10510
|
-
constructor(question, data, options) {
|
|
10511
|
-
super(question, data, options);
|
|
10512
|
-
}
|
|
10513
|
-
get type() {
|
|
10514
|
-
return "matrixDynamic";
|
|
11053
|
+
constructor(question, data, options, name) {
|
|
11054
|
+
super(question, data, options, name || "matrixDynamic");
|
|
10515
11055
|
}
|
|
10516
11056
|
getQuestions() {
|
|
10517
11057
|
const matrixdynamic = this.question;
|
|
@@ -10537,28 +11077,29 @@ function isChoicesArraysEqual(choices1, choices2) {
|
|
|
10537
11077
|
class VisualizationMatrixDropdown extends VisualizerBase {
|
|
10538
11078
|
constructor(question, data, options = {}, name) {
|
|
10539
11079
|
super(question, data, options, name || "matrixDropdown");
|
|
10540
|
-
this.
|
|
11080
|
+
this._contentVisualizer = undefined;
|
|
10541
11081
|
this.onPanelAfterRenderCallback = () => {
|
|
10542
11082
|
this.afterRender(this.contentContainer);
|
|
10543
11083
|
};
|
|
10544
11084
|
this.loadingData = false;
|
|
10545
11085
|
this._childOptions = Object.assign({}, options);
|
|
10546
11086
|
this._childOptions.disableLocaleSwitch = true;
|
|
10547
|
-
this._childOptions.dataProvider = undefined;
|
|
10548
11087
|
this._childOptions.allowDynamicLayout = false;
|
|
10549
11088
|
this._childOptions.transposeData = true;
|
|
11089
|
+
this._childOptions.dataProvider = this.dataProvider;
|
|
11090
|
+
this._childOptions.dataPath = this.dataNames[0];
|
|
10550
11091
|
this._childOptions.seriesValues = question.rows.map((row) => row.value);
|
|
10551
11092
|
this._childOptions.seriesLabels = question.rows.map((row) => row.text);
|
|
11093
|
+
this.dataProvider.fixDropdownData(this.dataNames);
|
|
10552
11094
|
if (this.canGroupColumns) {
|
|
10553
11095
|
var creators = VisualizationManager.getVisualizersByType("matrixdropdown-grouped");
|
|
10554
|
-
this.
|
|
11096
|
+
this._contentVisualizer = new creators[0](this.question, [], this._childOptions);
|
|
10555
11097
|
}
|
|
10556
11098
|
else {
|
|
10557
11099
|
const innerQuestions = this.getQuestions();
|
|
10558
|
-
this.
|
|
11100
|
+
this._contentVisualizer = new VisualizationPanel(innerQuestions, [], this._childOptions, undefined, false);
|
|
10559
11101
|
}
|
|
10560
|
-
this.
|
|
10561
|
-
this.updateData(data);
|
|
11102
|
+
this._contentVisualizer.onAfterRender.add(this.onPanelAfterRenderCallback);
|
|
10562
11103
|
}
|
|
10563
11104
|
get canGroupColumns() {
|
|
10564
11105
|
const innerQuestions = this.getQuestions();
|
|
@@ -10568,32 +11109,14 @@ class VisualizationMatrixDropdown extends VisualizerBase {
|
|
|
10568
11109
|
setLocale(newLocale) {
|
|
10569
11110
|
super.setLocale(newLocale);
|
|
10570
11111
|
this._childOptions.seriesLabels = this.question.rows.map((row) => row.text);
|
|
10571
|
-
this.
|
|
11112
|
+
this._contentVisualizer.locale = newLocale;
|
|
10572
11113
|
}
|
|
10573
|
-
get
|
|
10574
|
-
return this.
|
|
10575
|
-
}
|
|
10576
|
-
updateDropdownVisualizerData() {
|
|
10577
|
-
let panelData = [];
|
|
10578
|
-
this.data.forEach((dataItem) => {
|
|
10579
|
-
let rawDataItem = dataItem[this.question.name];
|
|
10580
|
-
if (!!rawDataItem) {
|
|
10581
|
-
Object.keys(rawDataItem).forEach((key) => {
|
|
10582
|
-
var nestedDataItem = Object.assign({}, rawDataItem[key]);
|
|
10583
|
-
nestedDataItem[DataProvider.seriesMarkerKey] = key;
|
|
10584
|
-
panelData.push(nestedDataItem);
|
|
10585
|
-
});
|
|
10586
|
-
}
|
|
10587
|
-
});
|
|
10588
|
-
this._matrixDropdownVisualizer.updateData(panelData);
|
|
11114
|
+
get contentVisualizer() {
|
|
11115
|
+
return this._contentVisualizer;
|
|
10589
11116
|
}
|
|
10590
11117
|
updateData(data) {
|
|
10591
11118
|
super.updateData(data);
|
|
10592
|
-
this.
|
|
10593
|
-
}
|
|
10594
|
-
onDataChanged() {
|
|
10595
|
-
this.updateDropdownVisualizerData();
|
|
10596
|
-
super.onDataChanged();
|
|
11119
|
+
this.dataProvider.fixDropdownData(this.dataNames);
|
|
10597
11120
|
}
|
|
10598
11121
|
getQuestions() {
|
|
10599
11122
|
const matrixdropdown = this.question;
|
|
@@ -10606,19 +11129,32 @@ class VisualizationMatrixDropdown extends VisualizerBase {
|
|
|
10606
11129
|
});
|
|
10607
11130
|
}
|
|
10608
11131
|
destroyContent(container) {
|
|
10609
|
-
this.
|
|
11132
|
+
this._contentVisualizer.clear();
|
|
10610
11133
|
super.destroyContent(this.contentContainer);
|
|
10611
11134
|
}
|
|
10612
11135
|
renderContent(container) {
|
|
10613
|
-
this.
|
|
11136
|
+
this._contentVisualizer.render(container);
|
|
10614
11137
|
}
|
|
10615
11138
|
destroy() {
|
|
10616
11139
|
super.destroy();
|
|
10617
|
-
this.
|
|
11140
|
+
this._contentVisualizer.onAfterRender.remove(this.onPanelAfterRenderCallback);
|
|
10618
11141
|
}
|
|
10619
11142
|
}
|
|
10620
11143
|
VisualizationManager.registerVisualizer("matrixdropdown", VisualizationMatrixDropdown);
|
|
10621
11144
|
|
|
11145
|
+
class VisualizationComposite extends VisualizationPanelDynamic {
|
|
11146
|
+
constructor(question, data, options, name) {
|
|
11147
|
+
super(question, data, options, name || "composite");
|
|
11148
|
+
}
|
|
11149
|
+
getQuestions() {
|
|
11150
|
+
const questionComposite = this.question;
|
|
11151
|
+
const innerQuestions = [];
|
|
11152
|
+
questionComposite.contentPanel.addQuestionsToList(innerQuestions);
|
|
11153
|
+
return innerQuestions;
|
|
11154
|
+
}
|
|
11155
|
+
}
|
|
11156
|
+
VisualizationManager.registerVisualizer("composite", VisualizationComposite);
|
|
11157
|
+
|
|
10622
11158
|
var stopWords$3 = [
|
|
10623
11159
|
"...",
|
|
10624
11160
|
"a",
|
|
@@ -12627,5 +13163,5 @@ NpsVisualizer.DetractorScore = 6;
|
|
|
12627
13163
|
NpsVisualizer.PromoterScore = 9;
|
|
12628
13164
|
// VisualizationManager.registerVisualizer("rating", NpsVisualizer);
|
|
12629
13165
|
|
|
12630
|
-
export { AlternativeVisualizersWrapper as A, BooleanModel as B, DataProvider as D, HistogramModel as H, Matrix as M, NumberModel as N, PostponeHelper as P, RankingModel as R, SelectBase as S, TextTableAdapter as T, VisualizerFactory as V, WordCloudAdapter as W, __awaiter as _, VisualizerBase as a, VisualizationManager as b, VisualizationPanel as c, VisualizationPanelDynamic as d, VisualizationMatrixDynamic as e, VisualizationMatrixDropdown as f,
|
|
13166
|
+
export { AlternativeVisualizersWrapper as A, BooleanModel as B, DataProvider as D, HistogramModel as H, Matrix as M, NumberModel as N, PostponeHelper as P, RankingModel as R, SelectBase as S, TextTableAdapter as T, VisualizerFactory as V, WordCloudAdapter as W, __awaiter as _, VisualizerBase as a, VisualizationManager as b, VisualizationPanel as c, VisualizationPanelDynamic as d, VisualizationMatrixDynamic as e, VisualizationMatrixDropdown as f, getBestIntervalMode as g, hideEmptyAnswersInData as h, intervalCalculators as i, VisualizationComposite as j, WordCloud as k, Text as l, StatisticsTableAdapter as m, StatisticsTable as n, StatisticsTableBoolean as o, NpsVisualizerWidget as p, NpsAdapter as q, NpsVisualizer as r, PivotModel as s, textHelper as t, defaultStatisticsCalculator as u };
|
|
12631
13167
|
//# sourceMappingURL=shared2.mjs.map
|