diff --git a/f500/css/site.css b/f500/css/site.css new file mode 100644 index 0000000..099d4f1 --- /dev/null +++ b/f500/css/site.css @@ -0,0 +1,266 @@ +body +{ + font-family: Calibri, Tahoma; + font-size: 16px; +} + +div#app-holder div#steps +{ + height: 30px; + background-color: #F0F0F0; + width:860px; +} + +div#app-holder div#steps div +{ + display: inline-block; +} + +div#app-holder div#steps span +{ + font-weight: bold; + padding: 5px 0 0 10px; + height: 25px; + float: left; +} + +div#app-holder div#steps img +{ + float: right; +} + +div#app-holder div#steps div#company +{ + width: 185px; +} + +div#app-holder div#steps div#indicator +{ + width: 335px; +} + +div#app-holder div#steps div#time +{ + width: 95px; +} + +div#app-holder div#steps div#number +{ + width: 255px; +} + +div#app-holder div#steps div#number div +{ + float: left; + display: inline-block; + height: 25px; + margin: 5px 0 0 10px; + font-weight: bold; +} + +div#app-holder div.step-container +{ + border-right: 1px solid #D2D2D2; + float: left; + font-size: 10pt; +} + +div#app-holder div.step-container.company +{ + margin-top: 10px; + width:180px; +} + +div#app-holder div.step-container.company input +{ + height: 25px; + padding: 0px; + color: #c8c8c8; + width: 170px; +} + +div#app-holder div.step-container.company div +{ + margin: 10px 10px 0 0px; +} + +div#app-holder div.step-container.indicator +{ + margin-top: 35px; + width: 335px; +} + +div#app-holder div.step-container.indicator input +{ + height: 25px; + padding: 0px; + color: #c8c8c8; + width: 315px; + margin:0px 10px; +} + +div#app-holder div.step-container.indicator div +{ + margin: 10px 10px 0 10px; +} + +div#app-holder div.step-container.time +{ + margin-top: 35px; + width: 100px; +} + +div#app-holder div.step-container.time input +{ + height: 25px; + padding: 0px; + color: #c8c8c8; + width: 120px; + margin: 0px 10px 0 10px; +} + +div#app-holder div.step-container.time div +{ + margin: 10px 10px 0 10px; +} + +div.step-container.company div, div.step-container.indicator div, div.step-container.time div +{ + height: 460px; + overflow-y: auto; +} + +div#app-holder div.last-step-container +{ + display: inline-block; + width: 240px; + height: 445px; + float: none; + font-size: 10pt; + margin-top: 10px; +} + +div#app-holder div.last-step-container div#options +{ + background-color: #F0F0F0; + padding: 5px; + margin: 0px 0 0 10px; + +} + +div#app-holder div.last-step-container div#options div +{ + display: inline-block; + margin-left: 20px; + cursor: pointer; + width:85px; +} + +div#app-holder div.last-step-container div#options img +{ + float: left; + padding-right: 5px; +} + +div#app-holder div.last-step-container div.number +{ + margin: 0px 0 10px 10px; + font-weight: bold; + font-size: 18pt; + border: 1px dashed #D2D2D2; + text-align: center; +} + +div#app-holder div.last-step-container div.unit +{ + font-size:10pt; + margin-top:5px; + font-weight:normal; +} + +div#app-holder div.last-step-container div.no-number +{ + margin: 0px 0 10px 10px; + border: 1px dashed #D2D2D2; + text-align: center; + font-size: 10pt; + font-weight: normal; +} + +div#app-holder div.last-step-container div.map, div.last-step-container div.chart +{ + width: 245px; + height: 150px; + margin: 10px 0 0 10px; +} + +div#app-holder div.last-step-container div.table +{ + width: 245px; + height: 330px; + margin: 10px 0 0 20px; +} + +div#app-holder div.last-step-container div#result div.chart +{ + width: 245px; + height: 150px; + margin: 10px 0 0 10px; +} + +div#app-holder div.step-container ul +{ + padding: 0px; + margin: 0px; + list-style-type: none; +} + +div#app-holder div.step-container ul li +{ + margin: 0 5px; + padding: 2px; + cursor: pointer; +} + +div#app-holder div.step-container.time ul li +{ + margin: 0 2px; + padding: 0px; + cursor: pointer; + display:inline; + font-size: 13px; +} +div#app-holder div.step-container ul li:hover +{ + background-color: #F0F0F0; +} + +div#app-holder div.step-container ul li.selected +{ + background-color: #059BDA; + color:#fff; +} + +div#app-holder div.step-container ul li.capital +{ + font-weight: bold; +} + +div#app-holder div.last-step-container div.fields +{ + margin:10px 10px 0 15px; + height:350px; + overflow-y:auto; +} + +div#app-holder div.last-step-container div.field +{ + margin-bottom:5px; +} + +div#app-holder div.last-step-container div.field span.property +{ + font-weight:bold; + margin-right:5px; +} + diff --git a/f500/img/chart.png b/f500/img/chart.png new file mode 100644 index 0000000..6d5460e Binary files /dev/null and b/f500/img/chart.png differ diff --git a/f500/img/loading.gif b/f500/img/loading.gif new file mode 100644 index 0000000..5597051 Binary files /dev/null and b/f500/img/loading.gif differ diff --git a/f500/img/separator.png b/f500/img/separator.png new file mode 100644 index 0000000..10cf0be Binary files /dev/null and b/f500/img/separator.png differ diff --git a/f500/img/table.png b/f500/img/table.png new file mode 100644 index 0000000..3742c3e Binary files /dev/null and b/f500/img/table.png differ diff --git a/f500/index.html b/f500/index.html new file mode 100644 index 0000000..c4dbe6b --- /dev/null +++ b/f500/index.html @@ -0,0 +1,57 @@ + + + + + + + + Find your number + + +
+
+
+ Company + +
+
+ Indicator + +
+
+ Time + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ chart + Chart +
+
+ table + Table +
+
+
+
+
+
+ + diff --git a/f500/js/fyn.js b/f500/js/fyn.js new file mode 100644 index 0000000..fc92330 --- /dev/null +++ b/f500/js/fyn.js @@ -0,0 +1,505 @@ +'use strict' +Knoema.Helpers.ready(function () { + var app = new apps.findYourNumber(); +}); + +var apps = apps || {}; +apps.findYourNumber = function () { + + Knoema.Helpers.clientId = 'fsSa7bQ='; + + this.start = 2001; + this.end = 2012; + + this.company = null; + this.indicator = null; + this.time = null; + this.unit = null; + this.dataset = 'US500COMPFINST2012R'; + this.dimension = 'indicator'; + this.meta = null; + this.indicators = null; + this.visualization = 'chart'; + + $.get('/js/meta.json?version=1.0', $.proxy(function(result){ + this.meta = result; + this.load(); + }, this)); + }; + + +apps.findYourNumber.prototype.load = function(){ + this.getCompanies(); + this.getIndicators(); + this.getTime(); + this.bindEvents(); +}; + +apps.findYourNumber.prototype.getCompanies = function () { + + var container = $('div#list-company'); + this.setLoadingState(container); + + Knoema.Helpers.get('/api/1.0/meta/dataset/US500COMPFINST2012R/dimension/company', $.proxy(function (result) { + + var companies = []; + $.each(result.items, function () { + companies.push(this); + }); + + if (companies.length > 0) { + + //companies.sort(); + var ul = $(Knoema.Helpers.buildHTML('ul', { 'id': 'companies' })).appendTo(container); + + var capital = ''; + $.each(companies, $.proxy(function (index, item) { + + var addCompany = true; + if(item.level==0) + { + $(Knoema.Helpers.buildHTML('li', { 'class': 'capital' })) + .appendTo(ul) + .append(item.name); + } + else + { + $(Knoema.Helpers.buildHTML('li', { 'id': this.getKey(result, item.name) })) + .appendTo(ul) + .append(item.name).click($.proxy(function (item) { + this.selectionChanged(item.target); + this.visualize(this.visualization); + }, this)); + + } + }, this)); + + }; + + this.removeLoadingState(container); + + }, this)); +}; + +apps.findYourNumber.prototype.getIndicators = function () { + + var container = $('div#list-indicator'); + this.setLoadingState(container); + + var ul = $(Knoema.Helpers.buildHTML('ul', { 'id': 'indicators' })).appendTo(container); + Knoema.Helpers.get('/api/1.0/meta/dataset/US500COMPFINST2012R/dimension/indicator', $.proxy(function (result) { + + this.indicators = result.items; + var topic = { "id" : -1}; + + $.each(this.meta.indicators, $.proxy(function (index, item) { + + var indicator = this.getIndicator(item.name) + if (indicator != null){ + + if (topic.id != item.topic){ + topic = this.getTopic(item.topic); + $(Knoema.Helpers.buildHTML('li', { 'class': 'capital'})) + .appendTo(ul) + .append(topic.name); + }; + + $(Knoema.Helpers.buildHTML('li', + { + 'id': indicator.key, + 'unit': indicator.fields.unit + })).appendTo(ul) + .append(item.name) + .click($.proxy(function (item) { + this.selectionChanged(item.target); + this.visualize(this.visualization); + }, this)); + }; + + }, this)); + this.removeLoadingState(container); + }, this)); +}; + +apps.findYourNumber.prototype.getTime = function () { + + var container = $('div#list-time'); + var ul = $(Knoema.Helpers.buildHTML('ul', { 'id': 'time' })).appendTo(container); + var quater=''; + var first=true; + for (var i = this.end; i > this.start; i--) { + $(Knoema.Helpers.buildHTML('li', { 'id': i,'style':'display:list-item; font-size: 26px'})) + .appendTo(ul) + .append(i); + if(i>2006) + { + for(var j=1;j<5;j++) + { + if(j==4) + { + quater=i+'Q'+j; + $(Knoema.Helpers.buildHTML('li', { 'id': i+'Q'+j })) + .appendTo(ul) + .append('Q'+j); + } + else + { + quater=i+'Q'+j; + $(Knoema.Helpers.buildHTML('li', { 'id': i+'Q'+j })) + .appendTo(ul) + .append('Q'+j); + } + } + } + + }; +}; + +apps.findYourNumber.prototype.getNumber = function () { + + if (this.isValidParameters()) { + + // Get data descriptor + var dataDescriptor = this.getDataDescriptor([this.company], [this.indicator], [this.time]); + + // Get number + var container = $('div#result'); + this.setLoadingState(container); + + Knoema.Helpers.post('/api/1.0/data/pivot', dataDescriptor, $.proxy(function (pivotResponse) { + + $(container).html(''); + $(container).removeClass(); + + if (pivotResponse.data.length > 0) { + + $(container).addClass('number'); + + // Round number and devide into digits + var number = Knoema.Helpers.roundToNDecimalPlaces(pivotResponse.data[0].Value, 2); + $(container).append(number.replace(/(\d)(?=(\d\d\d)+([^\d]|$))/g, '$1 ')) + + // Append to container + $(Knoema.Helpers.buildHTML('div', { 'class': 'unit' })) + .appendTo(container) + .text(this.unit); + + } + else { + + // Show no result message + $(Knoema.Helpers.buildHTML('div', { 'class': 'no-number' })) + .appendTo(container) + .html('Your current selection does not contain any data'); + }; + + this.removeLoadingState(container); + + }, this)); + }; +}; + + +apps.findYourNumber.prototype.getIndicator = function (query) { + + var result = null; + $.each(this.indicators, function (index, item) { + if (item.name == query) + result = item; + }); + + return result; +} + +apps.findYourNumber.prototype.getTopic = function (id) { + + var result = null; + $.each(this.meta.topics, function (index, item) { + if (id == item.id) + result = item; + }); + + return result; +}; + + +apps.findYourNumber.prototype.getUnits = function (indicator) { + + var result = ''; + var start = indicator.lastIndexOf('('); + var end = indicator.lastIndexOf(')'); + + if (start != -1 && end != -1) + result = indicator.substring(start + 1, end); + + return result; +}; + +apps.findYourNumber.prototype.visualizationChanged = function (item) { + + if (this.isValidParameters()) + { + this.visualization=$(item).text().toLowerCase(); + this.visualize($(item).text().toLowerCase()); + } +}; + +apps.findYourNumber.prototype.displayDimensionFields = function (indicator) { + + $('div#visualization').html(''); + var container = $(Knoema.Helpers.buildHTML('div', {'class':'fields'})).appendTo($('div#visualization')); + + for (var prop in indicator.fields){ + if (prop == 'long definition'){ + var field = $(Knoema.Helpers.buildHTML('div', {'class':'field'})).appendTo(container); + $(Knoema.Helpers.buildHTML('span', "Definition:", {'class': 'property'})).appendTo(field); + $(Knoema.Helpers.buildHTML('span', indicator.fields[prop])).appendTo(field); + } + else if (prop == 'source'){ + var field = $(Knoema.Helpers.buildHTML('div', {'class':'field'})).appendTo(container); + $(Knoema.Helpers.buildHTML('span', "Source:", {'class': 'property'})).appendTo(field); + $(Knoema.Helpers.buildHTML('span', indicator.fields[prop])).appendTo(field); + } + }; +}; + +apps.findYourNumber.prototype.visualize = function (type) { + + var container = $('div#visualization'); + $(container).html(''); + + switch (type) { + case 'chart': + this.chart(container); + break; + case 'table': + this.table(container) + break; + default: + break; + }; +}; + +apps.findYourNumber.prototype.chart = function (container) { + + var time = []; + for (var i = this.start; i < this.end; i++) + time.push(i.toString()); + + var data = + { + gadget: { + dataDescriptor: this.getDataDescriptor([this.company], [this.indicator], time), + gadgetClass: "Knoema.Chart", + viewState: { ignoreUnit: "checked" }, + naked: true + }, + size: { + width: 245, + height: 150 + } + }; + + $(container).gadget(data); +}; + +apps.findYourNumber.prototype.table = function (container) { + + var time = []; + for (var i = this.end; i > this.start; i--) + time.push(i.toString()); + + var dataDescriptor = + { + "Header": [ + { + "DimensionId": "Company", + "Members": [this.company] + + }], + "Stub": [ + { + "DimensionId": "Time", + "Members": time, + "UiMode": "range" + }], + "Filter": [ + { + "DimensionId": this.dimension, + "Members": [this.indicator] + }], + "Frequencies": ["A","Q"], + "Dataset": this.dataset + }; + + var data = + { + gadget: { + dataDescriptor: dataDescriptor, + gadgetClass: "Knoema.HtmlTable", + viewState: {}, + naked: true + }, + size: { + width: 245, + height: 330 + } + }; + + $(container).gadget(data); +}; +/* +apps.findYourNumber.prototype.map = function (container) { + + this.setLoadingState(container); + Knoema.Helpers.get('/api/1.0/meta/dataset/US500COMPFINST2012R/dimension/company', $.proxy(function (result) { + + var companies = []; + $.each(result.items, function () { + companies.push(this.key.toString()); + }); + + var data = + { + gadget: { + dataDescriptor: this.getDataDescriptor(companies, [this.indicator], this.time), + gadgetClass: "Knoema.Map", + viewState: {}, + naked: true + }, + size: { + width: 245, + height: 160 + } + }; + + $(container).gadget(data); + this.removeLoadingState(container); + + }, this)); +}; +*/ +apps.findYourNumber.prototype.getDataDescriptor = function (companies, indicators, time) { + var dataDescriptor = + { + "Header": [ + { + "DimensionId": "Time", + "Members": time, + "UiMode": "range" + }], + "Stub": [ + { + "DimensionId": "Company", + "Members": companies + }, + { + "DimensionId": this.dimension, + "Members": indicators + }], + "Filter": [], + "Frequencies": ["A","Q"], + "Dataset": this.dataset + }; + return dataDescriptor; +}; + +apps.findYourNumber.prototype.getKey = function (array, name) { + + var result = null; + $.each(array.items, function () { + if (this.name == name) { + result = this.key; + }; + }); + + return result; +}; + +apps.findYourNumber.prototype.selectionChanged = function (item) { + + $(item).parent().find('li').each(function (index, item) { + $(item).removeClass('selected'); + }); + $(item).addClass('selected'); + + // Define company, indicator or time + var id = $(item).parent().attr('id') + var value = $(item).attr('id'); + + switch (id) { + case 'companies': + this.company = value; + break; + case 'indicators': + this.indicator = value; + this.unit = $(item).attr('unit'); + this.displayDimensionFields(this.getIndicator($(item).text())); + break; + case 'time': + this.time = value; + break; + default: + break; + }; + + this.getNumber(); +}; + +var filter = ''; +apps.findYourNumber.prototype.isValidParameters = function () { + + if (this.company != null && this.indicator != null && this.time != null) + return true; + else return false; +}; + +apps.findYourNumber.prototype.bindEvents = function(){ + + $('div.step-container ul li').click($.proxy(function (item) { + this.selectionChanged(item.target); + }, this)); + + $('div#options div').click($.proxy(function (item) { + this.visualizationChanged(item.target); + }, this)); + + $('input#filter-company, input#filter-indicator, input#filter-time').mousedown(function () { + $(this).css('color', '#222'); + if ($(this).val() == 'Just type...') + $(this).val(''); + }); + + $('input#filter-company, input#filter-indicator, input#filter-time').live('keyup', function () { + var val = $(this).val().toLowerCase(); + if (filter != val) { + filter = val; + $(this).parent().find('ul li').each(function () { + if ((filter == '') || $(this).text().toLowerCase().indexOf(filter) != -1) + $(this).show(); + else + $(this).hide(); + }); + }; + }); +}; + +apps.findYourNumber.prototype.setLoadingState = function (container) { + + var div = $('
'); + + var initialPosition = $(container).css("position"); + if (initialPosition == "static") { + $(container).css("position", "relative"); + } + $(div).appendTo($(container)); + + var img = div.find("img"); + img.css("position", "relative").css("top", ($(container).height() - img.height()) / 2); + + div.fadeIn(1000); +}; + +apps.findYourNumber.prototype.removeLoadingState= function (container) { + $(container).find('div.loading').remove(); +}; diff --git a/f500/js/meta.json b/f500/js/meta.json new file mode 100644 index 0000000..acb84a8 --- /dev/null +++ b/f500/js/meta.json @@ -0,0 +1,104 @@ +{ + "topics" : [ + { + "id": 0, + "name": "Income Statement" + }, + { + "id": 1, + "name": "Assets" + }, + { + "id": 2, + "name": "Liabilities and Shareholders' Equity" + } + ], + "indicators" :[ + { + "name": "Operating Revenue", + "topic": 0 + }, + { + "name": "Cost of Sales With Depreciation", + "topic": 0 + }, + { + "name": "Operating Income", + "topic": 0 + }, + { + "name": "EBITDA", + "topic": 0 + }, + { + "name": "Depreciation", + "topic": 0 + }, + { + "name": "Operating Profit After Depreciation", + "topic": 0 + }, + { + "name": "EBIT", + "topic": 0 + }, + { + "name": "Pre-Tax Income", + "topic": 0 + }, + { + "name": "Total Net Income", + "topic": 0 + }, + { + "name": "Basic EPS - Total", + "topic": 0 + }, + { + "name": "Diluted EPS - Total", + "topic": 0 + }, + { + "name": "Dividends Paid Per Share (DPS)", + "topic": 0 + }, + { + "name": "Cash & Equivalents", + "topic": 1 + }, + { + "name": "Total Current Assets", + "topic": 1 + }, + { + "name": "Total Assets", + "topic": 1 + }, + { + "name": "Total Current Liabilities", + "topic": 2 + }, + { + "name": "Total Liabilities", + "topic": 2 + }, + { + "name": "Total Equity", + "topic": 2 + }, + { + "name": "Total Liabilities & Stock Equity", + "topic": 2 + }, + { + "name": "Cash Flow", + "topic": 2 + }, + { + "name": "Working Capital", + "topic": 2 + } + ], + "companies" :[ + ] +}