Skip to content

Commit

Permalink
Merge pull request #177 from Flipkart/single-stat-tile
Browse files Browse the repository at this point in the history
Added single stat tile
  • Loading branch information
santanusinha committed Aug 2, 2016
2 parents 151530c + 7ccfaa5 commit 791c248
Show file tree
Hide file tree
Showing 4 changed files with 304 additions and 3 deletions.
101 changes: 98 additions & 3 deletions foxtrot-server/src/main/resources/console/index.htm
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ <h4 class="modal-title" id="addWidgetModalLabel">Add widget</h4>
<option value="histogram">Event Ingestion Histogram</option>
<option value="stacked_bar">Classified Event Ingestion Histogram</option>
<option value="statstrend">Numerical statistics trend view</option>
<option value="stats">Numerical statistics</option>
<option value="fql_table">Table View</option>
<!--<option value="eventbrowser">Event Browser</option>-->
</select>
Expand Down Expand Up @@ -712,7 +713,7 @@ <h4 class="modal-title" id="setupStackedBarChartModalLabel">Setup Stacked Bar Ch
</div>

<div class="form-group">
<label class="col-sm-4 control-label" for="pie_rt"><strong>Field to classify</strong></label>
<label class="col-sm-4 control-label" for="stacked-bar-chart-field"><strong>Field to classify</strong></label>
<div class="col-sm-8">
<select class="selectpicker stacked-bar-chart-field" data-style="btn-warning" id="stacked-bar-chart-field">
</select>
Expand All @@ -736,7 +737,100 @@ <h4 class="modal-title" id="setupStackedBarChartModalLabel">Setup Stacked Bar Ch
</div>
</div>

<!--Stats trend chart-->
<!--Stats-->
<div class="modal fade" id="setupStatsModal" tabindex="-1" role="dialog" aria-labelledby="setupStatsModalLabel" aria-hidden="true">
<div class="modal-dialog">
<form class="form-horizontal settings-form" role="form" data-toggle="validate" data-delay="" id="setupStatsModalForm">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title" id="setupStatsModalLabel">Setup Statistics</h4>
</div>
<div class="modal-body">
<div class="form-group">
<div class="col-sm-12">
<input type="hidden" class="tileId">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label"><strong>Table</strong></label>
<div class="col-sm-8">
<select class="selectpicker tile-table" data-style="btn-warning" required></select>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label"><strong>Title</strong></label>
<div class="col-sm-8">
<input type="text" class="form-control tile-title" placeholder="Give a title" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label"><strong>Time Unit</strong></label>
<div class="col-sm-8">
<select class="selectpicker tile-time-unit">
<option value="minutes" selected="selected">Minute</option>
<option value="hours">Hour</option>
<option value="days">Day</option>
</select>
<div class="help-block with-errors">Select time unit resolution</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label"><strong>Timeframe</strong></label>
<div class="col-sm-8">
<input type="number" min="5" max="10080" class="form-control tile-time-value" required>
<div class="help-block with-errors">Enter a number</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label" for="stats-field"><strong>Field to run statistics on</strong></label>
<div class="col-sm-8">
<select class="selectpicker stats-field" data-style="btn-warning" id="stats-field">
</select>
<div class="help-block with-errors">Select the field from the above list.</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label" for="statistic_to_plot"><strong>Statistic to plot</strong></label>
<div class="col-sm-8">
<select id="statistic_to_plot" class="statistic_to_plot">
<option value=percentiles.1.0>1 percentile</option>
<option value=percentiles.25.0>25 percentile</option>
<option value=percentiles.5.0>5 percentile</option>
<option value=percentiles.50.0>50 percentile</option>
<option value=percentiles.75.0>75 percentile</option>
<option value=percentiles.95.0>95 percentile</option>
<option value=percentiles.99.0>99 percentile</option>
<option value=stats.avg>Average</option>
<option value=stats.count>Count</option>
<option value=stats.max>Max</option>
<option value=stats.min>Min</option>
<option value=stats.std_deviation>Standard Deviation</option>
<option value=stats.sum>Sum</option>
<option value=stats.sum_of_squares>Sum of squares</option>
<option value=stats.variance>Variance</option>
</select>
<div class="help-block with-errors">Select the field from the above list.</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label" for="stats_selected_filters"><strong>Filters</strong></label>
<div class="col-sm-8">
<textarea class="form-control selected-filters" placeholder="JSON string containing the filters" id="stats_selected_filters"></textarea>
<div class="help-block with-errors">Enter a JSON string</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary save-changes" disabled="disabled">Done</button>
</div>
</div>
</form>
</div>
</div>

<!--Stats trend chart-->
<div class="modal fade" id="setupStatsTrendChartModal" tabindex="-1" role="dialog" aria-labelledby="setupStatsTrendChartModalLabel" aria-hidden="true">
<div class="modal-dialog">
<form class="form-horizontal settings-form" role="form" data-toggle="validate" data-delay="" id="setupStatsTrendChartModalForm">
Expand Down Expand Up @@ -784,7 +878,7 @@ <h4 class="modal-title" id="setupStatsTrendChartModalLabel">Setup Stats Trend Ch
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label" for="pie_rt"><strong>Field to run stats on</strong></label>
<label class="col-sm-4 control-label" for="statstrend-bar-chart-field"><strong>Field to run stats on</strong></label>
<div class="col-sm-8">
<select class="selectpicker statstrend-bar-chart-field" data-style="btn-warning" id="statstrend-bar-chart-field">
</select>
Expand Down Expand Up @@ -1000,6 +1094,7 @@ <h4 class="modal-title" id="setupFilterModalLabel">Setup Filters</h4>
<script src="js/tiles/histogram.js"></script>
<script src="js/tiles/eventbrowser-tile.js"></script>
<script src="js/tiles/stacked-bar-tile.js"></script>
<script src="js/tiles/stats-tile.js"></script>
<script src="js/tiles/statstrend-tile.js"></script>
<script src="js/consolemanager.js"></script>
<script src="js/eventsearch.js"></script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ $(document).ready(function(){
$("#setupEventBrowser").validator();
$("#setupStackedBarChartModal").validator();
$("#setupFqlTableModal").validator();
$("#setupStatsModal").validator();
$("#setupStatsTrendChartModal").validator();
$("#saveConsoleModal").validator();
$("#loadConsoleModal").validator();
Expand Down
203 changes: 203 additions & 0 deletions foxtrot-server/src/main/resources/console/js/tiles/stats-tile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
/**
* Copyright 2014 Flipkart Internet Pvt. Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

function Stats() {
this.typeName = "stats";
this.refresh = true;
this.setupModalName = "#setupStatsModal";
//Instance properties
this.statsFieldName = null;
this.periodUnit = "minutes";
this.periodValue = 0;
this.customPeriod = "custom";
this.selectedFilters = null;
this.selectedStat = null;
}

Stats.prototype = new Tile();

Stats.prototype.render = function (data, animate) {
if (this.title) {
$("#" + this.id).find(".tile-header").text(this.title);
} else {
$("#" + this.id).find(".tile-header").text(this.selectedStat + " for " + this.statsFieldName);
}

var parent = $("#content-for-" + this.id);

if (0 != parent.find(".dataview-table").length) {
parent.find(".dataview-table").remove()
}

if (!data.hasOwnProperty("result")) {
return;
}
var result = data.result;
var selected = this.selectedStat;

var value = 0;
if (selected.startsWith('percentiles.')) {
value = result.percentiles[selected.split("percentiles.")[1]].toFixed(2);
}
if (selected.startsWith('stats.')) {
value = result.stats[selected.split("stats.")[1]].toFixed(2);
}


var chartLabel = null;
if (0 == parent.find(".pielabel").length) {
chartLabel = $("<div>", {class: "pielabel"});
parent.append(chartLabel);
}
else {
chartLabel = parent.find(".pielabel");
}
chartLabel.text(value);

var headers = [selected];
var rows = [[value]];
var tableData = {headers: headers, data: rows};
//parent.append(handlebars('#table-template', tableData))
};

Stats.prototype.getQuery = function () {
if (this.isSetupDone()) {
var timestamp = new Date().getTime();
var filters = [];
filters.push(timeValue(this.periodUnit, this.periodValue, this.customPeriod));
if (this.selectedFilters && this.selectedFilters.filters) {
for (var i = 0; i < this.selectedFilters.filters.length; i++) {
filters.push(this.selectedFilters.filters[i]);
}
}
var table = this.table;
if (!table) {
table = this.tables.selectedTable.name;
}
return JSON.stringify({
opcode: "stats",
table: table,
filters: filters,
field: this.statsFieldName
});
}
};

Stats.prototype.isSetupDone = function () {
return this.statsFieldName && this.periodValue != 0 && this.periodUnit;
};

Stats.prototype.configChanged = function () {
var modal = $(this.setupModalName);
this.table = modal.find(".tile-table").first().val();
if (!this.table) {
this.table = this.tables.selectedTable.name;
}
this.title = modal.find(".tile-title").val();
this.periodUnit = modal.find(".tile-time-unit").first().val();
this.periodValue = parseInt(modal.find(".tile-time-value").first().val());
this.customPeriod = $("#" + this.id).find(".period-select").val();
this.statsFieldName = modal.find(".stats-field").val();
var filters = modal.find(".selected-filters").val();
if (filters != undefined && filters != "") {
var selectedFilters = JSON.parse(filters);
if (selectedFilters != undefined) {
this.selectedFilters = selectedFilters;
}
}
else {
this.selectedFilters = null;
}
this.selectedStat = modal.find(".statistic_to_plot").val();
};

Stats.prototype.loadFieldList = function () {
var modal = $(this.setupModalName);
var selected_table_name = modal.find(".tile-table").first().val();
console.log("Loading Field List for " + selected_table_name);
var selected_table = extractSelectedTable(selected_table_name, this.tables.tables);
var field_select = modal.find("#stats-field");
field_select.find('option').remove();

this.tables.loadTableMeta(selected_table, function () {
for (var i = selected_table.mappings.length - 1; i >= 0; i--) {
field_select.append('<option>' + selected_table.mappings[i].field + '</option>');
}

if (this.statsFieldName) {
field_select.val(this.statsFieldName);
}
field_select.selectpicker('refresh');
}.bind(this));
};


Stats.prototype.populateSetupDialog = function () {
var modal = $(this.setupModalName);
if (!this.table) {
this.table = this.tables.selectedTable.name;
}

modal.find(".tile-title").val(this.title);

// Create list of tables
this.loadTableList();

// Setup list of initial fields available
var selected_table = extractSelectedTable(this.table, this.tables.tables);
this.tables.loadTableMeta(selected_table, this.loadFieldList.bind(this));

// Now attach listener for change event so that changing table name changes field list as well
var selected_table_tag = modal.find(".tile-table").first();
selected_table_tag.on("change", this.loadFieldList.bind(this));

modal.find(".tile-time-unit").first().val(this.periodUnit);
modal.find(".tile-time-unit").first().selectpicker("refresh");
modal.find(".tile-time-value").first().val(this.periodValue);

if (this.selectedFilters) {
modal.find(".selected-filters").val(JSON.stringify(this.selectedFilters));
}
modal.find('statistic_to_plot').val(this.selectedStat)
};

Stats.prototype.registerSpecificData = function (representation) {
representation['periodUnit'] = this.periodUnit;
representation['periodValue'] = this.periodValue;
representation['statsFieldName'] = this.statsFieldName;
if (this.selectedFilters) {
representation['selectedFilters'] = btoa(JSON.stringify(this.selectedFilters));
}
representation['selectedStat'] = this.selectedStat;
};

Stats.prototype.loadSpecificData = function (representation) {
this.periodUnit = representation['periodUnit'];
if (!this.periodUnit) {
this.periodUnit = "minutes";
}
if (representation['period']) {
this.periodValue = representation['period'];
} else {
this.periodValue = representation['periodValue'];
}

this.statsFieldName = representation['statsFieldName'];
if (representation.hasOwnProperty('selectedFilters')) {
this.selectedFilters = JSON.parse(atob(representation['selectedFilters']));
}
this.selectedStat = representation['selectedStat'];
};
2 changes: 2 additions & 0 deletions foxtrot-server/src/main/resources/console/js/tiles/tile.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,8 @@ TileFactory.create = function (type) {
return new EventBrowser();
} else if (type === "stacked_bar") {
return new StackedBar();
} else if (type === "stats") {
return new Stats();
} else if (type === "statstrend") {
return new StatsTrend();
} else if (type === 'fql_table') {
Expand Down

0 comments on commit 791c248

Please sign in to comment.