survey-analytics 2.2.2 → 2.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm/shared.mjs +10 -2
- package/fesm/shared.mjs.map +1 -1
- package/fesm/shared2.mjs +748 -262
- package/fesm/shared2.mjs.map +1 -1
- package/fesm/survey.analytics.core.mjs +2 -2
- package/fesm/survey.analytics.mjs +315 -538
- package/fesm/survey.analytics.mjs.map +1 -1
- package/fesm/survey.analytics.tabulator.mjs +1 -1
- package/package.json +8 -8
- package/survey-analytics-tabulator.types/analytics-localization/english.d.ts +2 -0
- package/survey-analytics-tabulator.types/localizationManager.d.ts +2 -0
- package/survey-analytics-tabulator.types/utils/index.d.ts +1 -1
- package/survey-analytics.types/alternativeVizualizersWrapper.d.ts +2 -0
- package/survey-analytics.types/analytics-localization/english.d.ts +2 -0
- package/survey-analytics.types/boolean.d.ts +0 -1
- package/survey-analytics.types/entries/summary.core.d.ts +3 -1
- package/survey-analytics.types/histogram.d.ts +1 -1
- package/survey-analytics.types/localizationManager.d.ts +2 -0
- package/survey-analytics.types/matrix.d.ts +0 -1
- package/survey-analytics.types/pivot.d.ts +64 -0
- package/survey-analytics.types/plotly/chart-adapter.d.ts +13 -0
- package/survey-analytics.types/plotly/index.d.ts +2 -7
- package/survey-analytics.types/plotly/legacy.d.ts +33 -0
- package/survey-analytics.types/plotly/setup.d.ts +5 -3
- package/survey-analytics.types/{plotly/ranking.d.ts → ranking.d.ts} +2 -2
- package/survey-analytics.types/selectBase.d.ts +3 -1
- package/survey-analytics.types/utils/index.d.ts +1 -1
- package/survey-analytics.types/visualizationManager.d.ts +3 -0
- package/survey-analytics.types/visualizerBase.d.ts +13 -1
- package/survey.analytics.core.css +7 -1
- package/survey.analytics.core.css.map +1 -1
- package/survey.analytics.core.js +659 -51
- package/survey.analytics.core.js.map +1 -1
- package/survey.analytics.core.min.css +2 -2
- package/survey.analytics.core.min.js +1 -1
- package/survey.analytics.core.min.js.LICENSE.txt +1 -1
- package/survey.analytics.css +7 -1
- package/survey.analytics.css.map +1 -1
- package/survey.analytics.js +1048 -817
- package/survey.analytics.js.map +1 -1
- package/survey.analytics.min.css +2 -2
- package/survey.analytics.min.js +1 -1
- package/survey.analytics.min.js.LICENSE.txt +1 -1
- package/survey.analytics.tabulator.css +1 -1
- package/survey.analytics.tabulator.js +10 -2
- package/survey.analytics.tabulator.js.map +1 -1
- package/survey.analytics.tabulator.min.css +1 -1
- package/survey.analytics.tabulator.min.js +1 -1
- package/survey.analytics.tabulator.min.js.LICENSE.txt +1 -1
- package/survey-analytics.types/plotly/boolean.d.ts +0 -16
- package/survey-analytics.types/plotly/histogram.d.ts +0 -13
- package/survey-analytics.types/plotly/matrix.d.ts +0 -11
- package/survey-analytics.types/plotly/matrixdropdown-grouped.d.ts +0 -11
- package/survey-analytics.types/plotly/rating.d.ts +0 -20
- package/survey-analytics.types/plotly/selectBase.d.ts +0 -26
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* surveyjs - SurveyJS Dashboard library v2.2.
|
|
2
|
+
* surveyjs - SurveyJS Dashboard library v2.2.4
|
|
3
3
|
* Copyright (c) 2015-2025 Devsoft Baltic OÜ - http://surveyjs.io/
|
|
4
4
|
* License: MIT (http://www.opensource.org/licenses/mit-license.php)
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { Event, ItemValue } from 'survey-core';
|
|
8
|
-
import { l as localization,
|
|
9
|
-
export { s as surveyStrings } from './shared.mjs';
|
|
10
|
-
import { b as VisualizationManager, S as SelectBase,
|
|
11
|
-
export { A as AlternativeVisualizersWrapper, D as DataProvider, n as NpsAdapter, o as NpsVisualizer, m as NpsVisualizerWidget, P as PostponeHelper, l as StatisticsTable, k as StatisticsTableAdapter, j as Text, T as TextTableAdapter, g as VisualizationMatrixDropdown, f as VisualizationMatrixDynamic, c as VisualizationPanel, e as VisualizationPanelDynamic,
|
|
8
|
+
import { l as localization, a as DataHelper } from './shared.mjs';
|
|
9
|
+
export { D as DocumentHelper, s as surveyStrings } from './shared.mjs';
|
|
10
|
+
import { N as NumberModel, b as VisualizationManager, S as SelectBase, d as defaultStatisticsCalculator, B as BooleanModel, H as HistogramModel, M as Matrix, p as PivotModel, R as RankingModel, a as VisualizerBase, _ as __awaiter } from './shared2.mjs';
|
|
11
|
+
export { A as AlternativeVisualizersWrapper, D as DataProvider, n as NpsAdapter, o as NpsVisualizer, m as NpsVisualizerWidget, P as PostponeHelper, l as StatisticsTable, k as StatisticsTableAdapter, j as Text, T as TextTableAdapter, g as VisualizationMatrixDropdown, f as VisualizationMatrixDynamic, c as VisualizationPanel, e as VisualizationPanelDynamic, V as VisualizerFactory, i as WordCloud, W as WordCloudAdapter, h as hideEmptyAnswersInData, t as textHelper } from './shared2.mjs';
|
|
12
12
|
import Plotly from 'plotly.js-dist-min';
|
|
13
13
|
|
|
14
14
|
class PlotlySetup {
|
|
@@ -17,38 +17,44 @@ class PlotlySetup {
|
|
|
17
17
|
}
|
|
18
18
|
static setupPie(model, answersData) {
|
|
19
19
|
let { datasets, labels, colors, texts, seriesLabels, } = answersData;
|
|
20
|
-
let traces = [];
|
|
21
20
|
const hasSeries = seriesLabels.length > 1 || model.question.getType() === "matrix";
|
|
21
|
+
const layoutColumns = 2;
|
|
22
|
+
let traces = [];
|
|
22
23
|
const traceConfig = {
|
|
23
24
|
type: model.chartType,
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
labels: labels,
|
|
26
|
+
customdata: labels,
|
|
27
|
+
text: labels.map((label) => {
|
|
26
28
|
return PlotlySetup.getTruncatedLabel(label, model.labelTruncateLength);
|
|
27
29
|
}),
|
|
28
|
-
hoverinfo: "
|
|
29
|
-
|
|
30
|
-
marker: {},
|
|
30
|
+
hoverinfo: "label+value+percent",
|
|
31
|
+
textposition: "inside",
|
|
31
32
|
};
|
|
32
|
-
traceConfig.hoverinfo = "label+value+percent";
|
|
33
|
-
traceConfig.marker.colors = colors;
|
|
34
|
-
traceConfig.textposition = "inside";
|
|
35
33
|
if (model.chartType === "doughnut") {
|
|
36
34
|
traceConfig.type = "pie";
|
|
37
35
|
traceConfig.hole = 0.4;
|
|
38
36
|
}
|
|
39
37
|
if (!hasSeries) {
|
|
38
|
+
traceConfig.mode = "markers",
|
|
39
|
+
traceConfig.marker = { color: colors };
|
|
40
40
|
traceConfig.marker.symbol = "circle";
|
|
41
41
|
traceConfig.marker.size = 16;
|
|
42
42
|
}
|
|
43
43
|
datasets.forEach((dataset, index) => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
const isNotEmpty = dataset.some((value) => value != 0);
|
|
45
|
+
if (isNotEmpty) {
|
|
46
|
+
traces.push(Object.assign({}, traceConfig, {
|
|
47
|
+
values: dataset,
|
|
48
|
+
domain: {
|
|
49
|
+
column: traces.length % layoutColumns,
|
|
50
|
+
row: Math.floor(traces.length / layoutColumns),
|
|
51
|
+
},
|
|
52
|
+
title: { position: "bottom center", text: seriesLabels[index] }
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
49
55
|
});
|
|
50
56
|
const radius = labels.length < 10 ? labels.length * 50 + 100 : 550;
|
|
51
|
-
const height = radius * Math.
|
|
57
|
+
const height = (radius + 25) * Math.ceil(traces.length / layoutColumns);
|
|
52
58
|
const layout = {
|
|
53
59
|
font: {
|
|
54
60
|
family: "Segoe UI, sans-serif",
|
|
@@ -71,21 +77,7 @@ class PlotlySetup {
|
|
|
71
77
|
};
|
|
72
78
|
if (hasSeries) {
|
|
73
79
|
layout.annotations = [];
|
|
74
|
-
|
|
75
|
-
traces[index].title = { position: "bottom center", text: label };
|
|
76
|
-
});
|
|
77
|
-
traces = traces.filter(t => !(t.values.length === 1 && t.values[0] === 0));
|
|
78
|
-
traces.forEach((label, index) => {
|
|
79
|
-
traces[index].domain = {
|
|
80
|
-
column: index % 2,
|
|
81
|
-
row: Math.floor(index / 2),
|
|
82
|
-
};
|
|
83
|
-
});
|
|
84
|
-
layout.grid = {
|
|
85
|
-
rows: Math.round(traces.length / 2),
|
|
86
|
-
columns: 2,
|
|
87
|
-
};
|
|
88
|
-
layout.height = radius * Math.round(traces.length / 2) + 25;
|
|
80
|
+
layout.grid = { rows: Math.ceil(traces.length / layoutColumns), columns: layoutColumns };
|
|
89
81
|
}
|
|
90
82
|
return { traces, layout, hasSeries };
|
|
91
83
|
}
|
|
@@ -94,36 +86,45 @@ class PlotlySetup {
|
|
|
94
86
|
let topMargin = 30;
|
|
95
87
|
let bottomMargin = 30;
|
|
96
88
|
let { datasets, labels, colors, texts, seriesLabels, } = answersData;
|
|
97
|
-
const traces = [];
|
|
98
89
|
const hasSeries = seriesLabels.length > 1 || model.question.getType() === "matrix";
|
|
99
|
-
const
|
|
90
|
+
const traces = [];
|
|
100
91
|
const traceConfig = {
|
|
101
|
-
type: model.chartType,
|
|
102
|
-
y:
|
|
103
|
-
|
|
104
|
-
customdata: hasSeries ? seriesLabels : labels,
|
|
92
|
+
type: model.chartType === "line" ? "line" : "bar",
|
|
93
|
+
y: labels,
|
|
94
|
+
customdata: labels,
|
|
105
95
|
hoverinfo: "text",
|
|
106
96
|
orientation: "h",
|
|
107
|
-
mode: "markers",
|
|
108
97
|
textposition: "none",
|
|
109
|
-
width: 0.5,
|
|
110
|
-
bargap: 0.5,
|
|
111
|
-
marker: {},
|
|
112
98
|
};
|
|
113
|
-
|
|
99
|
+
if (!hasSeries) {
|
|
100
|
+
traceConfig.width = 0.5;
|
|
101
|
+
traceConfig.bargap = 0.5;
|
|
102
|
+
traceConfig.mode = "markers",
|
|
103
|
+
traceConfig.marker = { color: colors };
|
|
104
|
+
}
|
|
114
105
|
datasets.forEach((dataset, index) => {
|
|
115
|
-
|
|
106
|
+
const traceName = hasSeries ? seriesLabels[index] : labels[index];
|
|
107
|
+
const percentString = model.showPercentages ? "%" : "";
|
|
108
|
+
const trace = Object.assign({}, traceConfig, {
|
|
116
109
|
x: dataset,
|
|
110
|
+
name: traceName,
|
|
111
|
+
width: hasSeries && model.chartType !== "stackedbar" ? 0.5 / seriesLabels.length : 0.5,
|
|
117
112
|
text: texts[index],
|
|
118
|
-
hovertext:
|
|
119
|
-
|
|
113
|
+
hovertext: labels.map((label, labelIndex) => {
|
|
114
|
+
if (model.showOnlyPercentages) {
|
|
115
|
+
return `${texts[index][labelIndex]}${percentString}`;
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
return hasSeries ? `${traceName} : ${label}, ${texts[index][labelIndex]}${percentString}` : `${texts[index][labelIndex]}${percentString}, ${label}`;
|
|
119
|
+
}
|
|
120
120
|
}),
|
|
121
121
|
});
|
|
122
122
|
if (model.showPercentages) {
|
|
123
123
|
let texttemplate = model.showOnlyPercentages ? "%{text}%" : "%{value} (%{text}%)";
|
|
124
124
|
trace.textposition = "inside";
|
|
125
125
|
trace.texttemplate = texttemplate;
|
|
126
|
-
trace.
|
|
126
|
+
trace.width = hasSeries && model.chartType !== "stackedbar" ? 0.7 / seriesLabels.length : 0.9;
|
|
127
|
+
trace.bargap = hasSeries && model.chartType !== "stackedbar" ? 0.3 / seriesLabels.length : 0.1;
|
|
127
128
|
}
|
|
128
129
|
traces.push(trace);
|
|
129
130
|
});
|
|
@@ -143,60 +144,49 @@ class PlotlySetup {
|
|
|
143
144
|
},
|
|
144
145
|
colorway: colors,
|
|
145
146
|
hovermode: "closest",
|
|
147
|
+
plot_bgcolor: model.backgroundColor,
|
|
148
|
+
paper_bgcolor: model.backgroundColor,
|
|
149
|
+
showlegend: hasSeries,
|
|
150
|
+
barmode: hasSeries && model.chartType == "stackedbar" ? "stack" : "group",
|
|
151
|
+
xaxis: {
|
|
152
|
+
rangemode: "nonnegative",
|
|
153
|
+
automargin: true,
|
|
154
|
+
},
|
|
146
155
|
yaxis: {
|
|
147
156
|
automargin: true,
|
|
148
157
|
type: "category",
|
|
149
158
|
orientation: "h",
|
|
150
159
|
tickmode: "array",
|
|
151
|
-
tickvals:
|
|
152
|
-
ticktext:
|
|
160
|
+
tickvals: labels,
|
|
161
|
+
ticktext: labels.map((label) => {
|
|
153
162
|
return PlotlySetup.getTruncatedLabel(label, model.labelTruncateLength) + " ";
|
|
154
163
|
}),
|
|
155
164
|
},
|
|
156
|
-
xaxis: {
|
|
157
|
-
rangemode: "nonnegative",
|
|
158
|
-
automargin: true,
|
|
159
|
-
// dtick: 1
|
|
160
|
-
},
|
|
161
|
-
plot_bgcolor: model.backgroundColor,
|
|
162
|
-
paper_bgcolor: model.backgroundColor,
|
|
163
|
-
showlegend: false,
|
|
164
165
|
};
|
|
165
|
-
if (hasSeries) {
|
|
166
|
-
layout.
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
(seriesLabels.length + 1) * lineHeight +
|
|
171
|
-
topMargin +
|
|
172
|
-
bottomMargin;
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
layout.height =
|
|
176
|
-
(labels.length + 1) * lineHeight * seriesLabels.length +
|
|
177
|
-
topMargin +
|
|
178
|
-
bottomMargin;
|
|
179
|
-
}
|
|
180
|
-
labels.forEach((label, index) => {
|
|
181
|
-
traces[index].marker.color = undefined;
|
|
182
|
-
traces[index].name = label;
|
|
183
|
-
if (model.chartType === "stackedbar") {
|
|
184
|
-
traces[index].type = "bar";
|
|
185
|
-
traces[index].width = 0.5;
|
|
186
|
-
}
|
|
187
|
-
else {
|
|
188
|
-
traces[index].width =
|
|
189
|
-
(model.showPercentages ? 0.7 : 0.5) / traces.length;
|
|
190
|
-
}
|
|
191
|
-
});
|
|
192
|
-
traces.forEach((trace, traceIndex) => {
|
|
193
|
-
const percentString = model.showPercentages ? "%" : "";
|
|
194
|
-
traces[traceIndex].hovertext = [];
|
|
195
|
-
yFullTexts.forEach((yFullText, yFullTextIndex) => {
|
|
196
|
-
traces[traceIndex].hovertext.push(`${trace.y[yFullTextIndex]} : ${trace.name}, ${trace.text[yFullTextIndex]}${percentString}`);
|
|
197
|
-
});
|
|
198
|
-
});
|
|
166
|
+
if (hasSeries && model.chartType !== "stackedbar") {
|
|
167
|
+
layout.height =
|
|
168
|
+
(labels.length * seriesLabels.length + 1) * lineHeight +
|
|
169
|
+
topMargin +
|
|
170
|
+
bottomMargin;
|
|
199
171
|
}
|
|
172
|
+
// labels.forEach((label, index) => {
|
|
173
|
+
// traces[index].marker.color = undefined;
|
|
174
|
+
// traces[index].name = label;
|
|
175
|
+
// if (model.chartType === "stackedbar") {
|
|
176
|
+
// traces[index].type = "bar";
|
|
177
|
+
// traces[index].width = 0.5;
|
|
178
|
+
// } else {
|
|
179
|
+
// traces[index].width =
|
|
180
|
+
// (model.showPercentages ? 0.7 : 0.5) / traces.length;
|
|
181
|
+
// }
|
|
182
|
+
// });
|
|
183
|
+
// traces.forEach((trace, traceIndex) => {
|
|
184
|
+
// const percentString = model.showPercentages ? "%" : "";
|
|
185
|
+
// traces[traceIndex].hovertext = [];
|
|
186
|
+
// yFullTexts.forEach((yFullText, yFullTextIndex) => {
|
|
187
|
+
// traces[traceIndex].hovertext.push(`${trace.y[yFullTextIndex]} : ${trace.name}, ${trace.text[yFullTextIndex]}${percentString}`);
|
|
188
|
+
// });
|
|
189
|
+
// });
|
|
200
190
|
if (["ar", "fa"].indexOf(localization.currentLocale) !== -1) {
|
|
201
191
|
layout.xaxis.autorange = "reversed";
|
|
202
192
|
layout.yaxis.side = "right";
|
|
@@ -213,9 +203,11 @@ class PlotlySetup {
|
|
|
213
203
|
let topMargin = 30;
|
|
214
204
|
let bottomMargin = 30;
|
|
215
205
|
let { datasets, labels, colors, texts, seriesLabels, } = answersData;
|
|
216
|
-
|
|
206
|
+
const hasSeries = seriesLabels.length > 1 || model.question.getType() === "matrix";
|
|
207
|
+
if (model.type !== "histogram" && model.type !== "pivot") {
|
|
217
208
|
labels = [].concat(labels).reverse();
|
|
218
|
-
|
|
209
|
+
seriesLabels = [].concat(seriesLabels).reverse();
|
|
210
|
+
colors = [].concat(colors.slice(0, hasSeries ? seriesLabels.length : labels.length)).reverse();
|
|
219
211
|
const ts = [];
|
|
220
212
|
texts.forEach(text => {
|
|
221
213
|
ts.push([].concat(text).reverse());
|
|
@@ -228,7 +220,37 @@ class PlotlySetup {
|
|
|
228
220
|
datasets = ds;
|
|
229
221
|
}
|
|
230
222
|
const traces = [];
|
|
231
|
-
const
|
|
223
|
+
const traceConfig = {
|
|
224
|
+
type: model.chartType === "line" ? "line" : "bar",
|
|
225
|
+
x: labels,
|
|
226
|
+
customdata: hasSeries ? seriesLabels : labels,
|
|
227
|
+
hoverinfo: hasSeries ? undefined : "x+y",
|
|
228
|
+
orientation: "v",
|
|
229
|
+
textposition: "none",
|
|
230
|
+
};
|
|
231
|
+
if (model.type === "histogram" || !hasSeries) {
|
|
232
|
+
traceConfig.width = 0.5;
|
|
233
|
+
traceConfig.bargap = 0.5;
|
|
234
|
+
traceConfig.mode = "markers",
|
|
235
|
+
traceConfig.marker = { color: colors };
|
|
236
|
+
}
|
|
237
|
+
datasets.forEach((dataset, index) => {
|
|
238
|
+
var trace = Object.assign({}, traceConfig, {
|
|
239
|
+
y: dataset,
|
|
240
|
+
name: hasSeries ? seriesLabels[index] : labels[index],
|
|
241
|
+
text: texts[index],
|
|
242
|
+
});
|
|
243
|
+
if (model.showPercentages) {
|
|
244
|
+
let texttemplate = model.showOnlyPercentages ? "%{text}%" : "%{value} (%{text}%)";
|
|
245
|
+
trace.textposition = "inside";
|
|
246
|
+
trace.texttemplate = texttemplate;
|
|
247
|
+
if (!hasSeries) {
|
|
248
|
+
trace.width = 0.9;
|
|
249
|
+
trace.bargap = 0.1;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
traces.push(trace);
|
|
253
|
+
});
|
|
232
254
|
const layout = {
|
|
233
255
|
font: {
|
|
234
256
|
family: "Segoe UI, sans-serif",
|
|
@@ -245,34 +267,21 @@ class PlotlySetup {
|
|
|
245
267
|
hovermode: "closest",
|
|
246
268
|
plot_bgcolor: model.backgroundColor,
|
|
247
269
|
paper_bgcolor: model.backgroundColor,
|
|
248
|
-
showlegend:
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
270
|
+
showlegend: hasSeries,
|
|
271
|
+
yaxis: {
|
|
272
|
+
rangemode: "nonnegative",
|
|
273
|
+
automargin: true,
|
|
274
|
+
},
|
|
275
|
+
xaxis: {
|
|
276
|
+
automargin: true,
|
|
277
|
+
type: "category",
|
|
278
|
+
tickmode: "array",
|
|
279
|
+
tickvals: labels,
|
|
280
|
+
ticktext: labels.map((label) => {
|
|
281
|
+
return PlotlySetup.getTruncatedLabel(label, model.labelTruncateLength) + " ";
|
|
282
|
+
}),
|
|
283
|
+
},
|
|
259
284
|
};
|
|
260
|
-
traceConfig.marker.color = colors;
|
|
261
|
-
datasets.forEach((dataset, index) => {
|
|
262
|
-
var trace = Object.assign({}, traceConfig, {
|
|
263
|
-
x: labels,
|
|
264
|
-
y: model.showPercentages ? texts[index].map(y => y / 100) : dataset,
|
|
265
|
-
text: texts[index],
|
|
266
|
-
});
|
|
267
|
-
if (model.showPercentages) {
|
|
268
|
-
let texttemplate = model.showOnlyPercentages ? "%{text}%" : "%{value} (%{text}%)";
|
|
269
|
-
trace.textposition = "inside";
|
|
270
|
-
trace.texttemplate = texttemplate;
|
|
271
|
-
trace.width = 0.9;
|
|
272
|
-
trace.bargap = 0.1;
|
|
273
|
-
}
|
|
274
|
-
traces.push(trace);
|
|
275
|
-
});
|
|
276
285
|
if (model.showPercentages && model.showOnlyPercentages) {
|
|
277
286
|
layout.yaxis = {
|
|
278
287
|
automargin: true,
|
|
@@ -363,6 +372,49 @@ class PlotlySetup {
|
|
|
363
372
|
}
|
|
364
373
|
return { traces, layout, hasSeries };
|
|
365
374
|
}
|
|
375
|
+
static setupGauge(model, answersData) {
|
|
376
|
+
let [level, minValue, maxValue] = answersData;
|
|
377
|
+
if (model.question.getType() === "rating") {
|
|
378
|
+
const rateValues = model.question.visibleRateValues;
|
|
379
|
+
maxValue = rateValues[rateValues.length - 1].value;
|
|
380
|
+
minValue = rateValues[0].value;
|
|
381
|
+
}
|
|
382
|
+
const colors = model.generateColors(maxValue, minValue, NumberModel.stepsCount);
|
|
383
|
+
if (NumberModel.showAsPercentage) {
|
|
384
|
+
level = DataHelper.toPercentage(level, maxValue);
|
|
385
|
+
minValue = DataHelper.toPercentage(minValue, maxValue);
|
|
386
|
+
maxValue = DataHelper.toPercentage(maxValue, maxValue);
|
|
387
|
+
}
|
|
388
|
+
var traces = [
|
|
389
|
+
{
|
|
390
|
+
type: "indicator",
|
|
391
|
+
mode: "gauge+number",
|
|
392
|
+
gauge: {
|
|
393
|
+
axis: { range: [minValue, maxValue] },
|
|
394
|
+
shape: model.chartType,
|
|
395
|
+
bgcolor: "white",
|
|
396
|
+
bar: { color: colors[0] },
|
|
397
|
+
},
|
|
398
|
+
value: level,
|
|
399
|
+
text: model.name,
|
|
400
|
+
domain: { x: [0, 1], y: [0, 1] },
|
|
401
|
+
},
|
|
402
|
+
];
|
|
403
|
+
const chartMargin = model.chartType === "bullet" ? 60 : 30;
|
|
404
|
+
var layout = {
|
|
405
|
+
height: 250,
|
|
406
|
+
margin: {
|
|
407
|
+
l: chartMargin,
|
|
408
|
+
r: chartMargin,
|
|
409
|
+
b: chartMargin,
|
|
410
|
+
t: chartMargin,
|
|
411
|
+
pad: 5
|
|
412
|
+
},
|
|
413
|
+
plot_bgcolor: model.backgroundColor,
|
|
414
|
+
paper_bgcolor: model.backgroundColor,
|
|
415
|
+
};
|
|
416
|
+
return { traces, layout, hasSeries: false };
|
|
417
|
+
}
|
|
366
418
|
}
|
|
367
419
|
PlotlySetup.imageExportFormat = "png";
|
|
368
420
|
/**
|
|
@@ -382,6 +434,8 @@ PlotlySetup.setups = {
|
|
|
382
434
|
doughnut: PlotlySetup.setupPie,
|
|
383
435
|
pie: PlotlySetup.setupPie,
|
|
384
436
|
scatter: PlotlySetup.setupScatter,
|
|
437
|
+
gauge: PlotlySetup.setupGauge,
|
|
438
|
+
bullet: PlotlySetup.setupGauge,
|
|
385
439
|
};
|
|
386
440
|
PlotlySetup.getTruncatedLabel = (label, labelTruncateLength) => {
|
|
387
441
|
const truncateSymbols = "...";
|
|
@@ -395,276 +449,9 @@ PlotlySetup.getTruncatedLabel = (label, labelTruncateLength) => {
|
|
|
395
449
|
return label.substring(0, labelTruncateLength) + truncateSymbols;
|
|
396
450
|
};
|
|
397
451
|
|
|
398
|
-
class PlotlyChartAdapter {
|
|
399
|
-
constructor(model) {
|
|
400
|
-
this.model = model;
|
|
401
|
-
this._chart = undefined;
|
|
402
|
-
}
|
|
403
|
-
patchConfigParameters(chartNode, traces, layout, config) { }
|
|
404
|
-
get chart() {
|
|
405
|
-
return this._chart;
|
|
406
|
-
}
|
|
407
|
-
create(chartNode) {
|
|
408
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
409
|
-
const [plot, plotlyOptions] = yield this.update(chartNode);
|
|
410
|
-
chartNode["on"]("plotly_click", (data) => {
|
|
411
|
-
if (data.points.length > 0) {
|
|
412
|
-
let itemText = "";
|
|
413
|
-
if (!plotlyOptions.hasSeries) {
|
|
414
|
-
itemText = Array.isArray(data.points[0].customdata)
|
|
415
|
-
? data.points[0].customdata[0]
|
|
416
|
-
: data.points[0].customdata;
|
|
417
|
-
const item = this.model.getSelectedItemByText(itemText);
|
|
418
|
-
this.model.setSelection(item);
|
|
419
|
-
}
|
|
420
|
-
else {
|
|
421
|
-
itemText = data.points[0].data.name;
|
|
422
|
-
const propertyLabel = data.points[0].label;
|
|
423
|
-
const seriesValues = this.model.getSeriesValues();
|
|
424
|
-
const seriesLabels = this.model.getSeriesLabels();
|
|
425
|
-
const propertyValue = seriesValues[seriesLabels.indexOf(propertyLabel)];
|
|
426
|
-
const selectedItem = this.model.getSelectedItemByText(itemText);
|
|
427
|
-
const item = new ItemValue({ [propertyValue]: selectedItem.value }, propertyLabel + ": " + selectedItem.text);
|
|
428
|
-
this.model.setSelection(item);
|
|
429
|
-
}
|
|
430
|
-
// const itemText = plotlyOptions.hasSeries
|
|
431
|
-
// ? data.points[0].data.name
|
|
432
|
-
// : Array.isArray(data.points[0].customdata)
|
|
433
|
-
// ? data.points[0].customdata[0]
|
|
434
|
-
// : data.points[0].customdata;
|
|
435
|
-
// const item: ItemValue = this.model.getSelectedItemByText(itemText);
|
|
436
|
-
// this.model.setSelection(item);
|
|
437
|
-
}
|
|
438
|
-
});
|
|
439
|
-
var getDragLayer = () => chartNode.getElementsByClassName("nsewdrag")[0];
|
|
440
|
-
chartNode["on"]("plotly_hover", () => {
|
|
441
|
-
const dragLayer = getDragLayer();
|
|
442
|
-
dragLayer && (dragLayer.style.cursor = "pointer");
|
|
443
|
-
});
|
|
444
|
-
chartNode["on"]("plotly_unhover", () => {
|
|
445
|
-
const dragLayer = getDragLayer();
|
|
446
|
-
dragLayer && (dragLayer.style.cursor = "");
|
|
447
|
-
});
|
|
448
|
-
// setTimeout(() => Plotly.Plots.resize(chartNode), 10);
|
|
449
|
-
this._chart = plot;
|
|
450
|
-
return plot;
|
|
451
|
-
});
|
|
452
|
-
}
|
|
453
|
-
update(chartNode) {
|
|
454
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
455
|
-
const answersData = yield this.model.getAnswersData();
|
|
456
|
-
var plotlyOptions = PlotlySetup.setup(this.model.chartType, this.model, answersData);
|
|
457
|
-
let config = {
|
|
458
|
-
displaylogo: false,
|
|
459
|
-
responsive: true,
|
|
460
|
-
locale: localization.currentLocale,
|
|
461
|
-
modeBarButtonsToRemove: ["toImage"],
|
|
462
|
-
modeBarButtonsToAdd: [
|
|
463
|
-
{
|
|
464
|
-
name: "toImageSjs",
|
|
465
|
-
title: localization.getString("saveDiagramAsPNG"),
|
|
466
|
-
icon: Plotly.Icons.camera,
|
|
467
|
-
click: (gd) => {
|
|
468
|
-
let options = {
|
|
469
|
-
format: PlotlySetup.imageExportFormat,
|
|
470
|
-
// width: 800,
|
|
471
|
-
// height: 600,
|
|
472
|
-
filename: this.model.question.name,
|
|
473
|
-
};
|
|
474
|
-
PlotlySetup.onImageSaving.fire(this.model, options);
|
|
475
|
-
Plotly.downloadImage(gd, options);
|
|
476
|
-
},
|
|
477
|
-
},
|
|
478
|
-
],
|
|
479
|
-
};
|
|
480
|
-
if (SelectBasePlotly.displayModeBar !== undefined) {
|
|
481
|
-
config.displayModeBar = SelectBasePlotly.displayModeBar;
|
|
482
|
-
}
|
|
483
|
-
this.patchConfigParameters(chartNode, plotlyOptions.traces, plotlyOptions.layout, config);
|
|
484
|
-
let options = {
|
|
485
|
-
traces: plotlyOptions.traces,
|
|
486
|
-
layout: plotlyOptions.layout,
|
|
487
|
-
config: config,
|
|
488
|
-
};
|
|
489
|
-
PlotlySetup.onPlotCreating.fire(this.model, options);
|
|
490
|
-
const plot = Plotly.react(chartNode, options.traces, options.layout, options.config);
|
|
491
|
-
return [plot, plotlyOptions];
|
|
492
|
-
});
|
|
493
|
-
}
|
|
494
|
-
destroy(node) {
|
|
495
|
-
if (!!node) {
|
|
496
|
-
Plotly.purge(node);
|
|
497
|
-
}
|
|
498
|
-
this._chart = undefined;
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
class SelectBasePlotly extends SelectBase {
|
|
502
|
-
constructor(question, data, options = {}, name) {
|
|
503
|
-
super(question, data, options, name);
|
|
504
|
-
this.chartTypes = [].concat(SelectBasePlotly.types);
|
|
505
|
-
if (this.getSeriesValues().length > 0 && this.chartTypes.indexOf("stackedbar") === -1) {
|
|
506
|
-
this.chartTypes.push("stackedbar");
|
|
507
|
-
}
|
|
508
|
-
if (options.allowExperimentalFeatures) ;
|
|
509
|
-
this._chartType = this.chartTypes[0];
|
|
510
|
-
if (this.chartTypes.indexOf(options.defaultChartType) !== -1) {
|
|
511
|
-
this._chartType = options.defaultChartType;
|
|
512
|
-
}
|
|
513
|
-
this._chartAdapter = new PlotlyChartAdapter(this);
|
|
514
|
-
}
|
|
515
|
-
destroyContent(container) {
|
|
516
|
-
this._chartAdapter.destroy(container.children[0]);
|
|
517
|
-
super.destroyContent(container);
|
|
518
|
-
}
|
|
519
|
-
renderContentAsync(container) {
|
|
520
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
521
|
-
const chartNode = DocumentHelper.createElement("div");
|
|
522
|
-
container.innerHTML = "";
|
|
523
|
-
container.appendChild(chartNode);
|
|
524
|
-
yield this._chartAdapter.create(chartNode);
|
|
525
|
-
return container;
|
|
526
|
-
});
|
|
527
|
-
}
|
|
528
|
-
updateContent() {
|
|
529
|
-
var _a;
|
|
530
|
-
const chartNode = (_a = this.contentContainer) === null || _a === void 0 ? void 0 : _a.children[0];
|
|
531
|
-
if (chartNode) {
|
|
532
|
-
this._chartAdapter.update(chartNode);
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
getCalculatedValuesCore() {
|
|
536
|
-
const statistics = super.getCalculatedValuesCore();
|
|
537
|
-
const series = this.getSeriesValues();
|
|
538
|
-
const values = this.getValues();
|
|
539
|
-
if (series.length > 1) {
|
|
540
|
-
const preparedData = [];
|
|
541
|
-
values.forEach((val, valueIndex) => {
|
|
542
|
-
const seriesData = series.map((seriesValue, seriesIndex) => statistics[seriesIndex][valueIndex]);
|
|
543
|
-
preparedData.push(seriesData);
|
|
544
|
-
});
|
|
545
|
-
return preparedData;
|
|
546
|
-
}
|
|
547
|
-
return statistics;
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
SelectBasePlotly.types = ["bar", "vbar", "pie", "doughnut"];
|
|
551
|
-
SelectBasePlotly.displayModeBar = undefined;
|
|
552
|
-
VisualizationManager.registerVisualizer("checkbox", SelectBasePlotly);
|
|
553
|
-
VisualizationManager.registerVisualizer("radiogroup", SelectBasePlotly);
|
|
554
|
-
VisualizationManager.registerVisualizer("dropdown", SelectBasePlotly);
|
|
555
|
-
VisualizationManager.registerVisualizer("imagepicker", SelectBasePlotly);
|
|
556
|
-
VisualizationManager.registerVisualizer("tagbox", SelectBasePlotly);
|
|
557
|
-
|
|
558
|
-
class MatrixPlotly extends Matrix {
|
|
559
|
-
constructor(question, data, options, name) {
|
|
560
|
-
super(question, data, options, name);
|
|
561
|
-
this.chartTypes = MatrixPlotly.types;
|
|
562
|
-
this._chartType = this.chartTypes[0];
|
|
563
|
-
this._chartAdapter = new PlotlyChartAdapter(this);
|
|
564
|
-
}
|
|
565
|
-
destroyContent(container) {
|
|
566
|
-
this._chartAdapter.destroy(container.children[0]);
|
|
567
|
-
super.destroyContent(container);
|
|
568
|
-
}
|
|
569
|
-
renderContentAsync(container) {
|
|
570
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
571
|
-
const chartNode = DocumentHelper.createElement("div");
|
|
572
|
-
container.innerHTML = "";
|
|
573
|
-
container.appendChild(chartNode);
|
|
574
|
-
yield this._chartAdapter.create(chartNode);
|
|
575
|
-
return container;
|
|
576
|
-
});
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
MatrixPlotly.types = ["bar", "stackedbar", "pie", "doughnut"];
|
|
580
|
-
VisualizationManager.registerVisualizer("matrix", MatrixPlotly);
|
|
581
|
-
|
|
582
|
-
class PlotlyBoolChartAdapter extends PlotlyChartAdapter {
|
|
583
|
-
constructor(model) {
|
|
584
|
-
super(model);
|
|
585
|
-
}
|
|
586
|
-
patchConfigParameters(chartNode, traces, layout, config) {
|
|
587
|
-
const colors = this.model.getColors();
|
|
588
|
-
const boolColors = [
|
|
589
|
-
BooleanPlotly.trueColor || colors[0],
|
|
590
|
-
BooleanPlotly.falseColor || colors[1],
|
|
591
|
-
];
|
|
592
|
-
if (this.model.showMissingAnswers) {
|
|
593
|
-
boolColors.push(colors[2]);
|
|
594
|
-
}
|
|
595
|
-
if (this.model.chartType === "pie" || this.model.chartType === "doughnut") {
|
|
596
|
-
traces.forEach((trace) => {
|
|
597
|
-
trace.marker.colors = boolColors;
|
|
598
|
-
});
|
|
599
|
-
}
|
|
600
|
-
else if (this.model.chartType === "bar") {
|
|
601
|
-
traces.forEach((trace) => {
|
|
602
|
-
trace.marker.color = boolColors;
|
|
603
|
-
});
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
class BooleanPlotly extends BooleanModel {
|
|
608
|
-
constructor(question, data, options, name) {
|
|
609
|
-
super(question, data, options, name);
|
|
610
|
-
this.chartTypes = BooleanPlotly.types;
|
|
611
|
-
this._chartType = this.chartTypes[0];
|
|
612
|
-
this._chartAdapter = new PlotlyBoolChartAdapter(this);
|
|
613
|
-
}
|
|
614
|
-
destroyContent(container) {
|
|
615
|
-
this._chartAdapter.destroy(container.children[0]);
|
|
616
|
-
super.destroyContent(container);
|
|
617
|
-
}
|
|
618
|
-
renderContentAsync(container) {
|
|
619
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
620
|
-
const chartNode = DocumentHelper.createElement("div");
|
|
621
|
-
yield this._chartAdapter.create(chartNode);
|
|
622
|
-
container.innerHTML = "";
|
|
623
|
-
container.appendChild(chartNode);
|
|
624
|
-
return container;
|
|
625
|
-
});
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
BooleanPlotly.types = ["pie", "bar", "doughnut"];
|
|
629
|
-
VisualizationManager.registerVisualizer("boolean", BooleanPlotly);
|
|
630
|
-
|
|
631
|
-
class RankingPlotly extends SelectBasePlotly {
|
|
632
|
-
getQuestionResults() {
|
|
633
|
-
const name = this.question.name;
|
|
634
|
-
return this.data.map((dataItem) => dataItem[name]);
|
|
635
|
-
}
|
|
636
|
-
getEmptyData() {
|
|
637
|
-
const choices = this.getValues();
|
|
638
|
-
let data = [];
|
|
639
|
-
data.length = choices.length;
|
|
640
|
-
data.fill(0);
|
|
641
|
-
return data;
|
|
642
|
-
}
|
|
643
|
-
getCalculatedValuesCore() {
|
|
644
|
-
const results = this.getQuestionResults();
|
|
645
|
-
const choices = this.getValues();
|
|
646
|
-
let plotlyData = this.getEmptyData();
|
|
647
|
-
results.forEach((result) => {
|
|
648
|
-
this.applyResultToPlotlyData(result, plotlyData, choices);
|
|
649
|
-
});
|
|
650
|
-
return [plotlyData];
|
|
651
|
-
}
|
|
652
|
-
applyResultToPlotlyData(result, plotlyData, choices) {
|
|
653
|
-
if (!result || !plotlyData || !choices)
|
|
654
|
-
return;
|
|
655
|
-
result.forEach((resultValue, resultValueIndex, result) => {
|
|
656
|
-
let index = choices.indexOf(resultValue);
|
|
657
|
-
plotlyData[index] =
|
|
658
|
-
+plotlyData[index] + (result.length - resultValueIndex);
|
|
659
|
-
});
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
VisualizationManager.registerVisualizer("ranking", RankingPlotly);
|
|
663
|
-
|
|
664
452
|
class MatrixDropdownGrouped extends SelectBase {
|
|
665
453
|
constructor(question, data, options, name) {
|
|
666
454
|
super(question, data, options, name || "matrixDropdownGrouped");
|
|
667
|
-
// this.getAnswersData();
|
|
668
455
|
}
|
|
669
456
|
get matrixQuestion() {
|
|
670
457
|
return this.question;
|
|
@@ -701,138 +488,153 @@ class MatrixDropdownGrouped extends SelectBase {
|
|
|
701
488
|
getSeriesValues: () => rows,
|
|
702
489
|
getSeriesLabels: () => rows,
|
|
703
490
|
});
|
|
704
|
-
|
|
705
|
-
values.forEach((val, valueIndex) => {
|
|
706
|
-
const seriesData = series.map((seriesName, seriesIndex) => statistics[seriesIndex][0][valueIndex]);
|
|
707
|
-
preparedData.push(seriesData);
|
|
708
|
-
});
|
|
709
|
-
return preparedData;
|
|
491
|
+
return statistics.map(s => s[0]);
|
|
710
492
|
}
|
|
711
493
|
}
|
|
494
|
+
VisualizationManager.registerVisualizer("matrixdropdown-grouped", MatrixDropdownGrouped);
|
|
712
495
|
|
|
713
|
-
class
|
|
714
|
-
constructor(question, data, options, name) {
|
|
715
|
-
super(question, data, options, name);
|
|
716
|
-
this.chartTypes = MatrixDropdownGroupedPlotly.types;
|
|
717
|
-
this._chartType = this.chartTypes[0];
|
|
718
|
-
this._chartAdapter = new PlotlyChartAdapter(this);
|
|
719
|
-
}
|
|
720
|
-
destroyContent(container) {
|
|
721
|
-
this._chartAdapter.destroy(container.children[0]);
|
|
722
|
-
super.destroyContent(container);
|
|
723
|
-
}
|
|
724
|
-
renderContentAsync(container) {
|
|
725
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
726
|
-
const chartNode = DocumentHelper.createElement("div");
|
|
727
|
-
container.innerHTML = "";
|
|
728
|
-
container.appendChild(chartNode);
|
|
729
|
-
yield this._chartAdapter.create(chartNode);
|
|
730
|
-
return container;
|
|
731
|
-
});
|
|
732
|
-
}
|
|
496
|
+
class SelectBasePlotly extends SelectBase {
|
|
733
497
|
}
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
498
|
+
SelectBasePlotly.types = ["bar", "vbar", "pie", "doughnut"];
|
|
499
|
+
SelectBasePlotly.displayModeBar = undefined;
|
|
500
|
+
class BooleanPlotly extends BooleanModel {
|
|
501
|
+
}
|
|
502
|
+
BooleanPlotly.types = ["pie", "bar", "doughnut"];
|
|
737
503
|
class HistogramPlotly extends HistogramModel {
|
|
738
|
-
constructor(question, data, options, name) {
|
|
739
|
-
super(question, data, options, name);
|
|
740
|
-
this.chartTypes = HistogramPlotly.types;
|
|
741
|
-
this._chartType = this.chartTypes[0];
|
|
742
|
-
this._chartAdapter = new PlotlyChartAdapter(this);
|
|
743
|
-
}
|
|
744
|
-
destroyContent(container) {
|
|
745
|
-
this._chartAdapter.destroy(container.children[0]);
|
|
746
|
-
super.destroyContent(container);
|
|
747
|
-
}
|
|
748
|
-
renderContentAsync(container) {
|
|
749
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
750
|
-
const chartNode = DocumentHelper.createElement("div");
|
|
751
|
-
container.innerHTML = "";
|
|
752
|
-
container.appendChild(chartNode);
|
|
753
|
-
yield this._chartAdapter.create(chartNode);
|
|
754
|
-
return container;
|
|
755
|
-
});
|
|
756
|
-
}
|
|
757
|
-
getCalculatedValuesCore() {
|
|
758
|
-
const statistics = super.getCalculatedValuesCore();
|
|
759
|
-
const series = this.getSeriesValues();
|
|
760
|
-
const values = this.getValues();
|
|
761
|
-
if (series.length > 1) {
|
|
762
|
-
const preparedData = [];
|
|
763
|
-
values.forEach((val, valueIndex) => {
|
|
764
|
-
const seriesData = series.map((seriesValue, seriesIndex) => statistics[seriesIndex][valueIndex]);
|
|
765
|
-
preparedData.push(seriesData);
|
|
766
|
-
});
|
|
767
|
-
return preparedData;
|
|
768
|
-
}
|
|
769
|
-
return statistics;
|
|
770
|
-
}
|
|
771
|
-
getValueType() {
|
|
772
|
-
return this.valueType;
|
|
773
|
-
}
|
|
774
504
|
}
|
|
775
505
|
HistogramPlotly.types = ["vbar", "bar"];
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
506
|
+
class MatrixPlotly extends Matrix {
|
|
507
|
+
}
|
|
508
|
+
MatrixPlotly.types = ["bar", "stackedbar", "pie", "doughnut"];
|
|
509
|
+
class MatrixDropdownGroupedPlotly extends MatrixDropdownGrouped {
|
|
510
|
+
}
|
|
511
|
+
MatrixDropdownGroupedPlotly.types = ["stackedbar", "bar", "pie", "doughnut"];
|
|
512
|
+
class PivotPlotly extends PivotModel {
|
|
513
|
+
}
|
|
514
|
+
PivotPlotly.types = ["vbar", "bar", "line", "stackedbar", "pie", "doughnut"]; // ["vbar", "bar"];
|
|
515
|
+
class GaugePlotly extends NumberModel {
|
|
516
|
+
}
|
|
517
|
+
GaugePlotly.displayModeBar = undefined;
|
|
518
|
+
GaugePlotly.types = ["gauge", "bullet"];
|
|
519
|
+
class RankingPlotly extends RankingModel {
|
|
520
|
+
}
|
|
779
521
|
|
|
780
|
-
class
|
|
522
|
+
class PlotlyChartAdapter {
|
|
781
523
|
constructor(model) {
|
|
782
524
|
this.model = model;
|
|
783
525
|
this._chart = undefined;
|
|
784
526
|
}
|
|
527
|
+
patchConfigParameters(chartNode, traces, layout, config) {
|
|
528
|
+
if (this.model.question.getType() === "boolean") {
|
|
529
|
+
const colors = this.model.getColors();
|
|
530
|
+
const boolColors = [
|
|
531
|
+
BooleanModel.trueColor || colors[0],
|
|
532
|
+
BooleanModel.falseColor || colors[1],
|
|
533
|
+
];
|
|
534
|
+
if (this.model.showMissingAnswers) {
|
|
535
|
+
boolColors.push(colors[2]);
|
|
536
|
+
}
|
|
537
|
+
const chartType = this.model.chartType;
|
|
538
|
+
if (chartType === "pie" || chartType === "doughnut") {
|
|
539
|
+
traces.forEach((trace) => {
|
|
540
|
+
trace.marker.colors = boolColors;
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
else if (chartType === "bar") {
|
|
544
|
+
traces.forEach((trace) => {
|
|
545
|
+
trace.marker.color = boolColors;
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
if (this.model.type === "number") {
|
|
550
|
+
config.displayModeBar = true;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
785
553
|
get chart() {
|
|
786
554
|
return this._chart;
|
|
787
555
|
}
|
|
556
|
+
getChartTypes() {
|
|
557
|
+
const visualizerType = this.model.type;
|
|
558
|
+
if (visualizerType === "boolean") {
|
|
559
|
+
return BooleanPlotly.types;
|
|
560
|
+
}
|
|
561
|
+
else if (visualizerType === "number") {
|
|
562
|
+
return GaugePlotly.types;
|
|
563
|
+
}
|
|
564
|
+
else if (visualizerType === "selectBase") {
|
|
565
|
+
return SelectBasePlotly.types;
|
|
566
|
+
}
|
|
567
|
+
else if (visualizerType === "histogram") {
|
|
568
|
+
return HistogramPlotly.types;
|
|
569
|
+
}
|
|
570
|
+
else if (visualizerType === "matrix") {
|
|
571
|
+
return MatrixPlotly.types;
|
|
572
|
+
}
|
|
573
|
+
else if (visualizerType === "matrixDropdownGrouped") {
|
|
574
|
+
return MatrixDropdownGroupedPlotly.types;
|
|
575
|
+
}
|
|
576
|
+
else if (visualizerType === "pivot") {
|
|
577
|
+
return PivotPlotly.types;
|
|
578
|
+
}
|
|
579
|
+
return [];
|
|
580
|
+
}
|
|
788
581
|
create(chartNode) {
|
|
789
582
|
return __awaiter(this, void 0, void 0, function* () {
|
|
790
|
-
const
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
583
|
+
const [plot, plotlyOptions] = yield this.update(chartNode);
|
|
584
|
+
if (this.model instanceof SelectBase) {
|
|
585
|
+
const _model = this.model;
|
|
586
|
+
chartNode["on"]("plotly_click", (data) => {
|
|
587
|
+
if (data.points.length > 0) {
|
|
588
|
+
let itemText = "";
|
|
589
|
+
if (!plotlyOptions.hasSeries) {
|
|
590
|
+
itemText = Array.isArray(data.points[0].customdata)
|
|
591
|
+
? data.points[0].customdata[0]
|
|
592
|
+
: data.points[0].customdata;
|
|
593
|
+
const item = _model.getSelectedItemByText(itemText);
|
|
594
|
+
_model.setSelection(item);
|
|
595
|
+
}
|
|
596
|
+
else {
|
|
597
|
+
itemText = data.points[0].data.name;
|
|
598
|
+
const propertyLabel = data.points[0].label;
|
|
599
|
+
const seriesValues = this.model.getSeriesValues();
|
|
600
|
+
const seriesLabels = this.model.getSeriesLabels();
|
|
601
|
+
const propertyValue = seriesValues[seriesLabels.indexOf(propertyLabel)];
|
|
602
|
+
const selectedItem = _model.getSelectedItemByText(itemText);
|
|
603
|
+
const item = new ItemValue({ [propertyValue]: selectedItem.value }, propertyLabel + ": " + selectedItem.text);
|
|
604
|
+
_model.setSelection(item);
|
|
605
|
+
}
|
|
606
|
+
// const itemText = plotlyOptions.hasSeries
|
|
607
|
+
// ? data.points[0].data.name
|
|
608
|
+
// : Array.isArray(data.points[0].customdata)
|
|
609
|
+
// ? data.points[0].customdata[0]
|
|
610
|
+
// : data.points[0].customdata;
|
|
611
|
+
// const item: ItemValue = this.model.getSelectedItemByText(itemText);
|
|
612
|
+
// this.model.setSelection(item);
|
|
613
|
+
}
|
|
614
|
+
});
|
|
802
615
|
}
|
|
803
|
-
var
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
l: chartMargin,
|
|
823
|
-
r: chartMargin,
|
|
824
|
-
b: chartMargin,
|
|
825
|
-
t: chartMargin,
|
|
826
|
-
pad: 5
|
|
827
|
-
},
|
|
828
|
-
plot_bgcolor: this.model.backgroundColor,
|
|
829
|
-
paper_bgcolor: this.model.backgroundColor,
|
|
830
|
-
};
|
|
831
|
-
const config = {
|
|
832
|
-
displayModeBar: true,
|
|
833
|
-
locale: localization.currentLocale,
|
|
834
|
-
responsive: true,
|
|
616
|
+
var getDragLayer = () => chartNode.getElementsByClassName("nsewdrag")[0];
|
|
617
|
+
chartNode["on"]("plotly_hover", () => {
|
|
618
|
+
const dragLayer = getDragLayer();
|
|
619
|
+
dragLayer && (dragLayer.style.cursor = "pointer");
|
|
620
|
+
});
|
|
621
|
+
chartNode["on"]("plotly_unhover", () => {
|
|
622
|
+
const dragLayer = getDragLayer();
|
|
623
|
+
dragLayer && (dragLayer.style.cursor = "");
|
|
624
|
+
});
|
|
625
|
+
// setTimeout(() => Plotly.Plots.resize(chartNode), 10);
|
|
626
|
+
this._chart = plot;
|
|
627
|
+
return plot;
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
update(chartNode) {
|
|
631
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
632
|
+
const answersData = (this.model instanceof SelectBase) ? yield this.model.getAnswersData() : yield this.model.getCalculatedValues();
|
|
633
|
+
var plotlyOptions = PlotlySetup.setup(this.model.chartType, this.model, answersData);
|
|
634
|
+
let config = {
|
|
835
635
|
displaylogo: false,
|
|
636
|
+
responsive: true,
|
|
637
|
+
locale: localization.currentLocale,
|
|
836
638
|
modeBarButtonsToRemove: ["toImage"],
|
|
837
639
|
modeBarButtonsToAdd: [
|
|
838
640
|
{
|
|
@@ -852,18 +654,18 @@ class PlotlyGaugeAdapter {
|
|
|
852
654
|
},
|
|
853
655
|
],
|
|
854
656
|
};
|
|
855
|
-
if (
|
|
856
|
-
config.displayModeBar =
|
|
657
|
+
if (SelectBasePlotly.displayModeBar !== undefined) {
|
|
658
|
+
config.displayModeBar = SelectBasePlotly.displayModeBar;
|
|
857
659
|
}
|
|
660
|
+
this.patchConfigParameters(chartNode, plotlyOptions.traces, plotlyOptions.layout, config);
|
|
858
661
|
let options = {
|
|
859
|
-
|
|
860
|
-
layout: layout,
|
|
662
|
+
traces: plotlyOptions.traces,
|
|
663
|
+
layout: plotlyOptions.layout,
|
|
861
664
|
config: config,
|
|
862
665
|
};
|
|
863
666
|
PlotlySetup.onPlotCreating.fire(this.model, options);
|
|
864
|
-
const plot = Plotly.
|
|
865
|
-
|
|
866
|
-
return plot;
|
|
667
|
+
const plot = Plotly.react(chartNode, options.traces, options.layout, options.config);
|
|
668
|
+
return [plot, plotlyOptions];
|
|
867
669
|
});
|
|
868
670
|
}
|
|
869
671
|
destroy(node) {
|
|
@@ -873,32 +675,7 @@ class PlotlyGaugeAdapter {
|
|
|
873
675
|
this._chart = undefined;
|
|
874
676
|
}
|
|
875
677
|
}
|
|
876
|
-
|
|
877
|
-
constructor(question, data, options, name) {
|
|
878
|
-
super(question, data, options, name);
|
|
879
|
-
this.chartTypes = GaugePlotly.types;
|
|
880
|
-
this.chartType = this.chartTypes[0];
|
|
881
|
-
this._chartAdapter = new PlotlyGaugeAdapter(this);
|
|
882
|
-
}
|
|
883
|
-
destroyContent(container) {
|
|
884
|
-
this._chartAdapter.destroy(container.children[0]);
|
|
885
|
-
super.destroyContent(container);
|
|
886
|
-
}
|
|
887
|
-
renderContentAsync(container) {
|
|
888
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
889
|
-
const chartNode = DocumentHelper.createElement("div");
|
|
890
|
-
container.innerHTML = "";
|
|
891
|
-
container.appendChild(chartNode);
|
|
892
|
-
yield this._chartAdapter.create(chartNode);
|
|
893
|
-
return container;
|
|
894
|
-
});
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
GaugePlotly.displayModeBar = undefined;
|
|
898
|
-
GaugePlotly.types = ["gauge", "bullet"];
|
|
899
|
-
VisualizationManager.registerVisualizer("number", GaugePlotly);
|
|
900
|
-
VisualizationManager.registerVisualizer("rating", GaugePlotly);
|
|
901
|
-
VisualizationManager.registerVisualizer("expression", GaugePlotly);
|
|
678
|
+
VisualizerBase.chartAdapterType = PlotlyChartAdapter;
|
|
902
679
|
|
|
903
|
-
export { BooleanModel, BooleanPlotly,
|
|
680
|
+
export { BooleanModel, BooleanPlotly, GaugePlotly, HistogramModel, HistogramPlotly, Matrix, MatrixDropdownGroupedPlotly, MatrixPlotly, NumberModel, PivotModel, PivotPlotly, PlotlyChartAdapter, PlotlySetup, RankingModel, RankingPlotly, SelectBase, SelectBasePlotly, VisualizationManager, VisualizerBase, defaultStatisticsCalculator, localization };
|
|
904
681
|
//# sourceMappingURL=survey.analytics.mjs.map
|