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.
- package/fesm/shared.mjs +10 -2
- package/fesm/shared.mjs.map +1 -1
- package/fesm/shared2.mjs +412 -31
- package/fesm/shared2.mjs.map +1 -1
- package/fesm/survey.analytics.core.mjs +2 -2
- package/fesm/survey.analytics.mjs +158 -150
- 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/entries/summary.core.d.ts +1 -0
- 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 +62 -0
- package/survey-analytics.types/plotly/histogram.d.ts +0 -1
- package/survey-analytics.types/plotly/index.d.ts +1 -0
- package/survey-analytics.types/plotly/pivot.d.ts +12 -0
- package/survey-analytics.types/plotly/selectBase.d.ts +0 -1
- package/survey-analytics.types/selectBase.d.ts +1 -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 +2 -1
- package/survey.analytics.core.css +7 -1
- package/survey.analytics.core.css.map +1 -1
- package/survey.analytics.core.js +487 -34
- 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 +682 -180
- 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/fesm/shared2.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* surveyjs - SurveyJS Dashboard library v2.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
|
|
1060
|
-
for (var
|
|
1061
|
-
if (answersData.datasets[
|
|
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
|
|
1079
|
-
if (
|
|
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
|
|
1083
|
-
if (
|
|
1084
|
-
dataset.push(answersData.datasets[
|
|
1085
|
-
texts.push(answersData.texts[
|
|
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
|
-
|
|
1123
|
-
|
|
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
|
|
1585
|
+
for (let j = 0; j < series.length; j++) {
|
|
1566
1586
|
const seriesData = [];
|
|
1567
|
-
for (let
|
|
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
|
-
|
|
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
|