Thursday, October 23, 2014

JQuery Plugin Creation – with Sample Code!


Ben Daland
Business Analytics Specialist

With JQuery being one of the most widely used JavaScript libraries, there are times where you have to reuse code.  A function isn’t always the answer and oftentimes you need to write your own JQuery plugin or extend an already existing one. The purpose of this post is to show how to make a simple JQuery plugin.

Before starting your plugin, there are a few things to consider. Will this plugin be used for one element or will it perform actions on a group of elements? Will it be chainable with other methods or plugins? Will it allow customization? This example will be for a group of elements, chainable and customizable. The plugin will be a simple length validator that will add a CSS class to an input based on whether it is a valid or invalid length.

To start off, we will add a new property to the JQuery.fn object—the property will be the name of your plugin. In the example below, I named the plugin LengthValidator. Now we are going to make the plugin work for multiple elements and have it chainable to other events. To do that, we need to make sure the plugin returns the ‘this’ keyword; to work with a group of elements simply perform the ‘each’ method. See example below.
_________________________________________________________________________________________________________________

(function($) {
    $.fn.LengthValidator = function () {
               return this.each(function () {
                //add code here
        });
    };
} (jQuery));

_________________________________________________________________________________________________________________
Now we can allow this plugin to be customized by the user. We need to change our plugin method to allow one argument by adding the ‘options’ argument.  
_________________________________________________________________________________________________________________
$.fn.LengthValidator = function (options) {
_________________________________________________________________________________________________________________
When allowing customization, it’s a good idea to have a default object that has default values for the settings. This allows the user to set whatever they want or none at all.
_________________________________________________________________________________________________________________
   $.fn.LengthValidator.defaults = {
min: 1,
max: 999,
valid: 'valid',
invalid: 'invalid'
    };
_________________________________________________________________________________________________________________
With the plugin accepting options and our own default settings, we need to merge them using the JQuery method ‘extend’. This method combines two or more objects into one, which is the option we will use throughout the plugin.
_________________________________________________________________________________________________________________
options = $.extend({}, $.fn.LengthValidator.defaults, options);
_________________________________________________________________________________________________________________
Now we can make this plugin actually do something! In my example, I’m going to have this plugin register the focusin, focusout and change events to each object in the collection. This needs to happen inside of the ‘each’ method so these events get registered to the object(s). See example below.
_________________________________________________________________________________________________________________
 $.fn.LengthValidator = function (options) {                                                                                                            
        options = $.extend({}, $.fn.LengthValidator.defaults, options);
        return this.each(function () {
               var elm = $(this);
               elm.focusin(function () {  })
                              .focusout(function () {  })
                              .change(function () { });                 
        });
    };
_________________________________________________________________________________________________________________
Since this plugin will be preforming the same length validation for each event, I added the method ‘checkLength’ inside the scope to reduce the same validation being written more than once. The method will be added inside of the events to perform the validation.
_________________________________________________________________________________________________________________
checkLength($(this), options, $.trim(elm.val()).length);
_________________________________________________________________________________________________________________
With this method, we pass the element, settings and length of the input value to check if it meets our min and max settings. If the value is less than or greater than, it will add the invalid class. If not, it will add the valid class. The method is being called before the events are registered—this is to validate the inputs when the plugin is assigned to the element. The complete plugin code is below.
_________________________________________________________________________________________________________________
(function($) {
    $.fn.LengthValidator = function (options) {
        options = $.extend({}, $.fn.LengthValidator.defaults, options);
        return this.each(function () {
               var elm = $(this);              
               checkLength($(this), options, $.trim(elm.val()).length);      
               elm.focusin(function () { checkLength($(this), options, $.trim(elm.val()).length); })
                              .focusout(function () { checkLength($(this), options, $.trim(elm.val()).length); })
                              .change(function () { checkLength($(this), options, $.trim(elm.val()).length); });                       
        });
    };
    function checkLength(elm, opts, len) {
               if(elm.hasClass(opts.valid)){ elm.removeClass(opts.valid); }
               if(elm.hasClass(opts.invalid)){ elm.removeClass(opts.invalid); }
               if( len < opts.min || len > opts.max ){
                              elm.addClass(opts.invalid);
               } else {
                              elm.addClass(opts.valid);
               }
    }
    $.fn.LengthValidator.defaults = {
        min: 1,
        max: 999,
        valid: 'valid',
        invalid: 'invalid'
    };
} (jQuery));
_________________________________________________________________________________________________________________
Now we are ready to use this plugin!
_________________________________________________________________________________________________________________
$('input[type=text]').LengthValidator({ min: 5, max: 10, valid: 'input-valid', invalid: 'input-invalid' });
_________________________________________________________________________________________________________________
This is a very simple JQuery plugin that can be extended to meet your needs. This is a good option for keeping your JavaScript nice and clean when using the same code over and over again. 

This example can be viewed and downloaded here. 

Thursday, October 9, 2014

How much memory is needed for a great user experience in QlikView?



Susie Bann
Business Analytics Specialist

This is a question I am always asked when designing and releasing QlikView applications to various user groups.  As I’m sure you know, QlikView allows users to analyze data quickly due to the associative in-memory technology design.  Unique entries are only stored once in-memory; other entries are pointers to the parent data.  Therefore, memory and CPU sizing is very important for the end-user experience.  Performance is directly connected to the hardware QlikView is running on.

The main performance factors in QlikView are data model complexity, amount of unique data, UI design and concurrent users.  All of these factors play into scalability, which is pretty linear when discussing QlikView.

There is a basic formula that can be used to determine the amount of memory that is needed as a starting point. 

The formula:

For every QVW
((Size of Disk) * 4) + (Size of Disk * 4) * .05 * (Number of Concurrent Users)

Here’s an example:

Source Data size = 50GB
Compression Ratio = 90%
File Size = 4 for multiplier
User Ratio = 5%
Concurrent Users = 50

*Note that concurrent users is NOT the total number of supported users

The size of disk is (50GB * (1-0.9)) = 5GB

RAM = (5GB * 4) + (5GB * 4) * 0.05 * 50 = 70GB for 50 concurrent users

Given the formula and these specs, the suggested minimum would be 70GB HD at the start of an implementation.

Under normal QlikView deployments, word eventually gets out about return-on-investment and more departments will request to have their own QlikView deployments.  Additional departments = more diverse sets of data and increase of demand on the server.

It is important to know of any increases in demand, as you need to make sure that the size of server is still appropriate.  One tool that is very helpful for performance monitoring is the QVS System Monitor.  Please follow this link for more details about the QVS System Monitor app and how to deploy: http://community.qlik.com/docs/DOC-6699

Thursday, September 25, 2014

BI Proactive: Four Common Sense Tips for Business Intelligence Implementation Success



David Toole
Business Analytics Specialist

Each business intelligence initiative comes with a unique set of challenges and obstacles that must be overcome before reaching the proverbial golden analytics palace on the hill; where the reporting is accurate, the discoveries are actionable, and the ROI flows like wine.  While no two implementation journeys are the same, there are indeed several identifiable similarities in the roadmaps, which if followed, will help lighten your load as you progress towards the front gates.  Let’s take a look at 4 important ones:

·        Say What? –Many (many, many…) years ago I took my first trip to Massachusetts to visit with family.  One afternoon, my uncle decided to take my cousins and me to the movies. After buying the tickets we quickly made our way to the concession stand, where I attempted to ask the clerk for an “orange pop.”  “Pop, do you mean like, a popsicle?” the clerk replied.  “No, orange pop, in a cup,” I retorted.  This continued on for a bit until my uncle, fluent in both Western PA and New England-speak, translated… “He means soda.”  I tried to interject as to me, soda was the nasty, clear, and tasteless version of pop that my mom used to get stains off of clothing.  The clerk seemed to understand as I was quickly handed a gigantic cup of pseudo orange flavored goodness.  This story illustrates a common obstacle among businesses of all sizes where different vernacular is used to describe the same thing.  For example, Sales Analyst, Tom, may call the company who purchased the product as the “Customer” but VP of Sales, Sally, views the “Customer” as the company who the products were shipped to.  Even more troubling is defining business rules.  For example, a sales department and a finance department may explain “gross margin” differently or have a disconnect on which costs should be categorized as “overhead” vs “cost of goods sold.”  The power of BI is bringing data from several different silos together so the business can be viewed and analyzed as a whole. Without uniformity in data definitions this cannot be achieved.  Before beginning a BI implementation there should be open discussion between departments to find commonality among the language used to define their business.

·        Divide and Conquer – Drinking from a bottle is a lot easier than drinking from a fire hose. The same concept is true when implementing BI.  Instead of tackling the whole project at once, focus on a single key area within the business, build a few accurate, easy-to-digest reports based on this focal point, and release them to a limited number of end users and business analysts for validation. While small and seemingly insignificant, getting a few quick wins into the hands of the users will build trust and hopefully excitement about what else is yet to come!  At the same time, the slow and steady release schedule gives the end user time to grow comfortable with the look and feel of the tool and oftentimes leads to specific formatting, query, or layout requests in future reports.  As a BI administrator, getting feedback from users is essentially winning the analytics development lottery!  Positive or negative, receiving feedback means the users care about the tool, see potential, and (whether they know it or not) have actively expressed a desire to help shape the future of the business.  That brings me to the next suggestion for success.

·        Power to the People-  You could have the cleanest data, the most efficiently modeled warehouse, and  the trendiest BI tool on the market, but if no one at the company is taking advantage of it, your BI is about as valuable as the chewing gum on the bottom of my shoe.  To maximize adoption rates and to prevent your BI initiative from becoming an unseen and trampled upon minty mess, the end-user perspective must be considered from the very beginning.  By involving end-users early on in the process, you’ll grow into the software together, making the process less intimidating and creating an environment where it’s easy to ask questions or to suggest improvements. The user will essentially shape the solution to their needs, allowing business requirements to be met more effectively and a broader overall use of the tools.   

·        The Data Cleanse- It’s not the newest health trend to sweep the nation, but it should be a top priority for companies looking to implement a BI initiative.  Whether the underlying data is incomplete, outdated, or contaminated with misspellings and typos generated from the use of manual data entry, it needs to be rehabbed as much as possible before the modeling begins.  Skipping this step will end up causing headaches down the road where your BI team will be spending their time correcting mistakes vs utilizing the in-depth analysis offered by the tools.  To avoid this nightmare, sit down with your team and brainstorm reporting requirements.  Any fields that come up in conversation (ex. salesperson, customer location, etc.) should be identified in the database tables, inspected for completeness (are all desired attributes available), consistency (capital vs lowercase, 5 digit zip or 9 digit zip, etc.), and quality (spelling, partially completed data, etc.).  Any issues that arise should be dealt with in this phase. Your analytics, reporting, and forecasting will only be as good as the stuff you have in your database so put the time in early on and avoid the need for Advil down the road!

              

Friday, September 5, 2014

Whose data is it anyway?



Dan Volitich (@DanVolitich)
President

Good News, Bad News.

Good news is that Excel can now hold more than 65,536 rows of data. Bad news is that Excel can now hold more than 65,536 rows of data.

It is not uncommon for users to ask for everything they “need” downloaded into Excel.  This confuses the IT group and usually generates responses such as, “Huh? We already have that information in a database,” “Why would you want to do that?” or my favorite, “You do not need that.”   So what we really have here is an IT individual determining what a business user needs.  The business user making this request typically helps generate sales in an organization.  This is also the same business user that if they did not do their job well, the IT group and other support areas would have no purpose and therefore no job.

There is stress to deliver value on all parties in an organization.  IT is responsible for keeping systems up and running so that mountains of data concerning sales and operations can be collected.  The business user is responsible for increasing sales year after year, driving profitability, and winning market share.  Some organizations have a culture that encourages these two areas to work together for the betterment of the company.  Others are still struggling. 

When the business wants to track something new and the IT process does not support that change, many times the business will just track it themselves.  There are multimillion dollar organizations out there that have critical business information in Excel.  And that the Excel 65K row limit has been eliminated, the only real limit is the amount of memory on the workstation.  More sophisticated users will use Access Databases. 

How do we fix this?  We fix it together – time to order a pizza for lunch.  BOTH business and IT have to come to the pizza lunch open minded.  BOTH business and IT cannot blame the other for where they are.  Gone are traditional SDLC waterfall methods of developing BI and Analytics.  The business needs to see that today’s technology can enable IT to be more responsive to them.  When the business sees that IT can respond to them in less than 6 months, they will stop asking for data dumps and also stop collecting data on their own.  IT needs to show that when the business comes back to “ask for more” it is not because the business user is stupid, it is because until they could see what was initially delivered, they are now better able to articulate the refinements that will add even more value to the organization. 

This iteration the first time through is tough. IT is afraid that the business will have an uncompleted or open project for-ev-ver (shine flashlight up on your face).  What really happens is an alignment of IT and the business.  IT begins to understand what the true business needs are, and the business begins to understand that if they share their goals and strategies with IT, IT can better server them.  Ahhh…the beauty of iterative development…

After the first cycle of development, business request, and IT fulfillment, the culture of the organization MUST not find fault in the business user for incomplete requirements.  In addition, the culture of the organization MUST not find fault in IT for delivering what the business asked for but not what they wanted. 

The jury is in; conversational design and iterative development for BI and analytics brings IT and business back together aligning strategic goals of the organization.  This results in improved process, increased profitability, and an aligned culture – a good thing, right?