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
@@ -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
  */
@@ -7007,6 +7007,12 @@ var AlternativeVisualizersWrapper = /** @class */ (function (_super) {
7007
7007
  this.visualizer.setState(state.state);
7008
7008
  }
7009
7009
  };
7010
+ AlternativeVisualizersWrapper.prototype.getValues = function () {
7011
+ return this.visualizer.getValues();
7012
+ };
7013
+ AlternativeVisualizersWrapper.prototype.getLabels = function () {
7014
+ return this.visualizer.getLabels();
7015
+ };
7010
7016
  AlternativeVisualizersWrapper.prototype.getCalculatedValues = function () {
7011
7017
  return this.visualizer.getCalculatedValues();
7012
7018
  };
@@ -7314,6 +7320,8 @@ var englishStrings = {
7314
7320
  npsPromoters: "Promoters",
7315
7321
  npsPassives: "Passives",
7316
7322
  npsDetractors: "Detractors",
7323
+ axisXSelectorTitle: "X axis:",
7324
+ axisYSelectorTitle: "Y axis:"
7317
7325
  };
7318
7326
  // Uncomment the lines below if you create a custom dictionary.
7319
7327
  // Replace "en" with a custom locale code (for example, "fr" or "de"),
@@ -8661,13 +8669,14 @@ __webpack_require__.r(__webpack_exports__);
8661
8669
  /* harmony export */ AlternativeVisualizersWrapper: () => (/* reexport safe */ _alternativeVizualizersWrapper__WEBPACK_IMPORTED_MODULE_27__.AlternativeVisualizersWrapper),
8662
8670
  /* harmony export */ BooleanModel: () => (/* reexport safe */ _boolean__WEBPACK_IMPORTED_MODULE_19__.BooleanModel),
8663
8671
  /* harmony export */ DataProvider: () => (/* reexport safe */ _dataProvider__WEBPACK_IMPORTED_MODULE_14__.DataProvider),
8664
- /* harmony export */ DocumentHelper: () => (/* reexport safe */ _utils_index__WEBPACK_IMPORTED_MODULE_33__.DocumentHelper),
8672
+ /* harmony export */ DocumentHelper: () => (/* reexport safe */ _utils_index__WEBPACK_IMPORTED_MODULE_34__.DocumentHelper),
8665
8673
  /* harmony export */ HistogramModel: () => (/* reexport safe */ _histogram__WEBPACK_IMPORTED_MODULE_20__.HistogramModel),
8666
8674
  /* harmony export */ Matrix: () => (/* reexport safe */ _matrix__WEBPACK_IMPORTED_MODULE_18__.Matrix),
8667
8675
  /* harmony export */ NpsAdapter: () => (/* reexport safe */ _nps__WEBPACK_IMPORTED_MODULE_32__.NpsAdapter),
8668
8676
  /* harmony export */ NpsVisualizer: () => (/* reexport safe */ _nps__WEBPACK_IMPORTED_MODULE_32__.NpsVisualizer),
8669
8677
  /* harmony export */ NpsVisualizerWidget: () => (/* reexport safe */ _nps__WEBPACK_IMPORTED_MODULE_32__.NpsVisualizerWidget),
8670
8678
  /* harmony export */ NumberModel: () => (/* reexport safe */ _number__WEBPACK_IMPORTED_MODULE_16__.NumberModel),
8679
+ /* harmony export */ PivotModel: () => (/* reexport safe */ _pivot__WEBPACK_IMPORTED_MODULE_33__.PivotModel),
8671
8680
  /* harmony export */ PostponeHelper: () => (/* reexport safe */ _visualizerBase__WEBPACK_IMPORTED_MODULE_21__.PostponeHelper),
8672
8681
  /* harmony export */ SelectBase: () => (/* reexport safe */ _selectBase__WEBPACK_IMPORTED_MODULE_17__.SelectBase),
8673
8682
  /* harmony export */ StatisticsTable: () => (/* reexport safe */ _statistics_table__WEBPACK_IMPORTED_MODULE_31__.StatisticsTable),
@@ -8722,7 +8731,8 @@ __webpack_require__.r(__webpack_exports__);
8722
8731
  /* harmony import */ var _text__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ../text */ "./src/text.ts");
8723
8732
  /* harmony import */ var _statistics_table__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ../statistics-table */ "./src/statistics-table.ts");
8724
8733
  /* harmony import */ var _nps__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ../nps */ "./src/nps.ts");
8725
- /* harmony import */ var _utils_index__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ../utils/index */ "./src/utils/index.ts");
8734
+ /* harmony import */ var _pivot__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ../pivot */ "./src/pivot.ts");
8735
+ /* harmony import */ var _utils_index__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ../utils/index */ "./src/utils/index.ts");
8726
8736
 
8727
8737
  //localization
8728
8738
 
@@ -8758,6 +8768,7 @@ __webpack_require__.r(__webpack_exports__);
8758
8768
 
8759
8769
 
8760
8770
 
8771
+
8761
8772
 
8762
8773
 
8763
8774
  /***/ }),
@@ -8842,6 +8853,7 @@ var HistogramModel = /** @class */ (function (_super) {
8842
8853
  _this._continiousData = undefined;
8843
8854
  _this._cachedIntervals = undefined;
8844
8855
  _this._intervalPrecision = 2;
8856
+ _this._transposeData = false;
8845
8857
  if (_this.options.intervalPrecision !== undefined) {
8846
8858
  _this._intervalPrecision = _this.options.intervalPrecision;
8847
8859
  }
@@ -9389,7 +9401,9 @@ __webpack_require__.r(__webpack_exports__);
9389
9401
  var Matrix = /** @class */ (function (_super) {
9390
9402
  (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__extends)(Matrix, _super);
9391
9403
  function Matrix(question, data, options, name) {
9392
- return _super.call(this, question, data, options, name || "matrix") || this;
9404
+ var _this = _super.call(this, question, data, options, name || "matrix") || this;
9405
+ _this._transposeData = true;
9406
+ return _this;
9393
9407
  // this.getAnswersData();
9394
9408
  }
9395
9409
  Object.defineProperty(Matrix.prototype, "matrixQuestion", {
@@ -9472,17 +9486,6 @@ var Matrix = /** @class */ (function (_super) {
9472
9486
  }
9473
9487
  return result;
9474
9488
  };
9475
- Matrix.prototype.getCalculatedValuesCore = function () {
9476
- var statistics = _super.prototype.getCalculatedValuesCore.call(this);
9477
- var series = this.getSeriesValues();
9478
- var values = this.getValues();
9479
- var preparedData = [];
9480
- values.forEach(function (val, valueIndex) {
9481
- var seriesData = series.map(function (seriesName, seriesIndex) { return statistics[seriesIndex][valueIndex]; });
9482
- preparedData.push(seriesData);
9483
- });
9484
- return preparedData;
9485
- };
9486
9489
  return Matrix;
9487
9490
  }(_selectBase__WEBPACK_IMPORTED_MODULE_2__.SelectBase));
9488
9491
 
@@ -9923,6 +9926,416 @@ var NumberModel = /** @class */ (function (_super) {
9923
9926
 
9924
9927
 
9925
9928
 
9929
+ /***/ }),
9930
+
9931
+ /***/ "./src/pivot.ts":
9932
+ /*!**********************!*\
9933
+ !*** ./src/pivot.ts ***!
9934
+ \**********************/
9935
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
9936
+
9937
+ "use strict";
9938
+ __webpack_require__.r(__webpack_exports__);
9939
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
9940
+ /* harmony export */ PivotModel: () => (/* binding */ PivotModel)
9941
+ /* harmony export */ });
9942
+ /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "./src/utils/helpers.ts");
9943
+ /* harmony import */ var survey_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! survey-core */ "survey-core");
9944
+ /* harmony import */ var survey_core__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(survey_core__WEBPACK_IMPORTED_MODULE_1__);
9945
+ /* harmony import */ var _selectBase__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./selectBase */ "./src/selectBase.ts");
9946
+ /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils */ "./src/utils/index.ts");
9947
+ /* harmony import */ var _visualizerBase__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./visualizerBase */ "./src/visualizerBase.ts");
9948
+ /* harmony import */ var _localizationManager__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./localizationManager */ "./src/localizationManager.ts");
9949
+
9950
+
9951
+
9952
+
9953
+
9954
+
9955
+ var PivotModel = /** @class */ (function (_super) {
9956
+ (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__extends)(PivotModel, _super);
9957
+ function PivotModel(questions, data, options, name) {
9958
+ var _this = _super.call(this, null, data, options, name || "pivot") || this;
9959
+ _this.questions = questions;
9960
+ _this.valueType = "enum";
9961
+ _this._cachedValues = undefined;
9962
+ _this._continiousData = undefined;
9963
+ _this._cachedIntervals = undefined;
9964
+ _this._intervalPrecision = 2;
9965
+ _this.axisYSelectors = [];
9966
+ _this.axisYQuestionNames = [];
9967
+ _this.questionsY = [];
9968
+ _this.questions = _this.questions.filter(function (question) { return ["matrixdropdown", "matrixdynamic", "matrix", "file", "signature", "multipletext", "comment", "html", "image"].indexOf(question.getType()) === -1; });
9969
+ if (_this.options.intervalPrecision !== undefined) {
9970
+ _this._intervalPrecision = _this.options.intervalPrecision;
9971
+ }
9972
+ _this.axisXQuestionName = _this.questions.length > 0 ? _this.questions[0].name : undefined;
9973
+ _this.registerToolbarItem("axisXSelector", function () {
9974
+ return _this.axisXSelector = _utils__WEBPACK_IMPORTED_MODULE_3__.DocumentHelper.createSelector(_this.questions.map(function (question) {
9975
+ return {
9976
+ value: question.name,
9977
+ text: question.title || question.name,
9978
+ };
9979
+ }), function (option) { return _this.axisXQuestionName === option.value; }, function (e) { _this.axisXQuestionName = e.target.value; _this.setupPivot(); }, _localizationManager__WEBPACK_IMPORTED_MODULE_5__.localization.getString("axisXSelectorTitle"));
9980
+ });
9981
+ _this.registerToolbarItem("axisYSelector0", _this.createYSelecterGenerator());
9982
+ _this.setupPivot();
9983
+ return _this;
9984
+ }
9985
+ PivotModel.prototype.createYSelecterGenerator = function () {
9986
+ var _this = this;
9987
+ var selectorIndex = this.axisYSelectors.length;
9988
+ return function () {
9989
+ var selector = _this.axisYSelectors[selectorIndex];
9990
+ if (!selector) {
9991
+ selector = _this.createAxisYSelector(selectorIndex);
9992
+ _this.axisYSelectors.push(selector);
9993
+ }
9994
+ return selector;
9995
+ };
9996
+ };
9997
+ PivotModel.prototype.setAxisQuestions = function () {
9998
+ var axisQuestionNames = [];
9999
+ for (var _i = 0; _i < arguments.length; _i++) {
10000
+ axisQuestionNames[_i] = arguments[_i];
10001
+ }
10002
+ if (axisQuestionNames.length < 1) {
10003
+ return;
10004
+ }
10005
+ this.axisXQuestionName = axisQuestionNames[0];
10006
+ this.axisYQuestionNames = axisQuestionNames.splice(1);
10007
+ this.setupPivot();
10008
+ };
10009
+ PivotModel.prototype.onAxisYSelectorChanged = function (index, value) {
10010
+ this.axisYQuestionNames[index] = value;
10011
+ if (index < this.axisYSelectors.length - 1) {
10012
+ if (!value) {
10013
+ for (var i = index + 1; i < this.axisYSelectors.length; ++i) {
10014
+ this.unregisterToolbarItem("axisYSelector" + i);
10015
+ }
10016
+ this.axisYSelectors = this.axisYSelectors.slice(0, index + 1);
10017
+ this.axisYQuestionNames = this.axisYQuestionNames.slice(0, index + 1);
10018
+ this.updateToolbar();
10019
+ }
10020
+ }
10021
+ else {
10022
+ if (!!value) {
10023
+ this.registerToolbarItem("axisYSelector" + this.axisYSelectors.length, this.createYSelecterGenerator());
10024
+ this.updateToolbar();
10025
+ }
10026
+ }
10027
+ this.setupPivot();
10028
+ };
10029
+ PivotModel.prototype.createAxisYSelector = function (selectorIndex) {
10030
+ var _this = this;
10031
+ var selector = _utils__WEBPACK_IMPORTED_MODULE_3__.DocumentHelper.createSelector([{ value: "", text: "Not selected" }].concat(this.questions.map(function (question) {
10032
+ return {
10033
+ value: question.name,
10034
+ text: question.title || question.name,
10035
+ };
10036
+ })), function (option) { return _this.axisYQuestionNames[selectorIndex] === option.value; }, function (e) { _this.onAxisYSelectorChanged(selectorIndex, e.target.value); }, selectorIndex ? undefined : _localizationManager__WEBPACK_IMPORTED_MODULE_5__.localization.getString("axisYSelectorTitle"));
10037
+ return selector;
10038
+ };
10039
+ PivotModel.prototype.getQuestionValueType = function (question) {
10040
+ var questionType = question.getType();
10041
+ if (questionType === "text" && (question["inputType"] === "date" || question["inputType"] === "datetime")) {
10042
+ return "date";
10043
+ }
10044
+ else if (questionType === "text" || questionType === "rating" || questionType === "expression" || questionType === "range") {
10045
+ return "number";
10046
+ }
10047
+ return "enum";
10048
+ };
10049
+ PivotModel.prototype.setupPivot = function () {
10050
+ var _this = this;
10051
+ var questionX = this.questions.filter(function (q) { return q.name === _this.axisXQuestionName; })[0];
10052
+ if (!questionX) {
10053
+ return;
10054
+ }
10055
+ this.question = questionX;
10056
+ this.valueType = this.getQuestionValueType(questionX);
10057
+ this.questionsY = this.axisYQuestionNames.map(function (name) {
10058
+ var questionY = _this.questions.filter(function (q) { return q.name === name; })[0];
10059
+ if (!!questionY) {
10060
+ return _this.getQuestionValueType(questionY) === "enum" ? new _selectBase__WEBPACK_IMPORTED_MODULE_2__.SelectBase(questionY, []) : new _visualizerBase__WEBPACK_IMPORTED_MODULE_4__.VisualizerBase(questionY, []);
10061
+ }
10062
+ }).filter(function (q) { return !!q; });
10063
+ this.onDataChanged();
10064
+ };
10065
+ PivotModel.prototype.reset = function () {
10066
+ this._continiousData = undefined;
10067
+ this._cachedValues = undefined;
10068
+ this._cachedIntervals = undefined;
10069
+ };
10070
+ PivotModel.prototype.getContiniousValue = function (value) {
10071
+ if (this.valueType === "date") {
10072
+ return Date.parse(value);
10073
+ }
10074
+ return parseFloat(value);
10075
+ };
10076
+ PivotModel.prototype.getString = function (value) {
10077
+ if (this.valueType === "date") {
10078
+ return new Date(value).toLocaleDateString();
10079
+ }
10080
+ return "" + value;
10081
+ };
10082
+ PivotModel.prototype.toPrecision = function (value) {
10083
+ var base = Math.pow(10, this._intervalPrecision);
10084
+ return Math.round(base * value) / base;
10085
+ };
10086
+ PivotModel.prototype.getSelectedItemByText = function (itemText) {
10087
+ if (this.hasCustomIntervals || this.getContiniousValues().length > PivotModel.UseIntervalsFrom) {
10088
+ var interval = this.intervals.filter(function (interval) { return interval.label === itemText; })[0];
10089
+ return new survey_core__WEBPACK_IMPORTED_MODULE_1__.ItemValue(interval, interval !== undefined ? interval.label : "");
10090
+ }
10091
+ var labels = this.getLabels();
10092
+ var labelIndex = labels.indexOf(itemText);
10093
+ return new survey_core__WEBPACK_IMPORTED_MODULE_1__.ItemValue(this.getValues()[labelIndex], labels[labelIndex]);
10094
+ };
10095
+ /**
10096
+ * Updates visualizer data.
10097
+ */
10098
+ PivotModel.prototype.updateData = function (data) {
10099
+ this.reset();
10100
+ _super.prototype.updateData.call(this, data);
10101
+ };
10102
+ PivotModel.prototype.onDataChanged = function () {
10103
+ this.reset();
10104
+ _super.prototype.onDataChanged.call(this);
10105
+ };
10106
+ PivotModel.prototype.getContiniousValues = function () {
10107
+ var _this = this;
10108
+ if (this._cachedValues === undefined) {
10109
+ this._continiousData = [];
10110
+ if (this.valueType === "enum") {
10111
+ this._cachedValues = [];
10112
+ return this._cachedValues;
10113
+ }
10114
+ var hash_1 = {};
10115
+ this.data.forEach(function (dataItem) {
10116
+ var answerData = dataItem[_this.name];
10117
+ if (answerData !== undefined) {
10118
+ // TODO: _continiousData should be sorted in order to speed-up statistics calculation in the getData function
10119
+ _this._continiousData.push({ continious: _this.getContiniousValue(answerData), row: dataItem });
10120
+ hash_1[answerData] = { value: answerData, row: dataItem };
10121
+ }
10122
+ });
10123
+ this._cachedValues = Object.keys(hash_1).map(function (key) { return ({ original: hash_1[key].value, continious: _this.getContiniousValue(key), row: hash_1[key].row }); });
10124
+ this._cachedValues.sort(function (a, b) { return a.continious - b.continious; });
10125
+ }
10126
+ return this._cachedValues;
10127
+ };
10128
+ PivotModel.prototype.isSupportAnswersOrder = function () {
10129
+ return false;
10130
+ };
10131
+ PivotModel.prototype.isSupportMissingAnswers = function () {
10132
+ return false;
10133
+ };
10134
+ Object.defineProperty(PivotModel.prototype, "needUseRateValues", {
10135
+ get: function () {
10136
+ return this.question.getType() == "rating" && Array.isArray(this.question["rateValues"]) && this.question["rateValues"].length > 0;
10137
+ },
10138
+ enumerable: false,
10139
+ configurable: true
10140
+ });
10141
+ PivotModel.prototype.getSeriesValues = function () {
10142
+ var _this = this;
10143
+ if (this.questionsY.length === 0) {
10144
+ return this.options.seriesValues || [];
10145
+ }
10146
+ var seriesValues = [];
10147
+ this.questionsY.forEach(function (q) {
10148
+ if (_this.getQuestionValueType(q.question) === "enum") {
10149
+ seriesValues.push.apply(seriesValues, q.getValues().reverse());
10150
+ }
10151
+ else {
10152
+ seriesValues.push(q.question.name);
10153
+ }
10154
+ });
10155
+ return seriesValues;
10156
+ };
10157
+ PivotModel.prototype.getSeriesLabels = function () {
10158
+ var _this = this;
10159
+ if (this.questionsY.length === 0) {
10160
+ return this.getSeriesValues();
10161
+ }
10162
+ var seriesLabels = [];
10163
+ this.questionsY.forEach(function (q) {
10164
+ if (_this.getQuestionValueType(q.question) === "enum") {
10165
+ seriesLabels.push.apply(seriesLabels, q.getLabels().reverse());
10166
+ }
10167
+ else {
10168
+ seriesLabels.push(q.question.title || q.question.name);
10169
+ }
10170
+ });
10171
+ return seriesLabels;
10172
+ };
10173
+ PivotModel.prototype.getValues = function () {
10174
+ if (this.valueType === "enum") {
10175
+ return _super.prototype.getValues.call(this).reverse();
10176
+ }
10177
+ return this.intervals.map(function (interval) { return interval.start; });
10178
+ };
10179
+ PivotModel.prototype.getLabels = function () {
10180
+ if (this.valueType === "enum") {
10181
+ return _super.prototype.getLabels.call(this).reverse();
10182
+ }
10183
+ return this.intervals.map(function (interval) { return interval.label; });
10184
+ };
10185
+ Object.defineProperty(PivotModel.prototype, "hasCustomIntervals", {
10186
+ get: function () {
10187
+ return !!this.questionOptions && Array.isArray(this.questionOptions.intervals);
10188
+ },
10189
+ enumerable: false,
10190
+ configurable: true
10191
+ });
10192
+ Object.defineProperty(PivotModel.prototype, "intervals", {
10193
+ get: function () {
10194
+ if (this.hasCustomIntervals) {
10195
+ return this.questionOptions.intervals;
10196
+ }
10197
+ if (this.question.getType() == "rating") {
10198
+ if (this.needUseRateValues) {
10199
+ var rateValues_1 = this.question["rateValues"];
10200
+ rateValues_1.sort(function (iv1, iv2) { return iv1.value - iv2.value; });
10201
+ return rateValues_1.map(function (rateValue, i) { return ({
10202
+ start: rateValue.value,
10203
+ end: i < rateValues_1.length - 1 ? rateValues_1[i + 1].value : rateValue.value + 1,
10204
+ label: rateValue.text
10205
+ }); });
10206
+ }
10207
+ else {
10208
+ var rateIntervals = [];
10209
+ for (var i = (this.question["rateMin"] || 0); i <= (this.question["rateMax"] || (PivotModel.IntervalsCount - 1)); i += (this.question["rateStep"] || 1)) {
10210
+ rateIntervals.push({
10211
+ start: i,
10212
+ end: i + 1,
10213
+ label: "" + (!!this.question["rateMin"] && !!this.question["rateMax"] ? i : (i + "-" + (i + 1)))
10214
+ });
10215
+ }
10216
+ return rateIntervals;
10217
+ }
10218
+ }
10219
+ if (this._cachedIntervals === undefined) {
10220
+ var continiousValues = this.getContiniousValues();
10221
+ this._cachedIntervals = [];
10222
+ if (continiousValues.length) {
10223
+ var start = continiousValues[0].continious;
10224
+ var end = continiousValues[continiousValues.length - 1].continious;
10225
+ var intervalsCount = PivotModel.IntervalsCount;
10226
+ var delta = (end - start) / intervalsCount;
10227
+ for (var i = 0; i < intervalsCount; ++i) {
10228
+ var next = start + delta;
10229
+ var istart = this.toPrecision(start);
10230
+ var inext = this.toPrecision(next);
10231
+ this._cachedIntervals.push({
10232
+ start: istart,
10233
+ end: i < intervalsCount - 1 ? inext : inext + delta / 100,
10234
+ label: "" + this.getString(istart) + "-" + this.getString(inext)
10235
+ });
10236
+ start = next;
10237
+ }
10238
+ }
10239
+ }
10240
+ return this._cachedIntervals;
10241
+ },
10242
+ enumerable: false,
10243
+ configurable: true
10244
+ });
10245
+ PivotModel.prototype.convertFromExternalData = function (externalCalculatedData) {
10246
+ return [externalCalculatedData];
10247
+ };
10248
+ PivotModel.prototype.getSeriesValueIndexes = function () {
10249
+ var _this = this;
10250
+ var seriesValueIndexes = {};
10251
+ var valueIndex = 0;
10252
+ for (var i = 0; i < this.questionsY.length; ++i) {
10253
+ var questionValueType = this.getQuestionValueType(this.questionsY[i].question);
10254
+ if (questionValueType === "enum") {
10255
+ this.questionsY[i].getValues().reverse().forEach(function (value) {
10256
+ seriesValueIndexes[_this.questionsY[i].name + "_" + value] = valueIndex++;
10257
+ });
10258
+ }
10259
+ else {
10260
+ seriesValueIndexes[this.questionsY[i].name] = valueIndex++;
10261
+ }
10262
+ }
10263
+ return seriesValueIndexes;
10264
+ };
10265
+ PivotModel.prototype.updateStatisticsSeriesValue = function (statistics, dataRow, valueIndex, seriesValueIndexes) {
10266
+ for (var j = 0; j < this.questionsY.length; ++j) {
10267
+ if (dataRow[this.questionsY[j].name] !== undefined) {
10268
+ var questionValueType = this.getQuestionValueType(this.questionsY[j].question);
10269
+ if (questionValueType === "enum" || questionValueType === "date") {
10270
+ var seriesValueIndex = seriesValueIndexes[this.questionsY[j].name + "_" + dataRow[this.questionsY[j].name]];
10271
+ statistics[seriesValueIndex][valueIndex]++;
10272
+ }
10273
+ else {
10274
+ var seriesValueIndex = seriesValueIndexes[this.questionsY[j].name];
10275
+ statistics[seriesValueIndex][valueIndex] += parseFloat(dataRow[this.questionsY[j].name]);
10276
+ }
10277
+ }
10278
+ }
10279
+ };
10280
+ PivotModel.prototype.getCalculatedValuesCore = function () {
10281
+ var _this = this;
10282
+ var statistics = [];
10283
+ var series = this.getSeriesValues();
10284
+ if (series.length === 0) {
10285
+ series.push("");
10286
+ }
10287
+ var seriesValueIndexes = this.getSeriesValueIndexes();
10288
+ if (this.valueType === "enum") {
10289
+ var values = this.getValues();
10290
+ var valueIndexes_1 = {};
10291
+ values.forEach(function (value, index) {
10292
+ valueIndexes_1[value] = index;
10293
+ });
10294
+ for (var i = 0; i < series.length; ++i) {
10295
+ statistics.push(values.map(function (i) { return 0; }));
10296
+ }
10297
+ this.data.forEach(function (dataRow) {
10298
+ var answerData = dataRow[_this.name];
10299
+ if (answerData !== undefined && valueIndexes_1[answerData] !== undefined) {
10300
+ var valueIndex = valueIndexes_1[answerData];
10301
+ if (_this.questionsY.length === 0) {
10302
+ statistics[0][valueIndex]++;
10303
+ }
10304
+ else {
10305
+ _this.updateStatisticsSeriesValue(statistics, dataRow, valueIndex, seriesValueIndexes);
10306
+ }
10307
+ }
10308
+ });
10309
+ }
10310
+ else {
10311
+ var continiousValues = this.getContiniousValues();
10312
+ var intervals_1 = this.intervals;
10313
+ for (var i = 0; i < series.length; ++i) {
10314
+ statistics.push(intervals_1.map(function (i) { return 0; }));
10315
+ }
10316
+ this._continiousData.forEach(function (dataValue) {
10317
+ for (var valueIndex = 0; valueIndex < intervals_1.length; ++valueIndex) {
10318
+ if (intervals_1[valueIndex].start <= dataValue.continious && (dataValue.continious < intervals_1[valueIndex].end || valueIndex == intervals_1.length - 1)) {
10319
+ if (_this.questionsY.length === 0) {
10320
+ statistics[0][valueIndex]++;
10321
+ }
10322
+ else {
10323
+ _this.updateStatisticsSeriesValue(statistics, dataValue.row, valueIndex, seriesValueIndexes);
10324
+ }
10325
+ break;
10326
+ }
10327
+ }
10328
+ });
10329
+ }
10330
+ return statistics;
10331
+ };
10332
+ PivotModel.IntervalsCount = 10;
10333
+ PivotModel.UseIntervalsFrom = 10;
10334
+ return PivotModel;
10335
+ }(_selectBase__WEBPACK_IMPORTED_MODULE_2__.SelectBase));
10336
+
10337
+
10338
+
9926
10339
  /***/ }),
9927
10340
 
9928
10341
  /***/ "./src/plotly/boolean.ts":
@@ -10065,20 +10478,6 @@ var HistogramPlotly = /** @class */ (function (_super) {
10065
10478
  });
10066
10479
  });
10067
10480
  };
10068
- HistogramPlotly.prototype.getCalculatedValuesCore = function () {
10069
- var statistics = _super.prototype.getCalculatedValuesCore.call(this);
10070
- var series = this.getSeriesValues();
10071
- var values = this.getValues();
10072
- if (series.length > 1) {
10073
- var preparedData_1 = [];
10074
- values.forEach(function (val, valueIndex) {
10075
- var seriesData = series.map(function (seriesValue, seriesIndex) { return statistics[seriesIndex][valueIndex]; });
10076
- preparedData_1.push(seriesData);
10077
- });
10078
- return preparedData_1;
10079
- }
10080
- return statistics;
10081
- };
10082
10481
  HistogramPlotly.prototype.getValueType = function () {
10083
10482
  return this.valueType;
10084
10483
  };
@@ -10107,6 +10506,7 @@ __webpack_require__.r(__webpack_exports__);
10107
10506
  /* harmony export */ HistogramPlotly: () => (/* reexport safe */ _histogram__WEBPACK_IMPORTED_MODULE_6__.HistogramPlotly),
10108
10507
  /* harmony export */ MatrixDropdownGroupedPlotly: () => (/* reexport safe */ _matrixdropdown_grouped__WEBPACK_IMPORTED_MODULE_5__.MatrixDropdownGroupedPlotly),
10109
10508
  /* harmony export */ MatrixPlotly: () => (/* reexport safe */ _matrix__WEBPACK_IMPORTED_MODULE_2__.MatrixPlotly),
10509
+ /* harmony export */ PivotPlotly: () => (/* reexport safe */ _pivot__WEBPACK_IMPORTED_MODULE_8__.PivotPlotly),
10110
10510
  /* harmony export */ PlotlyBoolChartAdapter: () => (/* reexport safe */ _boolean__WEBPACK_IMPORTED_MODULE_3__.PlotlyBoolChartAdapter),
10111
10511
  /* harmony export */ PlotlyChartAdapter: () => (/* reexport safe */ _selectBase__WEBPACK_IMPORTED_MODULE_1__.PlotlyChartAdapter),
10112
10512
  /* harmony export */ PlotlyGaugeAdapter: () => (/* reexport safe */ _rating__WEBPACK_IMPORTED_MODULE_7__.PlotlyGaugeAdapter),
@@ -10122,6 +10522,8 @@ __webpack_require__.r(__webpack_exports__);
10122
10522
  /* harmony import */ var _matrixdropdown_grouped__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./matrixdropdown-grouped */ "./src/plotly/matrixdropdown-grouped.ts");
10123
10523
  /* harmony import */ var _histogram__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./histogram */ "./src/plotly/histogram.ts");
10124
10524
  /* harmony import */ var _rating__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./rating */ "./src/plotly/rating.ts");
10525
+ /* harmony import */ var _pivot__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./pivot */ "./src/plotly/pivot.ts");
10526
+
10125
10527
 
10126
10528
 
10127
10529
 
@@ -10252,6 +10654,69 @@ var MatrixDropdownGroupedPlotly = /** @class */ (function (_super) {
10252
10654
  _visualizationManager__WEBPACK_IMPORTED_MODULE_1__.VisualizationManager.registerVisualizer("matrixdropdown-grouped", MatrixDropdownGroupedPlotly);
10253
10655
 
10254
10656
 
10657
+ /***/ }),
10658
+
10659
+ /***/ "./src/plotly/pivot.ts":
10660
+ /*!*****************************!*\
10661
+ !*** ./src/plotly/pivot.ts ***!
10662
+ \*****************************/
10663
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
10664
+
10665
+ "use strict";
10666
+ __webpack_require__.r(__webpack_exports__);
10667
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
10668
+ /* harmony export */ PivotPlotly: () => (/* binding */ PivotPlotly)
10669
+ /* harmony export */ });
10670
+ /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "./src/utils/helpers.ts");
10671
+ /* harmony import */ var _pivot__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../pivot */ "./src/pivot.ts");
10672
+ /* harmony import */ var _selectBase__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./selectBase */ "./src/plotly/selectBase.ts");
10673
+ /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils */ "./src/utils/index.ts");
10674
+ /* harmony import */ var _visualizationManager__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../visualizationManager */ "./src/visualizationManager.ts");
10675
+
10676
+
10677
+
10678
+
10679
+
10680
+ var PivotPlotly = /** @class */ (function (_super) {
10681
+ (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__extends)(PivotPlotly, _super);
10682
+ function PivotPlotly(questions, data, options, name) {
10683
+ var _this = _super.call(this, questions, data, options, name) || this;
10684
+ _this.chartTypes = PivotPlotly.types;
10685
+ _this._chartType = _this.chartTypes[0];
10686
+ _this._chartAdapter = new _selectBase__WEBPACK_IMPORTED_MODULE_2__.PlotlyChartAdapter(_this);
10687
+ return _this;
10688
+ }
10689
+ PivotPlotly.prototype.destroyContent = function (container) {
10690
+ this._chartAdapter.destroy(container.children[0]);
10691
+ _super.prototype.destroyContent.call(this, container);
10692
+ };
10693
+ PivotPlotly.prototype.renderContentAsync = function (container) {
10694
+ return (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__awaiter)(this, void 0, void 0, function () {
10695
+ var chartNode;
10696
+ return (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__generator)(this, function (_a) {
10697
+ switch (_a.label) {
10698
+ case 0:
10699
+ chartNode = _utils__WEBPACK_IMPORTED_MODULE_3__.DocumentHelper.createElement("div");
10700
+ container.innerHTML = "";
10701
+ container.appendChild(chartNode);
10702
+ return [4 /*yield*/, this._chartAdapter.create(chartNode)];
10703
+ case 1:
10704
+ _a.sent();
10705
+ return [2 /*return*/, container];
10706
+ }
10707
+ });
10708
+ });
10709
+ };
10710
+ PivotPlotly.prototype.getValueType = function () {
10711
+ return this.valueType;
10712
+ };
10713
+ PivotPlotly.types = ["vbar", "bar", "line", "stackedbar", "pie", "doughnut"]; // ["vbar", "bar"];
10714
+ return PivotPlotly;
10715
+ }(_pivot__WEBPACK_IMPORTED_MODULE_1__.PivotModel));
10716
+
10717
+ _visualizationManager__WEBPACK_IMPORTED_MODULE_4__.VisualizationManager.registerPivotVisualizer(PivotPlotly);
10718
+
10719
+
10255
10720
  /***/ }),
10256
10721
 
10257
10722
  /***/ "./src/plotly/ranking.ts":
@@ -10699,20 +11164,6 @@ var SelectBasePlotly = /** @class */ (function (_super) {
10699
11164
  this._chartAdapter.update(chartNode);
10700
11165
  }
10701
11166
  };
10702
- SelectBasePlotly.prototype.getCalculatedValuesCore = function () {
10703
- var statistics = _super.prototype.getCalculatedValuesCore.call(this);
10704
- var series = this.getSeriesValues();
10705
- var values = this.getValues();
10706
- if (series.length > 1) {
10707
- var preparedData_1 = [];
10708
- values.forEach(function (val, valueIndex) {
10709
- var seriesData = series.map(function (seriesValue, seriesIndex) { return statistics[seriesIndex][valueIndex]; });
10710
- preparedData_1.push(seriesData);
10711
- });
10712
- return preparedData_1;
10713
- }
10714
- return statistics;
10715
- };
10716
11167
  SelectBasePlotly.types = ["bar", "vbar", "pie", "doughnut"];
10717
11168
  SelectBasePlotly.displayModeBar = undefined;
10718
11169
  return SelectBasePlotly;
@@ -10751,38 +11202,44 @@ var PlotlySetup = /** @class */ (function () {
10751
11202
  };
10752
11203
  PlotlySetup.setupPie = function (model, answersData) {
10753
11204
  var datasets = answersData.datasets, labels = answersData.labels, colors = answersData.colors, texts = answersData.texts, seriesLabels = answersData.seriesLabels;
10754
- var traces = [];
10755
11205
  var hasSeries = seriesLabels.length > 1 || model.question.getType() === "matrix";
11206
+ var layoutColumns = 2;
11207
+ var traces = [];
10756
11208
  var traceConfig = {
10757
11209
  type: model.chartType,
10758
- y: hasSeries ? seriesLabels : labels,
10759
- text: (hasSeries ? seriesLabels : labels).map(function (label) {
11210
+ labels: labels,
11211
+ customdata: labels,
11212
+ text: labels.map(function (label) {
10760
11213
  return PlotlySetup.getTruncatedLabel(label, model.labelTruncateLength);
10761
11214
  }),
10762
- hoverinfo: "x+y",
10763
- mode: "markers",
10764
- marker: {},
11215
+ hoverinfo: "label+value+percent",
11216
+ textposition: "inside",
10765
11217
  };
10766
- traceConfig.hoverinfo = "label+value+percent";
10767
- traceConfig.marker.colors = colors;
10768
- traceConfig.textposition = "inside";
10769
11218
  if (model.chartType === "doughnut") {
10770
11219
  traceConfig.type = "pie";
10771
11220
  traceConfig.hole = 0.4;
10772
11221
  }
10773
11222
  if (!hasSeries) {
11223
+ traceConfig.mode = "markers",
11224
+ traceConfig.marker = { color: colors };
10774
11225
  traceConfig.marker.symbol = "circle";
10775
11226
  traceConfig.marker.size = 16;
10776
11227
  }
10777
11228
  datasets.forEach(function (dataset, index) {
10778
- traces.push(Object.assign({}, traceConfig, {
10779
- values: dataset,
10780
- labels: hasSeries ? seriesLabels : labels,
10781
- customdata: hasSeries ? seriesLabels : labels,
10782
- }));
11229
+ var isNotEmpty = dataset.some(function (value) { return value != 0; });
11230
+ if (isNotEmpty) {
11231
+ traces.push(Object.assign({}, traceConfig, {
11232
+ values: dataset,
11233
+ domain: {
11234
+ column: traces.length % layoutColumns,
11235
+ row: Math.floor(traces.length / layoutColumns),
11236
+ },
11237
+ title: { position: "bottom center", text: seriesLabels[index] }
11238
+ }));
11239
+ }
10783
11240
  });
10784
11241
  var radius = labels.length < 10 ? labels.length * 50 + 100 : 550;
10785
- var height = radius * Math.round(traces.length / 2) + 25;
11242
+ var height = (radius + 25) * Math.ceil(traces.length / layoutColumns);
10786
11243
  var layout = {
10787
11244
  font: {
10788
11245
  family: "Segoe UI, sans-serif",
@@ -10805,21 +11262,7 @@ var PlotlySetup = /** @class */ (function () {
10805
11262
  };
10806
11263
  if (hasSeries) {
10807
11264
  layout.annotations = [];
10808
- labels.forEach(function (label, index) {
10809
- traces[index].title = { position: "bottom center", text: label };
10810
- });
10811
- traces = traces.filter(function (t) { return !(t.values.length === 1 && t.values[0] === 0); });
10812
- traces.forEach(function (label, index) {
10813
- traces[index].domain = {
10814
- column: index % 2,
10815
- row: Math.floor(index / 2),
10816
- };
10817
- });
10818
- layout.grid = {
10819
- rows: Math.round(traces.length / 2),
10820
- columns: 2,
10821
- };
10822
- layout.height = radius * Math.round(traces.length / 2) + 25;
11265
+ layout.grid = { rows: Math.ceil(traces.length / layoutColumns), columns: layoutColumns };
10823
11266
  }
10824
11267
  return { traces: traces, layout: layout, hasSeries: hasSeries };
10825
11268
  };
@@ -10828,36 +11271,45 @@ var PlotlySetup = /** @class */ (function () {
10828
11271
  var topMargin = 30;
10829
11272
  var bottomMargin = 30;
10830
11273
  var datasets = answersData.datasets, labels = answersData.labels, colors = answersData.colors, texts = answersData.texts, seriesLabels = answersData.seriesLabels;
10831
- var traces = [];
10832
11274
  var hasSeries = seriesLabels.length > 1 || model.question.getType() === "matrix";
10833
- var yFullTexts = hasSeries ? seriesLabels : labels;
11275
+ var traces = [];
10834
11276
  var traceConfig = {
10835
- type: model.chartType,
10836
- y: yFullTexts,
10837
- text: yFullTexts,
10838
- customdata: hasSeries ? seriesLabels : labels,
11277
+ type: model.chartType === "line" ? "line" : "bar",
11278
+ y: labels,
11279
+ customdata: labels,
10839
11280
  hoverinfo: "text",
10840
11281
  orientation: "h",
10841
- mode: "markers",
10842
11282
  textposition: "none",
10843
- width: 0.5,
10844
- bargap: 0.5,
10845
- marker: {},
10846
11283
  };
10847
- traceConfig.marker.color = colors;
11284
+ if (!hasSeries) {
11285
+ traceConfig.width = 0.5;
11286
+ traceConfig.bargap = 0.5;
11287
+ traceConfig.mode = "markers",
11288
+ traceConfig.marker = { color: colors };
11289
+ }
10848
11290
  datasets.forEach(function (dataset, index) {
11291
+ var traceName = hasSeries ? seriesLabels[index] : labels[index];
11292
+ var percentString = model.showPercentages ? "%" : "";
10849
11293
  var trace = Object.assign({}, traceConfig, {
10850
11294
  x: dataset,
11295
+ name: traceName,
11296
+ width: hasSeries && model.chartType !== "stackedbar" ? 0.5 / seriesLabels.length : 0.5,
10851
11297
  text: texts[index],
10852
- hovertext: yFullTexts.map(function (label, labelIndex) {
10853
- return "".concat(texts[index][labelIndex], ", ").concat(label);
11298
+ hovertext: labels.map(function (label, labelIndex) {
11299
+ if (model.showOnlyPercentages) {
11300
+ return "".concat(texts[index][labelIndex]).concat(percentString);
11301
+ }
11302
+ else {
11303
+ return hasSeries ? "".concat(traceName, " : ").concat(label, ", ").concat(texts[index][labelIndex]).concat(percentString) : "".concat(texts[index][labelIndex]).concat(percentString, ", ").concat(label);
11304
+ }
10854
11305
  }),
10855
11306
  });
10856
11307
  if (model.showPercentages) {
10857
11308
  var texttemplate = model.showOnlyPercentages ? "%{text}%" : "%{value} (%{text}%)";
10858
11309
  trace.textposition = "inside";
10859
11310
  trace.texttemplate = texttemplate;
10860
- trace.bargap = 0.1;
11311
+ trace.width = hasSeries && model.chartType !== "stackedbar" ? 0.7 / seriesLabels.length : 0.9;
11312
+ trace.bargap = hasSeries && model.chartType !== "stackedbar" ? 0.3 / seriesLabels.length : 0.1;
10861
11313
  }
10862
11314
  traces.push(trace);
10863
11315
  });
@@ -10877,60 +11329,49 @@ var PlotlySetup = /** @class */ (function () {
10877
11329
  },
10878
11330
  colorway: colors,
10879
11331
  hovermode: "closest",
11332
+ plot_bgcolor: model.backgroundColor,
11333
+ paper_bgcolor: model.backgroundColor,
11334
+ showlegend: hasSeries,
11335
+ barmode: hasSeries && model.chartType == "stackedbar" ? "stack" : "group",
11336
+ xaxis: {
11337
+ rangemode: "nonnegative",
11338
+ automargin: true,
11339
+ },
10880
11340
  yaxis: {
10881
11341
  automargin: true,
10882
11342
  type: "category",
10883
11343
  orientation: "h",
10884
11344
  tickmode: "array",
10885
- tickvals: yFullTexts,
10886
- ticktext: yFullTexts.map(function (label) {
11345
+ tickvals: labels,
11346
+ ticktext: labels.map(function (label) {
10887
11347
  return PlotlySetup.getTruncatedLabel(label, model.labelTruncateLength) + " ";
10888
11348
  }),
10889
11349
  },
10890
- xaxis: {
10891
- rangemode: "nonnegative",
10892
- automargin: true,
10893
- // dtick: 1
10894
- },
10895
- plot_bgcolor: model.backgroundColor,
10896
- paper_bgcolor: model.backgroundColor,
10897
- showlegend: false,
10898
11350
  };
10899
- if (hasSeries) {
10900
- layout.showlegend = true;
10901
- if (model.chartType == "stackedbar") {
10902
- layout.barmode = "stack";
10903
- layout.height =
10904
- (seriesLabels.length + 1) * lineHeight +
10905
- topMargin +
10906
- bottomMargin;
10907
- }
10908
- else {
10909
- layout.height =
10910
- (labels.length + 1) * lineHeight * seriesLabels.length +
10911
- topMargin +
10912
- bottomMargin;
10913
- }
10914
- labels.forEach(function (label, index) {
10915
- traces[index].marker.color = undefined;
10916
- traces[index].name = label;
10917
- if (model.chartType === "stackedbar") {
10918
- traces[index].type = "bar";
10919
- traces[index].width = 0.5;
10920
- }
10921
- else {
10922
- traces[index].width =
10923
- (model.showPercentages ? 0.7 : 0.5) / traces.length;
10924
- }
10925
- });
10926
- traces.forEach(function (trace, traceIndex) {
10927
- var percentString = model.showPercentages ? "%" : "";
10928
- traces[traceIndex].hovertext = [];
10929
- yFullTexts.forEach(function (yFullText, yFullTextIndex) {
10930
- traces[traceIndex].hovertext.push("".concat(trace.y[yFullTextIndex], " : ").concat(trace.name, ", ").concat(trace.text[yFullTextIndex]).concat(percentString));
10931
- });
10932
- });
11351
+ if (hasSeries && model.chartType !== "stackedbar") {
11352
+ layout.height =
11353
+ (labels.length * seriesLabels.length + 1) * lineHeight +
11354
+ topMargin +
11355
+ bottomMargin;
10933
11356
  }
11357
+ // labels.forEach((label, index) => {
11358
+ // traces[index].marker.color = undefined;
11359
+ // traces[index].name = label;
11360
+ // if (model.chartType === "stackedbar") {
11361
+ // traces[index].type = "bar";
11362
+ // traces[index].width = 0.5;
11363
+ // } else {
11364
+ // traces[index].width =
11365
+ // (model.showPercentages ? 0.7 : 0.5) / traces.length;
11366
+ // }
11367
+ // });
11368
+ // traces.forEach((trace, traceIndex) => {
11369
+ // const percentString = model.showPercentages ? "%" : "";
11370
+ // traces[traceIndex].hovertext = [];
11371
+ // yFullTexts.forEach((yFullText, yFullTextIndex) => {
11372
+ // traces[traceIndex].hovertext.push(`${trace.y[yFullTextIndex]} : ${trace.name}, ${trace.text[yFullTextIndex]}${percentString}`);
11373
+ // });
11374
+ // });
10934
11375
  if (["ar", "fa"].indexOf(_localizationManager__WEBPACK_IMPORTED_MODULE_1__.localization.currentLocale) !== -1) {
10935
11376
  layout.xaxis.autorange = "reversed";
10936
11377
  layout.yaxis.side = "right";
@@ -10947,9 +11388,11 @@ var PlotlySetup = /** @class */ (function () {
10947
11388
  var topMargin = 30;
10948
11389
  var bottomMargin = 30;
10949
11390
  var datasets = answersData.datasets, labels = answersData.labels, colors = answersData.colors, texts = answersData.texts, seriesLabels = answersData.seriesLabels;
10950
- if (model.type !== "histogram") {
11391
+ var hasSeries = seriesLabels.length > 1 || model.question.getType() === "matrix";
11392
+ if (model.type !== "histogram" && model.type !== "pivot") {
10951
11393
  labels = [].concat(labels).reverse();
10952
- colors = [].concat(colors.slice(0, labels.length)).reverse();
11394
+ seriesLabels = [].concat(seriesLabels).reverse();
11395
+ colors = [].concat(colors.slice(0, hasSeries ? seriesLabels.length : labels.length)).reverse();
10953
11396
  var ts_1 = [];
10954
11397
  texts.forEach(function (text) {
10955
11398
  ts_1.push([].concat(text).reverse());
@@ -10962,7 +11405,37 @@ var PlotlySetup = /** @class */ (function () {
10962
11405
  datasets = ds_1;
10963
11406
  }
10964
11407
  var traces = [];
10965
- var hasSeries = seriesLabels.length > 1 || model.question.getType() === "matrix";
11408
+ var traceConfig = {
11409
+ type: model.chartType === "line" ? "line" : "bar",
11410
+ x: labels,
11411
+ customdata: hasSeries ? seriesLabels : labels,
11412
+ hoverinfo: hasSeries ? undefined : "x+y",
11413
+ orientation: "v",
11414
+ textposition: "none",
11415
+ };
11416
+ if (model.type === "histogram" || !hasSeries) {
11417
+ traceConfig.width = 0.5;
11418
+ traceConfig.bargap = 0.5;
11419
+ traceConfig.mode = "markers",
11420
+ traceConfig.marker = { color: colors };
11421
+ }
11422
+ datasets.forEach(function (dataset, index) {
11423
+ var trace = Object.assign({}, traceConfig, {
11424
+ y: dataset,
11425
+ name: hasSeries ? seriesLabels[index] : labels[index],
11426
+ text: texts[index],
11427
+ });
11428
+ if (model.showPercentages) {
11429
+ var texttemplate = model.showOnlyPercentages ? "%{text}%" : "%{value} (%{text}%)";
11430
+ trace.textposition = "inside";
11431
+ trace.texttemplate = texttemplate;
11432
+ if (!hasSeries) {
11433
+ trace.width = 0.9;
11434
+ trace.bargap = 0.1;
11435
+ }
11436
+ }
11437
+ traces.push(trace);
11438
+ });
10966
11439
  var layout = {
10967
11440
  font: {
10968
11441
  family: "Segoe UI, sans-serif",
@@ -10979,34 +11452,21 @@ var PlotlySetup = /** @class */ (function () {
10979
11452
  hovermode: "closest",
10980
11453
  plot_bgcolor: model.backgroundColor,
10981
11454
  paper_bgcolor: model.backgroundColor,
10982
- showlegend: false,
10983
- };
10984
- var traceConfig = {
10985
- type: model.chartType === "line" ? "line" : "bar",
10986
- customdata: hasSeries ? seriesLabels : labels,
10987
- hoverinfo: "x+y",
10988
- mode: model.chartType === "line" ? "lines+markers" : "markers",
10989
- textposition: "none",
10990
- width: 0.5,
10991
- bargap: 0.5,
10992
- marker: {},
11455
+ showlegend: hasSeries,
11456
+ yaxis: {
11457
+ rangemode: "nonnegative",
11458
+ automargin: true,
11459
+ },
11460
+ xaxis: {
11461
+ automargin: true,
11462
+ type: "category",
11463
+ tickmode: "array",
11464
+ tickvals: labels,
11465
+ ticktext: labels.map(function (label) {
11466
+ return PlotlySetup.getTruncatedLabel(label, model.labelTruncateLength) + " ";
11467
+ }),
11468
+ },
10993
11469
  };
10994
- traceConfig.marker.color = colors;
10995
- datasets.forEach(function (dataset, index) {
10996
- var trace = Object.assign({}, traceConfig, {
10997
- x: labels,
10998
- y: model.showPercentages ? texts[index].map(function (y) { return y / 100; }) : dataset,
10999
- text: texts[index],
11000
- });
11001
- if (model.showPercentages) {
11002
- var texttemplate = model.showOnlyPercentages ? "%{text}%" : "%{value} (%{text}%)";
11003
- trace.textposition = "inside";
11004
- trace.texttemplate = texttemplate;
11005
- trace.width = 0.9;
11006
- trace.bargap = 0.1;
11007
- }
11008
- traces.push(trace);
11009
- });
11010
11470
  if (model.showPercentages && model.showOnlyPercentages) {
11011
11471
  layout.yaxis = {
11012
11472
  automargin: true,
@@ -11182,9 +11642,9 @@ function hideEmptyAnswersInData(answersData) {
11182
11642
  seriesDataExistence.length = answersData.seriesLabels.length;
11183
11643
  var valuesDataExistence = [];
11184
11644
  valuesDataExistence.length = answersData.labels.length;
11185
- for (var valueIndex = 0; valueIndex < answersData.labels.length; valueIndex++) {
11186
- for (var seriesIndex = 0; seriesIndex < answersData.seriesLabels.length; seriesIndex++) {
11187
- if (answersData.datasets[valueIndex][seriesIndex] != 0) {
11645
+ for (var seriesIndex = 0; seriesIndex < answersData.seriesLabels.length; seriesIndex++) {
11646
+ for (var valueIndex = 0; valueIndex < answersData.labels.length; valueIndex++) {
11647
+ if (answersData.datasets[seriesIndex][valueIndex] != 0) {
11188
11648
  seriesDataExistence[seriesIndex] = true;
11189
11649
  valuesDataExistence[valueIndex] = true;
11190
11650
  }
@@ -11201,14 +11661,14 @@ function hideEmptyAnswersInData(answersData) {
11201
11661
  result.seriesLabels.push(answersData.seriesLabels[seriesIndex]);
11202
11662
  }
11203
11663
  }
11204
- for (var valueIndex = 0; valueIndex < answersData.labels.length; valueIndex++) {
11205
- if (valuesDataExistence[valueIndex]) {
11664
+ for (var seriesIndex = 0; seriesIndex < answersData.datasets.length; seriesIndex++) {
11665
+ if (seriesDataExistence[seriesIndex]) {
11206
11666
  var dataset = [];
11207
11667
  var texts = [];
11208
- for (var seriesIndex = 0; seriesIndex < answersData.datasets.length; seriesIndex++) {
11209
- if (seriesDataExistence[seriesIndex]) {
11210
- dataset.push(answersData.datasets[valueIndex][seriesIndex]);
11211
- texts.push(answersData.texts[valueIndex][seriesIndex]);
11668
+ for (var valueIndex = 0; valueIndex < answersData.labels.length; valueIndex++) {
11669
+ if (valuesDataExistence[valueIndex]) {
11670
+ dataset.push(answersData.datasets[seriesIndex][valueIndex]);
11671
+ texts.push(answersData.texts[seriesIndex][valueIndex]);
11212
11672
  }
11213
11673
  }
11214
11674
  result.datasets.push(dataset);
@@ -11246,14 +11706,19 @@ var SelectBase = /** @class */ (function (_super) {
11246
11706
  * options fields can be modified
11247
11707
  */
11248
11708
  _this.onAnswersDataReady = new survey_core__WEBPACK_IMPORTED_MODULE_1__.Event();
11249
- question.visibleChoicesChangedCallback = function () {
11250
- _this.dataProvider.raiseDataChanged();
11251
- };
11709
+ if (!!question) { // TODO: move somewhere else
11710
+ question.visibleChoicesChangedCallback = function () {
11711
+ _this.dataProvider.raiseDataChanged();
11712
+ };
11713
+ }
11252
11714
  _this._showPercentages = _this.options.showPercentages === true;
11253
11715
  _this._showOnlyPercentages = _this.options.showOnlyPercentages === true;
11254
11716
  if (_this.options.percentagePrecision) {
11255
11717
  _this._percentagePrecision = _this.options.percentagePrecision;
11256
11718
  }
11719
+ if (_this.options.transposeData !== undefined) {
11720
+ _this._transposeData = _this.options.transposeData;
11721
+ }
11257
11722
  _this._hideEmptyAnswers = _this.options.hideEmptyAnswers === true;
11258
11723
  _this._answersOrder = _this.options.answersOrder || "default";
11259
11724
  _this._showMissingAnswers = _this.isSupportMissingAnswers() && _this.options.showMissingAnswers === true;
@@ -11741,9 +12206,9 @@ var SelectBase = /** @class */ (function (_super) {
11741
12206
  var series = this.getSeriesValues();
11742
12207
  var innerCalculatedData = [];
11743
12208
  if (series.length > 0) {
11744
- for (var i = 0; i < values.length; i++) {
12209
+ for (var j = 0; j < series.length; j++) {
11745
12210
  var seriesData = [];
11746
- for (var j = 0; j < series.length; j++) {
12211
+ for (var i = 0; i < values.length; i++) {
11747
12212
  if (!!externalCalculatedData[series[j]]) {
11748
12213
  seriesData.push(externalCalculatedData[series[j]][values[i]] || 0);
11749
12214
  }
@@ -12357,9 +12822,15 @@ __webpack_require__.r(__webpack_exports__);
12357
12822
  var DocumentHelper = /** @class */ (function () {
12358
12823
  function DocumentHelper() {
12359
12824
  }
12360
- DocumentHelper.createSelector = function (options, isSelected, handler) {
12825
+ DocumentHelper.createSelector = function (options, isSelected, handler, title) {
12361
12826
  var selectWrapper = document.createElement("div");
12362
12827
  selectWrapper.className = "sa-question__select-wrapper";
12828
+ if (title) {
12829
+ var titleElement = DocumentHelper.createElement("span", "sa-question__select-title", {
12830
+ innerText: title,
12831
+ });
12832
+ selectWrapper.appendChild(titleElement);
12833
+ }
12363
12834
  var select = document.createElement("select");
12364
12835
  select.className = "sa-question__select";
12365
12836
  options.forEach(function (option) {
@@ -12665,7 +13136,14 @@ var VisualizationManager = /** @class */ (function () {
12665
13136
  VisualizationManager.registerAltVisualizerSelector = function (constructor) {
12666
13137
  VisualizationManager.alternativesVisualizer = constructor;
12667
13138
  };
13139
+ VisualizationManager.getPivotVisualizerConstructor = function () {
13140
+ return VisualizationManager.pivotVisualizer || _visualizerBase__WEBPACK_IMPORTED_MODULE_0__.VisualizerBase;
13141
+ };
13142
+ VisualizationManager.registerPivotVisualizer = function (constructor) {
13143
+ VisualizationManager.pivotVisualizer = constructor;
13144
+ };
12668
13145
  VisualizationManager.alternativesVisualizer = undefined;
13146
+ VisualizationManager.pivotVisualizer = undefined;
12669
13147
  VisualizationManager.vizualizers = {};
12670
13148
  return VisualizationManager;
12671
13149
  }());
@@ -12712,6 +13190,7 @@ var VisualizationMatrixDropdown = /** @class */ (function (_super) {
12712
13190
  _this._childOptions.disableLocaleSwitch = true;
12713
13191
  _this._childOptions.dataProvider = undefined;
12714
13192
  _this._childOptions.allowDynamicLayout = false;
13193
+ _this._childOptions.transposeData = true;
12715
13194
  _this._childOptions.seriesValues = question.rows.map(function (row) { return row.value; });
12716
13195
  _this._childOptions.seriesLabels = question.rows.map(function (row) { return row.text; });
12717
13196
  var innerQuestions = _this.getQuestions();
@@ -12871,6 +13350,8 @@ __webpack_require__.r(__webpack_exports__);
12871
13350
  /* harmony import */ var _layoutEngine__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./layoutEngine */ "./src/layoutEngine.ts");
12872
13351
  /* harmony import */ var _svgbundle__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./svgbundle */ "./src/svgbundle.ts");
12873
13352
  /* harmony import */ var _visualizationPanel_scss__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./visualizationPanel.scss */ "./src/visualizationPanel.scss");
13353
+ /* harmony import */ var _visualizationManager__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./visualizationManager */ "./src/visualizationManager.ts");
13354
+
12874
13355
 
12875
13356
 
12876
13357
 
@@ -13192,7 +13673,15 @@ var VisualizationPanel = /** @class */ (function (_super) {
13192
13673
  VisualizationPanel.prototype.buildVisualizers = function (questions) {
13193
13674
  var _this = this;
13194
13675
  questions.forEach(function (question) {
13195
- var visualizer = _this.createVisualizer(question);
13676
+ var visualizerOptions = Object.assign({}, _this.options);
13677
+ var visualizerData = _this.surveyData;
13678
+ var visualizer;
13679
+ if (Array.isArray(question)) {
13680
+ visualizer = new (_visualizationManager__WEBPACK_IMPORTED_MODULE_11__.VisualizationManager.getPivotVisualizerConstructor())(question, visualizerData, visualizerOptions);
13681
+ }
13682
+ else {
13683
+ visualizer = _this.createVisualizer(question, visualizerOptions, visualizerData);
13684
+ }
13196
13685
  if (!visualizer) {
13197
13686
  return;
13198
13687
  }
@@ -13261,6 +13750,7 @@ var VisualizationPanel = /** @class */ (function (_super) {
13261
13750
  var _this = this;
13262
13751
  _super.prototype.setLocale.call(this, newLocale);
13263
13752
  (this.questions || []).forEach(function (question) {
13753
+ question = Array.isArray(question) ? question[0] : question;
13264
13754
  var element = _this.getElement(question.name);
13265
13755
  if (!!element) {
13266
13756
  element.displayName = _this.processText(question.title);
@@ -13328,6 +13818,7 @@ var VisualizationPanel = /** @class */ (function (_super) {
13328
13818
  VisualizationPanel.prototype.buildElements = function (questions) {
13329
13819
  var _this = this;
13330
13820
  return (questions || []).map(function (question) {
13821
+ question = Array.isArray(question) ? question[0] : question;
13331
13822
  return {
13332
13823
  name: question.name,
13333
13824
  displayName: _this.processText(question.title),
@@ -13552,7 +14043,7 @@ var VisualizationPanel = /** @class */ (function (_super) {
13552
14043
  this._settingState = true;
13553
14044
  try {
13554
14045
  if (Array.isArray(newState.elements)) {
13555
- var questionNames_1 = this.questions.map(function (q) { return q.name; });
14046
+ var questionNames_1 = this.questions.map(function (q) { return Array.isArray(q) ? q[0].name : q.name; });
13556
14047
  this._elements = [].concat(newState.elements.filter(function (e) { return (questionNames_1.indexOf(e.name) !== -1); }));
13557
14048
  }
13558
14049
  if (typeof newState.locale !== "undefined")
@@ -13929,12 +14420,12 @@ var VisualizerBase = /** @class */ (function () {
13929
14420
  enumerable: false,
13930
14421
  configurable: true
13931
14422
  });
13932
- VisualizerBase.prototype.createVisualizer = function (question, options) {
14423
+ VisualizerBase.prototype.createVisualizer = function (question, options, data) {
13933
14424
  var visualizerOptions = Object.assign({}, options || this.options);
13934
14425
  if (visualizerOptions.dataProvider === undefined) {
13935
14426
  visualizerOptions.dataProvider = this.dataProvider;
13936
14427
  }
13937
- return _visualizerFactory__WEBPACK_IMPORTED_MODULE_3__.VisualizerFactory.createVisualizer(question, this.data, visualizerOptions);
14428
+ return _visualizerFactory__WEBPACK_IMPORTED_MODULE_3__.VisualizerFactory.createVisualizer(question, data || this.data, visualizerOptions);
13938
14429
  };
13939
14430
  Object.defineProperty(VisualizerBase.prototype, "footerVisualizer", {
13940
14431
  /**
@@ -14277,6 +14768,15 @@ var VisualizerBase = /** @class */ (function () {
14277
14768
  targetElement.appendChild(this.footerContainer);
14278
14769
  this.renderFooter(this.footerContainer);
14279
14770
  };
14771
+ VisualizerBase.prototype.updateToolbar = function () {
14772
+ var _this = this;
14773
+ if (!!this.toolbarContainer) {
14774
+ PostponeHelper.postpone(function () {
14775
+ _this.destroyToolbar(_this.toolbarContainer);
14776
+ _this.renderToolbar(_this.toolbarContainer);
14777
+ });
14778
+ }
14779
+ };
14280
14780
  VisualizerBase.prototype.updateContent = function () {
14281
14781
  this.destroyContent(this.contentContainer);
14282
14782
  this.renderContent(this.contentContainer);
@@ -16554,6 +17054,8 @@ __webpack_require__.r(__webpack_exports__);
16554
17054
  /* harmony export */ NpsVisualizer: () => (/* reexport safe */ _summary_core__WEBPACK_IMPORTED_MODULE_1__.NpsVisualizer),
16555
17055
  /* harmony export */ NpsVisualizerWidget: () => (/* reexport safe */ _summary_core__WEBPACK_IMPORTED_MODULE_1__.NpsVisualizerWidget),
16556
17056
  /* harmony export */ NumberModel: () => (/* reexport safe */ _summary_core__WEBPACK_IMPORTED_MODULE_1__.NumberModel),
17057
+ /* harmony export */ PivotModel: () => (/* reexport safe */ _summary_core__WEBPACK_IMPORTED_MODULE_1__.PivotModel),
17058
+ /* harmony export */ PivotPlotly: () => (/* reexport safe */ _plotly_index__WEBPACK_IMPORTED_MODULE_0__.PivotPlotly),
16557
17059
  /* harmony export */ PlotlyBoolChartAdapter: () => (/* reexport safe */ _plotly_index__WEBPACK_IMPORTED_MODULE_0__.PlotlyBoolChartAdapter),
16558
17060
  /* harmony export */ PlotlyChartAdapter: () => (/* reexport safe */ _plotly_index__WEBPACK_IMPORTED_MODULE_0__.PlotlyChartAdapter),
16559
17061
  /* harmony export */ PlotlyGaugeAdapter: () => (/* reexport safe */ _plotly_index__WEBPACK_IMPORTED_MODULE_0__.PlotlyGaugeAdapter),