Hello Readers,
Time fly so fast. Its became months since I update my blog. Busy timings @work and the real reason is that I became so lazy to write. But that did not stop me exploring things. Here is my thought about the computer "charts" for dekstop applications.
Charts - A graphical representaion of the data (numbers mostly). We all love to see charts because human mind can easily grasp the picture than words or numbers. The right chart that displays the data will greatly assist human brain and help us to think more to make sense out of it.
Think of an example of weather forecast. If we have years and years of the data which is plotted nicely, we could predict the future, It might save human life !!
On the other side, Poor selection of charts / less flexibility of viewing data in various timelines (Ex: zoom into timelines) will not do any better job than just showing the huge data.
Its a developer / UI designers reposibility to choose right chart with maximum flexibility.
Charting Libraries: Fortunatly for a desktop / web applicaion developers, There is no need to write a graphics code for plotting charts. There are tons of charting tools avilable both for desktop applications / web applications.
I used JFreeChart, GD::Graph, SWF::Chart etc ... (I don't remember which charting lib I have used in VB6).
All of these charting libaries are awesome and served their purpose at that point of view but we need to evolve.
I find few drawbacks in the traditional charting libraries,
I always envy the JavaScript charting libraries.
Did you get the answer?. Yes the idea is to embedded the Browser widget into desktop GUI application and leave the Charting work to Javascript. !!
I hear that. You need to see the code believe it. Here is my GTK2 based dektop application to demonstrate Java Script charting technique.
Note: This code is not optimized. I create a full html string every time and then load into Gtk2::WebKit browser widget. The more elegant way would be writing the changed data into a PIPE / Other IPC mechanism, From Javascript read from the PIPE. Hey, didn't I tell you already, Its only for demo .... Having said that, This code runs very very fast. I see the charts are alive within no time.
What am I doing?
1. I created a binomial distribution data for the purpose of charting. Mostly inspired from http://maths.uncommons.org/
2. I used perl language and GTK2 GUI framework. I use Perl + Gtk2 a lot @work for creating cross platform GUI applications. I really like the Gtk's Glade GUI designer. It gratly simplifies the effort of GUI design.
3. I choose WebKit as my browser of choice. Webkit is running in iPhone!!. I used Gtk2::WebKit perl binding of the WebKit
4. I AMCharts JavaScript awesome library. They do provide online chart creator tool. My most of the HTML and Java Script code is just copy paste from their online chart designer's output.
Note: AMCharts allows to use their charting library for free for personal usage and you need to use their javascript libs from their site. For commercial usage there is a license option. This blog post's idea is to illustae the concept, You can choose other free javascript charting library.
5. In the code, I load all the widgets, Bring up the GUI and calculate the Binomial probability distribution.
6. Once the data is avilable, I feed the data to the AMCharts via Java Script, JSON kind of data format.
7. Finally the whole HTML string (including Java script code) goes to browser widget, It renders the chart in micro seconds.
8. Any zoom in / Zoom out or Interactive popups are taken care by browser widget and my main application loop is free to do other jobs.
Here are the screenshots of the above code,
Conclusion
In the early days of computer science, The thought process was to keep the whole system to limit to one programming language and limited libraries and toolkits.
In the modern object oriented thinking, Use the best toolkit or language which serves the purpose.
Javascripts and browsers are highly optimised for the chart works and very simple to use.
I think, Modern computer chartings to be best done by the Javascript + Browser.
P.S: Thanks to Shakthi, for patiently explaining the probability distribution mathematical concepts to me.
Time fly so fast. Its became months since I update my blog. Busy timings @work and the real reason is that I became so lazy to write. But that did not stop me exploring things. Here is my thought about the computer "charts" for dekstop applications.
Charts - A graphical representaion of the data (numbers mostly). We all love to see charts because human mind can easily grasp the picture than words or numbers. The right chart that displays the data will greatly assist human brain and help us to think more to make sense out of it.
Think of an example of weather forecast. If we have years and years of the data which is plotted nicely, we could predict the future, It might save human life !!
Example: weather data chart. Thanks to http://www.tgomagazine.co.uk |
Its a developer / UI designers reposibility to choose right chart with maximum flexibility.
Charting Libraries: Fortunatly for a desktop / web applicaion developers, There is no need to write a graphics code for plotting charts. There are tons of charting tools avilable both for desktop applications / web applications.
I used JFreeChart, GD::Graph, SWF::Chart etc ... (I don't remember which charting lib I have used in VB6).
All of these charting libaries are awesome and served their purpose at that point of view but we need to evolve.
I find few drawbacks in the traditional charting libraries,
- Developer need to write a code (Though minimal) to create, customize (colors, look and feel etc...) and plot the graph. This means that developer need to touch the code to update the Chart style.
- Usually traditional charting libraries wont provide any IDE / Char designer to visualize how your real data look in the particular chart. You really need to write code first (or see demo applications and visualize your data in your mind)
- Traditional charting libraries render the data into some kind of image format internally (Ex: PNG, GIF, SVG etc..) and shows that image in the image viewer widget. This is not an efficient process if your data changes so quickly or User wants to zoom into the timeliness or for interactive charts. Keep rendering new image is a heay process for the GPUs (Though the modern GPUs are fast enough).
- Suddenly if you want to provide you application as a web application. At least there is an extra work to replace traditional charts to web ready.
I always envy the JavaScript charting libraries.
- Java script charting libaries are awesome looking
- They are so interactive
- They are not crated as a image and displayed, instead, The data is fed into Java script low level graphics functions and its drawn in browser canvas widget directly. So the zoom in, Zoom out are so fast
- Java Script runs in the browser platform, Browsers are optimized to run the Java Script and Browsers are also optimized to use the GPUs
- Most of the JavaScript libs provide an online WYSWYG editor to quickly visualize the real data with real charts.
- Modern browser's memory foot print is optimized.
- Most of the GUI frameworks support embedding a Browser inside the GUI applications.
Did you get the answer?. Yes the idea is to embedded the Browser widget into desktop GUI application and leave the Charting work to Javascript. !!
I hear that. You need to see the code believe it. Here is my GTK2 based dektop application to demonstrate Java Script charting technique.
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 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | #!/usr/bin/perl use strict; use warnings; use Gtk2 -init; use Gtk2::WebKit; use Glib qw(TRUE FALSE); use Math::Random::MT::Auto qw(binomial); use Data::Dumper; use FindBin qw($RealBin); #Globals $| = 1; my $webHTML = ""; #Create Binomial distribution gui my $win = Gtk2::Window->new; $win->set_default_size( 800, 600 ); $win->signal_connect( destroy => sub { Gtk2->main_quit } ); my $vbox = Gtk2::VBox->new( FALSE, 2 ); $vbox->set_border_width(2); $win->add($vbox); my $toolbar = Gtk2::Toolbar->new; $toolbar->set_icon_size('large-toolbar'); $toolbar->set_show_arrow(FALSE); $toolbar->set_orientation('GTK_ORIENTATION_HORIZONTAL'); my $button = Gtk2::ToolButton->new_from_stock('gtk-refresh'); $button->signal_connect( "clicked" => \&refreshBinomialDataandLoad, undef ); $toolbar->insert( $button,-1 ); $toolbar->insert( Gtk2::SeparatorToolItem->new, -1 ); $vbox->pack_start( $toolbar, FALSE, FALSE, 0 ); #Create Gtk WebKit browser widget and add to GUI my $sw = Gtk2::ScrolledWindow->new(); $sw->set_policy( 'automatic', 'automatic' ); $sw->set_size_request( 600, 600 ); # hack to set initial empty browser size my $webkitView = Gtk2::WebKit::WebView->new(); print "\n Gtk2 WebKit Version: ", Gtk2::WebKit->major_version(), ".", Gtk2::WebKit->minor_version(), ".", Gtk2::WebKit->micro_version(); $webkitView->get_settings()->set_property( 'enable-file-access-from-file-uris', TRUE ); $sw->add($webkitView); $vbox->pack_start( $sw, 1, 1, 0 ); $win->show_all; Gtk2->main; #Start GTK Main loop. Nothing after this #Subs sub genBinomialChartData { my $probabilityP = 0.5; my $trialsN = 100; my $count = 10000; my %binomial; # Get random numbers and put them in bins $webHTML = ' Generating ' . $count . ' Random Numbers. Please wait...'; loadAndShowHTML(); for ( 1 .. $count ) { my $exprimentResult = binomial( $probabilityP, $trialsN ); $binomial{$exprimentResult}++ ; #Store the expriment results as a keys in hash } #Load chart html $webHTML = startHTMLChart( $probabilityP, $trialsN, $count ); foreach my $exprimentResult ( sort keys(%binomial) ) { my $exprimentResultProbability = ( $binomial{$exprimentResult} / $count ); print "\n Probability for $exprimentResult = ", $exprimentResultProbability, " (", $binomial{$exprimentResult}, '/', $count, ')'; #Add chart data $webHTML .= insertHTMLChartData( $exprimentResult, $exprimentResultProbability ); } print "\n"; #Add chart footer $webHTML .= finishHTMLChart(); print "\n HTML \n\n", $webHTML, "\n\nHTML"; } sub insertHTMLChartData { my $value = shift @_; my $probability = shift @_; return '{ "Value": "' . $value . '", "Probability": "' . $probability . '" },'; } sub finishHTMLChart { return '] } ); </script> </head> <body> <div id="chartdiv" style="width: 100%; height: 400px; background-color: #FFFFFF;" ></div> </body> </html>'; } sub startHTMLChart { my $p = shift @_; my $t = shift @_; my $c = shift @_; return '<!DOCTYPE html> <html> <head> <title>chart created with amCharts | amCharts</title> <meta name="description" content="chart created using amCharts live editor" /> <!-- amCharts javascript sources --> <script src="file://' . $RealBin . '/amcharts/amcharts.js" type="text/javascript"></script> <script src="file://' . $RealBin . '/amcharts/serial.js" type="text/javascript"></script> <!-- amCharts javascript code --> <script type="text/javascript"> AmCharts.makeChart("chartdiv", { "type": "serial", "path": "https://www.amcharts.com/lib/3/", "categoryField": "Value", "mouseWheelZoomEnabled": true, "startDuration": 1, "handDrawn": true, "categoryAxis": { "gridPosition": "start" }, "trendLines": [], "graphs": [ { "balloonText": " Value=[[category]], Probability=[[value]]", "bullet": "round", "bulletBorderThickness": 5, "bulletSize": 10, "gapPeriod": 0, "id": "AmGraph-1", "labelOffset": 2, "title": "Observed", "type": "smoothedLine", "valueField": "Probability" } ], "guides": [], "valueAxes": [ { "id": "ValueAxis-1", "title": "Probability" } ], "allLabels": [], "balloon": {}, "legend": { "labelText": "Observed ", "useGraphSettings": true, "valueWidth": 20 }, "titles": [ { "id": "Title-1", "size": 15, "text": "Binomial Probability Distribution \n (p=' . $p . ', n=' . $t . ', count=' . $c . ')" } ], "dataProvider": [ '; } sub loadAndShowHTML { $webkitView->load_string( $webHTML, 'text/html', 'UTF-8', 'file://' ); } sub refreshBinomialDataandLoad { my $htmlString; genBinomialChartData(); #Load HTML Now loadAndShowHTML(); return TRUE; } |
Note: This code is not optimized. I create a full html string every time and then load into Gtk2::WebKit browser widget. The more elegant way would be writing the changed data into a PIPE / Other IPC mechanism, From Javascript read from the PIPE. Hey, didn't I tell you already, Its only for demo .... Having said that, This code runs very very fast. I see the charts are alive within no time.
What am I doing?
1. I created a binomial distribution data for the purpose of charting. Mostly inspired from http://maths.uncommons.org/
2. I used perl language and GTK2 GUI framework. I use Perl + Gtk2 a lot @work for creating cross platform GUI applications. I really like the Gtk's Glade GUI designer. It gratly simplifies the effort of GUI design.
3. I choose WebKit as my browser of choice. Webkit is running in iPhone!!. I used Gtk2::WebKit perl binding of the WebKit
4. I AMCharts JavaScript awesome library. They do provide online chart creator tool. My most of the HTML and Java Script code is just copy paste from their online chart designer's output.
Note: AMCharts allows to use their charting library for free for personal usage and you need to use their javascript libs from their site. For commercial usage there is a license option. This blog post's idea is to illustae the concept, You can choose other free javascript charting library.
5. In the code, I load all the widgets, Bring up the GUI and calculate the Binomial probability distribution.
6. Once the data is avilable, I feed the data to the AMCharts via Java Script, JSON kind of data format.
7. Finally the whole HTML string (including Java script code) goes to browser widget, It renders the chart in micro seconds.
8. Any zoom in / Zoom out or Interactive popups are taken care by browser widget and my main application loop is free to do other jobs.
Here are the screenshots of the above code,
Sample Binomial Distribution |
Interactive Chart, Shows the point details when cursor move on data point |
Zoom in. So fast zoom in and Zoom out |
In the early days of computer science, The thought process was to keep the whole system to limit to one programming language and limited libraries and toolkits.
In the modern object oriented thinking, Use the best toolkit or language which serves the purpose.
Javascripts and browsers are highly optimised for the chart works and very simple to use.
I think, Modern computer chartings to be best done by the Javascript + Browser.
P.S: Thanks to Shakthi, for patiently explaining the probability distribution mathematical concepts to me.