survey-analytics 2.2.2 → 2.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/fesm/shared.mjs +10 -2
  2. package/fesm/shared.mjs.map +1 -1
  3. package/fesm/shared2.mjs +412 -31
  4. package/fesm/shared2.mjs.map +1 -1
  5. package/fesm/survey.analytics.core.mjs +2 -2
  6. package/fesm/survey.analytics.mjs +158 -150
  7. package/fesm/survey.analytics.mjs.map +1 -1
  8. package/fesm/survey.analytics.tabulator.mjs +1 -1
  9. package/package.json +8 -8
  10. package/survey-analytics-tabulator.types/analytics-localization/english.d.ts +2 -0
  11. package/survey-analytics-tabulator.types/localizationManager.d.ts +2 -0
  12. package/survey-analytics-tabulator.types/utils/index.d.ts +1 -1
  13. package/survey-analytics.types/alternativeVizualizersWrapper.d.ts +2 -0
  14. package/survey-analytics.types/analytics-localization/english.d.ts +2 -0
  15. package/survey-analytics.types/entries/summary.core.d.ts +1 -0
  16. package/survey-analytics.types/localizationManager.d.ts +2 -0
  17. package/survey-analytics.types/matrix.d.ts +0 -1
  18. package/survey-analytics.types/pivot.d.ts +62 -0
  19. package/survey-analytics.types/plotly/histogram.d.ts +0 -1
  20. package/survey-analytics.types/plotly/index.d.ts +1 -0
  21. package/survey-analytics.types/plotly/pivot.d.ts +12 -0
  22. package/survey-analytics.types/plotly/selectBase.d.ts +0 -1
  23. package/survey-analytics.types/selectBase.d.ts +1 -1
  24. package/survey-analytics.types/utils/index.d.ts +1 -1
  25. package/survey-analytics.types/visualizationManager.d.ts +3 -0
  26. package/survey-analytics.types/visualizerBase.d.ts +2 -1
  27. package/survey.analytics.core.css +7 -1
  28. package/survey.analytics.core.css.map +1 -1
  29. package/survey.analytics.core.js +487 -34
  30. package/survey.analytics.core.js.map +1 -1
  31. package/survey.analytics.core.min.css +2 -2
  32. package/survey.analytics.core.min.js +1 -1
  33. package/survey.analytics.core.min.js.LICENSE.txt +1 -1
  34. package/survey.analytics.css +7 -1
  35. package/survey.analytics.css.map +1 -1
  36. package/survey.analytics.js +682 -180
  37. package/survey.analytics.js.map +1 -1
  38. package/survey.analytics.min.css +2 -2
  39. package/survey.analytics.min.js +1 -1
  40. package/survey.analytics.min.js.LICENSE.txt +1 -1
  41. package/survey.analytics.tabulator.css +1 -1
  42. package/survey.analytics.tabulator.js +10 -2
  43. package/survey.analytics.tabulator.js.map +1 -1
  44. package/survey.analytics.tabulator.min.css +1 -1
  45. package/survey.analytics.tabulator.min.js +1 -1
  46. package/survey.analytics.tabulator.min.js.LICENSE.txt +1 -1
package/fesm/shared2.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * surveyjs - SurveyJS Dashboard library v2.2.2
2
+ * surveyjs - SurveyJS Dashboard library v2.2.3
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
  */
@@ -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
  /**
@@ -447,12 +454,12 @@ class VisualizerBase {
447
454
  get hasFooter() {
448
455
  return (!!this.question && (this.question.hasComment || this.question.hasOther));
449
456
  }
450
- createVisualizer(question, options) {
457
+ createVisualizer(question, options, data) {
451
458
  let visualizerOptions = Object.assign({}, options || this.options);
452
459
  if (visualizerOptions.dataProvider === undefined) {
453
460
  visualizerOptions.dataProvider = this.dataProvider;
454
461
  }
455
- return VisualizerFactory.createVisualizer(question, this.data, visualizerOptions);
462
+ return VisualizerFactory.createVisualizer(question, data || this.data, visualizerOptions);
456
463
  }
457
464
  /**
458
465
  * Allows you to access the footer visualizer. Returns `undefined` if the footer is absent.
@@ -764,6 +771,14 @@ class VisualizerBase {
764
771
  targetElement.appendChild(this.footerContainer);
765
772
  this.renderFooter(this.footerContainer);
766
773
  }
774
+ updateToolbar() {
775
+ if (!!this.toolbarContainer) {
776
+ PostponeHelper.postpone(() => {
777
+ this.destroyToolbar(this.toolbarContainer);
778
+ this.renderToolbar(this.toolbarContainer);
779
+ });
780
+ }
781
+ }
767
782
  updateContent() {
768
783
  this.destroyContent(this.contentContainer);
769
784
  this.renderContent(this.contentContainer);
@@ -1056,9 +1071,9 @@ function hideEmptyAnswersInData(answersData) {
1056
1071
  seriesDataExistence.length = answersData.seriesLabels.length;
1057
1072
  const valuesDataExistence = [];
1058
1073
  valuesDataExistence.length = answersData.labels.length;
1059
- for (var valueIndex = 0; valueIndex < answersData.labels.length; valueIndex++) {
1060
- for (var seriesIndex = 0; seriesIndex < answersData.seriesLabels.length; seriesIndex++) {
1061
- if (answersData.datasets[valueIndex][seriesIndex] != 0) {
1074
+ for (var seriesIndex = 0; seriesIndex < answersData.seriesLabels.length; seriesIndex++) {
1075
+ for (var valueIndex = 0; valueIndex < answersData.labels.length; valueIndex++) {
1076
+ if (answersData.datasets[seriesIndex][valueIndex] != 0) {
1062
1077
  seriesDataExistence[seriesIndex] = true;
1063
1078
  valuesDataExistence[valueIndex] = true;
1064
1079
  }
@@ -1075,14 +1090,14 @@ function hideEmptyAnswersInData(answersData) {
1075
1090
  result.seriesLabels.push(answersData.seriesLabels[seriesIndex]);
1076
1091
  }
1077
1092
  }
1078
- for (var valueIndex = 0; valueIndex < answersData.labels.length; valueIndex++) {
1079
- if (valuesDataExistence[valueIndex]) {
1093
+ for (var seriesIndex = 0; seriesIndex < answersData.datasets.length; seriesIndex++) {
1094
+ if (seriesDataExistence[seriesIndex]) {
1080
1095
  const dataset = [];
1081
1096
  const texts = [];
1082
- for (var seriesIndex = 0; seriesIndex < answersData.datasets.length; seriesIndex++) {
1083
- if (seriesDataExistence[seriesIndex]) {
1084
- dataset.push(answersData.datasets[valueIndex][seriesIndex]);
1085
- texts.push(answersData.texts[valueIndex][seriesIndex]);
1097
+ for (var valueIndex = 0; valueIndex < answersData.labels.length; valueIndex++) {
1098
+ if (valuesDataExistence[valueIndex]) {
1099
+ dataset.push(answersData.datasets[seriesIndex][valueIndex]);
1100
+ texts.push(answersData.texts[seriesIndex][valueIndex]);
1086
1101
  }
1087
1102
  }
1088
1103
  result.datasets.push(dataset);
@@ -1119,14 +1134,19 @@ class SelectBase extends VisualizerBase {
1119
1134
  * options fields can be modified
1120
1135
  */
1121
1136
  this.onAnswersDataReady = new Event();
1122
- question.visibleChoicesChangedCallback = () => {
1123
- this.dataProvider.raiseDataChanged();
1124
- };
1137
+ if (!!question) { // TODO: move somewhere else
1138
+ question.visibleChoicesChangedCallback = () => {
1139
+ this.dataProvider.raiseDataChanged();
1140
+ };
1141
+ }
1125
1142
  this._showPercentages = this.options.showPercentages === true;
1126
1143
  this._showOnlyPercentages = this.options.showOnlyPercentages === true;
1127
1144
  if (this.options.percentagePrecision) {
1128
1145
  this._percentagePrecision = this.options.percentagePrecision;
1129
1146
  }
1147
+ if (this.options.transposeData !== undefined) {
1148
+ this._transposeData = this.options.transposeData;
1149
+ }
1130
1150
  this._hideEmptyAnswers = this.options.hideEmptyAnswers === true;
1131
1151
  this._answersOrder = this.options.answersOrder || "default";
1132
1152
  this._showMissingAnswers = this.isSupportMissingAnswers() && this.options.showMissingAnswers === true;
@@ -1562,9 +1582,9 @@ class SelectBase extends VisualizerBase {
1562
1582
  const series = this.getSeriesValues();
1563
1583
  const innerCalculatedData = [];
1564
1584
  if (series.length > 0) {
1565
- for (let i = 0; i < values.length; i++) {
1585
+ for (let j = 0; j < series.length; j++) {
1566
1586
  const seriesData = [];
1567
- for (let j = 0; j < series.length; j++) {
1587
+ for (let i = 0; i < values.length; i++) {
1568
1588
  if (!!externalCalculatedData[series[j]]) {
1569
1589
  seriesData.push(externalCalculatedData[series[j]][values[i]] || 0);
1570
1590
  }
@@ -1621,6 +1641,7 @@ SelectBase._stateProperties = ["chartType", "answersOrder", "hideEmptyAnswers",
1621
1641
  class Matrix extends SelectBase {
1622
1642
  constructor(question, data, options, name) {
1623
1643
  super(question, data, options, name || "matrix");
1644
+ this._transposeData = true;
1624
1645
  // this.getAnswersData();
1625
1646
  }
1626
1647
  get matrixQuestion() {
@@ -1696,17 +1717,6 @@ class Matrix extends SelectBase {
1696
1717
  }
1697
1718
  return result;
1698
1719
  }
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
1720
  }
1711
1721
 
1712
1722
  class BooleanModel extends SelectBase {
@@ -1770,6 +1780,7 @@ class HistogramModel extends SelectBase {
1770
1780
  this._continiousData = undefined;
1771
1781
  this._cachedIntervals = undefined;
1772
1782
  this._intervalPrecision = 2;
1783
+ this._transposeData = false;
1773
1784
  if (this.options.intervalPrecision !== undefined) {
1774
1785
  this._intervalPrecision = this.options.intervalPrecision;
1775
1786
  }
@@ -2054,6 +2065,359 @@ class NumberModel extends VisualizerBase {
2054
2065
  NumberModel.stepsCount = 5;
2055
2066
  NumberModel.showAsPercentage = false;
2056
2067
 
2068
+ class PivotModel extends SelectBase {
2069
+ constructor(questions, data, options, name) {
2070
+ super(null, data, options, name || "pivot");
2071
+ this.questions = questions;
2072
+ this.valueType = "enum";
2073
+ this._cachedValues = undefined;
2074
+ this._continiousData = undefined;
2075
+ this._cachedIntervals = undefined;
2076
+ this._intervalPrecision = 2;
2077
+ this.axisYSelectors = [];
2078
+ this.axisYQuestionNames = [];
2079
+ this.questionsY = [];
2080
+ this.questions = this.questions.filter((question) => ["matrixdropdown", "matrixdynamic", "matrix", "file", "signature", "multipletext", "comment", "html", "image"].indexOf(question.getType()) === -1);
2081
+ if (this.options.intervalPrecision !== undefined) {
2082
+ this._intervalPrecision = this.options.intervalPrecision;
2083
+ }
2084
+ this.axisXQuestionName = this.questions.length > 0 ? this.questions[0].name : undefined;
2085
+ this.registerToolbarItem("axisXSelector", () => this.axisXSelector = DocumentHelper.createSelector(this.questions.map((question) => {
2086
+ return {
2087
+ value: question.name,
2088
+ text: question.title || question.name,
2089
+ };
2090
+ }), (option) => this.axisXQuestionName === option.value, (e) => { this.axisXQuestionName = e.target.value; this.setupPivot(); }, localization.getString("axisXSelectorTitle")));
2091
+ this.registerToolbarItem("axisYSelector0", this.createYSelecterGenerator());
2092
+ this.setupPivot();
2093
+ }
2094
+ createYSelecterGenerator() {
2095
+ const selectorIndex = this.axisYSelectors.length;
2096
+ return () => {
2097
+ let selector = this.axisYSelectors[selectorIndex];
2098
+ if (!selector) {
2099
+ selector = this.createAxisYSelector(selectorIndex);
2100
+ this.axisYSelectors.push(selector);
2101
+ }
2102
+ return selector;
2103
+ };
2104
+ }
2105
+ setAxisQuestions(...axisQuestionNames) {
2106
+ if (axisQuestionNames.length < 1) {
2107
+ return;
2108
+ }
2109
+ this.axisXQuestionName = axisQuestionNames[0];
2110
+ this.axisYQuestionNames = axisQuestionNames.splice(1);
2111
+ this.setupPivot();
2112
+ }
2113
+ onAxisYSelectorChanged(index, value) {
2114
+ this.axisYQuestionNames[index] = value;
2115
+ if (index < this.axisYSelectors.length - 1) {
2116
+ if (!value) {
2117
+ for (let i = index + 1; i < this.axisYSelectors.length; ++i) {
2118
+ this.unregisterToolbarItem("axisYSelector" + i);
2119
+ }
2120
+ this.axisYSelectors = this.axisYSelectors.slice(0, index + 1);
2121
+ this.axisYQuestionNames = this.axisYQuestionNames.slice(0, index + 1);
2122
+ this.updateToolbar();
2123
+ }
2124
+ }
2125
+ else {
2126
+ if (!!value) {
2127
+ this.registerToolbarItem("axisYSelector" + this.axisYSelectors.length, this.createYSelecterGenerator());
2128
+ this.updateToolbar();
2129
+ }
2130
+ }
2131
+ this.setupPivot();
2132
+ }
2133
+ createAxisYSelector(selectorIndex) {
2134
+ const selector = DocumentHelper.createSelector([{ value: "", text: "Not selected" }].concat(this.questions.map((question) => {
2135
+ return {
2136
+ value: question.name,
2137
+ text: question.title || question.name,
2138
+ };
2139
+ })), (option) => this.axisYQuestionNames[selectorIndex] === option.value, (e) => { this.onAxisYSelectorChanged(selectorIndex, e.target.value); }, selectorIndex ? undefined : localization.getString("axisYSelectorTitle"));
2140
+ return selector;
2141
+ }
2142
+ getQuestionValueType(question) {
2143
+ const questionType = question.getType();
2144
+ if (questionType === "text" && (question["inputType"] === "date" || question["inputType"] === "datetime")) {
2145
+ return "date";
2146
+ }
2147
+ else if (questionType === "text" || questionType === "rating" || questionType === "expression" || questionType === "range") {
2148
+ return "number";
2149
+ }
2150
+ return "enum";
2151
+ }
2152
+ setupPivot() {
2153
+ const questionX = this.questions.filter((q) => q.name === this.axisXQuestionName)[0];
2154
+ if (!questionX) {
2155
+ return;
2156
+ }
2157
+ this.question = questionX;
2158
+ this.valueType = this.getQuestionValueType(questionX);
2159
+ this.questionsY = this.axisYQuestionNames.map((name) => {
2160
+ const questionY = this.questions.filter((q) => q.name === name)[0];
2161
+ if (!!questionY) {
2162
+ return this.getQuestionValueType(questionY) === "enum" ? new SelectBase(questionY, []) : new VisualizerBase(questionY, []);
2163
+ }
2164
+ }).filter((q) => !!q);
2165
+ this.onDataChanged();
2166
+ }
2167
+ reset() {
2168
+ this._continiousData = undefined;
2169
+ this._cachedValues = undefined;
2170
+ this._cachedIntervals = undefined;
2171
+ }
2172
+ getContiniousValue(value) {
2173
+ if (this.valueType === "date") {
2174
+ return Date.parse(value);
2175
+ }
2176
+ return parseFloat(value);
2177
+ }
2178
+ getString(value) {
2179
+ if (this.valueType === "date") {
2180
+ return new Date(value).toLocaleDateString();
2181
+ }
2182
+ return "" + value;
2183
+ }
2184
+ toPrecision(value) {
2185
+ const base = Math.pow(10, this._intervalPrecision);
2186
+ return Math.round(base * value) / base;
2187
+ }
2188
+ getSelectedItemByText(itemText) {
2189
+ if (this.hasCustomIntervals || this.getContiniousValues().length > PivotModel.UseIntervalsFrom) {
2190
+ const interval = this.intervals.filter(interval => interval.label === itemText)[0];
2191
+ return new ItemValue(interval, interval !== undefined ? interval.label : "");
2192
+ }
2193
+ const labels = this.getLabels();
2194
+ const labelIndex = labels.indexOf(itemText);
2195
+ return new ItemValue(this.getValues()[labelIndex], labels[labelIndex]);
2196
+ }
2197
+ /**
2198
+ * Updates visualizer data.
2199
+ */
2200
+ updateData(data) {
2201
+ this.reset();
2202
+ super.updateData(data);
2203
+ }
2204
+ onDataChanged() {
2205
+ this.reset();
2206
+ super.onDataChanged();
2207
+ }
2208
+ getContiniousValues() {
2209
+ if (this._cachedValues === undefined) {
2210
+ this._continiousData = [];
2211
+ if (this.valueType === "enum") {
2212
+ this._cachedValues = [];
2213
+ return this._cachedValues;
2214
+ }
2215
+ const hash = {};
2216
+ this.data.forEach(dataItem => {
2217
+ const answerData = dataItem[this.name];
2218
+ if (answerData !== undefined) {
2219
+ // TODO: _continiousData should be sorted in order to speed-up statistics calculation in the getData function
2220
+ this._continiousData.push({ continious: this.getContiniousValue(answerData), row: dataItem });
2221
+ hash[answerData] = { value: answerData, row: dataItem };
2222
+ }
2223
+ });
2224
+ this._cachedValues = Object.keys(hash).map(key => ({ original: hash[key].value, continious: this.getContiniousValue(key), row: hash[key].row }));
2225
+ this._cachedValues.sort((a, b) => a.continious - b.continious);
2226
+ }
2227
+ return this._cachedValues;
2228
+ }
2229
+ isSupportAnswersOrder() {
2230
+ return false;
2231
+ }
2232
+ isSupportMissingAnswers() {
2233
+ return false;
2234
+ }
2235
+ get needUseRateValues() {
2236
+ return this.question.getType() == "rating" && Array.isArray(this.question["rateValues"]) && this.question["rateValues"].length > 0;
2237
+ }
2238
+ getSeriesValues() {
2239
+ if (this.questionsY.length === 0) {
2240
+ return this.options.seriesValues || [];
2241
+ }
2242
+ const seriesValues = [];
2243
+ this.questionsY.forEach(q => {
2244
+ if (this.getQuestionValueType(q.question) === "enum") {
2245
+ seriesValues.push.apply(seriesValues, q.getValues().reverse());
2246
+ }
2247
+ else {
2248
+ seriesValues.push(q.question.name);
2249
+ }
2250
+ });
2251
+ return seriesValues;
2252
+ }
2253
+ getSeriesLabels() {
2254
+ if (this.questionsY.length === 0) {
2255
+ return this.getSeriesValues();
2256
+ }
2257
+ const seriesLabels = [];
2258
+ this.questionsY.forEach(q => {
2259
+ if (this.getQuestionValueType(q.question) === "enum") {
2260
+ seriesLabels.push.apply(seriesLabels, q.getLabels().reverse());
2261
+ }
2262
+ else {
2263
+ seriesLabels.push(q.question.title || q.question.name);
2264
+ }
2265
+ });
2266
+ return seriesLabels;
2267
+ }
2268
+ getValues() {
2269
+ if (this.valueType === "enum") {
2270
+ return super.getValues().reverse();
2271
+ }
2272
+ return this.intervals.map(interval => interval.start);
2273
+ }
2274
+ getLabels() {
2275
+ if (this.valueType === "enum") {
2276
+ return super.getLabels().reverse();
2277
+ }
2278
+ return this.intervals.map(interval => interval.label);
2279
+ }
2280
+ get hasCustomIntervals() {
2281
+ return !!this.questionOptions && Array.isArray(this.questionOptions.intervals);
2282
+ }
2283
+ get intervals() {
2284
+ if (this.hasCustomIntervals) {
2285
+ return this.questionOptions.intervals;
2286
+ }
2287
+ if (this.question.getType() == "rating") {
2288
+ if (this.needUseRateValues) {
2289
+ const rateValues = this.question["rateValues"];
2290
+ rateValues.sort((iv1, iv2) => iv1.value - iv2.value);
2291
+ return rateValues.map((rateValue, i) => ({
2292
+ start: rateValue.value,
2293
+ end: i < rateValues.length - 1 ? rateValues[i + 1].value : rateValue.value + 1,
2294
+ label: rateValue.text
2295
+ }));
2296
+ }
2297
+ else {
2298
+ const rateIntervals = [];
2299
+ for (let i = (this.question["rateMin"] || 0); i <= (this.question["rateMax"] || (PivotModel.IntervalsCount - 1)); i += (this.question["rateStep"] || 1)) {
2300
+ rateIntervals.push({
2301
+ start: i,
2302
+ end: i + 1,
2303
+ label: "" + (!!this.question["rateMin"] && !!this.question["rateMax"] ? i : (i + "-" + (i + 1)))
2304
+ });
2305
+ }
2306
+ return rateIntervals;
2307
+ }
2308
+ }
2309
+ if (this._cachedIntervals === undefined) {
2310
+ const continiousValues = this.getContiniousValues();
2311
+ this._cachedIntervals = [];
2312
+ if (continiousValues.length) {
2313
+ let start = continiousValues[0].continious;
2314
+ const end = continiousValues[continiousValues.length - 1].continious;
2315
+ const intervalsCount = PivotModel.IntervalsCount;
2316
+ const delta = (end - start) / intervalsCount;
2317
+ for (let i = 0; i < intervalsCount; ++i) {
2318
+ const next = start + delta;
2319
+ const istart = this.toPrecision(start);
2320
+ const inext = this.toPrecision(next);
2321
+ this._cachedIntervals.push({
2322
+ start: istart,
2323
+ end: i < intervalsCount - 1 ? inext : inext + delta / 100,
2324
+ label: "" + this.getString(istart) + "-" + this.getString(inext)
2325
+ });
2326
+ start = next;
2327
+ }
2328
+ }
2329
+ }
2330
+ return this._cachedIntervals;
2331
+ }
2332
+ convertFromExternalData(externalCalculatedData) {
2333
+ return [externalCalculatedData];
2334
+ }
2335
+ getSeriesValueIndexes() {
2336
+ const seriesValueIndexes = {};
2337
+ let valueIndex = 0;
2338
+ for (var i = 0; i < this.questionsY.length; ++i) {
2339
+ const questionValueType = this.getQuestionValueType(this.questionsY[i].question);
2340
+ if (questionValueType === "enum") {
2341
+ this.questionsY[i].getValues().reverse().forEach((value) => {
2342
+ seriesValueIndexes[this.questionsY[i].name + "_" + value] = valueIndex++;
2343
+ });
2344
+ }
2345
+ else {
2346
+ seriesValueIndexes[this.questionsY[i].name] = valueIndex++;
2347
+ }
2348
+ }
2349
+ return seriesValueIndexes;
2350
+ }
2351
+ updateStatisticsSeriesValue(statistics, dataRow, valueIndex, seriesValueIndexes) {
2352
+ for (let j = 0; j < this.questionsY.length; ++j) {
2353
+ if (dataRow[this.questionsY[j].name] !== undefined) {
2354
+ const questionValueType = this.getQuestionValueType(this.questionsY[j].question);
2355
+ if (questionValueType === "enum" || questionValueType === "date") {
2356
+ const seriesValueIndex = seriesValueIndexes[this.questionsY[j].name + "_" + dataRow[this.questionsY[j].name]];
2357
+ statistics[seriesValueIndex][valueIndex]++;
2358
+ }
2359
+ else {
2360
+ const seriesValueIndex = seriesValueIndexes[this.questionsY[j].name];
2361
+ statistics[seriesValueIndex][valueIndex] += parseFloat(dataRow[this.questionsY[j].name]);
2362
+ }
2363
+ }
2364
+ }
2365
+ }
2366
+ getCalculatedValuesCore() {
2367
+ const statistics = [];
2368
+ const series = this.getSeriesValues();
2369
+ if (series.length === 0) {
2370
+ series.push("");
2371
+ }
2372
+ const seriesValueIndexes = this.getSeriesValueIndexes();
2373
+ if (this.valueType === "enum") {
2374
+ const values = this.getValues();
2375
+ const valueIndexes = {};
2376
+ values.forEach((value, index) => {
2377
+ valueIndexes[value] = index;
2378
+ });
2379
+ for (var i = 0; i < series.length; ++i) {
2380
+ statistics.push(values.map(i => 0));
2381
+ }
2382
+ this.data.forEach(dataRow => {
2383
+ const answerData = dataRow[this.name];
2384
+ if (answerData !== undefined && valueIndexes[answerData] !== undefined) {
2385
+ const valueIndex = valueIndexes[answerData];
2386
+ if (this.questionsY.length === 0) {
2387
+ statistics[0][valueIndex]++;
2388
+ }
2389
+ else {
2390
+ this.updateStatisticsSeriesValue(statistics, dataRow, valueIndex, seriesValueIndexes);
2391
+ }
2392
+ }
2393
+ });
2394
+ }
2395
+ else {
2396
+ this.getContiniousValues();
2397
+ const intervals = this.intervals;
2398
+ for (var i = 0; i < series.length; ++i) {
2399
+ statistics.push(intervals.map(i => 0));
2400
+ }
2401
+ this._continiousData.forEach(dataValue => {
2402
+ for (let valueIndex = 0; valueIndex < intervals.length; ++valueIndex) {
2403
+ if (intervals[valueIndex].start <= dataValue.continious && (dataValue.continious < intervals[valueIndex].end || valueIndex == intervals.length - 1)) {
2404
+ if (this.questionsY.length === 0) {
2405
+ statistics[0][valueIndex]++;
2406
+ }
2407
+ else {
2408
+ this.updateStatisticsSeriesValue(statistics, dataValue.row, valueIndex, seriesValueIndexes);
2409
+ }
2410
+ break;
2411
+ }
2412
+ }
2413
+ });
2414
+ }
2415
+ return statistics;
2416
+ }
2417
+ }
2418
+ PivotModel.IntervalsCount = 10;
2419
+ PivotModel.UseIntervalsFrom = 10;
2420
+
2057
2421
  class AlternativeVisualizersWrapper extends VisualizerBase {
2058
2422
  updateVisualizerSelector() {
2059
2423
  if (!!this.visualizerSelector) {
@@ -2188,6 +2552,12 @@ class AlternativeVisualizersWrapper extends VisualizerBase {
2188
2552
  this.visualizer.setState(state.state);
2189
2553
  }
2190
2554
  }
2555
+ getValues() {
2556
+ return this.visualizer.getValues();
2557
+ }
2558
+ getLabels() {
2559
+ return this.visualizer.getLabels();
2560
+ }
2191
2561
  getCalculatedValues() {
2192
2562
  return this.visualizer.getCalculatedValues();
2193
2563
  }
@@ -9443,7 +9813,15 @@ class VisualizationPanel extends VisualizerBase {
9443
9813
  }
9444
9814
  buildVisualizers(questions) {
9445
9815
  questions.forEach((question) => {
9446
- const visualizer = this.createVisualizer(question);
9816
+ let visualizerOptions = Object.assign({}, this.options);
9817
+ let visualizerData = this.surveyData;
9818
+ let visualizer;
9819
+ if (Array.isArray(question)) {
9820
+ visualizer = new (VisualizationManager.getPivotVisualizerConstructor())(question, visualizerData, visualizerOptions);
9821
+ }
9822
+ else {
9823
+ visualizer = this.createVisualizer(question, visualizerOptions, visualizerData);
9824
+ }
9447
9825
  if (!visualizer) {
9448
9826
  return;
9449
9827
  }
@@ -9510,6 +9888,7 @@ class VisualizationPanel extends VisualizerBase {
9510
9888
  setLocale(newLocale) {
9511
9889
  super.setLocale(newLocale);
9512
9890
  (this.questions || []).forEach((question) => {
9891
+ question = Array.isArray(question) ? question[0] : question;
9513
9892
  const element = this.getElement(question.name);
9514
9893
  if (!!element) {
9515
9894
  element.displayName = this.processText(question.title);
@@ -9556,6 +9935,7 @@ class VisualizationPanel extends VisualizerBase {
9556
9935
  }
9557
9936
  buildElements(questions) {
9558
9937
  return (questions || []).map((question) => {
9938
+ question = Array.isArray(question) ? question[0] : question;
9559
9939
  return {
9560
9940
  name: question.name,
9561
9941
  displayName: this.processText(question.title),
@@ -9756,7 +10136,7 @@ class VisualizationPanel extends VisualizerBase {
9756
10136
  this._settingState = true;
9757
10137
  try {
9758
10138
  if (Array.isArray(newState.elements)) {
9759
- const questionNames = this.questions.map(q => q.name);
10139
+ const questionNames = this.questions.map(q => Array.isArray(q) ? q[0].name : q.name);
9760
10140
  this._elements = [].concat(newState.elements.filter(e => (questionNames.indexOf(e.name) !== -1)));
9761
10141
  }
9762
10142
  if (typeof newState.locale !== "undefined")
@@ -9890,6 +10270,7 @@ class VisualizationMatrixDropdown extends VisualizerBase {
9890
10270
  this._childOptions.disableLocaleSwitch = true;
9891
10271
  this._childOptions.dataProvider = undefined;
9892
10272
  this._childOptions.allowDynamicLayout = false;
10273
+ this._childOptions.transposeData = true;
9893
10274
  this._childOptions.seriesValues = question.rows.map((row) => row.value);
9894
10275
  this._childOptions.seriesLabels = question.rows.map((row) => row.text);
9895
10276
  const innerQuestions = this.getQuestions();
@@ -11941,5 +12322,5 @@ NpsVisualizer.DetractorScore = 6;
11941
12322
  NpsVisualizer.PromoterScore = 9;
11942
12323
  // VisualizationManager.registerVisualizer("rating", NpsVisualizer);
11943
12324
 
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 };
12325
+ 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, PivotModel as p, textHelper as t };
11945
12326
  //# sourceMappingURL=shared2.mjs.map