UNPKG

survey-analytics

Version:

SurveyJS Dashboard is a UI component for visualizing and analyzing survey data. It interprets the form JSON schema to identify question types and renders collected responses using interactive charts and tables.

222 lines (217 loc) 7.36 kB
/*! * surveyjs - SurveyJS Dashboard library v2.5.2 * Copyright (c) 2015-2025 Devsoft Baltic OÜ - http://surveyjs.io/ * License: MIT (http://www.opensource.org/licenses/mit-license.php) */ function choiceTransformationPipeline(result) { let res = {}; let totalCount = 0; result.forEach(item => { res[item._id] = item.count; totalCount += item.count; }); return { data: res, totalCount: totalCount }; } function numberTransformationPipeline(result) { if (result.length == 0) return { value: 0, minValue: 0, maxValue: 0 }; return { data: { value: result[0].average, minValue: result[0].min, maxValue: result[0].max } }; } function histogramTransformationPipeline(result) { let res = []; let totalCount = 0; result.forEach(item => { res.push(item.count); totalCount += item.count; }); return { data: res, intervals: result, totalCount: totalCount }; } const transformers = { "boolean": choiceTransformationPipeline, "radiogroup": choiceTransformationPipeline, "dropdown": choiceTransformationPipeline, "checkbox": choiceTransformationPipeline, "tagbox": choiceTransformationPipeline, "number": numberTransformationPipeline, "rating": numberTransformationPipeline, "histogram": histogramTransformationPipeline }; function createPipeline(surveyId, questionId, visualizerType, questionType) { const singleChoicePipeline = [ { $match: { postid: surveyId } }, { $project: { value: "$json." + questionId } }, { $match: { value: { $exists: true } } }, { $group: { _id: "$value", count: { $sum: 1 }, } } ]; const multipleChoicePipeline = [ { $match: { postid: surveyId } }, { $project: { value: "$json." + questionId } }, { $match: { value: { $exists: true } } }, { $unwind: "$value" }, { $group: { _id: "$value", count: { $sum: 1 }, } } ]; const numberPipeline = [ { $match: { postid: surveyId } }, { $project: { value: "$json." + questionId } }, { $match: { value: { $exists: true } } }, { $group: { _id: null, count: { $sum: 1 }, average: { $avg: "$value" }, min: { $min: "$value" }, max: { $max: "$value" }, values: { $push: "$value" } } } ]; const histogramPipeline = [ { $match: { postid: surveyId } }, { $project: { value: "$json." + questionId } }, { $match: { value: { $exists: true } } }, { $bucketAuto: { groupBy: "$value", buckets: 10, output: { count: { $sum: 1 }, minValue: { $min: "$value" }, maxValue: { $max: "$value" } } } }, { $project: { _id: 0, start: "$minValue", end: "$maxValue", label: { $concat: [ { $toString: { $round: ["$minValue", 2] } }, " - ", { $toString: { $round: ["$maxValue", 2] } } ] }, count: 1 } } ]; const mongoPipelines = { "boolean": singleChoicePipeline, "radiogroup": singleChoicePipeline, "dropdown": singleChoicePipeline, "checkbox": multipleChoicePipeline, "tagbox": multipleChoicePipeline, "number": numberPipeline, "rating": numberPipeline, "histogram": histogramPipeline }; const pipeline = mongoPipelines[visualizerType] || mongoPipelines[questionType] || []; return pipeline; } class MongoDbAdapter { constructor(db, getId) { this.db = db; this.getId = getId; } create(collectionName, object) { object.id = object.id || this.getId(); return new Promise((resolve, reject) => { this.db.collection(collectionName).insertOne(object) .then((results) => { resolve(object.id); }) .catch((e) => { reject(JSON.stringify(e)); }); }); } retrieve(collectionName, filter) { filter = filter || []; const query = {}; filter.forEach(fi => query[fi.field] = fi.value); return new Promise((resolve, reject) => { this.db.collection(collectionName).find(query).toArray() .then((results) => { resolve(results); }) .catch((e) => { reject(JSON.stringify(e)); }); }); } update(collectionName, object) { return new Promise((resolve, reject) => { this.db.collection(collectionName).updateOne({ id: object.id }, { $set: object }) .then((results) => { resolve(results); }) .catch((e) => { reject(JSON.stringify(e)); }); }); } delete(collectionName, id) { return new Promise((resolve, reject) => { this.db.collection(collectionName).deleteMany({ id: id }) .then((results) => { resolve(results); }) .catch((e) => { reject(JSON.stringify(e)); }); }); } retrievePaginated(collectionName, filter, order, offset, limit) { filter = filter || []; let query = {}; filter.forEach(fi => { if (!!fi.value) { let val = fi.value; query[fi.field] = val; } }); let sort = {}; order.forEach(fi => { sort[fi.field] = fi.value == "desc" ? -1 : 1; }); return new Promise((resolve, reject) => { this.db.collection(collectionName).count(query).then(count => { this.db.collection(collectionName).find(query).sort(sort).skip(offset).limit(limit).toArray() .then((results) => { const result = { data: results, totalCount: count }; resolve(result); }) .catch((e) => { reject(JSON.stringify(e)); }); }); }); } retrieveSummary(collectionName, surveyId, questionId, questionType, visualizerType, filter) { const pipeline = createPipeline(surveyId, questionId, visualizerType, questionType); return new Promise((resolve, reject) => { this.db.collection(collectionName).aggregate(pipeline).toArray() .then((results) => { const transformer = transformers[visualizerType] || transformers[questionType] || (r => r); const result = transformer(results); resolve(result); }) .catch((e) => { reject(JSON.stringify(e)); }); }); } } export { MongoDbAdapter }; //# sourceMappingURL=survey.analytics.mongo.mjs.map