$(document).ready(function () {
smartFilterClient.onLoad();
});
smartFilterClient = {
dimension: {},
onLoad: function () {
"use strict";
var self = this;
self.crossFilter_socket = io.connect('http://54.251.110.52:5001' + '/crossFilter', {
'reconnect': false,
'reconnection limit': Infinity,
'max reconnection attempts': Infinity
});
self.crossFilter_socket.on('connect', function (data) {
document.querySelector("#divContainer").style.display = "block";
});
self.crossFilter_socket.on('error', function (data) {
document.querySelector('#statusMessage').innerText = JSON.stringify(data);
self.hideMessage();
});
self.crossFilter_socket.on('records', function (data) {
self.hideMessage();
});
self.crossFilter_socket.on('count', function (data) {
document.querySelector('#countOfRecords #chart').innerHTML = self.numberWithCommas(data[0].totalCount);
document.querySelector('#countOfRecords').style.display = "block";
//self.hideMessage();
});
self.crossFilter_socket.on('connectSuccess', function (data) {
document.querySelector('#statusMessage').innerText = JSON.stringify(data);
self.fetchCount();
});
self.crossFilter_socket.on('data', function (data) {
var keys = Object.keys(data);
for (var i = 0; i < keys.length; i++) {
self.dimension[keys[i].toLowerCase()].data = data[keys[i]];
var iDiv = document.querySelector('#crossFilterContainer #' + (keys[i].toLowerCase() === "" ? "noneID" : keys[i].toLowerCase()));
if (iDiv === null) {
iDiv = document.createElement('div');
iDiv.id = (keys[i].toLowerCase() === "" ? "noneID" : keys[i].toLowerCase());
document.querySelector('#crossFilterContainer').appendChild(iDiv);
}
iDiv.style.border = '5px solid #EEE';
iDiv.style.margin = '10px';
iDiv.style.float = 'left';
iDiv.style.fontSize = "14px";
iDiv.style.background = "#FFF";
iDiv.innerHTML = '
' + keys[i] + 'Reset
';
//iDiv.innerText = JSON.stringify(data[keys[i]], null, 4);
if (self.dimension[keys[i].toLowerCase()].chartType === "pie") {
var childElement = document.createElement('div')
childElement.id = 'chart';
childElement.style.margin = "5px";
iDiv.appendChild(childElement);
self.createPieChart(data[keys[i]], keys[i], self.dimension[keys[i].toLowerCase()].measure.name);
}
else if (self.dimension[keys[i].toLowerCase()].chartType === "range") {
var childElement = document.createElement('div')
childElement.id = 'chart';
childElement.style.margin = "5px";
iDiv.appendChild(childElement);
self.dimension[keys[i].toLowerCase()].filterType = 'range';
self.createRangeChart(data[keys[i]], keys[i], self.dimension[keys[i].toLowerCase()].measure.name, self.dimension[keys[i].toLowerCase()].width);
}
else {
//iDiv.innerHTML = '' + data[keys[i]][0][self.dimension[keys[i].toLowerCase()].measure.name] + ':' + data[keys[i]][0][] + '
';
var stringArr = [];
var childElement = document.createElement('div')
childElement.id = 'chart';
childElement.style.margin = "5px";
iDiv.appendChild(childElement);
stringArr.push('');
for (var j = -1; j < data[keys[i]].length; j++) {
if(j==-1){
stringArr.push('');
}
else{
var myIndex = self.dimension[keys[i].toLowerCase()].filters.indexOf((data[keys[i]][j][keys[i]] == null ? "" : data[keys[i]][j][keys[i]]).toString());
if (myIndex !== -1 || self.dimension[keys[i].toLowerCase()].filters.length === 0) {
stringArr.push('
');
}
else {
stringArr.push('
');
}
}
stringArr.push('');
if(j==-1){
stringArr.push(keys[i].toLowerCase() === "" ? "noneID" : keys[i].toLowerCase());
}
else{
stringArr.push(data[keys[i]][j][keys[i]]);
}
stringArr.push(' | ');
stringArr.push('');
if(j==-1){
stringArr.push(self.dimension[keys[i].toLowerCase()].measure.name);
}
else{
stringArr.push(self.numberWithCommas(data[keys[i]][j][self.dimension[keys[i].toLowerCase()].measure.name]));
}
stringArr.push(' | ');
stringArr.push('
');
}
stringArr.push('
');
childElement.innerHTML = stringArr.join("\n");
}
if (self.dimension[keys[i].toLowerCase()].filters.length === 0) {
document.querySelector('.reset#' + (keys[i].toLowerCase() === "" ? "noneID" : keys[i].toLowerCase())).style.display = "none";
}
else {
document.querySelector('.reset#' + (keys[i].toLowerCase() === "" ? "noneID" : keys[i].toLowerCase())).style.display = "block";
}
}
data = null;
//self.fetchCount();
self.hideMessage();
document.querySelector('#statusMessage').innerText = 'Success!!!';
});
self.crossFilter_socket.on('message', function (data) {
document.querySelector('#statusMessage').innerText = JSON.stringify(data);
self.hideMessage();
});
},
createRangeChart: function (data, key, measure, width) {
"use strict";
var self = this;
var h = 300;
var w = width;
if (w.trim() === '' || isNaN(w))
w = 500;
data.forEach(function (d) {
d = type(d);
});
var xDomain = d3.extent(data.map(function (d) { return d[key]; }));
var yDomain = [0, d3.max(data.map(function (d) { return d[measure]; }))];
d3.select('#crossFilterContainer #' + (key.toLowerCase() === "" ? "noneID" : key.toLowerCase()) + ' #chart').style('width', w + 'px').style('height', h + 'px');
var margin = { top: 10, right: 10, bottom: 100, left: 60 },
margin2 = { top: 230, right: 10, bottom: 20, left: 60 },
width = w - margin.left - margin.right,
height = h - margin.top - margin.bottom,
height2 = h - margin2.top - margin2.bottom;
var x = d3.scale.linear().range([0, width]),
x2 = d3.scale.linear().range([0, width]),
y = d3.scale.linear().range([height, 0]),
y2 = d3.scale.linear().range([height2, 0]);
var parseDate = undefined;
if (self.dimension[key.toLowerCase()].rangeType === 'date') {
if (self.dimension[key.toLowerCase()].formatType !== '') {
d3.time.format(self.dimension[key.toLowerCase()].formatType).parse;
}
x = d3.time.scale().range([0, width]);
x2 = d3.time.scale().range([0, width]);
}
var xAxis = d3.svg.axis().scale(x).orient("bottom"),
xAxis2 = d3.svg.axis().scale(x2).orient("bottom"),
yAxis = d3.svg.axis().scale(y).orient("left");
var brush = d3.svg.brush()
.x(x2)
.on("brush", brushed)
.on("brushend", brushEnd);
var area = d3.svg.area()
.interpolate("monotone")
.x(function (d) { return x(d[key]); })
.y0(height)
.y1(function (d) { return y(d[measure]); });
var area2 = d3.svg.area()
.interpolate("monotone")
.x(function (d) { return x2(d[key]); })
.y0(height2)
.y1(function (d) { return y2(d[measure]); });
var svg = d3.select('#crossFilterContainer #' + key.toLowerCase() + ' #chart').append("svg:svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
svg.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
var focus = svg.append("g")
.attr("class", "focus")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var context = svg.append("g")
.attr("class", "context")
.attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");
x.domain(xDomain);
y.domain(yDomain);
x2.domain(x.domain());
y2.domain(y.domain());
focus.append("path")
.datum(data)
.attr("class", "area")
.attr("d", area);
focus.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
focus.append("g")
.attr("class", "y axis")
.call(yAxis);
context.append("path")
.datum(data)
.attr("class", "area")
.attr("d", area2);
context.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height2 + ")")
.call(xAxis2);
context.append("g")
.attr("class", "x brush")
.call(brush)
.selectAll("rect")
.attr("y", -6)
.attr("height", height2 + 7);
if (self.dimension[key.toLowerCase()].filters.length === 2) {
brush.extent([self.dimension[key.toLowerCase()].filters[0], self.dimension[key.toLowerCase()].filters[1]]);
svg.select(".brush").call(brush);
x.domain(brush.empty() ? x2.domain() : brush.extent());
focus.select(".area").attr("d", area);
focus.select(".x.axis").call(xAxis);
}
function brushed() {
x.domain(brush.empty() ? x2.domain() : brush.extent());
focus.select(".area").attr("d", area);
focus.select(".x.axis").call(xAxis);
}
function brushEnd() {
if (brush.empty()) {
self.filterRange(key.toLowerCase(), []);
}
else {
self.filterRange(key.toLowerCase(), brush.extent());
}
}
function type(d) {
if (self.dimension[key.toLowerCase()].rangeType === 'date') {
if (self.dimension[key.toLowerCase()].formatType === '' || parseDate == undefined) {
d[key] = new Date(d[key]);
}
else {
d[key] = new parseDate(d[key]);
}
}
else {
d[key] = +d[key];
}
d[measure] = +d[measure];
return d;
}
//setData(data);
},
createPieChart: function (data, key, measure) {
"use strict";
var self = this;
var w = 200;
var h = 200;
var r = h / 2;
var color = d3.scale.category20c();
d3.select('#crossFilterContainer #' + (key.toLowerCase() === "" ? "noneID" : key.toLowerCase()) + ' #chart').style('width', w + 'px').style('height', h + 'px');
var vis = d3.select('#crossFilterContainer #' + key.toLowerCase() + ' #chart').append("svg:svg").data([data]).attr("width", w).attr("height", h).append("svg:g").attr("transform", "translate(" + r + "," + r + ")");
var pie = d3.layout.pie().value(function (d) { return d[measure]; });
// declare an arc generator function
var arc = d3.svg.arc().outerRadius(r);
// select paths, use arc generator to draw
var arcs = vis.selectAll("g.slice").data(pie).enter().append("svg:g").attr("class", "slice")
.on("click", function (d) {
self.filterSingleValue(key, d.data[key]);
});
arcs.append("svg:title").text(function (d) { return d.data[key] + ': ' + d.data[measure] });
arcs.append("svg:path")
.attr("fill", function (d, i) {
if (self.dimension[key.toLowerCase()].filters.length === 0) {
return color(i);
}
else {
var myIndex = self.dimension[key.toLowerCase()].filters.indexOf(d.data[key]);
if (myIndex === -1) {
return "#ccc";
}
else {
return color(i);
}
}
})
.attr("d", function (d) {
return arc(d);
});
// add the text
arcs.append("svg:text").attr("transform", function (d) {
d.innerRadius = 0;
d.outerRadius = r;
return "translate(" + arc.centroid(d) + ")";
}).attr("text-anchor", "middle")
.text(function (d, i) {
return data[i][key];
})
.attr("fill", "#fff");
},
createBarChart: function(){
},
connect: function () {
"use strict";
var self = this;
var tableName = document.querySelector("#divConnect #databaseTableName").value;
document.querySelector('#statusMessage').innerText = 'Trying to connect to ' + tableName + ' table ....';
document.querySelector("#divConnect").style.display = "none";
self.crossFilter_socket.emit('connect', {
tableName: tableName,
dbConfig: {
type: "database",
databaseType: document.querySelector("#divConnect #databaseType").value,
database: document.querySelector("#divConnect #databaseName").value,
host: document.querySelector("#divConnect #databaseHost").value,
port: document.querySelector("#divConnect #databasePort").value,
user: document.querySelector("#divConnect #databaseUser").value,
password: document.querySelector("#divConnect #databasePassword").value,
cacheResponse: false,
multipleStatements: false
}
});
},
addDimension: function () {
"use strict";
document.querySelector("#selectDimension #dimension").value = "";
document.querySelector("#selectDimension #measure").value = "";
document.querySelector("#selectDimension #measure").disabled = true;
document.querySelector("#selectDimension #measureType").selectedIndex = 0;
document.querySelector("#selectDimension").style.display = "block";
document.querySelector("#selectDimension #dimension").focus();
},
okDimension: function () {
"use strict";
var self = this;
var fieldName = document.querySelector("#selectDimension #dimension").value;
fieldName = fieldName.trim().toLowerCase();
if (false && fieldName === "") {
alert("Dimension can not be blank");
}
else {
self.dimension[fieldName.toLowerCase()] = {
measure: {},
filters: [],
data: [],
chartType: document.querySelectorAll("#chartType option")[document.querySelector("#chartType").selectedIndex].value.toLowerCase(),
rangeType: document.querySelectorAll('#rangeType option')[document.querySelector("#rangeType").selectedIndex].value.toLowerCase(),
formatType: document.querySelector("#formatType").value,
width: document.querySelector("#selectDimension #chartWidth").value
};
document.querySelector("#selectDimension").style.display = "none";
document.querySelector('#statusMessage').innerText = 'Adding Dimension : ' + fieldName + '....';
if (document.querySelector("#measureType").selectedIndex === 0) {
var measure = self.dimension[fieldName.toLowerCase()].measure;
measure.key = fieldName;
measure.aggregation = document.querySelectorAll("#measureType option")[document.querySelector("#measureType").selectedIndex].value.toLowerCase();
measure.name = measure.aggregation + '(' + measure.key + ')';
self.showMessage("Adding Dimension");
//self.crossFilter_socket.emit('dimension', { field: fieldName, key: measure.key, aggregation: measure.aggregation });
self.crossFilter_socket.emit('pivot', { reference: fieldName, dimensions:[fieldName], measures:[{key: measure.key, aggregation: measure.aggregation}]});
}
else {
if (measureName === "") {
alert("Measure can not be blank");
}
else {
var measureName = document.querySelector("#selectDimension #measure").value;
measureName = measureName.trim();
var measure = self.dimension[fieldName.toLowerCase()].measure;
measure.key = measureName;
measure.aggregation = document.querySelectorAll("#measureType option")[document.querySelector("#measureType").selectedIndex].value.toLowerCase();
measure.name = measure.aggregation + '(' + measure.key + ')';
self.showMessage("Adding Dimension");
//self.crossFilter_socket.emit('dimension', { field: fieldName, key: measure.key, aggregation: measure.aggregation });
self.crossFilter_socket.emit('pivot', { reference: fieldName, dimensions:[fieldName], measures:[{key: measure.key, aggregation: measure.aggregation}]});
}
}
}
},
cancelDimension: function () {
"use strict";
var self = this;
document.querySelector("#selectDimension").style.display = "none";
},
updateFilter: function (key) {
"use strict";
var self = this;
self.showMessage("Applying Filter");
self.crossFilter_socket.emit('filter', { field: key, filters: self.dimension[key.toLowerCase()].filters, filterType: self.dimension[key.toLowerCase()].filterType });
self.fetchCount();
},
measureTypeChanged: function () {
"use strict";
var self = this;
if (document.querySelectorAll("#measureType option")[document.querySelector("#measureType").selectedIndex].value.toLowerCase() === 'count') {
document.querySelector("#measure").disabled = true;
}
else {
document.querySelector("#measure").disabled = false;
}
self.chartTypeChanged();
},
chartTypeChanged: function () {
"use strict";
var self = this;
if (document.querySelectorAll("#chartType option")[document.querySelector("#chartType").selectedIndex].value.toLowerCase() === 'range') {
document.querySelector("#rangeType").disabled = false;
document.querySelector("#formatType").disabled = false;
}
else {
document.querySelector("#rangeType").disabled = true;
document.querySelector("#formatType").disabled = true;
}
},
rangeTypeChanged: function () {
"use strict";
var self = this;
if (document.querySelectorAll("#rangeType option")[document.querySelector("#rangeType").selectedIndex].value.toLowerCase() === 'date') {
document.querySelector("#formatType").disabled = false;
}
else {
document.querySelector("#formatType").disabled = true;
}
},
fetchData: function () {
"use strict";
var self = this;
self.showMessage("Fetching Data");
self.crossFilter_socket.emit('data', { from: 0, to: 100 });
},
fetchCount: function () {
"use strict";
var self = this;
//self.showMessage("Fetching Count");
self.crossFilter_socket.emit('count', {});
},
showMessage: function (msg) {
"use strict";
var self = this;
if (msg === undefined)
msg = "please wait";
document.querySelector("#applyFilterStatus p").innerText = msg;
document.querySelector("#applyFilterStatus").style.display = "block";
},
hideMessage: function () {
"use strict";
var self = this;
document.querySelector("#applyFilterStatus").style.display = "none";
},
numberWithCommas: function (x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
},
getBaseUrlString: function () {
var url = document.URL;
url = url.substr(0, url.indexOf('/', 8));
jQuery.support.cors = true;
return url;
},
reset: function (e) {
var key = e.id;
smartFilterClient.dimension[key.toLowerCase()].filters = [];
smartFilterClient.updateFilter(key);
},
filterSingleValue: function (key, value) {
var self = this;
var myIndex = self.dimension[key.toLowerCase()].filters.indexOf(value);
if (myIndex === -1) {
self.dimension[key.toLowerCase()].filters.push(value);
}
else {
self.dimension[key.toLowerCase()].filters.splice(myIndex, 1);
}
if (self.dimension[key.toLowerCase()].filters.length === self.dimension[key.toLowerCase()].data.length)
self.dimension[key.toLowerCase()].filters = [];
self.dimension[key.toLowerCase()].filterType = 'in';
self.updateFilter(key);
},
filterRange: function (key, values) {
var self = this;
self.dimension[key.toLowerCase()].filterType = 'range';
self.dimension[key.toLowerCase()].filters = values;
self.updateFilter(key);
},
}