Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 68 additions & 5 deletions plugins/dashboards/api/parts/dashboards.js
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,7 @@ async function getEventsDataForApp(params, apps, appId, widget) {
var breakdowns = widget.breakdowns;
var events = widget.events || [];
var widgetData = {}, segment;
var limit = 10; // model.getTableData(segment, 10);

switch (visualization) {
case 'time-series':
Expand All @@ -976,6 +977,7 @@ async function getEventsDataForApp(params, apps, appId, widget) {
var event = events[k].replace(appId + separator, "");
var collection = "events" + crypto.createHash('sha1').update(event + appId).digest('hex');
var model = await getEventsModel(params, apps, appId, collection, segment, event, widget);
var metrics = Array.isArray(widget.metrics) && widget.metrics.length ? widget.metrics : ["c", "s", "dur"];

switch (visualization) {
case 'time-series':
Expand All @@ -987,12 +989,9 @@ async function getEventsDataForApp(params, apps, appId, widget) {

break;
case 'bar-chart':
widgetData[event] = model.getBars(segment, 10);

break;
case 'table':
widgetData[event] = model.getTableData(segment, 10);

var segmentationData = await fetchSegmentedEventDataForWidget(params, apps, appId, event, segment, widget, limit, metrics);
widgetData[event] = segmentationData;
break;
default:
break;
Expand Down Expand Up @@ -1235,6 +1234,70 @@ function getEventsModel(params, apps, appId, collection, segment, event, widget)
});
}

/**
* Fetch segmented event data from Drill for events widget
* @param {Object} params - request params
* @param {Object} apps - apps map
* @param {string} appId - application id
* @param {string} event - event key
* @param {string} segment - segment name
* @param {Object} widget - widget definition
* @param {number} limit - max items to fetch
* @param {Array} metrics - metrics to fetch
* @returns {Promise<Array>} segment data
*/
async function fetchSegmentedEventDataForWidget(params, apps, appId, event, segment, widget, limit, metrics) {
if (!segment || segment === toSegment("no-segment")) {
return {
segment: segment,
metrics: metrics,
data: []
};
}
if (!common.drillQueryRunner || typeof common.drillQueryRunner.fetchAggregatedSegmentedEventData === "undefined") {
return {
segment: segment,
metrics: metrics,
data: []
};
}
try {
var timezone = (apps[appId] && apps[appId].timezone) || params.appTimezone || "UTC";
var period = widget.custom_period || params.qstring.period;
var offset = params.qstring && params.qstring.periodOffset ? parseInt(params.qstring.periodOffset) : undefined;
var tsRange = countlyCommon.getPeriodRange(period, timezone, offset);
var segmentationField = segment.indexOf("sg.") === 0 ? segment : "sg." + segment;
var drillRaw = await common.drillQueryRunner.fetchAggregatedSegmentedEventData({
apps: [appId + ""],
events: [event],
ts: tsRange,
segmentation: segmentationField,
limit: limit || 10
});
var drillData = Array.isArray(drillRaw) ? drillRaw : [];
var preparedDrillData = (drillData || []).map((item) => {
var data = Object.assign({}, item);
var segName = data.curr_segment || data._id || "";
data.curr_segment = countlyCommon.decode(segName);
delete data._id;
return data;
});
return {
segment: segment,
metrics: metrics,
data: preparedDrillData
};
}
catch (err) {
log.d("Error while fetching drill fallback data for events widget", err);
return {
segment: segment,
metrics: metrics,
data: []
};
}
}

/**
* Function to get push model
* @param {Object} params - params object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,30 +39,20 @@
return false;
},
getTableData: function() {
this.data = this.data || {};
var data = {"apps": [], dashData: {"data": {}}, "metrics": this.data.metrics, bar_color: this.data.bar_color};
if (this.data && this.data.dashData && this.data.dashData.data) { //Single app
for (var app in this.data.dashData.data) {
for (var event in this.data.dashData.data[app]) {
data.apps.push(app + event);
data.dashData.data[app + event] = this.data.dashData.data[app][event];
var segmentationDataset = this.getSegmentationDataset();
if (segmentationDataset && Array.isArray(segmentationDataset.data)) {
segmentationDataset.data.forEach(function(entry) {
if (typeof entry.dur === "number") {
entry.dur = countlyCommon.formatSecond(entry.dur);
}
}
});
return segmentationDataset.data;
}
return this.calculateTableDataFromWidget(data);
return [];
},
tableStructure: function() {
this.data = this.data || {};
var data = {"apps": [], dashData: {"data": {}}, "metrics": this.data.metrics, bar_color: this.data.bar_color};
if (this.data && this.data.dashData && this.data.dashData.data) { //Single app
for (var app in this.data.dashData.data) {
for (var event in this.data.dashData.data[app]) {
data.apps.push(app + event);
data.dashData.data[app + event] = this.data.dashData.data[app][event];
}
}
}
return this.calculateTableColsFromWidget(data, this.map);
var segmentationDataset = this.getSegmentationDataset();
return segmentationDataset && Array.isArray(segmentationDataset.data) ? this.buildSegmentationTableColumns(segmentationDataset) : [];
},
timelineGraph: function() {
this.data = this.data || {};
Expand Down Expand Up @@ -145,16 +135,8 @@
}
},
stackedBarOptions: function() {
this.data = this.data || {};
var data = {dashData: {"data": {}}, "metrics": this.data.metrics, bar_color: this.data.bar_color};
if (this.data && this.data.dashData && this.data.dashData.data) { //Single app
for (var app in this.data.dashData.data) {
for (var event in this.data.dashData.data[app]) {
data.dashData.data[app + event] = this.data.dashData.data[app][event];
}
}
}
return this.calculateStackedBarOptionsFromWidget(data, this.map);
var segmentationDataset = this.getSegmentationDataset();
return segmentationDataset && Array.isArray(segmentationDataset.data) ? this.buildSegmentationBarOptions(segmentationDataset) : null;
},
number: function() {
var eventsObj = this.calculateNumberFromWidget(this.data);
Expand Down Expand Up @@ -198,6 +180,68 @@
refresh: function() {
this.refreshNotes();
},
formatDuration: function(value) {
return countlyCommon.formatSecond(value || 0);
},
getSegmentationDataset: function() {
if (!this.data || !this.data.dashData || !this.data.dashData.data) {
return null;
}
var appIds = Object.keys(this.data.dashData.data);
if (!appIds.length) {
return null;
}
var firstApp = appIds[0];
var events = Object.keys(this.data.dashData.data[firstApp] || {});
if (!events.length) {
return null;
}
var dataset = this.data.dashData.data[firstApp][events[0]];
if (dataset && Array.isArray(dataset.data)) {
return dataset;
}
return null;
},
buildSegmentationTableColumns: function(dataset) {
dataset = dataset || {};
var metrics = Array.isArray(dataset.metrics) ? dataset.metrics : [];
var columns = [{
prop: "curr_segment",
title: CV.i18n("events.table.segmentation")
}];
for (var i = 0; i < metrics.length; i++) {
var metricKey = metrics[i];
var columnType = metricKey === "dur" ? "duration" : "number";
columns.push({
prop: metricKey,
title: this.map[metricKey] || metricKey,
type: columnType
});
}
return columns;
},
buildSegmentationBarOptions: function(dataset) {
dataset = dataset || {};
var metrics = Array.isArray(dataset.metrics) ? dataset.metrics : [];
var metricKey = metrics.length ? metrics[0] : "c";
var labels = [];
var values = [];
if (Array.isArray(dataset.data)) {
dataset.data.forEach(function(entry) {
labels.push(entry.curr_segment || "");
values.push(entry[metricKey] || 0);
});
}
var series = [{
name: this.map[metricKey] || metricKey,
data: values,
color: this.data.bar_color
}];
return {
xAxis: {data: labels},
series: series
};
},
onWidgetCommand: function(event) {
if (event === 'add' || event === 'manage' || event === 'show') {
this.graphNotesHandleCommand(event);
Expand Down