survey-analytics 2.3.0 → 2.3.2
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 +1506 -263
- package/fesm/shared.mjs.map +1 -1
- package/fesm/shared2.mjs +129 -62
- package/fesm/shared2.mjs.map +1 -1
- package/fesm/survey.analytics.core.mjs +2 -2
- package/fesm/survey.analytics.mjs +3 -3
- package/fesm/survey.analytics.tabulator.mjs +49 -6
- package/fesm/survey.analytics.tabulator.mjs.map +1 -1
- package/package.json +3 -3
- package/survey-analytics-tabulator.types/analytics-localization/arabic.d.ts +16 -0
- package/survey-analytics-tabulator.types/analytics-localization/dutch.d.ts +16 -0
- package/survey-analytics-tabulator.types/analytics-localization/english.d.ts +5 -0
- package/survey-analytics-tabulator.types/analytics-localization/farsi.d.ts +16 -0
- package/survey-analytics-tabulator.types/analytics-localization/finnish.d.ts +7 -0
- package/survey-analytics-tabulator.types/analytics-localization/french.d.ts +16 -0
- package/survey-analytics-tabulator.types/analytics-localization/german.d.ts +16 -0
- package/survey-analytics-tabulator.types/analytics-localization/italian.d.ts +16 -0
- package/survey-analytics-tabulator.types/analytics-localization/japanese.d.ts +16 -0
- package/survey-analytics-tabulator.types/analytics-localization/norwegian.d.ts +16 -0
- package/survey-analytics-tabulator.types/analytics-localization/polish.d.ts +15 -0
- package/survey-analytics-tabulator.types/analytics-localization/portuguese.d.ts +16 -0
- package/survey-analytics-tabulator.types/analytics-localization/russian.d.ts +15 -0
- package/survey-analytics-tabulator.types/analytics-localization/spanish.d.ts +16 -0
- package/survey-analytics-tabulator.types/analytics-localization/swedish.d.ts +82 -0
- package/survey-analytics-tabulator.types/entries/tabulator.d.ts +1 -0
- package/survey-analytics-tabulator.types/localizationManager.d.ts +12 -0
- package/survey-analytics-tabulator.types/tables/columnbuilder.d.ts +7 -1
- package/survey-analytics-tabulator.types/tables/columns.d.ts +10 -1
- package/survey-analytics-tabulator.types/utils/index.d.ts +2 -2
- package/survey-analytics.types/analytics-localization/arabic.d.ts +16 -0
- package/survey-analytics.types/analytics-localization/dutch.d.ts +16 -0
- package/survey-analytics.types/analytics-localization/english.d.ts +5 -0
- package/survey-analytics.types/analytics-localization/farsi.d.ts +16 -0
- package/survey-analytics.types/analytics-localization/finnish.d.ts +7 -0
- package/survey-analytics.types/analytics-localization/french.d.ts +16 -0
- package/survey-analytics.types/analytics-localization/german.d.ts +16 -0
- package/survey-analytics.types/analytics-localization/italian.d.ts +16 -0
- package/survey-analytics.types/analytics-localization/japanese.d.ts +16 -0
- package/survey-analytics.types/analytics-localization/norwegian.d.ts +16 -0
- package/survey-analytics.types/analytics-localization/polish.d.ts +15 -0
- package/survey-analytics.types/analytics-localization/portuguese.d.ts +16 -0
- package/survey-analytics.types/analytics-localization/russian.d.ts +15 -0
- package/survey-analytics.types/analytics-localization/spanish.d.ts +16 -0
- package/survey-analytics.types/analytics-localization/swedish.d.ts +82 -0
- package/survey-analytics.types/entries/summary.core.d.ts +1 -0
- package/survey-analytics.types/histogram.d.ts +4 -4
- package/survey-analytics.types/localizationManager.d.ts +12 -0
- package/survey-analytics.types/pivot.d.ts +7 -4
- package/survey-analytics.types/utils/index.d.ts +2 -2
- package/survey-analytics.types/visualizerBase.d.ts +11 -4
- package/survey.analytics.core.css +53 -22
- package/survey.analytics.core.css.map +1 -1
- package/survey.analytics.core.js +1712 -375
- 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 +53 -22
- package/survey.analytics.css.map +1 -1
- package/survey.analytics.js +1713 -375
- 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 +53 -21
- package/survey.analytics.tabulator.css.map +1 -1
- package/survey.analytics.tabulator.js +1645 -284
- package/survey.analytics.tabulator.js.map +1 -1
- package/survey.analytics.tabulator.min.css +2 -2
- package/survey.analytics.tabulator.min.js +1 -1
- package/survey.analytics.tabulator.min.js.LICENSE.txt +1 -1
package/fesm/shared2.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* surveyjs - SurveyJS Dashboard library v2.3.
|
|
2
|
+
* surveyjs - SurveyJS Dashboard library v2.3.2
|
|
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 { D as DocumentHelper, l as localization,
|
|
7
|
+
import { D as DocumentHelper, l as localization, g as createLoadingIndicator, b as DataHelper, f as svgTemplate, e as createCommercialLicenseLink, t as toPrecision } from './shared.mjs';
|
|
8
8
|
import { Event, QuestionCommentModel, settings, ItemValue, hasLicense, surveyLocalization, IsTouch } from 'survey-core';
|
|
9
9
|
|
|
10
10
|
/******************************************************************************
|
|
@@ -317,17 +317,24 @@ function defaultStatisticsCalculator(data, dataInfo) {
|
|
|
317
317
|
}
|
|
318
318
|
statistics.push(dataNameStatistics);
|
|
319
319
|
}
|
|
320
|
+
const getValueIndex = (val) => {
|
|
321
|
+
if (val !== null && typeof val === "object")
|
|
322
|
+
return valuesIndex[val.value];
|
|
323
|
+
return valuesIndex[val];
|
|
324
|
+
};
|
|
320
325
|
data.forEach((row) => {
|
|
321
326
|
dataNames.forEach((dataName, index) => {
|
|
322
327
|
const rowValue = row[dataName];
|
|
323
328
|
if (rowValue !== undefined || processMissingAnswers) {
|
|
324
329
|
const rowValues = Array.isArray(rowValue) ? rowValue : [rowValue];
|
|
325
330
|
if (series.length > 0) {
|
|
326
|
-
|
|
331
|
+
const rowName = row[DataProvider.seriesMarkerKey];
|
|
332
|
+
if (rowName !== undefined) {
|
|
327
333
|
// Series are labelled by seriesMarkerKey in row data
|
|
328
|
-
const seriesNo = seriesIndex[
|
|
334
|
+
const seriesNo = seriesIndex[rowName] || 0;
|
|
329
335
|
rowValues.forEach((val) => {
|
|
330
|
-
|
|
336
|
+
const valIndex = getValueIndex(val);
|
|
337
|
+
statistics[index][seriesNo][valIndex]++;
|
|
331
338
|
});
|
|
332
339
|
}
|
|
333
340
|
else {
|
|
@@ -337,7 +344,11 @@ function defaultStatisticsCalculator(data, dataInfo) {
|
|
|
337
344
|
series.forEach((seriesName) => {
|
|
338
345
|
if (val[seriesName] !== undefined) {
|
|
339
346
|
const seriesNo = seriesIndex[seriesName] || 0;
|
|
340
|
-
|
|
347
|
+
const values = Array.isArray(val[seriesName]) ? val[seriesName] : [val[seriesName]];
|
|
348
|
+
values.forEach(value => {
|
|
349
|
+
const valIndex = getValueIndex(value);
|
|
350
|
+
statistics[index][seriesNo][valIndex]++;
|
|
351
|
+
});
|
|
341
352
|
}
|
|
342
353
|
});
|
|
343
354
|
});
|
|
@@ -345,7 +356,10 @@ function defaultStatisticsCalculator(data, dataInfo) {
|
|
|
345
356
|
}
|
|
346
357
|
else {
|
|
347
358
|
// No series
|
|
348
|
-
rowValues.forEach((val) =>
|
|
359
|
+
rowValues.forEach((val) => {
|
|
360
|
+
const valIndex = getValueIndex(val);
|
|
361
|
+
statistics[0][0][valIndex]++;
|
|
362
|
+
});
|
|
349
363
|
}
|
|
350
364
|
}
|
|
351
365
|
});
|
|
@@ -439,6 +453,9 @@ class VisualizerBase {
|
|
|
439
453
|
}
|
|
440
454
|
this.onStateChanged.fire(this, this.getState());
|
|
441
455
|
}
|
|
456
|
+
getToolbarItemCreators() {
|
|
457
|
+
return Object.assign({}, this.toolbarItemCreators, this.onGetToolbarItemCreators && this.onGetToolbarItemCreators() || {});
|
|
458
|
+
}
|
|
442
459
|
constructor(question, data, options = {}, _type) {
|
|
443
460
|
var _a;
|
|
444
461
|
this.question = question;
|
|
@@ -645,8 +662,8 @@ class VisualizerBase {
|
|
|
645
662
|
* @param creator A function that accepts the toolbar and should return an `HTMLElement` with the toolbar item.
|
|
646
663
|
* @see unregisterToolbarItem
|
|
647
664
|
*/
|
|
648
|
-
registerToolbarItem(name, creator) {
|
|
649
|
-
this.toolbarItemCreators[name] = creator;
|
|
665
|
+
registerToolbarItem(name, creator, order = 100) {
|
|
666
|
+
this.toolbarItemCreators[name] = { creator, order };
|
|
650
667
|
}
|
|
651
668
|
/**
|
|
652
669
|
*
|
|
@@ -657,9 +674,9 @@ class VisualizerBase {
|
|
|
657
674
|
*/
|
|
658
675
|
unregisterToolbarItem(name) {
|
|
659
676
|
if (this.toolbarItemCreators[name] !== undefined) {
|
|
660
|
-
const
|
|
677
|
+
const item = this.toolbarItemCreators[name];
|
|
661
678
|
delete this.toolbarItemCreators[name];
|
|
662
|
-
return creator;
|
|
679
|
+
return item.creator;
|
|
663
680
|
}
|
|
664
681
|
return undefined;
|
|
665
682
|
}
|
|
@@ -741,8 +758,12 @@ class VisualizerBase {
|
|
|
741
758
|
}
|
|
742
759
|
}
|
|
743
760
|
createToolbarItems(toolbar) {
|
|
744
|
-
|
|
745
|
-
|
|
761
|
+
const toolbarItemCreators = this.getToolbarItemCreators();
|
|
762
|
+
const sortedItems = Object.keys(toolbarItemCreators || {})
|
|
763
|
+
.map(name => (Object.assign({ name }, toolbarItemCreators[name])))
|
|
764
|
+
.sort((a, b) => a.order - b.order);
|
|
765
|
+
sortedItems.forEach((item) => {
|
|
766
|
+
let toolbarItem = item.creator(toolbar);
|
|
746
767
|
if (!!toolbarItem) {
|
|
747
768
|
toolbar.appendChild(toolbarItem);
|
|
748
769
|
}
|
|
@@ -1377,7 +1398,7 @@ class SelectBase extends VisualizerBase {
|
|
|
1377
1398
|
this.updateEmptyAnswersBtn();
|
|
1378
1399
|
}
|
|
1379
1400
|
return this.emptyAnswersBtn;
|
|
1380
|
-
});
|
|
1401
|
+
}, 1000);
|
|
1381
1402
|
this.registerToolbarItem("topNAnswers", () => {
|
|
1382
1403
|
if (this.options.allowTopNAnswers &&
|
|
1383
1404
|
this.getSeriesValues().length === 0) {
|
|
@@ -1894,7 +1915,7 @@ class HistogramModel extends SelectBase {
|
|
|
1894
1915
|
super(question, data, options, name || "histogram");
|
|
1895
1916
|
this.valueType = "number";
|
|
1896
1917
|
this._cachedValues = undefined;
|
|
1897
|
-
this.
|
|
1918
|
+
this._continuousData = undefined;
|
|
1898
1919
|
this._cachedIntervals = undefined;
|
|
1899
1920
|
this._intervalPrecision = 2;
|
|
1900
1921
|
this._transposeData = false;
|
|
@@ -1910,11 +1931,11 @@ class HistogramModel extends SelectBase {
|
|
|
1910
1931
|
}
|
|
1911
1932
|
}
|
|
1912
1933
|
reset() {
|
|
1913
|
-
this.
|
|
1934
|
+
this._continuousData = undefined;
|
|
1914
1935
|
this._cachedValues = undefined;
|
|
1915
1936
|
this._cachedIntervals = undefined;
|
|
1916
1937
|
}
|
|
1917
|
-
|
|
1938
|
+
getContinuousValue(value) {
|
|
1918
1939
|
if (this.valueType === "date") {
|
|
1919
1940
|
return Date.parse(value);
|
|
1920
1941
|
}
|
|
@@ -1931,7 +1952,7 @@ class HistogramModel extends SelectBase {
|
|
|
1931
1952
|
return Math.round(base * value) / base;
|
|
1932
1953
|
}
|
|
1933
1954
|
getSelectedItemByText(itemText) {
|
|
1934
|
-
if (this.hasCustomIntervals || this.
|
|
1955
|
+
if (this.hasCustomIntervals || this.getContinuousValues().length > HistogramModel.UseIntervalsFrom) {
|
|
1935
1956
|
const interval = this.intervals.filter(interval => interval.label === itemText)[0];
|
|
1936
1957
|
return new ItemValue(interval, interval !== undefined ? interval.label : "");
|
|
1937
1958
|
}
|
|
@@ -1950,26 +1971,26 @@ class HistogramModel extends SelectBase {
|
|
|
1950
1971
|
this.reset();
|
|
1951
1972
|
super.onDataChanged();
|
|
1952
1973
|
}
|
|
1953
|
-
|
|
1974
|
+
getContinuousValues() {
|
|
1954
1975
|
if (this._cachedValues === undefined) {
|
|
1955
1976
|
const series = this.getSeriesValues();
|
|
1956
1977
|
if (series.length === 0) {
|
|
1957
1978
|
series.push("");
|
|
1958
1979
|
}
|
|
1959
|
-
this.
|
|
1960
|
-
series.forEach(seriesValue => this.
|
|
1980
|
+
this._continuousData = {};
|
|
1981
|
+
series.forEach(seriesValue => this._continuousData[seriesValue] = []);
|
|
1961
1982
|
const hash = {};
|
|
1962
1983
|
this.data.forEach(dataItem => {
|
|
1963
1984
|
const answerData = dataItem[this.name];
|
|
1964
1985
|
if (answerData !== undefined) {
|
|
1965
1986
|
const seriesValue = dataItem[DataProvider.seriesMarkerKey] || "";
|
|
1966
|
-
// TODO:
|
|
1967
|
-
this.
|
|
1987
|
+
// TODO: _continuousData should be sorted in order to speed-up statistics calculation in the getData function
|
|
1988
|
+
this._continuousData[seriesValue].push(this.getContinuousValue(answerData));
|
|
1968
1989
|
hash[answerData] = answerData;
|
|
1969
1990
|
}
|
|
1970
1991
|
});
|
|
1971
|
-
this._cachedValues = Object.keys(hash).map(key => ({ original: hash[key],
|
|
1972
|
-
this._cachedValues.sort((a, b) => a.
|
|
1992
|
+
this._cachedValues = Object.keys(hash).map(key => ({ original: hash[key], continuous: this.getContinuousValue(key) }));
|
|
1993
|
+
this._cachedValues.sort((a, b) => a.continuous - b.continuous);
|
|
1973
1994
|
}
|
|
1974
1995
|
return this._cachedValues;
|
|
1975
1996
|
}
|
|
@@ -2015,11 +2036,11 @@ class HistogramModel extends SelectBase {
|
|
|
2015
2036
|
}
|
|
2016
2037
|
}
|
|
2017
2038
|
if (this._cachedIntervals === undefined) {
|
|
2018
|
-
const
|
|
2039
|
+
const continuousValues = this.getContinuousValues();
|
|
2019
2040
|
this._cachedIntervals = [];
|
|
2020
|
-
if (
|
|
2021
|
-
let start =
|
|
2022
|
-
const end =
|
|
2041
|
+
if (continuousValues.length) {
|
|
2042
|
+
let start = continuousValues[0].continuous;
|
|
2043
|
+
const end = continuousValues[continuousValues.length - 1].continuous;
|
|
2023
2044
|
const intervalsCount = HistogramModel.IntervalsCount;
|
|
2024
2045
|
const delta = (end - start) / intervalsCount;
|
|
2025
2046
|
for (let i = 0; i < intervalsCount; ++i) {
|
|
@@ -2041,8 +2062,8 @@ class HistogramModel extends SelectBase {
|
|
|
2041
2062
|
return [externalCalculatedData];
|
|
2042
2063
|
}
|
|
2043
2064
|
getCalculatedValuesCore() {
|
|
2044
|
-
this.
|
|
2045
|
-
return histogramStatisticsCalculator(this.
|
|
2065
|
+
this.getContinuousValues();
|
|
2066
|
+
return histogramStatisticsCalculator(this._continuousData, this.intervals, this.getSeriesValues());
|
|
2046
2067
|
}
|
|
2047
2068
|
getValueType() {
|
|
2048
2069
|
return this.valueType;
|
|
@@ -2142,7 +2163,7 @@ class PivotModel extends SelectBase {
|
|
|
2142
2163
|
this.questions = questions;
|
|
2143
2164
|
this.valueType = "enum";
|
|
2144
2165
|
this._cachedValues = undefined;
|
|
2145
|
-
this.
|
|
2166
|
+
this._continuousData = undefined;
|
|
2146
2167
|
this._cachedIntervals = undefined;
|
|
2147
2168
|
this._intervalPrecision = 2;
|
|
2148
2169
|
this.axisYSelectors = [];
|
|
@@ -2158,7 +2179,12 @@ class PivotModel extends SelectBase {
|
|
|
2158
2179
|
value: question.name,
|
|
2159
2180
|
text: question.title || question.name,
|
|
2160
2181
|
};
|
|
2161
|
-
}), (option) => this.axisXQuestionName === option.value, (e) => {
|
|
2182
|
+
}), (option) => this.axisXQuestionName === option.value, (e) => {
|
|
2183
|
+
this.axisXQuestionName = e.target.value;
|
|
2184
|
+
this.updateQuestionsSelection();
|
|
2185
|
+
this.updateToolbar();
|
|
2186
|
+
this.setupPivot();
|
|
2187
|
+
}, () => this.isXYChart() ? localization.getString("axisXSelectorTitle") : localization.getString("axisXAlternativeSelectorTitle")));
|
|
2162
2188
|
this.registerToolbarItem("axisYSelector0", this.createYSelecterGenerator());
|
|
2163
2189
|
this.setupPivot();
|
|
2164
2190
|
}
|
|
@@ -2170,6 +2196,9 @@ class PivotModel extends SelectBase {
|
|
|
2170
2196
|
selector = this.createAxisYSelector(selectorIndex);
|
|
2171
2197
|
this.axisYSelectors.push(selector);
|
|
2172
2198
|
}
|
|
2199
|
+
else {
|
|
2200
|
+
selector["__updateSelect"] && selector["__updateSelect"]();
|
|
2201
|
+
}
|
|
2173
2202
|
return selector;
|
|
2174
2203
|
};
|
|
2175
2204
|
}
|
|
@@ -2190,26 +2219,62 @@ class PivotModel extends SelectBase {
|
|
|
2190
2219
|
}
|
|
2191
2220
|
this.axisYSelectors = this.axisYSelectors.slice(0, index + 1);
|
|
2192
2221
|
this.axisYQuestionNames = this.axisYQuestionNames.slice(0, index + 1);
|
|
2193
|
-
this.updateToolbar();
|
|
2194
2222
|
}
|
|
2195
2223
|
}
|
|
2196
2224
|
else {
|
|
2197
2225
|
if (!!value) {
|
|
2198
2226
|
this.registerToolbarItem("axisYSelector" + this.axisYSelectors.length, this.createYSelecterGenerator());
|
|
2199
|
-
this.updateToolbar();
|
|
2200
2227
|
}
|
|
2201
2228
|
}
|
|
2229
|
+
this.updateQuestionsSelection();
|
|
2230
|
+
this.updateToolbar();
|
|
2202
2231
|
this.setupPivot();
|
|
2203
2232
|
}
|
|
2233
|
+
updateQuestionsSelection() {
|
|
2234
|
+
const selectedQuestions = [this.axisXQuestionName];
|
|
2235
|
+
for (let i = 0; i < this.axisYQuestionNames.length; ++i) {
|
|
2236
|
+
const questionName = this.axisYQuestionNames[i];
|
|
2237
|
+
if (selectedQuestions.indexOf(questionName) !== -1) {
|
|
2238
|
+
this.onAxisYSelectorChanged(i, undefined);
|
|
2239
|
+
break;
|
|
2240
|
+
}
|
|
2241
|
+
else {
|
|
2242
|
+
selectedQuestions.push(questionName);
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
}
|
|
2204
2246
|
createAxisYSelector(selectorIndex) {
|
|
2205
|
-
const
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2247
|
+
const getChoices = () => {
|
|
2248
|
+
const choices = this.questions.filter(q => {
|
|
2249
|
+
if (q.name === this.axisXQuestionName) {
|
|
2250
|
+
return false;
|
|
2251
|
+
}
|
|
2252
|
+
const usedIndex = this.axisYQuestionNames.indexOf(q.name);
|
|
2253
|
+
return usedIndex == -1 || usedIndex >= selectorIndex;
|
|
2254
|
+
}).map((question) => {
|
|
2255
|
+
return {
|
|
2256
|
+
value: question.name,
|
|
2257
|
+
text: question.title || question.name,
|
|
2258
|
+
};
|
|
2259
|
+
});
|
|
2260
|
+
return [{ value: "", text: localization.getString("notSelected") }].concat(choices);
|
|
2261
|
+
};
|
|
2262
|
+
if (getChoices().length == 1) {
|
|
2263
|
+
return undefined;
|
|
2264
|
+
}
|
|
2265
|
+
const selector = DocumentHelper.createSelector(getChoices, (option) => this.axisYQuestionNames[selectorIndex] === option.value, (e) => { this.onAxisYSelectorChanged(selectorIndex, e.target.value); }, () => selectorIndex ? undefined : (this.isXYChart() ? localization.getString("axisYSelectorTitle") : localization.getString("axisYAlternativeSelectorTitle")));
|
|
2211
2266
|
return selector;
|
|
2212
2267
|
}
|
|
2268
|
+
setChartType(chartType) {
|
|
2269
|
+
const prev2Dchart = this.isXYChart();
|
|
2270
|
+
super.setChartType(chartType);
|
|
2271
|
+
if (prev2Dchart !== this.isXYChart()) {
|
|
2272
|
+
this.updateToolbar();
|
|
2273
|
+
}
|
|
2274
|
+
}
|
|
2275
|
+
isXYChart() {
|
|
2276
|
+
return ["pie", "doughnut"].indexOf(this.chartType) === -1;
|
|
2277
|
+
}
|
|
2213
2278
|
getQuestionValueType(question) {
|
|
2214
2279
|
const questionType = question.getType();
|
|
2215
2280
|
if (questionType === "text" && (question["inputType"] === "date" || question["inputType"] === "datetime")) {
|
|
@@ -2236,11 +2301,11 @@ class PivotModel extends SelectBase {
|
|
|
2236
2301
|
this.onDataChanged();
|
|
2237
2302
|
}
|
|
2238
2303
|
reset() {
|
|
2239
|
-
this.
|
|
2304
|
+
this._continuousData = undefined;
|
|
2240
2305
|
this._cachedValues = undefined;
|
|
2241
2306
|
this._cachedIntervals = undefined;
|
|
2242
2307
|
}
|
|
2243
|
-
|
|
2308
|
+
getContinuousValue(value) {
|
|
2244
2309
|
if (this.valueType === "date") {
|
|
2245
2310
|
return Date.parse(value);
|
|
2246
2311
|
}
|
|
@@ -2257,7 +2322,7 @@ class PivotModel extends SelectBase {
|
|
|
2257
2322
|
return Math.round(base * value) / base;
|
|
2258
2323
|
}
|
|
2259
2324
|
getSelectedItemByText(itemText) {
|
|
2260
|
-
if (this.hasCustomIntervals || this.
|
|
2325
|
+
if (this.hasCustomIntervals || this.getContinuousValues().length > PivotModel.UseIntervalsFrom) {
|
|
2261
2326
|
const interval = this.intervals.filter(interval => interval.label === itemText)[0];
|
|
2262
2327
|
return new ItemValue(interval, interval !== undefined ? interval.label : "");
|
|
2263
2328
|
}
|
|
@@ -2276,9 +2341,9 @@ class PivotModel extends SelectBase {
|
|
|
2276
2341
|
this.reset();
|
|
2277
2342
|
super.onDataChanged();
|
|
2278
2343
|
}
|
|
2279
|
-
|
|
2344
|
+
getContinuousValues() {
|
|
2280
2345
|
if (this._cachedValues === undefined) {
|
|
2281
|
-
this.
|
|
2346
|
+
this._continuousData = [];
|
|
2282
2347
|
if (this.valueType === "enum") {
|
|
2283
2348
|
this._cachedValues = [];
|
|
2284
2349
|
return this._cachedValues;
|
|
@@ -2287,13 +2352,13 @@ class PivotModel extends SelectBase {
|
|
|
2287
2352
|
this.data.forEach(dataItem => {
|
|
2288
2353
|
const answerData = dataItem[this.name];
|
|
2289
2354
|
if (answerData !== undefined) {
|
|
2290
|
-
// TODO:
|
|
2291
|
-
this.
|
|
2355
|
+
// TODO: _continuousData should be sorted in order to speed-up statistics calculation in the getData function
|
|
2356
|
+
this._continuousData.push({ continuous: this.getContinuousValue(answerData), row: dataItem });
|
|
2292
2357
|
hash[answerData] = { value: answerData, row: dataItem };
|
|
2293
2358
|
}
|
|
2294
2359
|
});
|
|
2295
|
-
this._cachedValues = Object.keys(hash).map(key => ({ original: hash[key].value,
|
|
2296
|
-
this._cachedValues.sort((a, b) => a.
|
|
2360
|
+
this._cachedValues = Object.keys(hash).map(key => ({ original: hash[key].value, continuous: this.getContinuousValue(key), row: hash[key].row }));
|
|
2361
|
+
this._cachedValues.sort((a, b) => a.continuous - b.continuous);
|
|
2297
2362
|
}
|
|
2298
2363
|
return this._cachedValues;
|
|
2299
2364
|
}
|
|
@@ -2378,11 +2443,11 @@ class PivotModel extends SelectBase {
|
|
|
2378
2443
|
}
|
|
2379
2444
|
}
|
|
2380
2445
|
if (this._cachedIntervals === undefined) {
|
|
2381
|
-
const
|
|
2446
|
+
const continuousValues = this.getContinuousValues();
|
|
2382
2447
|
this._cachedIntervals = [];
|
|
2383
|
-
if (
|
|
2384
|
-
let start =
|
|
2385
|
-
const end =
|
|
2448
|
+
if (continuousValues.length) {
|
|
2449
|
+
let start = continuousValues[0].continuous;
|
|
2450
|
+
const end = continuousValues[continuousValues.length - 1].continuous;
|
|
2386
2451
|
const intervalsCount = PivotModel.IntervalsCount;
|
|
2387
2452
|
const delta = (end - start) / intervalsCount;
|
|
2388
2453
|
for (let i = 0; i < intervalsCount; ++i) {
|
|
@@ -2464,14 +2529,14 @@ class PivotModel extends SelectBase {
|
|
|
2464
2529
|
});
|
|
2465
2530
|
}
|
|
2466
2531
|
else {
|
|
2467
|
-
this.
|
|
2532
|
+
this.getContinuousValues();
|
|
2468
2533
|
const intervals = this.intervals;
|
|
2469
2534
|
for (var i = 0; i < series.length; ++i) {
|
|
2470
2535
|
statistics.push(intervals.map(i => 0));
|
|
2471
2536
|
}
|
|
2472
|
-
this.
|
|
2537
|
+
this._continuousData.forEach(dataValue => {
|
|
2473
2538
|
for (let valueIndex = 0; valueIndex < intervals.length; ++valueIndex) {
|
|
2474
|
-
if (intervals[valueIndex].start <= dataValue.
|
|
2539
|
+
if (intervals[valueIndex].start <= dataValue.continuous && (dataValue.continuous < intervals[valueIndex].end || valueIndex == intervals.length - 1)) {
|
|
2475
2540
|
if (this.questionsY.length === 0) {
|
|
2476
2541
|
statistics[0][valueIndex]++;
|
|
2477
2542
|
}
|
|
@@ -2552,12 +2617,14 @@ class AlternativeVisualizersWrapper extends VisualizerBase {
|
|
|
2552
2617
|
* The event is fired right after AlternativeVisualizersWrapper content type has been changed.
|
|
2553
2618
|
**/
|
|
2554
2619
|
this.onVisualizerChanged = new Event();
|
|
2620
|
+
this.showToolbar = false;
|
|
2555
2621
|
this.loadingData = false;
|
|
2556
2622
|
if (!visualizers || visualizers.length < 2) {
|
|
2557
2623
|
throw new Error("VisualizerArrayWrapper works with visualizers collection only.");
|
|
2558
2624
|
}
|
|
2559
2625
|
this.visualizers.forEach((visualizer) => {
|
|
2560
2626
|
visualizer.onUpdate = () => this.invokeOnUpdate();
|
|
2627
|
+
visualizer.onGetToolbarItemCreators = () => this.toolbarItemCreators;
|
|
2561
2628
|
if (visualizer.supportSelection) {
|
|
2562
2629
|
this._supportSelection = true;
|
|
2563
2630
|
this.visualizersWithSelection.push(visualizer);
|
|
@@ -2568,7 +2635,7 @@ class AlternativeVisualizersWrapper extends VisualizerBase {
|
|
|
2568
2635
|
value: visualizer.type,
|
|
2569
2636
|
text: localization.getString("visualizer_" + visualizer.type),
|
|
2570
2637
|
};
|
|
2571
|
-
}), (option) => this.visualizer.type === option.value, (e) => this.setVisualizer(e.target.value)));
|
|
2638
|
+
}), (option) => this.visualizer.type === option.value, (e) => this.setVisualizer(e.target.value)), 0);
|
|
2572
2639
|
this.visualizer = visualizers[0];
|
|
2573
2640
|
this.visualizer.onAfterRender.add(this.onAfterVisualizerRenderCallback);
|
|
2574
2641
|
this.visualizer.onStateChanged.add(this.onVisualizerStateChangedCallback);
|
|
@@ -9771,7 +9838,7 @@ class VisualizationPanel extends VisualizerBase {
|
|
|
9771
9838
|
}
|
|
9772
9839
|
});
|
|
9773
9840
|
}, localization.getString("resetFilter"));
|
|
9774
|
-
});
|
|
9841
|
+
}, 900);
|
|
9775
9842
|
this.registerToolbarItem("addElement", (toolbar) => {
|
|
9776
9843
|
if (this.allowHideQuestions) {
|
|
9777
9844
|
let addElementSelector = undefined;
|
|
@@ -9812,7 +9879,7 @@ class VisualizationPanel extends VisualizerBase {
|
|
|
9812
9879
|
const localeChoices = this.locales.map((element) => {
|
|
9813
9880
|
return {
|
|
9814
9881
|
value: element,
|
|
9815
|
-
text: localization.
|
|
9882
|
+
text: localization.getLocaleName(element)
|
|
9816
9883
|
};
|
|
9817
9884
|
});
|
|
9818
9885
|
// localeChoices.unshift({
|
|
@@ -9944,7 +10011,7 @@ class VisualizationPanel extends VisualizerBase {
|
|
|
9944
10011
|
return DocumentHelper.createButton(() => {
|
|
9945
10012
|
setTimeout(() => this.hideElement(question.name), 0);
|
|
9946
10013
|
}, localization.getString("hideButton"));
|
|
9947
|
-
});
|
|
10014
|
+
}, 1000);
|
|
9948
10015
|
}
|
|
9949
10016
|
if (this.allowMakeQuestionsPrivate) {
|
|
9950
10017
|
visualizer.registerToolbarItem("makePrivatePublic", () => {
|
|
@@ -9969,7 +10036,7 @@ class VisualizationPanel extends VisualizerBase {
|
|
|
9969
10036
|
visualizer.registerToolbarItem("questionFilterInfo", () => {
|
|
9970
10037
|
filterInfo.update(visualizerWithSelection.selection);
|
|
9971
10038
|
return filterInfo.htmlElement;
|
|
9972
|
-
});
|
|
10039
|
+
}, 900);
|
|
9973
10040
|
visualizerWithSelection.onDataItemSelected = (selectedValue, selectedText) => {
|
|
9974
10041
|
filterInfo.update({ value: selectedValue, text: selectedText });
|
|
9975
10042
|
this.setFilter(question.name, selectedValue);
|