survey-analytics 2.2.2 → 2.2.4
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 +10 -2
- package/fesm/shared.mjs.map +1 -1
- package/fesm/shared2.mjs +748 -262
- package/fesm/shared2.mjs.map +1 -1
- package/fesm/survey.analytics.core.mjs +2 -2
- package/fesm/survey.analytics.mjs +315 -538
- package/fesm/survey.analytics.mjs.map +1 -1
- package/fesm/survey.analytics.tabulator.mjs +1 -1
- package/package.json +8 -8
- package/survey-analytics-tabulator.types/analytics-localization/english.d.ts +2 -0
- package/survey-analytics-tabulator.types/localizationManager.d.ts +2 -0
- package/survey-analytics-tabulator.types/utils/index.d.ts +1 -1
- package/survey-analytics.types/alternativeVizualizersWrapper.d.ts +2 -0
- package/survey-analytics.types/analytics-localization/english.d.ts +2 -0
- package/survey-analytics.types/boolean.d.ts +0 -1
- package/survey-analytics.types/entries/summary.core.d.ts +3 -1
- package/survey-analytics.types/histogram.d.ts +1 -1
- package/survey-analytics.types/localizationManager.d.ts +2 -0
- package/survey-analytics.types/matrix.d.ts +0 -1
- package/survey-analytics.types/pivot.d.ts +64 -0
- package/survey-analytics.types/plotly/chart-adapter.d.ts +13 -0
- package/survey-analytics.types/plotly/index.d.ts +2 -7
- package/survey-analytics.types/plotly/legacy.d.ts +33 -0
- package/survey-analytics.types/plotly/setup.d.ts +5 -3
- package/survey-analytics.types/{plotly/ranking.d.ts → ranking.d.ts} +2 -2
- package/survey-analytics.types/selectBase.d.ts +3 -1
- package/survey-analytics.types/utils/index.d.ts +1 -1
- package/survey-analytics.types/visualizationManager.d.ts +3 -0
- package/survey-analytics.types/visualizerBase.d.ts +13 -1
- package/survey.analytics.core.css +7 -1
- package/survey.analytics.core.css.map +1 -1
- package/survey.analytics.core.js +659 -51
- package/survey.analytics.core.js.map +1 -1
- package/survey.analytics.core.min.css +2 -2
- package/survey.analytics.core.min.js +1 -1
- package/survey.analytics.core.min.js.LICENSE.txt +1 -1
- package/survey.analytics.css +7 -1
- package/survey.analytics.css.map +1 -1
- package/survey.analytics.js +1048 -817
- package/survey.analytics.js.map +1 -1
- package/survey.analytics.min.css +2 -2
- package/survey.analytics.min.js +1 -1
- package/survey.analytics.min.js.LICENSE.txt +1 -1
- package/survey.analytics.tabulator.css +1 -1
- package/survey.analytics.tabulator.js +10 -2
- package/survey.analytics.tabulator.js.map +1 -1
- package/survey.analytics.tabulator.min.css +1 -1
- package/survey.analytics.tabulator.min.js +1 -1
- package/survey.analytics.tabulator.min.js.LICENSE.txt +1 -1
- package/survey-analytics.types/plotly/boolean.d.ts +0 -16
- package/survey-analytics.types/plotly/histogram.d.ts +0 -13
- package/survey-analytics.types/plotly/matrix.d.ts +0 -11
- package/survey-analytics.types/plotly/matrixdropdown-grouped.d.ts +0 -11
- package/survey-analytics.types/plotly/rating.d.ts +0 -20
- package/survey-analytics.types/plotly/selectBase.d.ts +0 -26
package/fesm/shared2.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* surveyjs - SurveyJS Dashboard library v2.2.
|
|
2
|
+
* surveyjs - SurveyJS Dashboard library v2.2.4
|
|
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
|
-
import { Event, QuestionCommentModel, settings, ItemValue, hasLicense, surveyLocalization, IsTouch, Helpers } from 'survey-core';
|
|
8
7
|
import { D as DocumentHelper, l as localization, f as createLoadingIndicator, a as DataHelper, e as svgTemplate, d as createCommercialLicenseLink, t as toPrecision } from './shared.mjs';
|
|
8
|
+
import { Event, QuestionCommentModel, settings, ItemValue, hasLicense, surveyLocalization, IsTouch, Helpers } from 'survey-core';
|
|
9
9
|
|
|
10
10
|
/******************************************************************************
|
|
11
11
|
Copyright (c) Microsoft Corporation.
|
|
@@ -240,8 +240,15 @@ class VisualizationManager {
|
|
|
240
240
|
static registerAltVisualizerSelector(constructor) {
|
|
241
241
|
VisualizationManager.alternativesVisualizer = constructor;
|
|
242
242
|
}
|
|
243
|
+
static getPivotVisualizerConstructor() {
|
|
244
|
+
return VisualizationManager.pivotVisualizer || VisualizerBase;
|
|
245
|
+
}
|
|
246
|
+
static registerPivotVisualizer(constructor) {
|
|
247
|
+
VisualizationManager.pivotVisualizer = constructor;
|
|
248
|
+
}
|
|
243
249
|
}
|
|
244
250
|
VisualizationManager.alternativesVisualizer = undefined;
|
|
251
|
+
VisualizationManager.pivotVisualizer = undefined;
|
|
245
252
|
VisualizationManager.vizualizers = {};
|
|
246
253
|
|
|
247
254
|
/**
|
|
@@ -349,6 +356,7 @@ class VisualizerBase {
|
|
|
349
356
|
this.contentContainer = undefined;
|
|
350
357
|
this.footerContainer = undefined;
|
|
351
358
|
this._supportSelection = false;
|
|
359
|
+
this._chartAdapter = undefined;
|
|
352
360
|
/**
|
|
353
361
|
* An event that is raised after the visualizer's content is rendered.
|
|
354
362
|
*
|
|
@@ -447,12 +455,12 @@ class VisualizerBase {
|
|
|
447
455
|
get hasFooter() {
|
|
448
456
|
return (!!this.question && (this.question.hasComment || this.question.hasOther));
|
|
449
457
|
}
|
|
450
|
-
createVisualizer(question, options) {
|
|
458
|
+
createVisualizer(question, options, data) {
|
|
451
459
|
let visualizerOptions = Object.assign({}, options || this.options);
|
|
452
460
|
if (visualizerOptions.dataProvider === undefined) {
|
|
453
461
|
visualizerOptions.dataProvider = this.dataProvider;
|
|
454
462
|
}
|
|
455
|
-
return VisualizerFactory.createVisualizer(question, this.data, visualizerOptions);
|
|
463
|
+
return VisualizerFactory.createVisualizer(question, data || this.data, visualizerOptions);
|
|
456
464
|
}
|
|
457
465
|
/**
|
|
458
466
|
* Allows you to access the footer visualizer. Returns `undefined` if the footer is absent.
|
|
@@ -666,9 +674,10 @@ class VisualizerBase {
|
|
|
666
674
|
if (!!this.options && typeof this.options.destroyContent === "function") {
|
|
667
675
|
this.options.destroyContent(container, this);
|
|
668
676
|
}
|
|
669
|
-
else {
|
|
670
|
-
container.
|
|
677
|
+
else if (this._chartAdapter) {
|
|
678
|
+
this._chartAdapter.destroy(container.children[0]);
|
|
671
679
|
}
|
|
680
|
+
container.innerHTML = "";
|
|
672
681
|
}
|
|
673
682
|
renderHeader(container) {
|
|
674
683
|
if (!!this.options && typeof this.options.renderHeader === "function") {
|
|
@@ -682,10 +691,16 @@ class VisualizerBase {
|
|
|
682
691
|
}
|
|
683
692
|
renderContentAsync(container) {
|
|
684
693
|
return __awaiter(this, void 0, void 0, function* () {
|
|
685
|
-
|
|
694
|
+
if (this._chartAdapter) {
|
|
695
|
+
const chartNode = DocumentHelper.createElement("div");
|
|
696
|
+
container.innerHTML = "";
|
|
697
|
+
container.appendChild(chartNode);
|
|
698
|
+
yield this._chartAdapter.create(chartNode);
|
|
699
|
+
}
|
|
700
|
+
else {
|
|
686
701
|
container.innerText = localization.getString("noVisualizerForQuestion");
|
|
687
|
-
|
|
688
|
-
|
|
702
|
+
}
|
|
703
|
+
return container;
|
|
689
704
|
});
|
|
690
705
|
}
|
|
691
706
|
ensureQuestionIsReady() {
|
|
@@ -764,10 +779,31 @@ class VisualizerBase {
|
|
|
764
779
|
targetElement.appendChild(this.footerContainer);
|
|
765
780
|
this.renderFooter(this.footerContainer);
|
|
766
781
|
}
|
|
767
|
-
|
|
782
|
+
updateToolbar() {
|
|
783
|
+
if (!!this.toolbarContainer) {
|
|
784
|
+
PostponeHelper.postpone(() => {
|
|
785
|
+
this.destroyToolbar(this.toolbarContainer);
|
|
786
|
+
this.renderToolbar(this.toolbarContainer);
|
|
787
|
+
});
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
isSupportSoftUpdateContent() {
|
|
791
|
+
return false;
|
|
792
|
+
}
|
|
793
|
+
softUpdateContent() {
|
|
794
|
+
}
|
|
795
|
+
hardUpdateContent() {
|
|
768
796
|
this.destroyContent(this.contentContainer);
|
|
769
797
|
this.renderContent(this.contentContainer);
|
|
770
798
|
}
|
|
799
|
+
updateContent() {
|
|
800
|
+
if (!this.isSupportSoftUpdateContent()) {
|
|
801
|
+
this.hardUpdateContent();
|
|
802
|
+
}
|
|
803
|
+
else {
|
|
804
|
+
this.softUpdateContent();
|
|
805
|
+
}
|
|
806
|
+
}
|
|
771
807
|
/**
|
|
772
808
|
* Re-renders the visualizer and its content.
|
|
773
809
|
*/
|
|
@@ -958,6 +994,7 @@ class VisualizerBase {
|
|
|
958
994
|
}
|
|
959
995
|
}
|
|
960
996
|
VisualizerBase.suppressVisualizerStubRendering = false;
|
|
997
|
+
VisualizerBase.chartAdapterType = undefined;
|
|
961
998
|
// public static otherCommentQuestionType = "comment"; // TODO: make it configureable - allow choose what kind of question/visualizer will be used for comments/others
|
|
962
999
|
VisualizerBase.otherCommentCollapsed = true;
|
|
963
1000
|
VisualizerBase.customColors = [];
|
|
@@ -1031,6 +1068,131 @@ function defaultStatisticsCalculator(data, dataInfo) {
|
|
|
1031
1068
|
return dataInfo.dataNames.length > 1 ? statistics : statistics[0];
|
|
1032
1069
|
}
|
|
1033
1070
|
|
|
1071
|
+
class NumberModel extends VisualizerBase {
|
|
1072
|
+
constructor(question, data, options = {}, name) {
|
|
1073
|
+
super(question, data, options, name || "number");
|
|
1074
|
+
if (VisualizerBase.chartAdapterType) {
|
|
1075
|
+
this._chartAdapter = new VisualizerBase.chartAdapterType(this);
|
|
1076
|
+
this.chartTypes = this._chartAdapter.getChartTypes();
|
|
1077
|
+
this.chartType = this.chartTypes[0];
|
|
1078
|
+
}
|
|
1079
|
+
this.registerToolbarItem("changeChartType", () => {
|
|
1080
|
+
if (this.chartTypes.length > 1) {
|
|
1081
|
+
return DocumentHelper.createSelector(this.chartTypes.map((chartType) => {
|
|
1082
|
+
return {
|
|
1083
|
+
value: chartType,
|
|
1084
|
+
text: localization.getString("chartType_" + chartType),
|
|
1085
|
+
};
|
|
1086
|
+
}), (option) => this.chartType === option.value, (e) => {
|
|
1087
|
+
this.setChartType(e.target.value);
|
|
1088
|
+
});
|
|
1089
|
+
}
|
|
1090
|
+
return null;
|
|
1091
|
+
});
|
|
1092
|
+
}
|
|
1093
|
+
onDataChanged() {
|
|
1094
|
+
this._resultAverage = undefined;
|
|
1095
|
+
this._resultMin = undefined;
|
|
1096
|
+
this._resultMax = undefined;
|
|
1097
|
+
super.onDataChanged();
|
|
1098
|
+
}
|
|
1099
|
+
onChartTypeChanged() { }
|
|
1100
|
+
setChartType(chartType) {
|
|
1101
|
+
if (this.chartTypes.indexOf(chartType) !== -1 &&
|
|
1102
|
+
this.chartType !== chartType) {
|
|
1103
|
+
this.chartType = chartType;
|
|
1104
|
+
this.onChartTypeChanged();
|
|
1105
|
+
if (!!this.contentContainer) {
|
|
1106
|
+
this.destroyContent(this.contentContainer);
|
|
1107
|
+
this.renderContent(this.contentContainer);
|
|
1108
|
+
}
|
|
1109
|
+
this.invokeOnUpdate();
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
destroy() {
|
|
1113
|
+
this._resultAverage = undefined;
|
|
1114
|
+
this._resultMin = undefined;
|
|
1115
|
+
this._resultMax = undefined;
|
|
1116
|
+
super.destroy();
|
|
1117
|
+
}
|
|
1118
|
+
generateText(maxValue, minValue, stepsCount) {
|
|
1119
|
+
let texts = [];
|
|
1120
|
+
if (stepsCount === 5) {
|
|
1121
|
+
texts = [
|
|
1122
|
+
"very high (" + maxValue + ")",
|
|
1123
|
+
"high",
|
|
1124
|
+
"medium",
|
|
1125
|
+
"low",
|
|
1126
|
+
"very low (" + minValue + ")",
|
|
1127
|
+
];
|
|
1128
|
+
}
|
|
1129
|
+
else {
|
|
1130
|
+
texts.push(maxValue);
|
|
1131
|
+
for (let i = 0; i < stepsCount - 2; i++) {
|
|
1132
|
+
texts.push("");
|
|
1133
|
+
}
|
|
1134
|
+
texts.push(minValue);
|
|
1135
|
+
}
|
|
1136
|
+
if (!!NumberModel.generateTextsCallback) {
|
|
1137
|
+
return NumberModel.generateTextsCallback(this.question, maxValue, minValue, stepsCount, texts);
|
|
1138
|
+
}
|
|
1139
|
+
return texts;
|
|
1140
|
+
}
|
|
1141
|
+
generateValues(maxValue, stepsCount) {
|
|
1142
|
+
const values = [];
|
|
1143
|
+
for (let i = 0; i < stepsCount; i++) {
|
|
1144
|
+
values.push(maxValue / stepsCount);
|
|
1145
|
+
}
|
|
1146
|
+
values.push(maxValue);
|
|
1147
|
+
return values;
|
|
1148
|
+
}
|
|
1149
|
+
generateColors(maxValue, minValue, stepsCount) {
|
|
1150
|
+
const palette = this.getColors();
|
|
1151
|
+
const colors = [];
|
|
1152
|
+
for (let i = 0; i < stepsCount; i++) {
|
|
1153
|
+
colors.push(palette[i]);
|
|
1154
|
+
}
|
|
1155
|
+
colors.push("rgba(255, 255, 255, 0)");
|
|
1156
|
+
return colors;
|
|
1157
|
+
}
|
|
1158
|
+
convertFromExternalData(externalCalculatedData) {
|
|
1159
|
+
return [externalCalculatedData.value || 0, externalCalculatedData.minValue || 0, externalCalculatedData.maxValue || 0];
|
|
1160
|
+
}
|
|
1161
|
+
getCalculatedValuesCore() {
|
|
1162
|
+
if (this._resultAverage === undefined ||
|
|
1163
|
+
this._resultMin === undefined ||
|
|
1164
|
+
this._resultMax === undefined) {
|
|
1165
|
+
this._resultMin = Number.MAX_VALUE;
|
|
1166
|
+
this._resultMax = -Number.MAX_VALUE;
|
|
1167
|
+
this._resultAverage = 0;
|
|
1168
|
+
let actualAnswerCount = 0;
|
|
1169
|
+
this.data.forEach((rowData) => {
|
|
1170
|
+
if (rowData[this.question.name] !== undefined) {
|
|
1171
|
+
const questionValue = +rowData[this.question.name];
|
|
1172
|
+
actualAnswerCount++;
|
|
1173
|
+
this._resultAverage += questionValue;
|
|
1174
|
+
if (this._resultMin > questionValue) {
|
|
1175
|
+
this._resultMin = questionValue;
|
|
1176
|
+
}
|
|
1177
|
+
if (this._resultMax < questionValue) {
|
|
1178
|
+
this._resultMax = questionValue;
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
});
|
|
1182
|
+
if (actualAnswerCount > 0) {
|
|
1183
|
+
this._resultAverage = this._resultAverage / actualAnswerCount;
|
|
1184
|
+
}
|
|
1185
|
+
this._resultAverage = Math.ceil(this._resultAverage * 100) / 100;
|
|
1186
|
+
}
|
|
1187
|
+
return [this._resultAverage, this._resultMin, this._resultMax];
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
NumberModel.stepsCount = 5;
|
|
1191
|
+
NumberModel.showAsPercentage = false;
|
|
1192
|
+
VisualizationManager.registerVisualizer("number", NumberModel, 200);
|
|
1193
|
+
VisualizationManager.registerVisualizer("rating", NumberModel, 200);
|
|
1194
|
+
VisualizationManager.registerVisualizer("expression", NumberModel);
|
|
1195
|
+
|
|
1034
1196
|
function hideEmptyAnswersInData(answersData) {
|
|
1035
1197
|
const result = {
|
|
1036
1198
|
datasets: [],
|
|
@@ -1056,9 +1218,9 @@ function hideEmptyAnswersInData(answersData) {
|
|
|
1056
1218
|
seriesDataExistence.length = answersData.seriesLabels.length;
|
|
1057
1219
|
const valuesDataExistence = [];
|
|
1058
1220
|
valuesDataExistence.length = answersData.labels.length;
|
|
1059
|
-
for (var
|
|
1060
|
-
for (var
|
|
1061
|
-
if (answersData.datasets[
|
|
1221
|
+
for (var seriesIndex = 0; seriesIndex < answersData.seriesLabels.length; seriesIndex++) {
|
|
1222
|
+
for (var valueIndex = 0; valueIndex < answersData.labels.length; valueIndex++) {
|
|
1223
|
+
if (answersData.datasets[seriesIndex][valueIndex] != 0) {
|
|
1062
1224
|
seriesDataExistence[seriesIndex] = true;
|
|
1063
1225
|
valuesDataExistence[valueIndex] = true;
|
|
1064
1226
|
}
|
|
@@ -1075,14 +1237,14 @@ function hideEmptyAnswersInData(answersData) {
|
|
|
1075
1237
|
result.seriesLabels.push(answersData.seriesLabels[seriesIndex]);
|
|
1076
1238
|
}
|
|
1077
1239
|
}
|
|
1078
|
-
for (var
|
|
1079
|
-
if (
|
|
1240
|
+
for (var seriesIndex = 0; seriesIndex < answersData.datasets.length; seriesIndex++) {
|
|
1241
|
+
if (seriesDataExistence[seriesIndex]) {
|
|
1080
1242
|
const dataset = [];
|
|
1081
1243
|
const texts = [];
|
|
1082
|
-
for (var
|
|
1083
|
-
if (
|
|
1084
|
-
dataset.push(answersData.datasets[
|
|
1085
|
-
texts.push(answersData.texts[
|
|
1244
|
+
for (var valueIndex = 0; valueIndex < answersData.labels.length; valueIndex++) {
|
|
1245
|
+
if (valuesDataExistence[valueIndex]) {
|
|
1246
|
+
dataset.push(answersData.datasets[seriesIndex][valueIndex]);
|
|
1247
|
+
texts.push(answersData.texts[seriesIndex][valueIndex]);
|
|
1086
1248
|
}
|
|
1087
1249
|
}
|
|
1088
1250
|
result.datasets.push(dataset);
|
|
@@ -1119,17 +1281,34 @@ class SelectBase extends VisualizerBase {
|
|
|
1119
1281
|
* options fields can be modified
|
|
1120
1282
|
*/
|
|
1121
1283
|
this.onAnswersDataReady = new Event();
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1284
|
+
if (!!question) { // TODO: move somewhere else
|
|
1285
|
+
question.visibleChoicesChangedCallback = () => {
|
|
1286
|
+
this.dataProvider.raiseDataChanged();
|
|
1287
|
+
};
|
|
1288
|
+
}
|
|
1125
1289
|
this._showPercentages = this.options.showPercentages === true;
|
|
1126
1290
|
this._showOnlyPercentages = this.options.showOnlyPercentages === true;
|
|
1127
1291
|
if (this.options.percentagePrecision) {
|
|
1128
1292
|
this._percentagePrecision = this.options.percentagePrecision;
|
|
1129
1293
|
}
|
|
1294
|
+
if (this.options.transposeData !== undefined) {
|
|
1295
|
+
this._transposeData = this.options.transposeData;
|
|
1296
|
+
}
|
|
1130
1297
|
this._hideEmptyAnswers = this.options.hideEmptyAnswers === true;
|
|
1131
1298
|
this._answersOrder = this.options.answersOrder || "default";
|
|
1132
1299
|
this._showMissingAnswers = this.isSupportMissingAnswers() && this.options.showMissingAnswers === true;
|
|
1300
|
+
if (this.options.allowExperimentalFeatures) ;
|
|
1301
|
+
if (VisualizerBase.chartAdapterType) {
|
|
1302
|
+
this._chartAdapter = new VisualizerBase.chartAdapterType(this);
|
|
1303
|
+
this.chartTypes = this._chartAdapter.getChartTypes();
|
|
1304
|
+
if (this.getSeriesValues().length > 0 && this.chartTypes.indexOf("stackedbar") === -1) {
|
|
1305
|
+
this.chartTypes.push("stackedbar");
|
|
1306
|
+
}
|
|
1307
|
+
this._chartType = this.chartTypes[0];
|
|
1308
|
+
if (this.chartTypes.indexOf(this.options.defaultChartType) !== -1) {
|
|
1309
|
+
this._chartType = this.options.defaultChartType;
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1133
1312
|
this.registerToolbarItem("changeChartType", () => {
|
|
1134
1313
|
if (this.chartTypes.length > 1) {
|
|
1135
1314
|
return DocumentHelper.createSelector(this.chartTypes.map((chartType) => {
|
|
@@ -1307,6 +1486,16 @@ class SelectBase extends VisualizerBase {
|
|
|
1307
1486
|
const selectBaseQuestion = this.question;
|
|
1308
1487
|
return resultValues.map((value) => ItemValue.getTextOrHtmlByValue(selectBaseQuestion.choices, value)).join(", ");
|
|
1309
1488
|
}
|
|
1489
|
+
isSupportSoftUpdateContent() {
|
|
1490
|
+
return true;
|
|
1491
|
+
}
|
|
1492
|
+
softUpdateContent() {
|
|
1493
|
+
var _a;
|
|
1494
|
+
const chartNode = (_a = this.contentContainer) === null || _a === void 0 ? void 0 : _a.children[0];
|
|
1495
|
+
if (chartNode) {
|
|
1496
|
+
this._chartAdapter.update(chartNode);
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1310
1499
|
getSelectedItemByText(itemText) {
|
|
1311
1500
|
const selBase = this.question;
|
|
1312
1501
|
if (this.question.hasOther && itemText == selBase.otherText) {
|
|
@@ -1562,9 +1751,9 @@ class SelectBase extends VisualizerBase {
|
|
|
1562
1751
|
const series = this.getSeriesValues();
|
|
1563
1752
|
const innerCalculatedData = [];
|
|
1564
1753
|
if (series.length > 0) {
|
|
1565
|
-
for (let
|
|
1754
|
+
for (let j = 0; j < series.length; j++) {
|
|
1566
1755
|
const seriesData = [];
|
|
1567
|
-
for (let
|
|
1756
|
+
for (let i = 0; i < values.length; i++) {
|
|
1568
1757
|
if (!!externalCalculatedData[series[j]]) {
|
|
1569
1758
|
seriesData.push(externalCalculatedData[series[j]][values[i]] || 0);
|
|
1570
1759
|
}
|
|
@@ -1617,10 +1806,252 @@ class SelectBase extends VisualizerBase {
|
|
|
1617
1806
|
}
|
|
1618
1807
|
SelectBase.topNValuesDefaults = [-1, 5, 10, 20];
|
|
1619
1808
|
SelectBase._stateProperties = ["chartType", "answersOrder", "hideEmptyAnswers", "topN"];
|
|
1809
|
+
VisualizationManager.registerVisualizer("checkbox", SelectBase);
|
|
1810
|
+
VisualizationManager.registerVisualizer("radiogroup", SelectBase);
|
|
1811
|
+
VisualizationManager.registerVisualizer("dropdown", SelectBase);
|
|
1812
|
+
VisualizationManager.registerVisualizer("imagepicker", SelectBase);
|
|
1813
|
+
VisualizationManager.registerVisualizer("tagbox", SelectBase);
|
|
1814
|
+
|
|
1815
|
+
class BooleanModel extends SelectBase {
|
|
1816
|
+
constructor(question, data, options, name) {
|
|
1817
|
+
super(question, data, options, name || "boolean");
|
|
1818
|
+
}
|
|
1819
|
+
getCorrectAnswerText() {
|
|
1820
|
+
const correctAnswerValue = this.booleanQuestion.correctAnswer;
|
|
1821
|
+
if (this.booleanQuestion.valueTrue !== undefined && this.booleanQuestion.valueTrue === correctAnswerValue || !!correctAnswerValue) {
|
|
1822
|
+
return this.booleanQuestion.locLabelTrue.textOrHtml;
|
|
1823
|
+
}
|
|
1824
|
+
if (this.booleanQuestion.valueFalse !== undefined && this.booleanQuestion.valueFalse === correctAnswerValue || !correctAnswerValue) {
|
|
1825
|
+
return this.booleanQuestion.locLabelFalse.textOrHtml;
|
|
1826
|
+
}
|
|
1827
|
+
return correctAnswerValue;
|
|
1828
|
+
}
|
|
1829
|
+
get booleanQuestion() {
|
|
1830
|
+
return this.question;
|
|
1831
|
+
}
|
|
1832
|
+
getSelectedItemByText(itemText) {
|
|
1833
|
+
const labels = this.getLabels();
|
|
1834
|
+
const values = this.getValues();
|
|
1835
|
+
return new ItemValue(values[labels.indexOf(itemText)], itemText);
|
|
1836
|
+
}
|
|
1837
|
+
getValues() {
|
|
1838
|
+
const values = [
|
|
1839
|
+
this.booleanQuestion.valueTrue !== undefined
|
|
1840
|
+
? this.booleanQuestion.valueTrue
|
|
1841
|
+
: true,
|
|
1842
|
+
this.booleanQuestion.valueFalse !== undefined
|
|
1843
|
+
? this.booleanQuestion.valueFalse
|
|
1844
|
+
: false,
|
|
1845
|
+
];
|
|
1846
|
+
if (this.showMissingAnswers) {
|
|
1847
|
+
values.push(undefined);
|
|
1848
|
+
}
|
|
1849
|
+
return values;
|
|
1850
|
+
}
|
|
1851
|
+
getLabels() {
|
|
1852
|
+
var labels = [].concat(this.getValues());
|
|
1853
|
+
if (this.booleanQuestion.labelTrue !== undefined) {
|
|
1854
|
+
labels[0] = this.booleanQuestion.locLabelTrue.textOrHtml;
|
|
1855
|
+
}
|
|
1856
|
+
if (this.booleanQuestion.labelFalse !== undefined) {
|
|
1857
|
+
labels[1] = this.booleanQuestion.locLabelFalse.textOrHtml;
|
|
1858
|
+
}
|
|
1859
|
+
if (this.showMissingAnswers) {
|
|
1860
|
+
labels[2] = localization.getString("missingAnswersLabel");
|
|
1861
|
+
}
|
|
1862
|
+
return labels;
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
BooleanModel.trueColor = "";
|
|
1866
|
+
BooleanModel.falseColor = "";
|
|
1867
|
+
VisualizationManager.registerVisualizer("boolean", BooleanModel);
|
|
1868
|
+
|
|
1869
|
+
class HistogramModel extends SelectBase {
|
|
1870
|
+
constructor(question, data, options, name) {
|
|
1871
|
+
super(question, data, options, name || "histogram");
|
|
1872
|
+
this.valueType = "number";
|
|
1873
|
+
this._cachedValues = undefined;
|
|
1874
|
+
this._continiousData = undefined;
|
|
1875
|
+
this._cachedIntervals = undefined;
|
|
1876
|
+
this._intervalPrecision = 2;
|
|
1877
|
+
this._transposeData = false;
|
|
1878
|
+
if (this.options.intervalPrecision !== undefined) {
|
|
1879
|
+
this._intervalPrecision = this.options.intervalPrecision;
|
|
1880
|
+
}
|
|
1881
|
+
const questionType = question.getType();
|
|
1882
|
+
if (questionType === "text" && (question["inputType"] === "date" || question["inputType"] === "datetime")) {
|
|
1883
|
+
this.valueType = "date";
|
|
1884
|
+
}
|
|
1885
|
+
else {
|
|
1886
|
+
this.valueType = "number";
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
reset() {
|
|
1890
|
+
this._continiousData = undefined;
|
|
1891
|
+
this._cachedValues = undefined;
|
|
1892
|
+
this._cachedIntervals = undefined;
|
|
1893
|
+
}
|
|
1894
|
+
getContiniousValue(value) {
|
|
1895
|
+
if (this.valueType === "date") {
|
|
1896
|
+
return Date.parse(value);
|
|
1897
|
+
}
|
|
1898
|
+
return parseFloat(value);
|
|
1899
|
+
}
|
|
1900
|
+
getString(value) {
|
|
1901
|
+
if (this.valueType === "date") {
|
|
1902
|
+
return new Date(value).toLocaleDateString();
|
|
1903
|
+
}
|
|
1904
|
+
return "" + value;
|
|
1905
|
+
}
|
|
1906
|
+
toPrecision(value) {
|
|
1907
|
+
const base = Math.pow(10, this._intervalPrecision);
|
|
1908
|
+
return Math.round(base * value) / base;
|
|
1909
|
+
}
|
|
1910
|
+
getSelectedItemByText(itemText) {
|
|
1911
|
+
if (this.hasCustomIntervals || this.getContiniousValues().length > HistogramModel.UseIntervalsFrom) {
|
|
1912
|
+
const interval = this.intervals.filter(interval => interval.label === itemText)[0];
|
|
1913
|
+
return new ItemValue(interval, interval !== undefined ? interval.label : "");
|
|
1914
|
+
}
|
|
1915
|
+
const labels = this.getLabels();
|
|
1916
|
+
const labelIndex = labels.indexOf(itemText);
|
|
1917
|
+
return new ItemValue(this.getValues()[labelIndex], labels[labelIndex]);
|
|
1918
|
+
}
|
|
1919
|
+
/**
|
|
1920
|
+
* Updates visualizer data.
|
|
1921
|
+
*/
|
|
1922
|
+
updateData(data) {
|
|
1923
|
+
this.reset();
|
|
1924
|
+
super.updateData(data);
|
|
1925
|
+
}
|
|
1926
|
+
onDataChanged() {
|
|
1927
|
+
this.reset();
|
|
1928
|
+
super.onDataChanged();
|
|
1929
|
+
}
|
|
1930
|
+
getContiniousValues() {
|
|
1931
|
+
if (this._cachedValues === undefined) {
|
|
1932
|
+
const series = this.getSeriesValues();
|
|
1933
|
+
if (series.length === 0) {
|
|
1934
|
+
series.push("");
|
|
1935
|
+
}
|
|
1936
|
+
this._continiousData = {};
|
|
1937
|
+
series.forEach(seriesValue => this._continiousData[seriesValue] = []);
|
|
1938
|
+
const hash = {};
|
|
1939
|
+
this.data.forEach(dataItem => {
|
|
1940
|
+
const answerData = dataItem[this.name];
|
|
1941
|
+
if (answerData !== undefined) {
|
|
1942
|
+
const seriesValue = dataItem[DataProvider.seriesMarkerKey] || "";
|
|
1943
|
+
// TODO: _continiousData should be sorted in order to speed-up statistics calculation in the getData function
|
|
1944
|
+
this._continiousData[seriesValue].push(this.getContiniousValue(answerData));
|
|
1945
|
+
hash[answerData] = answerData;
|
|
1946
|
+
}
|
|
1947
|
+
});
|
|
1948
|
+
this._cachedValues = Object.keys(hash).map(key => ({ original: hash[key], continious: this.getContiniousValue(key) }));
|
|
1949
|
+
this._cachedValues.sort((a, b) => a.continious - b.continious);
|
|
1950
|
+
}
|
|
1951
|
+
return this._cachedValues;
|
|
1952
|
+
}
|
|
1953
|
+
isSupportMissingAnswers() {
|
|
1954
|
+
return false;
|
|
1955
|
+
}
|
|
1956
|
+
get needUseRateValues() {
|
|
1957
|
+
return this.question.getType() == "rating" && Array.isArray(this.question["rateValues"]) && this.question["rateValues"].length > 0;
|
|
1958
|
+
}
|
|
1959
|
+
getValues() {
|
|
1960
|
+
return this.intervals.map(interval => interval.start);
|
|
1961
|
+
}
|
|
1962
|
+
getLabels() {
|
|
1963
|
+
return this.intervals.map(interval => interval.label);
|
|
1964
|
+
}
|
|
1965
|
+
get hasCustomIntervals() {
|
|
1966
|
+
return !!this.questionOptions && Array.isArray(this.questionOptions.intervals);
|
|
1967
|
+
}
|
|
1968
|
+
get intervals() {
|
|
1969
|
+
if (this.hasCustomIntervals) {
|
|
1970
|
+
return this.questionOptions.intervals;
|
|
1971
|
+
}
|
|
1972
|
+
if (this.question.getType() == "rating") {
|
|
1973
|
+
if (this.needUseRateValues) {
|
|
1974
|
+
const rateValues = this.question["rateValues"];
|
|
1975
|
+
rateValues.sort((iv1, iv2) => iv1.value - iv2.value);
|
|
1976
|
+
return rateValues.map((rateValue, i) => ({
|
|
1977
|
+
start: rateValue.value,
|
|
1978
|
+
end: i < rateValues.length - 1 ? rateValues[i + 1].value : rateValue.value + 1,
|
|
1979
|
+
label: rateValue.text
|
|
1980
|
+
}));
|
|
1981
|
+
}
|
|
1982
|
+
else {
|
|
1983
|
+
const rateIntervals = [];
|
|
1984
|
+
for (let i = (this.question["rateMin"] || 0); i <= (this.question["rateMax"] || (HistogramModel.IntervalsCount - 1)); i += (this.question["rateStep"] || 1)) {
|
|
1985
|
+
rateIntervals.push({
|
|
1986
|
+
start: i,
|
|
1987
|
+
end: i + 1,
|
|
1988
|
+
label: "" + (!!this.question["rateMin"] && !!this.question["rateMax"] ? i : (i + "-" + (i + 1)))
|
|
1989
|
+
});
|
|
1990
|
+
}
|
|
1991
|
+
return rateIntervals;
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
if (this._cachedIntervals === undefined) {
|
|
1995
|
+
const continiousValues = this.getContiniousValues();
|
|
1996
|
+
this._cachedIntervals = [];
|
|
1997
|
+
if (continiousValues.length) {
|
|
1998
|
+
let start = continiousValues[0].continious;
|
|
1999
|
+
const end = continiousValues[continiousValues.length - 1].continious;
|
|
2000
|
+
const intervalsCount = HistogramModel.IntervalsCount;
|
|
2001
|
+
const delta = (end - start) / intervalsCount;
|
|
2002
|
+
for (let i = 0; i < intervalsCount; ++i) {
|
|
2003
|
+
const next = start + delta;
|
|
2004
|
+
const istart = this.toPrecision(start);
|
|
2005
|
+
const inext = this.toPrecision(next);
|
|
2006
|
+
this._cachedIntervals.push({
|
|
2007
|
+
start: istart,
|
|
2008
|
+
end: i < intervalsCount - 1 ? inext : inext + delta / 100,
|
|
2009
|
+
label: "" + this.getString(istart) + "-" + this.getString(inext)
|
|
2010
|
+
});
|
|
2011
|
+
start = next;
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
}
|
|
2015
|
+
return this._cachedIntervals;
|
|
2016
|
+
}
|
|
2017
|
+
convertFromExternalData(externalCalculatedData) {
|
|
2018
|
+
return [externalCalculatedData];
|
|
2019
|
+
}
|
|
2020
|
+
getCalculatedValuesCore() {
|
|
2021
|
+
this.getContiniousValues();
|
|
2022
|
+
const intervals = this.intervals;
|
|
2023
|
+
const statistics = [];
|
|
2024
|
+
const series = this.getSeriesValues();
|
|
2025
|
+
if (series.length === 0) {
|
|
2026
|
+
series.push("");
|
|
2027
|
+
}
|
|
2028
|
+
for (var i = 0; i < series.length; ++i) {
|
|
2029
|
+
statistics.push(intervals.map(i => 0));
|
|
2030
|
+
this._continiousData[series[i]].forEach(dataValue => {
|
|
2031
|
+
for (let j = 0; j < intervals.length; ++j) {
|
|
2032
|
+
if (intervals[j].start <= dataValue && (dataValue < intervals[j].end || j == intervals.length - 1)) {
|
|
2033
|
+
statistics[i][j]++;
|
|
2034
|
+
break;
|
|
2035
|
+
}
|
|
2036
|
+
}
|
|
2037
|
+
});
|
|
2038
|
+
}
|
|
2039
|
+
return statistics;
|
|
2040
|
+
}
|
|
2041
|
+
getValueType() {
|
|
2042
|
+
return this.valueType;
|
|
2043
|
+
}
|
|
2044
|
+
}
|
|
2045
|
+
HistogramModel.IntervalsCount = 10;
|
|
2046
|
+
HistogramModel.UseIntervalsFrom = 10;
|
|
2047
|
+
VisualizationManager.registerVisualizer("date", HistogramModel);
|
|
2048
|
+
VisualizationManager.registerVisualizer("number", HistogramModel, 100);
|
|
2049
|
+
VisualizationManager.registerVisualizer("rating", HistogramModel, 100);
|
|
1620
2050
|
|
|
1621
2051
|
class Matrix extends SelectBase {
|
|
1622
2052
|
constructor(question, data, options, name) {
|
|
1623
2053
|
super(question, data, options, name || "matrix");
|
|
2054
|
+
this._transposeData = true;
|
|
1624
2055
|
// this.getAnswersData();
|
|
1625
2056
|
}
|
|
1626
2057
|
get matrixQuestion() {
|
|
@@ -1662,124 +2093,141 @@ class Matrix extends SelectBase {
|
|
|
1662
2093
|
}
|
|
1663
2094
|
hideEmptyAnswersInData(answersData) {
|
|
1664
2095
|
const result = {
|
|
1665
|
-
datasets: [],
|
|
1666
|
-
labels: [],
|
|
1667
|
-
colors: [],
|
|
1668
|
-
texts: [],
|
|
1669
|
-
seriesLabels: [],
|
|
1670
|
-
};
|
|
1671
|
-
const hasAnswersInAllSeriesArr = this.getHasAnswersInAllSeriesArray(answersData.datasets);
|
|
1672
|
-
for (let i = 0; i < answersData.datasets.length; i++) {
|
|
1673
|
-
const hasAnswersInSeries = this.getHasAnswersInSeries(answersData.datasets[i]);
|
|
1674
|
-
if (hasAnswersInSeries) {
|
|
1675
|
-
result.labels.push(answersData.labels[i]);
|
|
1676
|
-
result.colors.push(answersData.colors[i]);
|
|
1677
|
-
}
|
|
1678
|
-
else {
|
|
1679
|
-
continue;
|
|
1680
|
-
}
|
|
1681
|
-
const datasets = [];
|
|
1682
|
-
const texts = [];
|
|
1683
|
-
for (let j = 0; j < answersData.datasets[0].length; j++) {
|
|
1684
|
-
if (hasAnswersInAllSeriesArr[j]) {
|
|
1685
|
-
datasets.push(answersData.datasets[i][j]);
|
|
1686
|
-
texts.push(answersData.texts[i][j]);
|
|
1687
|
-
}
|
|
1688
|
-
}
|
|
1689
|
-
result.datasets.push(datasets);
|
|
1690
|
-
result.texts.push(texts);
|
|
1691
|
-
}
|
|
1692
|
-
for (let i = 0; i < answersData.datasets[0].length; i++) {
|
|
1693
|
-
if (hasAnswersInAllSeriesArr[i]) {
|
|
1694
|
-
result.seriesLabels.push(answersData.seriesLabels[i]);
|
|
1695
|
-
}
|
|
1696
|
-
}
|
|
1697
|
-
return result;
|
|
1698
|
-
}
|
|
1699
|
-
getCalculatedValuesCore() {
|
|
1700
|
-
const statistics = super.getCalculatedValuesCore();
|
|
1701
|
-
const series = this.getSeriesValues();
|
|
1702
|
-
const values = this.getValues();
|
|
1703
|
-
const preparedData = [];
|
|
1704
|
-
values.forEach((val, valueIndex) => {
|
|
1705
|
-
const seriesData = series.map((seriesName, seriesIndex) => statistics[seriesIndex][valueIndex]);
|
|
1706
|
-
preparedData.push(seriesData);
|
|
1707
|
-
});
|
|
1708
|
-
return preparedData;
|
|
1709
|
-
}
|
|
1710
|
-
}
|
|
1711
|
-
|
|
1712
|
-
class BooleanModel extends SelectBase {
|
|
1713
|
-
constructor(question, data, options, name) {
|
|
1714
|
-
super(question, data, options, name || "boolean");
|
|
1715
|
-
}
|
|
1716
|
-
getCorrectAnswerText() {
|
|
1717
|
-
const correctAnswerValue = this.booleanQuestion.correctAnswer;
|
|
1718
|
-
if (this.booleanQuestion.valueTrue !== undefined && this.booleanQuestion.valueTrue === correctAnswerValue || !!correctAnswerValue) {
|
|
1719
|
-
return this.booleanQuestion.locLabelTrue.textOrHtml;
|
|
1720
|
-
}
|
|
1721
|
-
if (this.booleanQuestion.valueFalse !== undefined && this.booleanQuestion.valueFalse === correctAnswerValue || !correctAnswerValue) {
|
|
1722
|
-
return this.booleanQuestion.locLabelFalse.textOrHtml;
|
|
1723
|
-
}
|
|
1724
|
-
return correctAnswerValue;
|
|
1725
|
-
}
|
|
1726
|
-
get booleanQuestion() {
|
|
1727
|
-
return this.question;
|
|
1728
|
-
}
|
|
1729
|
-
getSelectedItemByText(itemText) {
|
|
1730
|
-
const labels = this.getLabels();
|
|
1731
|
-
const values = this.getValues();
|
|
1732
|
-
return new ItemValue(values[labels.indexOf(itemText)], itemText);
|
|
1733
|
-
}
|
|
1734
|
-
getValues() {
|
|
1735
|
-
const values = [
|
|
1736
|
-
this.booleanQuestion.valueTrue !== undefined
|
|
1737
|
-
? this.booleanQuestion.valueTrue
|
|
1738
|
-
: true,
|
|
1739
|
-
this.booleanQuestion.valueFalse !== undefined
|
|
1740
|
-
? this.booleanQuestion.valueFalse
|
|
1741
|
-
: false,
|
|
1742
|
-
];
|
|
1743
|
-
if (this.showMissingAnswers) {
|
|
1744
|
-
values.push(undefined);
|
|
1745
|
-
}
|
|
1746
|
-
return values;
|
|
1747
|
-
}
|
|
1748
|
-
getLabels() {
|
|
1749
|
-
var labels = [].concat(this.getValues());
|
|
1750
|
-
if (this.booleanQuestion.labelTrue !== undefined) {
|
|
1751
|
-
labels[0] = this.booleanQuestion.locLabelTrue.textOrHtml;
|
|
1752
|
-
}
|
|
1753
|
-
if (this.booleanQuestion.labelFalse !== undefined) {
|
|
1754
|
-
labels[1] = this.booleanQuestion.locLabelFalse.textOrHtml;
|
|
2096
|
+
datasets: [],
|
|
2097
|
+
labels: [],
|
|
2098
|
+
colors: [],
|
|
2099
|
+
texts: [],
|
|
2100
|
+
seriesLabels: [],
|
|
2101
|
+
};
|
|
2102
|
+
const hasAnswersInAllSeriesArr = this.getHasAnswersInAllSeriesArray(answersData.datasets);
|
|
2103
|
+
for (let i = 0; i < answersData.datasets.length; i++) {
|
|
2104
|
+
const hasAnswersInSeries = this.getHasAnswersInSeries(answersData.datasets[i]);
|
|
2105
|
+
if (hasAnswersInSeries) {
|
|
2106
|
+
result.labels.push(answersData.labels[i]);
|
|
2107
|
+
result.colors.push(answersData.colors[i]);
|
|
2108
|
+
}
|
|
2109
|
+
else {
|
|
2110
|
+
continue;
|
|
2111
|
+
}
|
|
2112
|
+
const datasets = [];
|
|
2113
|
+
const texts = [];
|
|
2114
|
+
for (let j = 0; j < answersData.datasets[0].length; j++) {
|
|
2115
|
+
if (hasAnswersInAllSeriesArr[j]) {
|
|
2116
|
+
datasets.push(answersData.datasets[i][j]);
|
|
2117
|
+
texts.push(answersData.texts[i][j]);
|
|
2118
|
+
}
|
|
2119
|
+
}
|
|
2120
|
+
result.datasets.push(datasets);
|
|
2121
|
+
result.texts.push(texts);
|
|
1755
2122
|
}
|
|
1756
|
-
|
|
1757
|
-
|
|
2123
|
+
for (let i = 0; i < answersData.datasets[0].length; i++) {
|
|
2124
|
+
if (hasAnswersInAllSeriesArr[i]) {
|
|
2125
|
+
result.seriesLabels.push(answersData.seriesLabels[i]);
|
|
2126
|
+
}
|
|
1758
2127
|
}
|
|
1759
|
-
return
|
|
2128
|
+
return result;
|
|
1760
2129
|
}
|
|
1761
2130
|
}
|
|
1762
|
-
|
|
1763
|
-
BooleanModel.falseColor = "";
|
|
2131
|
+
VisualizationManager.registerVisualizer("matrix", Matrix);
|
|
1764
2132
|
|
|
1765
|
-
class
|
|
1766
|
-
constructor(
|
|
1767
|
-
super(
|
|
1768
|
-
this.
|
|
2133
|
+
class PivotModel extends SelectBase {
|
|
2134
|
+
constructor(questions, data, options, name) {
|
|
2135
|
+
super(null, data, options, name || "pivot");
|
|
2136
|
+
this.questions = questions;
|
|
2137
|
+
this.valueType = "enum";
|
|
1769
2138
|
this._cachedValues = undefined;
|
|
1770
2139
|
this._continiousData = undefined;
|
|
1771
2140
|
this._cachedIntervals = undefined;
|
|
1772
2141
|
this._intervalPrecision = 2;
|
|
2142
|
+
this.axisYSelectors = [];
|
|
2143
|
+
this.axisYQuestionNames = [];
|
|
2144
|
+
this.questionsY = [];
|
|
2145
|
+
this.questions = this.questions.filter((question) => ["matrixdropdown", "matrixdynamic", "matrix", "file", "signature", "multipletext", "comment", "html", "image"].indexOf(question.getType()) === -1);
|
|
1773
2146
|
if (this.options.intervalPrecision !== undefined) {
|
|
1774
2147
|
this._intervalPrecision = this.options.intervalPrecision;
|
|
1775
2148
|
}
|
|
2149
|
+
this.axisXQuestionName = this.questions.length > 0 ? this.questions[0].name : undefined;
|
|
2150
|
+
this.registerToolbarItem("axisXSelector", () => this.axisXSelector = DocumentHelper.createSelector(this.questions.map((question) => {
|
|
2151
|
+
return {
|
|
2152
|
+
value: question.name,
|
|
2153
|
+
text: question.title || question.name,
|
|
2154
|
+
};
|
|
2155
|
+
}), (option) => this.axisXQuestionName === option.value, (e) => { this.axisXQuestionName = e.target.value; this.setupPivot(); }, localization.getString("axisXSelectorTitle")));
|
|
2156
|
+
this.registerToolbarItem("axisYSelector0", this.createYSelecterGenerator());
|
|
2157
|
+
this.setupPivot();
|
|
2158
|
+
}
|
|
2159
|
+
createYSelecterGenerator() {
|
|
2160
|
+
const selectorIndex = this.axisYSelectors.length;
|
|
2161
|
+
return () => {
|
|
2162
|
+
let selector = this.axisYSelectors[selectorIndex];
|
|
2163
|
+
if (!selector) {
|
|
2164
|
+
selector = this.createAxisYSelector(selectorIndex);
|
|
2165
|
+
this.axisYSelectors.push(selector);
|
|
2166
|
+
}
|
|
2167
|
+
return selector;
|
|
2168
|
+
};
|
|
2169
|
+
}
|
|
2170
|
+
setAxisQuestions(...axisQuestionNames) {
|
|
2171
|
+
if (axisQuestionNames.length < 1) {
|
|
2172
|
+
return;
|
|
2173
|
+
}
|
|
2174
|
+
this.axisXQuestionName = axisQuestionNames[0];
|
|
2175
|
+
this.axisYQuestionNames = axisQuestionNames.splice(1);
|
|
2176
|
+
this.setupPivot();
|
|
2177
|
+
}
|
|
2178
|
+
onAxisYSelectorChanged(index, value) {
|
|
2179
|
+
this.axisYQuestionNames[index] = value;
|
|
2180
|
+
if (index < this.axisYSelectors.length - 1) {
|
|
2181
|
+
if (!value) {
|
|
2182
|
+
for (let i = index + 1; i < this.axisYSelectors.length; ++i) {
|
|
2183
|
+
this.unregisterToolbarItem("axisYSelector" + i);
|
|
2184
|
+
}
|
|
2185
|
+
this.axisYSelectors = this.axisYSelectors.slice(0, index + 1);
|
|
2186
|
+
this.axisYQuestionNames = this.axisYQuestionNames.slice(0, index + 1);
|
|
2187
|
+
this.updateToolbar();
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
else {
|
|
2191
|
+
if (!!value) {
|
|
2192
|
+
this.registerToolbarItem("axisYSelector" + this.axisYSelectors.length, this.createYSelecterGenerator());
|
|
2193
|
+
this.updateToolbar();
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2196
|
+
this.setupPivot();
|
|
2197
|
+
}
|
|
2198
|
+
createAxisYSelector(selectorIndex) {
|
|
2199
|
+
const selector = DocumentHelper.createSelector([{ value: "", text: "Not selected" }].concat(this.questions.map((question) => {
|
|
2200
|
+
return {
|
|
2201
|
+
value: question.name,
|
|
2202
|
+
text: question.title || question.name,
|
|
2203
|
+
};
|
|
2204
|
+
})), (option) => this.axisYQuestionNames[selectorIndex] === option.value, (e) => { this.onAxisYSelectorChanged(selectorIndex, e.target.value); }, selectorIndex ? undefined : localization.getString("axisYSelectorTitle"));
|
|
2205
|
+
return selector;
|
|
2206
|
+
}
|
|
2207
|
+
getQuestionValueType(question) {
|
|
1776
2208
|
const questionType = question.getType();
|
|
1777
2209
|
if (questionType === "text" && (question["inputType"] === "date" || question["inputType"] === "datetime")) {
|
|
1778
|
-
|
|
2210
|
+
return "date";
|
|
1779
2211
|
}
|
|
1780
|
-
else {
|
|
1781
|
-
|
|
2212
|
+
else if (questionType === "text" || questionType === "rating" || questionType === "expression" || questionType === "range") {
|
|
2213
|
+
return "number";
|
|
2214
|
+
}
|
|
2215
|
+
return "enum";
|
|
2216
|
+
}
|
|
2217
|
+
setupPivot() {
|
|
2218
|
+
const questionX = this.questions.filter((q) => q.name === this.axisXQuestionName)[0];
|
|
2219
|
+
if (!questionX) {
|
|
2220
|
+
return;
|
|
1782
2221
|
}
|
|
2222
|
+
this.question = questionX;
|
|
2223
|
+
this.valueType = this.getQuestionValueType(questionX);
|
|
2224
|
+
this.questionsY = this.axisYQuestionNames.map((name) => {
|
|
2225
|
+
const questionY = this.questions.filter((q) => q.name === name)[0];
|
|
2226
|
+
if (!!questionY) {
|
|
2227
|
+
return this.getQuestionValueType(questionY) === "enum" ? new SelectBase(questionY, []) : new VisualizerBase(questionY, []);
|
|
2228
|
+
}
|
|
2229
|
+
}).filter((q) => !!q);
|
|
2230
|
+
this.onDataChanged();
|
|
1783
2231
|
}
|
|
1784
2232
|
reset() {
|
|
1785
2233
|
this._continiousData = undefined;
|
|
@@ -1803,7 +2251,7 @@ class HistogramModel extends SelectBase {
|
|
|
1803
2251
|
return Math.round(base * value) / base;
|
|
1804
2252
|
}
|
|
1805
2253
|
getSelectedItemByText(itemText) {
|
|
1806
|
-
if (this.hasCustomIntervals || this.getContiniousValues().length >
|
|
2254
|
+
if (this.hasCustomIntervals || this.getContiniousValues().length > PivotModel.UseIntervalsFrom) {
|
|
1807
2255
|
const interval = this.intervals.filter(interval => interval.label === itemText)[0];
|
|
1808
2256
|
return new ItemValue(interval, interval !== undefined ? interval.label : "");
|
|
1809
2257
|
}
|
|
@@ -1824,37 +2272,74 @@ class HistogramModel extends SelectBase {
|
|
|
1824
2272
|
}
|
|
1825
2273
|
getContiniousValues() {
|
|
1826
2274
|
if (this._cachedValues === undefined) {
|
|
1827
|
-
|
|
1828
|
-
if (
|
|
1829
|
-
|
|
2275
|
+
this._continiousData = [];
|
|
2276
|
+
if (this.valueType === "enum") {
|
|
2277
|
+
this._cachedValues = [];
|
|
2278
|
+
return this._cachedValues;
|
|
1830
2279
|
}
|
|
1831
|
-
this._continiousData = {};
|
|
1832
|
-
series.forEach(seriesValue => this._continiousData[seriesValue] = []);
|
|
1833
2280
|
const hash = {};
|
|
1834
2281
|
this.data.forEach(dataItem => {
|
|
1835
2282
|
const answerData = dataItem[this.name];
|
|
1836
2283
|
if (answerData !== undefined) {
|
|
1837
|
-
const seriesValue = dataItem[DataProvider.seriesMarkerKey] || "";
|
|
1838
2284
|
// TODO: _continiousData should be sorted in order to speed-up statistics calculation in the getData function
|
|
1839
|
-
this._continiousData
|
|
1840
|
-
hash[answerData] = answerData;
|
|
2285
|
+
this._continiousData.push({ continious: this.getContiniousValue(answerData), row: dataItem });
|
|
2286
|
+
hash[answerData] = { value: answerData, row: dataItem };
|
|
1841
2287
|
}
|
|
1842
2288
|
});
|
|
1843
|
-
this._cachedValues = Object.keys(hash).map(key => ({ original: hash[key], continious: this.getContiniousValue(key) }));
|
|
2289
|
+
this._cachedValues = Object.keys(hash).map(key => ({ original: hash[key].value, continious: this.getContiniousValue(key), row: hash[key].row }));
|
|
1844
2290
|
this._cachedValues.sort((a, b) => a.continious - b.continious);
|
|
1845
2291
|
}
|
|
1846
2292
|
return this._cachedValues;
|
|
1847
2293
|
}
|
|
2294
|
+
isSupportAnswersOrder() {
|
|
2295
|
+
return false;
|
|
2296
|
+
}
|
|
1848
2297
|
isSupportMissingAnswers() {
|
|
1849
2298
|
return false;
|
|
1850
2299
|
}
|
|
1851
2300
|
get needUseRateValues() {
|
|
1852
2301
|
return this.question.getType() == "rating" && Array.isArray(this.question["rateValues"]) && this.question["rateValues"].length > 0;
|
|
1853
2302
|
}
|
|
2303
|
+
getSeriesValues() {
|
|
2304
|
+
if (!this.questionsY || this.questionsY.length === 0) {
|
|
2305
|
+
return this.options.seriesValues || [];
|
|
2306
|
+
}
|
|
2307
|
+
const seriesValues = [];
|
|
2308
|
+
this.questionsY.forEach(q => {
|
|
2309
|
+
if (this.getQuestionValueType(q.question) === "enum") {
|
|
2310
|
+
seriesValues.push.apply(seriesValues, q.getValues().reverse());
|
|
2311
|
+
}
|
|
2312
|
+
else {
|
|
2313
|
+
seriesValues.push(q.question.name);
|
|
2314
|
+
}
|
|
2315
|
+
});
|
|
2316
|
+
return seriesValues;
|
|
2317
|
+
}
|
|
2318
|
+
getSeriesLabels() {
|
|
2319
|
+
if (this.questionsY.length === 0) {
|
|
2320
|
+
return this.getSeriesValues();
|
|
2321
|
+
}
|
|
2322
|
+
const seriesLabels = [];
|
|
2323
|
+
this.questionsY.forEach(q => {
|
|
2324
|
+
if (this.getQuestionValueType(q.question) === "enum") {
|
|
2325
|
+
seriesLabels.push.apply(seriesLabels, q.getLabels().reverse());
|
|
2326
|
+
}
|
|
2327
|
+
else {
|
|
2328
|
+
seriesLabels.push(q.question.title || q.question.name);
|
|
2329
|
+
}
|
|
2330
|
+
});
|
|
2331
|
+
return seriesLabels;
|
|
2332
|
+
}
|
|
1854
2333
|
getValues() {
|
|
2334
|
+
if (this.valueType === "enum") {
|
|
2335
|
+
return super.getValues().reverse();
|
|
2336
|
+
}
|
|
1855
2337
|
return this.intervals.map(interval => interval.start);
|
|
1856
2338
|
}
|
|
1857
2339
|
getLabels() {
|
|
2340
|
+
if (this.valueType === "enum") {
|
|
2341
|
+
return super.getLabels().reverse();
|
|
2342
|
+
}
|
|
1858
2343
|
return this.intervals.map(interval => interval.label);
|
|
1859
2344
|
}
|
|
1860
2345
|
get hasCustomIntervals() {
|
|
@@ -1876,7 +2361,7 @@ class HistogramModel extends SelectBase {
|
|
|
1876
2361
|
}
|
|
1877
2362
|
else {
|
|
1878
2363
|
const rateIntervals = [];
|
|
1879
|
-
for (let i = (this.question["rateMin"] || 0); i <= (this.question["rateMax"] || (
|
|
2364
|
+
for (let i = (this.question["rateMin"] || 0); i <= (this.question["rateMax"] || (PivotModel.IntervalsCount - 1)); i += (this.question["rateStep"] || 1)) {
|
|
1880
2365
|
rateIntervals.push({
|
|
1881
2366
|
start: i,
|
|
1882
2367
|
end: i + 1,
|
|
@@ -1892,7 +2377,7 @@ class HistogramModel extends SelectBase {
|
|
|
1892
2377
|
if (continiousValues.length) {
|
|
1893
2378
|
let start = continiousValues[0].continious;
|
|
1894
2379
|
const end = continiousValues[continiousValues.length - 1].continious;
|
|
1895
|
-
const intervalsCount =
|
|
2380
|
+
const intervalsCount = PivotModel.IntervalsCount;
|
|
1896
2381
|
const delta = (end - start) / intervalsCount;
|
|
1897
2382
|
for (let i = 0; i < intervalsCount; ++i) {
|
|
1898
2383
|
const next = start + delta;
|
|
@@ -1912,147 +2397,131 @@ class HistogramModel extends SelectBase {
|
|
|
1912
2397
|
convertFromExternalData(externalCalculatedData) {
|
|
1913
2398
|
return [externalCalculatedData];
|
|
1914
2399
|
}
|
|
2400
|
+
getSeriesValueIndexes() {
|
|
2401
|
+
const seriesValueIndexes = {};
|
|
2402
|
+
let valueIndex = 0;
|
|
2403
|
+
for (var i = 0; i < this.questionsY.length; ++i) {
|
|
2404
|
+
const questionValueType = this.getQuestionValueType(this.questionsY[i].question);
|
|
2405
|
+
if (questionValueType === "enum") {
|
|
2406
|
+
this.questionsY[i].getValues().reverse().forEach((value) => {
|
|
2407
|
+
seriesValueIndexes[this.questionsY[i].name + "_" + value] = valueIndex++;
|
|
2408
|
+
});
|
|
2409
|
+
}
|
|
2410
|
+
else {
|
|
2411
|
+
seriesValueIndexes[this.questionsY[i].name] = valueIndex++;
|
|
2412
|
+
}
|
|
2413
|
+
}
|
|
2414
|
+
return seriesValueIndexes;
|
|
2415
|
+
}
|
|
2416
|
+
updateStatisticsSeriesValue(statistics, dataRow, valueIndex, seriesValueIndexes) {
|
|
2417
|
+
for (let j = 0; j < this.questionsY.length; ++j) {
|
|
2418
|
+
if (dataRow[this.questionsY[j].name] !== undefined) {
|
|
2419
|
+
const questionValueType = this.getQuestionValueType(this.questionsY[j].question);
|
|
2420
|
+
if (questionValueType === "enum" || questionValueType === "date") {
|
|
2421
|
+
const seriesValueIndex = seriesValueIndexes[this.questionsY[j].name + "_" + dataRow[this.questionsY[j].name]];
|
|
2422
|
+
statistics[seriesValueIndex][valueIndex]++;
|
|
2423
|
+
}
|
|
2424
|
+
else {
|
|
2425
|
+
const seriesValueIndex = seriesValueIndexes[this.questionsY[j].name];
|
|
2426
|
+
statistics[seriesValueIndex][valueIndex] += parseFloat(dataRow[this.questionsY[j].name]);
|
|
2427
|
+
}
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2430
|
+
}
|
|
1915
2431
|
getCalculatedValuesCore() {
|
|
1916
|
-
this.getContiniousValues();
|
|
1917
|
-
const intervals = this.intervals;
|
|
1918
2432
|
const statistics = [];
|
|
1919
2433
|
const series = this.getSeriesValues();
|
|
1920
2434
|
if (series.length === 0) {
|
|
1921
2435
|
series.push("");
|
|
1922
2436
|
}
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
this.
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
2437
|
+
const seriesValueIndexes = this.getSeriesValueIndexes();
|
|
2438
|
+
if (this.valueType === "enum") {
|
|
2439
|
+
const values = this.getValues();
|
|
2440
|
+
const valueIndexes = {};
|
|
2441
|
+
values.forEach((value, index) => {
|
|
2442
|
+
valueIndexes[value] = index;
|
|
2443
|
+
});
|
|
2444
|
+
for (var i = 0; i < series.length; ++i) {
|
|
2445
|
+
statistics.push(values.map(i => 0));
|
|
2446
|
+
}
|
|
2447
|
+
this.data.forEach(dataRow => {
|
|
2448
|
+
const answerData = dataRow[this.name];
|
|
2449
|
+
if (answerData !== undefined && valueIndexes[answerData] !== undefined) {
|
|
2450
|
+
const valueIndex = valueIndexes[answerData];
|
|
2451
|
+
if (this.questionsY.length === 0) {
|
|
2452
|
+
statistics[0][valueIndex]++;
|
|
2453
|
+
}
|
|
2454
|
+
else {
|
|
2455
|
+
this.updateStatisticsSeriesValue(statistics, dataRow, valueIndex, seriesValueIndexes);
|
|
1930
2456
|
}
|
|
1931
2457
|
}
|
|
1932
2458
|
});
|
|
1933
2459
|
}
|
|
1934
|
-
return statistics;
|
|
1935
|
-
}
|
|
1936
|
-
}
|
|
1937
|
-
HistogramModel.IntervalsCount = 10;
|
|
1938
|
-
HistogramModel.UseIntervalsFrom = 10;
|
|
1939
|
-
|
|
1940
|
-
class NumberModel extends VisualizerBase {
|
|
1941
|
-
constructor(question, data, options = {}, name) {
|
|
1942
|
-
super(question, data, options, name || "number");
|
|
1943
|
-
this.registerToolbarItem("changeChartType", () => {
|
|
1944
|
-
if (this.chartTypes.length > 1) {
|
|
1945
|
-
return DocumentHelper.createSelector(this.chartTypes.map((chartType) => {
|
|
1946
|
-
return {
|
|
1947
|
-
value: chartType,
|
|
1948
|
-
text: localization.getString("chartType_" + chartType),
|
|
1949
|
-
};
|
|
1950
|
-
}), (option) => this.chartType === option.value, (e) => {
|
|
1951
|
-
this.setChartType(e.target.value);
|
|
1952
|
-
});
|
|
1953
|
-
}
|
|
1954
|
-
return null;
|
|
1955
|
-
});
|
|
1956
|
-
}
|
|
1957
|
-
onDataChanged() {
|
|
1958
|
-
this._resultAverage = undefined;
|
|
1959
|
-
this._resultMin = undefined;
|
|
1960
|
-
this._resultMax = undefined;
|
|
1961
|
-
super.onDataChanged();
|
|
1962
|
-
}
|
|
1963
|
-
onChartTypeChanged() { }
|
|
1964
|
-
setChartType(chartType) {
|
|
1965
|
-
if (this.chartTypes.indexOf(chartType) !== -1 &&
|
|
1966
|
-
this.chartType !== chartType) {
|
|
1967
|
-
this.chartType = chartType;
|
|
1968
|
-
this.onChartTypeChanged();
|
|
1969
|
-
if (!!this.contentContainer) {
|
|
1970
|
-
this.destroyContent(this.contentContainer);
|
|
1971
|
-
this.renderContent(this.contentContainer);
|
|
1972
|
-
}
|
|
1973
|
-
this.invokeOnUpdate();
|
|
1974
|
-
}
|
|
1975
|
-
}
|
|
1976
|
-
destroy() {
|
|
1977
|
-
this._resultAverage = undefined;
|
|
1978
|
-
this._resultMin = undefined;
|
|
1979
|
-
this._resultMax = undefined;
|
|
1980
|
-
super.destroy();
|
|
1981
|
-
}
|
|
1982
|
-
generateText(maxValue, minValue, stepsCount) {
|
|
1983
|
-
let texts = [];
|
|
1984
|
-
if (stepsCount === 5) {
|
|
1985
|
-
texts = [
|
|
1986
|
-
"very high (" + maxValue + ")",
|
|
1987
|
-
"high",
|
|
1988
|
-
"medium",
|
|
1989
|
-
"low",
|
|
1990
|
-
"very low (" + minValue + ")",
|
|
1991
|
-
];
|
|
1992
|
-
}
|
|
1993
2460
|
else {
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
2461
|
+
this.getContiniousValues();
|
|
2462
|
+
const intervals = this.intervals;
|
|
2463
|
+
for (var i = 0; i < series.length; ++i) {
|
|
2464
|
+
statistics.push(intervals.map(i => 0));
|
|
1997
2465
|
}
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2466
|
+
this._continiousData.forEach(dataValue => {
|
|
2467
|
+
for (let valueIndex = 0; valueIndex < intervals.length; ++valueIndex) {
|
|
2468
|
+
if (intervals[valueIndex].start <= dataValue.continious && (dataValue.continious < intervals[valueIndex].end || valueIndex == intervals.length - 1)) {
|
|
2469
|
+
if (this.questionsY.length === 0) {
|
|
2470
|
+
statistics[0][valueIndex]++;
|
|
2471
|
+
}
|
|
2472
|
+
else {
|
|
2473
|
+
this.updateStatisticsSeriesValue(statistics, dataValue.row, valueIndex, seriesValueIndexes);
|
|
2474
|
+
}
|
|
2475
|
+
break;
|
|
2476
|
+
}
|
|
2477
|
+
}
|
|
2478
|
+
});
|
|
2002
2479
|
}
|
|
2003
|
-
return
|
|
2480
|
+
return statistics;
|
|
2004
2481
|
}
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
for (let i = 0; i < stepsCount; i++) {
|
|
2008
|
-
values.push(maxValue / stepsCount);
|
|
2009
|
-
}
|
|
2010
|
-
values.push(maxValue);
|
|
2011
|
-
return values;
|
|
2482
|
+
getValueType() {
|
|
2483
|
+
return this.valueType;
|
|
2012
2484
|
}
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
const colors = [];
|
|
2016
|
-
for (let i = 0; i < stepsCount; i++) {
|
|
2017
|
-
colors.push(palette[i]);
|
|
2018
|
-
}
|
|
2019
|
-
colors.push("rgba(255, 255, 255, 0)");
|
|
2020
|
-
return colors;
|
|
2485
|
+
isSupportSoftUpdateContent() {
|
|
2486
|
+
return false;
|
|
2021
2487
|
}
|
|
2022
|
-
|
|
2023
|
-
|
|
2488
|
+
}
|
|
2489
|
+
PivotModel.IntervalsCount = 10;
|
|
2490
|
+
PivotModel.UseIntervalsFrom = 10;
|
|
2491
|
+
VisualizationManager.registerPivotVisualizer(PivotModel);
|
|
2492
|
+
|
|
2493
|
+
class RankingModel extends SelectBase {
|
|
2494
|
+
getQuestionResults() {
|
|
2495
|
+
const name = this.question.name;
|
|
2496
|
+
return this.data.map((dataItem) => dataItem[name]);
|
|
2497
|
+
}
|
|
2498
|
+
getEmptyData() {
|
|
2499
|
+
const choices = this.getValues();
|
|
2500
|
+
let data = [];
|
|
2501
|
+
data.length = choices.length;
|
|
2502
|
+
data.fill(0);
|
|
2503
|
+
return data;
|
|
2024
2504
|
}
|
|
2025
2505
|
getCalculatedValuesCore() {
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
this.
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
this._resultMax = questionValue;
|
|
2043
|
-
}
|
|
2044
|
-
}
|
|
2045
|
-
});
|
|
2046
|
-
if (actualAnswerCount > 0) {
|
|
2047
|
-
this._resultAverage = this._resultAverage / actualAnswerCount;
|
|
2048
|
-
}
|
|
2049
|
-
this._resultAverage = Math.ceil(this._resultAverage * 100) / 100;
|
|
2050
|
-
}
|
|
2051
|
-
return [this._resultAverage, this._resultMin, this._resultMax];
|
|
2506
|
+
const results = this.getQuestionResults();
|
|
2507
|
+
const choices = this.getValues();
|
|
2508
|
+
let plotlyData = this.getEmptyData();
|
|
2509
|
+
results.forEach((result) => {
|
|
2510
|
+
this.applyResultToPlotlyData(result, plotlyData, choices);
|
|
2511
|
+
});
|
|
2512
|
+
return [plotlyData];
|
|
2513
|
+
}
|
|
2514
|
+
applyResultToPlotlyData(result, plotlyData, choices) {
|
|
2515
|
+
if (!result || !plotlyData || !choices)
|
|
2516
|
+
return;
|
|
2517
|
+
result.forEach((resultValue, resultValueIndex, result) => {
|
|
2518
|
+
let index = choices.indexOf(resultValue);
|
|
2519
|
+
plotlyData[index] =
|
|
2520
|
+
+plotlyData[index] + (result.length - resultValueIndex);
|
|
2521
|
+
});
|
|
2052
2522
|
}
|
|
2053
2523
|
}
|
|
2054
|
-
|
|
2055
|
-
NumberModel.showAsPercentage = false;
|
|
2524
|
+
VisualizationManager.registerVisualizer("ranking", RankingModel);
|
|
2056
2525
|
|
|
2057
2526
|
class AlternativeVisualizersWrapper extends VisualizerBase {
|
|
2058
2527
|
updateVisualizerSelector() {
|
|
@@ -2188,6 +2657,12 @@ class AlternativeVisualizersWrapper extends VisualizerBase {
|
|
|
2188
2657
|
this.visualizer.setState(state.state);
|
|
2189
2658
|
}
|
|
2190
2659
|
}
|
|
2660
|
+
getValues() {
|
|
2661
|
+
return this.visualizer.getValues();
|
|
2662
|
+
}
|
|
2663
|
+
getLabels() {
|
|
2664
|
+
return this.visualizer.getLabels();
|
|
2665
|
+
}
|
|
2191
2666
|
getCalculatedValues() {
|
|
2192
2667
|
return this.visualizer.getCalculatedValues();
|
|
2193
2668
|
}
|
|
@@ -9443,7 +9918,15 @@ class VisualizationPanel extends VisualizerBase {
|
|
|
9443
9918
|
}
|
|
9444
9919
|
buildVisualizers(questions) {
|
|
9445
9920
|
questions.forEach((question) => {
|
|
9446
|
-
|
|
9921
|
+
let visualizerOptions = Object.assign({}, this.options);
|
|
9922
|
+
let visualizerData = this.surveyData;
|
|
9923
|
+
let visualizer;
|
|
9924
|
+
if (Array.isArray(question)) {
|
|
9925
|
+
visualizer = new (VisualizationManager.getPivotVisualizerConstructor())(question, visualizerData, visualizerOptions);
|
|
9926
|
+
}
|
|
9927
|
+
else {
|
|
9928
|
+
visualizer = this.createVisualizer(question, visualizerOptions, visualizerData);
|
|
9929
|
+
}
|
|
9447
9930
|
if (!visualizer) {
|
|
9448
9931
|
return;
|
|
9449
9932
|
}
|
|
@@ -9510,6 +9993,7 @@ class VisualizationPanel extends VisualizerBase {
|
|
|
9510
9993
|
setLocale(newLocale) {
|
|
9511
9994
|
super.setLocale(newLocale);
|
|
9512
9995
|
(this.questions || []).forEach((question) => {
|
|
9996
|
+
question = Array.isArray(question) ? question[0] : question;
|
|
9513
9997
|
const element = this.getElement(question.name);
|
|
9514
9998
|
if (!!element) {
|
|
9515
9999
|
element.displayName = this.processText(question.title);
|
|
@@ -9556,6 +10040,7 @@ class VisualizationPanel extends VisualizerBase {
|
|
|
9556
10040
|
}
|
|
9557
10041
|
buildElements(questions) {
|
|
9558
10042
|
return (questions || []).map((question) => {
|
|
10043
|
+
question = Array.isArray(question) ? question[0] : question;
|
|
9559
10044
|
return {
|
|
9560
10045
|
name: question.name,
|
|
9561
10046
|
displayName: this.processText(question.title),
|
|
@@ -9756,7 +10241,7 @@ class VisualizationPanel extends VisualizerBase {
|
|
|
9756
10241
|
this._settingState = true;
|
|
9757
10242
|
try {
|
|
9758
10243
|
if (Array.isArray(newState.elements)) {
|
|
9759
|
-
const questionNames = this.questions.map(q => q.name);
|
|
10244
|
+
const questionNames = this.questions.map(q => Array.isArray(q) ? q[0].name : q.name);
|
|
9760
10245
|
this._elements = [].concat(newState.elements.filter(e => (questionNames.indexOf(e.name) !== -1)));
|
|
9761
10246
|
}
|
|
9762
10247
|
if (typeof newState.locale !== "undefined")
|
|
@@ -9890,6 +10375,7 @@ class VisualizationMatrixDropdown extends VisualizerBase {
|
|
|
9890
10375
|
this._childOptions.disableLocaleSwitch = true;
|
|
9891
10376
|
this._childOptions.dataProvider = undefined;
|
|
9892
10377
|
this._childOptions.allowDynamicLayout = false;
|
|
10378
|
+
this._childOptions.transposeData = true;
|
|
9893
10379
|
this._childOptions.seriesValues = question.rows.map((row) => row.value);
|
|
9894
10380
|
this._childOptions.seriesLabels = question.rows.map((row) => row.text);
|
|
9895
10381
|
const innerQuestions = this.getQuestions();
|
|
@@ -11941,5 +12427,5 @@ NpsVisualizer.DetractorScore = 6;
|
|
|
11941
12427
|
NpsVisualizer.PromoterScore = 9;
|
|
11942
12428
|
// VisualizationManager.registerVisualizer("rating", NpsVisualizer);
|
|
11943
12429
|
|
|
11944
|
-
export { AlternativeVisualizersWrapper as A, BooleanModel as B, DataProvider as D, HistogramModel as H, Matrix as M, NumberModel as N, PostponeHelper as P, SelectBase as S, TextTableAdapter as T, VisualizerFactory as V, WordCloudAdapter as W, __awaiter as _, VisualizerBase as a, VisualizationManager as b, VisualizationPanel as c, defaultStatisticsCalculator as d, VisualizationPanelDynamic as e, VisualizationMatrixDynamic as f, VisualizationMatrixDropdown as g, hideEmptyAnswersInData as h, WordCloud as i, Text as j, StatisticsTableAdapter as k, StatisticsTable as l, NpsVisualizerWidget as m, NpsAdapter as n, NpsVisualizer as o, textHelper as t };
|
|
12430
|
+
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, defaultStatisticsCalculator as d, VisualizationPanelDynamic as e, VisualizationMatrixDynamic as f, VisualizationMatrixDropdown as g, hideEmptyAnswersInData as h, WordCloud as i, Text as j, StatisticsTableAdapter as k, StatisticsTable as l, NpsVisualizerWidget as m, NpsAdapter as n, NpsVisualizer as o, PivotModel as p, textHelper as t };
|
|
11945
12431
|
//# sourceMappingURL=shared2.mjs.map
|