Jun 072010
 

A few weeks back, Ibrahim told me about a cool JQuery plugin – Flot which makes charting really easy. So I played around and worked out an example. It plots your total cost versus minutes for both postpaid and prepaid mobile connections. Just enter the plan details for both prepaid and postpaid and you get the graph, which could be used to compare which plan suits your usage range. Postpaid plans usually have a monthly recurring cost but also give away free minutes. So it makes sense to go for it only if your monthly usage exceeds certain number of minutes. This graph will show the minimum usage beyond which its profitable to go for a plan.

You can check out the demo page here. A Screenshot is below

Flot can be downloaded here. You can also check out the API documentation and the examples. The code for the example is given below and you can also download it from the site.

Javascript:-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/* ************************************************
* Developer: Ganesh Ranganathan
* Date: 07-June-2010
* Description: This is an example for Flot-  a Jquery plugin
* ***********************************************/
 
//A class which encapsulates the cost for both prepaid and postpaid
function Cost(monthly, free, local, std, sms) {
    this.monthly = monthly;
    this.free = free;
    this.local = local;
    this.std = std;
    this.sms = sms;
 
    //This function calculates  the cost, its supplied with the number of prepaid and post paid
    this.Calculate = function(minutes, stdProp) {
        //If the number of minutes is less than free minutes, just return the monthly recurring and SMS cost
        if (minutes < free)
            return parseInt(monthly) + (parseInt(sms * appVariables["sms"]));
        else
            minutes = minutes - free; // reduce free minutes
        var stdPropMin = minutes * stdProp; // calculate number of STD
        var localPropMin = minutes * (1 - stdProp);
        //return the total cost
        return (parseInt(monthly) + (parseInt(local * localPropMin)) + (parseInt(std * stdPropMin)) + (parseInt(sms * appVariables["sms"])));
    }
}
 
//No Magic numbers anywhere. Any constants/default variable value should be entered here
//and accessed. Customize defaults later using other controls
var appVariables =
{
    minuteRange: 800, //Max minutes per month
    allowedChars: [8, 190], //All allowed character inputs for cost boxes
    serviceTaxPercent: 10.2, //Service tax percentage - not applicable for prepaid
    sms: 50, // Number of SMS sent per month -- **customize later**
    stdProp: 0.5 //Proportion of STD to local -- **customize later**
}
 
//Chart options. Refer API.txt for complete list of
//available options
var chartOptions = {
    yaxis: { min: 0 },
    xaxis: { tickDecimals: 0 },
    series: {
        lines: { show: true }
    }
};
 
//This JSON variable will hold the data. Empty now - data will be calculated dynamically
//based on the cost
var dataset =
{
    "prepaid": {
        label: "prepaid",
        data: [[0,0]]
    },
    "postpaid": {
        label: "postpaid",
        data: [[0,0]]
    }
};
 
//This is the array which holds the data. We will pass
//it to FLOT.
var data = [dataset["prepaid"], dataset["postpaid"]];
 
//This is init function run after DOM loads
$(document).ready(function() {
 
    //Push all the allowed charcters in the array.
    for (var i = 48; i < 58; i++)
        appVariables["allowedChars"].push(i);
 
    //Set all cost boxes to 0
    $('.cost').each(function() {
        $(this).val(0);
    });
 
    //Hooking up event handlers - The keyup event redraws the chart, while keydown event validates data
    //If keydown validates false, it cancels the input
    $('.cost').keydown(checkInput);
    $('.cost').keyup(redrawChart);
 
    //Plot the chart. We pass the placeholder of the chart, the data array
    //and the options array
    var plot = $.plot($("#chart"), data, chartOptions);
 
});
 
//Function to check input. If the entered key isnt in the allowed character array, the input is cancelled.
//Its enough to validate here since keyup will be fired after here
var checkInput = function(event) {
    var found = false;
    for (var i = 0; i < appVariables["allowedChars"].length; i++) {
        if (event.keyCode == appVariables["allowedChars"][i])
            found = true;
    }
    if (!found)
        return false;
};
 
//Function to redraw the chart. IT will be fired once the costboxes's value is changed
var redrawChart = function(event) {
    //First all arrays need to be set to null. This
    //is important since we are pushing the data in
    //the array and not index setting it
    dataset["postpaid"]["data"] = [[]];
    dataset["prepaid"]["data"] = [[]];
    //Call the functions to populate the arrays.
    calculatePostPaid(appVariables["minuteRange"]);
    calculatePrePaid(appVariables["minuteRange"]);
 
    //Plot the chart. We pass the placeholder of the chart, the data array
    //and the options array
    var plot = $.plot($("#chart"), data, chartOptions);
};
 
var calculatePostPaid = function(minuteRange) {
    //Get monthly recurring cost. We need to add the service tax to it
var monthly = parseInt($('#postMonthly').val()) * (1 + appVariables["serviceTaxPercent"] / 100);
    //Get the free minutes, local cost, std cost and sms cost from the text boxes
    var free = $('#postFree').val();
    var local = $('#postLocal').val();
    var std = $('#postStd').val();
    var sms = $('#postSMS').val();
    //Create the cost object and pass all values to its
    //constructor
    var postCost = new Cost(monthly, free, local, std, sms);
    //Push the data into the array. Calculate for each minute the cost using the
    //Cost class's calculate method.
    for (var i = 0; i < minuteRange; i++)
        dataset["postpaid"]["data"].push(new Array(i, postCost.Calculate(i, appVariables["stdProp"])));
};
 
var calculatePrePaid = function(minuteRange) {
//Get the free minutes, local cost, std cost and sms cost from the text boxes
    var monthly = $('#preMonthly').val();
    var free = $('#preFree').val();
    var local = $('#preLocal').val();
    var std = $('#preStd').val();
    var sms = $('#preSMS').val();
    //Create the cost object and pass all values to its
    //constructor
    var preCost = new Cost(monthly, free, local, std, sms);
    //Push the data into the array. Calculate for each minute the cost using the
    //Cost class's calculate method.
    for (var i = 0; i < minuteRange; i++)
        dataset["prepaid"]["data"].push(new Array(i, preCost.Calculate(i,appVariables["stdProp"])));
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<html>
<head>
<title>Flot </title>
<link rel="Stylesheet" type="text/css" href="Styles/layout.css" />
<script language="javascript" type="text/javascript" src="js/jquery.js"></script>
<script language="javascript" type="text/javascript" src="js/jquery-ui-1.7.1.custom.min.js"></script>
<script language="javascript" type="text/javascript" src="js/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="js/myscript.js"></script>
</head>
<body>
<div id="chart">
</div>
<div id="optionsHolder" class="divOptions">
<table id="tblOptions">
<caption>Enter the cost</caption>
<tr>
<th scope="col">Charges For</th>
<th scope="col">Prepaid</th>
<th scope="col">PostPaid</th>
</tr>
<tr id="rental">
    <td>Monthly Recurring Cost</td>
    <td><input type="text" id="preMonthly" class="cost" /></td>
    <td><input type="text" id="postMonthly" class="cost"/></td>
</tr>
<tr id="freeMinutes">
    <td>Free Minutes</td>
    <td><input type="text" id="preFree" class="cost" /></td>
    <td><input type="text" id="postFree" class="cost"/></td>
</tr>
<tr id="localCost">
    <td>Local Call: </td>
    <td><input type="text" id="preLocal" class="cost" /></td>
    <td><input type="text" id="postLocal" class="cost"/></td>
</tr>
<tr id="stdCost">
    <td>STD Call: </td>
    <td><input type="text" id="preStd" class="cost" /></td>
    <td><input type="text" id="postStd" class="cost"/></td>
</tr>
<tr id="smsCost">
    <td>SMS: </td>
    <td><input type="text" id="preSMS" class="cost" /></td>
    <td><input type="text" id="postSMS" class="cost"/></td>
</tr>
</table>
</div>
</body>
</html>