UNPKG

survey-analytics

Version:

SurveyJS analytics Library.

1 lines 2.05 MB
{"version":3,"file":"shared2.mjs","sources":["../../node_modules/tslib/tslib.es6.js","../../src/dataProvider.ts","../../src/visualizationManager.ts","../../src/visualizerFactory.ts","../../src/statisticCalculators.ts","../../src/visualizerBase.ts","../../src/number.ts","../../src/selectBase.ts","../../src/boolean.ts","../../src/histogram.ts","../../src/matrix.ts","../../src/pivot.ts","../../src/ranking.ts","../../src/alternativeVizualizersWrapper.ts","../../src/filterInfo.ts","../../node_modules/muuri/dist/muuri.js","../../src/layoutEngine.ts","../../src/visualizationPanel.ts","../../src/visualizationPanelDynamic.ts","../../src/visualizationMatrixDynamic.ts","../../src/visualizationMatrixDropdown.ts","../../src/visualizationComposite.ts","../../src/wordcloud/stopwords/english.ts","../../src/wordcloud/stopwords/norwegian.ts","../../src/wordcloud/stopwords/dutch.ts","../../src/wordcloud/stopwords/spanish.ts","../../src/wordcloud/stopwords/index.ts","../../src/wordcloud/widget.ts","../../src/wordcloud/wordcloud.ts","../../src/text.ts","../../src/statistics-table.ts","../../src/nps.ts"],"sourcesContent":["/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\r\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\r\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\r\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n var _, done = false;\r\n for (var i = decorators.length - 1; i >= 0; i--) {\r\n var context = {};\r\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\r\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\r\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\r\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\r\n if (kind === \"accessor\") {\r\n if (result === void 0) continue;\r\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\r\n if (_ = accept(result.get)) descriptor.get = _;\r\n if (_ = accept(result.set)) descriptor.set = _;\r\n if (_ = accept(result.init)) initializers.unshift(_);\r\n }\r\n else if (_ = accept(result)) {\r\n if (kind === \"field\") initializers.unshift(_);\r\n else descriptor[key] = _;\r\n }\r\n }\r\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\r\n done = true;\r\n};\r\n\r\nexport function __runInitializers(thisArg, initializers, value) {\r\n var useValue = arguments.length > 2;\r\n for (var i = 0; i < initializers.length; i++) {\r\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\r\n }\r\n return useValue ? value : void 0;\r\n};\r\n\r\nexport function __propKey(x) {\r\n return typeof x === \"symbol\" ? x : \"\".concat(x);\r\n};\r\n\r\nexport function __setFunctionName(f, name, prefix) {\r\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\r\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\r\n};\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\r\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = Object.create((typeof AsyncIterator === \"function\" ? AsyncIterator : Object).prototype), verb(\"next\"), verb(\"throw\"), verb(\"return\", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }\r\n function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nvar ownKeys = function(o) {\r\n ownKeys = Object.getOwnPropertyNames || function (o) {\r\n var ar = [];\r\n for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;\r\n return ar;\r\n };\r\n return ownKeys(o);\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== \"default\") __createBinding(result, mod, k[i]);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nexport function __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n\r\nexport function __addDisposableResource(env, value, async) {\r\n if (value !== null && value !== void 0) {\r\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\r\n var dispose, inner;\r\n if (async) {\r\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\r\n dispose = value[Symbol.asyncDispose];\r\n }\r\n if (dispose === void 0) {\r\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\r\n dispose = value[Symbol.dispose];\r\n if (async) inner = dispose;\r\n }\r\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\r\n if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };\r\n env.stack.push({ value: value, dispose: dispose, async: async });\r\n }\r\n else if (async) {\r\n env.stack.push({ async: true });\r\n }\r\n return value;\r\n\r\n}\r\n\r\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\r\n var e = new Error(message);\r\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\r\n};\r\n\r\nexport function __disposeResources(env) {\r\n function fail(e) {\r\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\r\n env.hasError = true;\r\n }\r\n var r, s = 0;\r\n function next() {\r\n while (r = env.stack.pop()) {\r\n try {\r\n if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);\r\n if (r.dispose) {\r\n var result = r.dispose.call(r.value);\r\n if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\r\n }\r\n else s |= 1;\r\n }\r\n catch (e) {\r\n fail(e);\r\n }\r\n }\r\n if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\r\n if (env.hasError) throw env.error;\r\n }\r\n return next();\r\n}\r\n\r\nexport function __rewriteRelativeImportExtension(path, preserveJsx) {\r\n if (typeof path === \"string\" && /^\\.\\.?\\//.test(path)) {\r\n return path.replace(/\\.(tsx)$|((?:\\.d)?)((?:\\.[^./]+?)?)\\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {\r\n return tsx ? preserveJsx ? \".jsx\" : \".js\" : d && (!ext || !cm) ? m : (d + ext + \".\" + cm.toLowerCase() + \"js\");\r\n });\r\n }\r\n return path;\r\n}\r\n\r\nexport default {\r\n __extends: __extends,\r\n __assign: __assign,\r\n __rest: __rest,\r\n __decorate: __decorate,\r\n __param: __param,\r\n __esDecorate: __esDecorate,\r\n __runInitializers: __runInitializers,\r\n __propKey: __propKey,\r\n __setFunctionName: __setFunctionName,\r\n __metadata: __metadata,\r\n __awaiter: __awaiter,\r\n __generator: __generator,\r\n __createBinding: __createBinding,\r\n __exportStar: __exportStar,\r\n __values: __values,\r\n __read: __read,\r\n __spread: __spread,\r\n __spreadArrays: __spreadArrays,\r\n __spreadArray: __spreadArray,\r\n __await: __await,\r\n __asyncGenerator: __asyncGenerator,\r\n __asyncDelegator: __asyncDelegator,\r\n __asyncValues: __asyncValues,\r\n __makeTemplateObject: __makeTemplateObject,\r\n __importStar: __importStar,\r\n __importDefault: __importDefault,\r\n __classPrivateFieldGet: __classPrivateFieldGet,\r\n __classPrivateFieldSet: __classPrivateFieldSet,\r\n __classPrivateFieldIn: __classPrivateFieldIn,\r\n __addDisposableResource: __addDisposableResource,\r\n __disposeResources: __disposeResources,\r\n __rewriteRelativeImportExtension: __rewriteRelativeImportExtension,\r\n};\r\n","import { Event } from \"survey-core\";\r\n\r\nexport type SummaryFilter = { field: string, type: string, value: any };\r\nexport type GetDataUsingCallbackFn = (params: { visualizer: any, filter?: Array<SummaryFilter>, callback?: (response: { data: Array<Object>, error?: any }) => void }) => void;\r\nexport type GetDataUsingPromiseFn = (params: { visualizer: any, filter?: Array<SummaryFilter> }) => Promise<Array<Object>>;\r\nexport type GetDataFn = GetDataUsingCallbackFn | GetDataUsingPromiseFn;\r\n\r\nexport class DataProvider {\r\n public static seriesMarkerKey = \"__sa_series_name\";\r\n\r\n private _filteredData: Array<{ [index: string]: any }>;\r\n protected filterValues: { [index: string]: any } = {};\r\n\r\n constructor(private _data: Array<any> | GetDataFn = []) {\r\n }\r\n\r\n public get data(): Array<any> {\r\n if(Array.isArray(this._data)) {\r\n return this._data;\r\n }\r\n return undefined;\r\n }\r\n public set data(data: Array<any> | GetDataFn) {\r\n if(Array.isArray(data)) {\r\n this._data = [].concat(data);\r\n } else {\r\n this._data = data;\r\n }\r\n this.raiseDataChanged();\r\n }\r\n public get dataFn(): GetDataFn {\r\n if(typeof this._data === \"function\") {\r\n return this._data;\r\n }\r\n return undefined;\r\n }\r\n\r\n public get filteredData(): Array<any> {\r\n if (this._filteredData === undefined) {\r\n let filterKeys = Object.keys(this.filterValues);\r\n if (filterKeys.length > 0) {\r\n this._filteredData = this.data.filter((item) => {\r\n return !Object.keys(this.filterValues).some(\r\n (key) => {\r\n const filterValue = this.filterValues[key];\r\n const filterValueType = typeof filterValue;\r\n const questionValue = item[key];\r\n if (Array.isArray(questionValue)) {\r\n if (filterValueType !== \"object\")\r\n return questionValue.indexOf(filterValue) == -1;\r\n }\r\n if (typeof questionValue === \"object\") {\r\n if (filterValueType !== \"object\")\r\n return true;\r\n return !questionContainsValue(questionValue, filterValue);\r\n }\r\n const seriesValue = item[DataProvider.seriesMarkerKey];\r\n if (!!seriesValue && filterValueType === \"object\") {\r\n return questionValue !== filterValue[seriesValue];\r\n }\r\n if (filterValueType === \"object\" && filterValue.start !== undefined && filterValue.end !== undefined) {\r\n let continioiusValue = typeof questionValue === \"number\" ? questionValue : Date.parse(questionValue);\r\n if (isNaN(continioiusValue)) {\r\n continioiusValue = parseFloat(questionValue);\r\n if (isNaN(continioiusValue)) {\r\n return true;\r\n }\r\n }\r\n return continioiusValue < filterValue.start || continioiusValue >= filterValue.end;\r\n }\r\n return item[key] !== this.filterValues[key];\r\n }\r\n );\r\n });\r\n } else {\r\n this._filteredData = this.data;\r\n }\r\n }\r\n return this._filteredData;\r\n }\r\n\r\n /**\r\n * Sets filter by question name and value.\r\n */\r\n public setFilter(questionName: string, selectedValue: any): void {\r\n var filterChanged = true;\r\n if (selectedValue !== undefined) {\r\n filterChanged = this.filterValues[questionName] !== selectedValue;\r\n this.filterValues[questionName] = selectedValue;\r\n } else {\r\n filterChanged = this.filterValues[questionName] !== undefined;\r\n delete this.filterValues[questionName];\r\n }\r\n if (filterChanged) {\r\n this.raiseDataChanged();\r\n }\r\n }\r\n\r\n /**\r\n * Fires when data has been changed.\r\n */\r\n public onDataChanged = new Event<\r\n (sender: DataProvider, options: any) => any,\r\n DataProvider,\r\n any\r\n >();\r\n\r\n public raiseDataChanged(questionName?: string): void {\r\n this._filteredData = undefined;\r\n if (!this.onDataChanged.isEmpty) {\r\n this.onDataChanged.fire(this, { questionName });\r\n }\r\n }\r\n\r\n public getFilters(): SummaryFilter[] {\r\n return Object.keys(this.filterValues).map(key => ({ field: key, type: \"=\", value: this.filterValues[key] }));\r\n }\r\n\r\n}\r\n\r\nfunction questionContainsValue(questionValue: any, filterValue: any) {\r\n const questionValueKeys = Object.keys(questionValue);\r\n const filterValueKeys = Object.keys(filterValue);\r\n\r\n if (filterValueKeys.length > questionValueKeys.length) return false;\r\n\r\n for (var key of filterValueKeys) {\r\n if (filterValue[key] != questionValue[key]) return false;\r\n }\r\n\r\n return true;\r\n}\r\n","import { Question } from \"survey-core\";\n\ndeclare type VisualizerConstructor = new (\n question: Question,\n data: Array<{ [index: string]: any }>,\n options?: Object\n) => any;\n\n/**\n * An object with methods used to register and unregister visualizers for individual question types.\n *\n * [View Demo](https://surveyjs.io/dashboard/examples/custom-survey-data-visualizer/ (linkStyle))\n */\nexport class VisualizationManager {\n static defaultVisualizer: any = undefined;\n static alternativesVisualizer: any = undefined;\n static pivotVisualizer: any = undefined;\n static vizualizers: { [index: string]: Array<{ ctor: VisualizerConstructor, index: number }> } = {};\n /**\n * Registers a visualizer for a specified question type.\n *\n * [View Demo](https://surveyjs.io/dashboard/examples/custom-survey-data-visualizer/ (linkStyle))\n * @param questionType A question [type](https://surveyjs.io/form-library/documentation/api-reference/question#getType).\n * @param constructor A function that returns a visualizer constructor to register.\n * @param index A zero-based index that specifies the visualizer's position in the visualizer list for the specified question type. Pass `0` to insert the visualizer at the beginning of the list and use it by default. If `index` is not specified, the visualizer is added to the end of the list.\n */\n public static registerVisualizer(\n questionType: string,\n constructor: VisualizerConstructor,\n index = Number.MAX_VALUE\n ) {\n let visualizers = VisualizationManager.vizualizers[questionType];\n if (!visualizers) {\n visualizers = [];\n VisualizationManager.vizualizers[questionType] = visualizers;\n }\n visualizers.push({ ctor: constructor, index });\n }\n /**\n * Unregisters a visualizer for a specified question type.\n *\n * [View Demo](https://surveyjs.io/dashboard/examples/visualize-answers-from-text-entry-fields-with-charts/ (linkStyle))\n * @param questionType A question [type](https://surveyjs.io/form-library/documentation/api-reference/question#getType).\n * @param constructor A function that returns a visualizer constructor to unregister.\n */\n public static unregisterVisualizer(questionType: string | undefined, constructor: VisualizerConstructor): void {\n let questionTypes = [questionType];\n if(!questionType) {\n questionTypes = Object.keys(VisualizationManager.vizualizers);\n }\n questionTypes.forEach(qType => {\n if(constructor) {\n let visualizers = VisualizationManager.vizualizers[qType];\n if (!!visualizers) {\n const vDescr = visualizers.filter(v => v.ctor === constructor)[0];\n if(!!vDescr) {\n let index = visualizers.indexOf(vDescr);\n if (index !== -1) {\n visualizers.splice(index, 1);\n }\n }\n }\n } else {\n VisualizationManager.vizualizers[qType] = [];\n }\n });\n }\n /**\n * @deprecated Call the [`unregisterVisualizer()`](https://surveyjs.io/dashboard/documentation/api-reference/visualizationmanager#unregisterVisualizer) method instead.\n * @param constructor A function that returns a visualizer constructor to unregister.\n */\n public static unregisterVisualizerForAll(constructor: VisualizerConstructor): void {\n VisualizationManager.unregisterVisualizer(undefined, constructor);\n }\n /**\n * Returns all visualizer constructors for a specified question type.\n * @param visualizerType A question [type](https://surveyjs.io/form-library/documentation/api-reference/question#getType).\n */\n public static getVisualizersByType(\n visualizerType: string,\n fallbackVisualizerType?: string \n ): VisualizerConstructor[] {\n let vDescrs = VisualizationManager.vizualizers[visualizerType];\n if (!!fallbackVisualizerType && (!vDescrs || vDescrs.length == 0)) {\n vDescrs = VisualizationManager.vizualizers[fallbackVisualizerType];\n }\n if (!vDescrs) {\n if(VisualizationManager.defaultVisualizer.suppressVisualizerStubRendering) {\n return [];\n }\n return [VisualizationManager.defaultVisualizer];\n }\n vDescrs = [].concat(vDescrs);\n vDescrs.sort((v1, v2) => v1.index - v2.index);\n return vDescrs.map(v => v.ctor);\n }\n /**\n * Returns a constructor for an alternative visualizer selector.\n * @see registerAltVisualizerSelector\n */\n public static getAltVisualizerSelector() {\n return VisualizationManager.alternativesVisualizer || VisualizationManager.defaultVisualizer;\n }\n /**\n * Registers an alternative visualizer selector.\n * @param constructor A function that returns a constructor for an alternative visualizer selector.\n */\n public static registerAltVisualizerSelector(constructor: any) {\n VisualizationManager.alternativesVisualizer = constructor;\n }\n public static getPivotVisualizerConstructor() {\n return VisualizationManager.pivotVisualizer || VisualizationManager.defaultVisualizer;\n }\n public static registerPivotVisualizer(constructor: any) {\n VisualizationManager.pivotVisualizer = constructor;\n }\n}\n","import { Question, QuestionCompositeModel, QuestionCustomModel } from \"survey-core\";\nimport { VisualizerBase } from \"./visualizerBase\";\nimport { VisualizationManager } from \"./visualizationManager\";\n\n/**\n * An object that allows you to create individual visualizers without creating a [visualization panel](https://surveyjs.io/dashboard/documentation/api-reference/visualizationpanel).\n */\nexport class VisualizerFactory {\n /**\n * Creates a visualizer for a single question.\n *\n * ```js\n * import { VisualizerFactory } from \"survey-analytics\";\n *\n * const visualizer = new VisualizerFactory.createVisualizer(\n * question,\n * data,\n * options\n * );\n *\n * visualizer.render(\"containerId\")\n * ```\n *\n * If a question has more than one [registered](https://surveyjs.io/dashboard/documentation/api-reference/visualizationmanager#registerVisualizer) visualizer, users can switch between them using a drop-down menu.\n * @param question A question for which to create a visualizer.\n * @param data A data array with survey results to be visualized.\n * @param options An object with any custom properties you need within the visualizer.\n */\n public static createVisualizer(\n question: Question,\n data: Array<{ [index: string]: any }>,\n options?: { [index: string]: any }\n ): VisualizerBase {\n let type = question.getType();\n let creators = [];\n let questionForCreator: Question | Question[] = question;\n let optionsForCreator = Object.assign({}, options);\n\n if (type === \"text\" && (<any>question).inputType) {\n creators = VisualizationManager.getVisualizersByType((<any>question).inputType, type);\n } else {\n let fallbackType = undefined;\n if(question instanceof QuestionCustomModel) {\n fallbackType = question.getDynamicType();\n // questionForCreator = question.contentQuestion;\n } else if(question instanceof QuestionCompositeModel) {\n fallbackType = \"composite\";\n }\n creators = VisualizationManager.getVisualizersByType(type, fallbackType);\n }\n\n var visualizers = creators.map(\n (creator) => new creator(questionForCreator, data, optionsForCreator)\n );\n if (visualizers.length > 1) {\n const alternativesVisualizerConstructor = VisualizationManager.getAltVisualizerSelector();\n let visualizer = new alternativesVisualizerConstructor(\n visualizers,\n questionForCreator,\n data,\n optionsForCreator\n );\n return visualizer;\n }\n return visualizers[0];\n }\n}\n","import { DataProvider } from \"./dataProvider\";\nimport { IDataInfo } from \"./visualizerBase\";\n\nexport function defaultStatisticsCalculator(data: Array<any>, dataInfo: IDataInfo): Array<any> {\n const dataNames = dataInfo.dataNames;\n const statistics: Array<Array<Array<number>>> = [];\n\n const values = dataInfo.getValues();\n const valuesIndex: { [index: string]: number } = {};\n values.forEach((val: any, index: number) => {\n valuesIndex[val] = index;\n });\n const processMissingAnswers = values.indexOf(undefined) !== -1;\n\n const series = dataInfo.getSeriesValues();\n const seriesIndex: { [index: string]: number } = {};\n series.forEach((val: any, index: number) => {\n seriesIndex[val] = index;\n });\n\n const seriesLength = series.length || 1;\n for (var i = 0; i < dataNames.length; ++i) {\n const dataNameStatistics = new Array<Array<number>>();\n for (var j = 0; j < seriesLength; ++j) {\n dataNameStatistics.push(new Array<number>(values.length).fill(0));\n }\n statistics.push(dataNameStatistics);\n }\n const getValueIndex = (val) => {\n if(val !== null && typeof val === \"object\") return valuesIndex[val.value];\n return valuesIndex[val];\n };\n\n data.forEach((row: any) => {\n dataNames.forEach((dataName, index) => {\n const rowValue: any = row[dataName];\n if (rowValue !== undefined || processMissingAnswers) {\n const rowValues = Array.isArray(rowValue) ? rowValue : [rowValue];\n if (series.length > 0) {\n const rowName = row[DataProvider.seriesMarkerKey];\n if (rowName !== undefined) {\n // Series are labelled by seriesMarkerKey in row data\n const seriesNo = seriesIndex[rowName] || 0;\n rowValues.forEach((val) => {\n const valIndex = getValueIndex(val);\n statistics[index][seriesNo][valIndex]++;\n });\n } else {\n // Series are the keys in question value (matrix question)\n // TODO: think about the de-normalization and combine with the previous case\n rowValues.forEach((val) => {\n series.forEach((seriesName) => {\n if (val[seriesName] !== undefined) {\n const seriesNo = seriesIndex[seriesName] || 0;\n const values = Array.isArray(val[seriesName]) ? val[seriesName] : [val[seriesName]];\n values.forEach(value => {\n const valIndex = getValueIndex(value);\n statistics[index][seriesNo][valIndex]++;\n });\n }\n });\n });\n }\n } else {\n // No series\n rowValues.forEach((val) => {\n const valIndex = getValueIndex(val);\n statistics[0][0][valIndex]++;\n });\n }\n }\n });\n });\n\n return dataInfo.dataNames.length > 1 ? statistics : statistics[0] as any;\n}\n\nexport function histogramStatisticsCalculator(data: any, intervals: any, seriesValues: Array<string>): Array<any> {\n const statistics: Array<Array<number>> = [];\n if (seriesValues.length === 0) {\n seriesValues.push(\"\");\n }\n for (var i = 0; i < seriesValues.length; ++i) {\n statistics.push(intervals.map(i => 0));\n data[seriesValues[i]].forEach(dataValue => {\n for (let j = 0; j < intervals.length; ++j) {\n if (intervals[j].start <= dataValue && (dataValue < intervals[j].end || j == intervals.length - 1)) {\n statistics[i][j]++;\n break;\n }\n }\n });\n }\n return statistics;\n}\n\nexport function mathStatisticsCalculator(data: Array<any>, dataName: string) {\n let resultMin = Number.MAX_VALUE,\n resultMax = -Number.MAX_VALUE,\n resultAverage = 0;\n let actualAnswerCount = 0;\n\n data.forEach((rowData) => {\n if (rowData[dataName] !== undefined) {\n const questionValue: number = +rowData[dataName];\n actualAnswerCount++;\n resultAverage += questionValue;\n if (resultMin > questionValue) {\n resultMin = questionValue;\n }\n if (resultMax < questionValue) {\n resultMax = questionValue;\n }\n }\n });\n\n if (actualAnswerCount > 0) {\n resultAverage = resultAverage / actualAnswerCount;\n }\n resultAverage = Math.ceil(resultAverage * 100) / 100;\n\n return [resultAverage, resultMin, resultMax];\n}","import { Question, QuestionCommentModel, Event, settings, hasLicense } from \"survey-core\";\nimport { DataProvider, GetDataFn } from \"./dataProvider\";\nimport { VisualizerFactory } from \"./visualizerFactory\";\nimport { VisualizationManager } from \"./visualizationManager\";\nimport { DocumentHelper, createLoadingIndicator } from \"./utils\";\nimport { localization } from \"./localizationManager\";\nimport { defaultStatisticsCalculator } from \"./statisticCalculators\";\n\nimport \"./visualizerBase.scss\";\n\nexport interface IChartAdapter {\n getChartTypes(): string[];\n create(chartNode: HTMLElement): Promise<any>;\n update(chartNode: HTMLElement): Promise<any> ;\n destroy(node: HTMLElement): void;\n}\n\nexport interface IDataInfo {\n name: string; // TODO - remove from this interface\n dataNames: Array<string>;\n getValues(): Array<any>;\n getLabels(): Array<string>;\n getSeriesValues(): Array<string>;\n getSeriesLabels(): Array<string>;\n}\n\ntype ToolbarItemCreators = {\n [name: string]: {\n creator: (toolbar?: HTMLDivElement) => HTMLElement,\n // type: ToolbarItemType,\n order: number,\n // groupIndex: number,\n },\n};\n\nexport class PostponeHelper {\n public static postponeFunction: (fn: () => void, timeout?: number) => any;\n public static postpone(fn: () => void, timeout?: number): any {\n if(PostponeHelper.postponeFunction) {\n return PostponeHelper.postponeFunction(fn, timeout);\n } else {\n return setTimeout(fn, timeout);\n }\n }\n}\n\n/**\n * A base object for all visualizers. Use it to implement a custom visualizer.\n *\n * Constructor parameters:\n *\n * - `question`: [`Question`](https://surveyjs.io/form-library/documentation/api-reference/question)\\\n * A survey question to visualize.\n * - `data`: `Array<any>`\\\n * Survey results.\n * - `options`\\\n * An object with the following properties:\n * - `dataProvider`: `DataProvider`\\\n * A data provider for this visualizer.\n * - `renderContent`: `(contentContainer: HTMLElement, visualizer: VisualizerBase) => void`\\\n * A function that renders the visualizer's HTML markup. Append the markup to `contentContainer`.\n * - `survey`: [`SurveyModel`](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model)\\\n * Pass a `SurveyModel` instance if you want to use locales from the survey JSON schema.\n * - `seriesValues`: `Array<string>`\\\n * Series values used to group data.\n * - `seriesLabels`: `Array<string>`\\\n * Series labels to display. If this property is not set, `seriesValues` are used as labels.\n * - `type`: `string`\\\n * *(Optional)* The visualizer's type.\n *\n * [View Demo](https://surveyjs.io/dashboard/examples/how-to-plot-survey-data-in-custom-bar-chart/ (linkStyle))\n */\nexport class VisualizerBase implements IDataInfo {\n public static haveCommercialLicense: boolean = false;\n public static suppressVisualizerStubRendering: boolean = false;\n public static chartAdapterType: any = undefined;\n\n private _showToolbar = true;\n private _footerVisualizer: VisualizerBase = undefined;\n private _dataProvider: DataProvider = undefined;\n private _getDataCore: (dataInfo: IDataInfo) => number[][] = undefined\n public labelTruncateLength: number = 27;\n protected haveCommercialLicense: boolean = false;\n protected renderResult: HTMLElement = undefined;\n protected toolbarContainer: HTMLElement = undefined;\n protected headerContainer: HTMLElement = undefined;\n protected contentContainer: HTMLElement = undefined;\n protected footerContainer: HTMLElement = undefined;\n protected _supportSelection: boolean = false;\n protected _chartAdapter: IChartAdapter = undefined;\n // public static otherCommentQuestionType = \"comment\"; // TODO: make it configureable - allow choose what kind of question/visualizer will be used for comments/others\n public static otherCommentCollapsed = true;\n protected _footerIsCollapsed: boolean = undefined;\n\n /**\n * An event that is raised after the visualizer's content is rendered.\n *\n * Parameters:\n *\n * - `sender`: `VisualizerBase`\\\n * A `VisualizerBase` instance that raised the event.\n *\n * - `options.htmlElement`: `HTMLElement`\\\n * A page element with the visualizer's content.\n * @see render\n * @see refresh\n **/\n public onAfterRender: Event<\n (sender: VisualizerBase, options: any) => any,\n VisualizerBase,\n any\n > = new Event<(sender: VisualizerBase, options: any) => any, VisualizerBase, any>();\n\n protected afterRender(contentContainer: HTMLElement) {\n this.onAfterRender.fire(this, { htmlElement: contentContainer });\n }\n\n /**\n * An event that is raised after a new locale is set.\n *\n * Parameters:\n *\n * - `sender`: `VisualizerBase`\\\n * A `VisualizerBase` instance that raised the event.\n *\n * - `options.locale`: `string`\\\n * The indentifier of a new locale (for example, \"en\").\n * @see locale\n */\n public onLocaleChanged = new Event<\n (sender: VisualizerBase, options: { locale: string }) => any,\n VisualizerBase,\n any\n >();\n\n // public onStateChanged = new Event<\n // (sender: VisualizationPanel, state: IState) => any,\n // VisualizationPanel,\n // any\n // >();\n /**\n * An event that is raised when the visualizer's state has changed.\n *\n * The state includes selected chart types, chart layout, sorting, filtering, and other customizations that a user has made while using the dashboard. Handle the `onStateChanged` event to save these customizations, for example, in `localStorage` and restore them when the user reloads the page.\n *\n * Parameters:\n *\n * - `sender`: `VisualizerBase`\\\n * A `VisualizerBase` instance that raised the event.\n *\n * - `state`: `any`\\\n * A new state of the visualizer. Includes information about the visualized elements and current locale.\n *\n * [View Demo](https://surveyjs.io/dashboard/examples/save-dashboard-state-to-local-storage/ (linkStyle))\n * @see getState\n * @see setState\n */\n public onStateChanged: Event<\n (sender: VisualizerBase, options: any) => any,\n VisualizerBase,\n any\n > = new Event<(sender: VisualizerBase, options: any) => any, VisualizerBase, any>();\n\n protected stateChanged(name: string, value: any): void {\n if(this._settingState) {\n return;\n }\n this.onStateChanged.fire(this, this.getState());\n }\n\n protected toolbarItemCreators: ToolbarItemCreators = {};\n\n public onGetToolbarItemCreators: () => ToolbarItemCreators;\n\n protected getToolbarItemCreators(): ToolbarItemCreators {\n return Object.assign({}, this.toolbarItemCreators, this.onGetToolbarItemCreators && this.onGetToolbarItemCreators() || {});\n }\n\n constructor(\n public question: Question,\n data: Array<{ [index: string]: any }> | GetDataFn,\n public options: { [index: string]: any } = {},\n private _type?: string\n ) {\n const f = hasLicense;\n this.haveCommercialLicense = (!!f && f(4)) ||\n VisualizerBase.haveCommercialLicense ||\n (typeof options.haveCommercialLicense !== \"undefined\" ? options.haveCommercialLicense : false);\n\n this._getDataCore = this.questionOptions?.getDataCore;\n this._dataProvider = options.dataProvider || new DataProvider(data);\n this._dataProvider.onDataChanged.add(() => this.onDataChanged());\n this.loadingData = !!this._dataProvider.dataFn;\n\n if (typeof options.labelTruncateLength !== \"undefined\") {\n this.labelTruncateLength = options.labelTruncateLength;\n }\n }\n\n protected get questionOptions() {\n return this.options[this.question?.name];\n }\n\n protected onDataChanged(): void {\n this._calculationsCache = undefined;\n this.loadingData = !!this._dataProvider.dataFn;\n this.refresh();\n }\n\n /**\n * Returns the identifier of a visualized question.\n */\n get name(): string {\n return this.question.valueName || this.question.name;\n }\n\n get dataNames(): Array<string> {\n return [this.name];\n }\n\n /**\n * Indicates whether the visualizer displays a header. This property is `true` when a visualized question has a correct answer.\n * @see hasFooter\n */\n get hasHeader(): boolean {\n if (!this.options || !this.options.showCorrectAnswers) {\n return false;\n }\n return !!this.question && !!this.question.correctAnswer;\n }\n\n /**\n * Indicates whether the visualizer displays a footer. This property is `true` when a visualized question has a comment.\n * @see hasHeader\n */\n get hasFooter(): boolean {\n return (\n !!this.question && (this.question.hasComment || this.question.hasOther)\n );\n }\n\n protected createVisualizer<T = VisualizerBase>(question: Question, options?: { [index: string]: any }, data?: any[]): T {\n let visualizerOptions = Object.assign({}, options || this.options);\n if (visualizerOptions.dataProvider === undefined) {\n visualizerOptions.dataProvider = this.dataProvider;\n }\n return VisualizerFactory.createVisualizer(question, data || this.data, visualizerOptions) as T;\n }\n\n /**\n * Allows you to access the footer visualizer. Returns `undefined` if the footer is absent.\n * @see hasFooter\n */\n get footerVisualizer(): VisualizerBase {\n if (!this.hasFooter) {\n return undefined;\n }\n if (!this._footerVisualizer) {\n const question = new QuestionCommentModel(\n this.question.name + (settings || {}).commentPrefix\n );\n question.title = this.processText(this.question.title);\n\n let visualizerOptions = Object.assign({}, this.options);\n visualizerOptions.renderContent = undefined;\n this._footerVisualizer = this.createVisualizer(question, visualizerOptions);\n if(!!this._footerVisualizer) {\n this._footerVisualizer.onUpdate = () => this.invokeOnUpdate();\n }\n }\n return this._footerVisualizer;\n }\n\n /**\n * Indicates whether users can select series points to cross-filter charts. To allow or disallow selection, set the [`allowSelection`](https://surveyjs.io/dashboard/documentation/api-reference/ivisualizationpaneloptions#allowSelection) property of the `IVisualizationPanelOptions` object in the [`VisualizationPanel`](https://surveyjs.io/dashboard/documentation/api-reference/visualizationpanel) constructor.\n */\n public get supportSelection(): boolean {\n return (this.options.allowSelection === undefined ||\n this.options.allowSelection) &&\n this._supportSelection;\n }\n\n public getSeriesValues(): Array<string> {\n return this.options.seriesValues || [];\n }\n\n public getSeriesLabels(): Array<string> {\n return this.options.seriesLabels || this.getSeriesValues();\n }\n\n public getValues(): Array<any> {\n throw new Error(\"Method not implemented.\");\n }\n\n public getLabels(): Array<string> {\n return this.getValues();\n }\n\n /**\n * Registers a function used to create a toolbar item for this visualizer.\n *\n * The following code shows how to add a custom button and drop-down menu to the toolbar:\n *\n * ```js\n * import { VisualizationPanel, DocumentHelper } from \"survey-analytics\";\n *\n * const vizPanel = new VisualizationPanel( ... );\n *\n * // Add a custom button to the toolbar\n * vizPanel.visualizers[0].registerToolbarItem(\"my-toolbar-button\"