Gorilla Logic gets kosher-er

Posted in Stu Stern on October 31st, 2009 by admin
Since ICAAN has approved hebrew domain names, I think we need to register gorillalogic.chom.

Closing Time

Posted in Eric Daugherty on October 30th, 2009 by admin
I'm reminded of the Semisonic song Closing Time today, and the quote "Every new beginning comes from some other beginning's end".

Today was my last day with my current employer, and I will soon begin not only a new job but also the process of relocating to Colorado. We're not moving right away, but today is a major milestone.

It has been fun, and I will miss many aspects of my experience here, but my family and I are excited about the future.

But on this day, it is important to keep perspective. This new beginning comes from some other beginning's end.

Google Disrupts Another Industry

Posted in Eric Daugherty on October 28th, 2009 by admin
Google announced plans to release a turn-by-turn GPS Navigation application for the new Motorola Android 2.0 (Droid) phone. This is significant enough, but CNET also reports:
However, Google is working with Apple on bringing it to the iPhone, and it's not ruling out licensing the software to makers of portable navigation devices used in cars throughout the world, said Gundotra, vice president of engineering at Google for mobile and developers.
This could be a major disruptive force to Tom Tom, Garmin, and the entire mobile navigation industry. There is nothing like a free alternative to a $99 iPhone Application (US Version) to shake things up, let alone the impact on the automotive manufacturers and their in-dash software needs.

Microsoft and Apple are obviously concerned about Google, but Google's impact may be greater in less obvious market areas.

Signing AIR Applications: How AIR’s Certificate Requirement Complicates Open Source Development

Posted in Eric Daugherty on October 28th, 2009 by admin
Adobe AIR is the desktop runtime environment for deploying Flex applications. The main difference between a Flex application and an AIR application is that AIR applications are installed locally and have additional access to local resources, including the local file system, while a Flex application runs in the browser and is 'sandboxed'.

I've been developing an AIR version of my iTunes Export open source application. The original version was developed in .Net, making it Windows only. The AIR version will work across Windows and OS X, and will replace the existing .Net GUI.

As I prepare to release the first Beta I ran into the question of how to sign my AIR application. All Adobe Air applications must be signed using a digital certificate. There are a few companies that sell certificates that are recognized by Windows and OS X by default, and they charge $300/year and up. That is pocket change for any company selling an application but a pretty significant cost for an open source application that produces no revenue.

You can self-sign a certificate, but you are then presented with this dialog box:



If you want to avoid this dire warning, you must buy a certificate from one of the Root Certificate Authorities.

So what do I do? I'm tempted to release it using a self-signed certificate. The warning is annoying, but I've been releasing the .Net version unsigned for years, and it had as much or more 'destructive capability'. However, the users also were not faced with this warning dialog.

It would be nice if there was an 'Open Source' Certificate Authority (CA), that allowed open source projects access to free certificates, but the costs involved in becoming a Root CA and managing the issuance of certificates would require a very generous patron.

If you are looking for step by step instructions on HOWTO sign an AIR application, check out this tutorial.

Axiis and the Quest for Cool

Posted in Justin Shacklette on October 26th, 2009 by admin

Axiis is an advanced data visualization framework built on top of Degrafa. And when I say advanced, I mean really advanced. I found my way to Axiis because I wanted the maximum amount of visual control that I could get. Axiis is designed to support any kind of visualization you could possibly imagine, but I don’t really care about that part of the framework. Instead, I just want to take your average boring graph and make it way cool.

Lately, I’ve been working on a project at work that places a real premium on cool. This post has nothing to do with that project, of course. It’s all about the quest for cool and my personal journey with Axiis.

Simple Ass Column Chart

In the beginning, I had a simple data set and just wanted create a basic column chart. I tried to follow the Intro and Tutorial, but I must admit I got a little lost the first time through. Hopefully, this will be an even easier introduction to the Axiis framework.

Here is our data in MXML:

<mx:XML id="myXML">
    <columns>
        <col label="A" val="10" />
        <col label="B" val="9" />
        <col label="C" val="7" />
        <col label="D" val="5.5" />
        <col label="E" val="6" />
        <col label="F" val="3" />
        <col label="G" val="4" />
        <col label="H" val="2.5" />
    </columns>
</mx:XML>

We want to render this data to the screen as a bunch of columns (aka RegularRectangles). So, the next thing that we need to do is process our data and feed it into an Axiis Layout. A Layout is the main element in any Axiis chart; it takes incoming data and renders it to the display.

Here we process our data and set our Layout’s dataProvider:

private function complete():void {
    var ds:DataSet = new DataSet();
    ds.processXmlString(myXML.toXMLString());
    myLayout.dataProvider = ds.data.object.columns.col;
    dc.invalidateDisplayList();
}

And here is the basic shell of our entire application:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application ...>
    ...
 
    <axiis:LinearScale id="vScale" />
 
    <axiis:DataCanvas id="dc">
        <axiis:layouts>
            <axiis:BaseLayout id="myLayout">
                <axiis:drawingGeometries>
                    <degrafa:RegularRectangle id="myBar"... />
                    <degrafa:RasterText id="myBarLabel" ... />
                </axiis:drawingGeometries>
 
                <axiis:referenceRepeater>
                    <axiis:GeometryRepeater>
                        <axiis:geometry>
                            <degrafa:RegularRectangle ... />
                        </axiis:geometry>
                        <axiis:modifiers>
                            <axiis:PropertyModifier ... />
                        </axiis:modifiers>
                    </axiis:GeometryRepeater>
                </axiis:referenceRepeater>
            </axiis:BaseLayout>
        </axiis:layouts>
 
        <axiis:backgroundGeometries>
            <axiis:VAxis ... />
        </axiis:backgroundGeometries>
    </axiis:DataCanvas>
</mx:Application>

Stepping through the code element by element, we see:

  1. LinearScale – We use a LinearScale to convert from data values to screen values (aka pixels). So a data value of 5.5 might translate into 11 pixels, 42 pixels, or 55 pixels depending on the scale.
  2. DataCanvas – The DataCanvas contains all Axiis graph elements. This is analogous to Flex 4’s Graphic container for FXG elements, and Degrafa’s Surface container for drawing elements.
  3. LayoutBaseLayout is the parent of all layouts and the most flexible.
  4. drawingGeometries – We draw each column as a RegularRectangle and each label as a RasterText. Positioning and sizing is guided by the reference geometry created by the referenceRepeater. Column height is computed using the current value of the data from the Layout converted to screen coordinates by the LinearScale.
  5. referenceRepeater – The reference geometry and repeated property combine to create a visualization for the data. So, repeating rectangles horizontally gives a column chart, repeating rectangles vertically gives a bar chart, repeating line segments horizontally given a line chart, etc.
  6. VAxis – Draw a vertical axis underneath our graph layer by using the backgroundGeometries layer of the DataCanvas. I like to use a negative x value to shift the axis left to get it out from underneath the chart (and compensate by shifting the entire DataCanvas right with a positive x value).

That’s it for the high-level stuff, the dirty little details are in the code. A little trial-and-error went a long way to teach me what the hell each of the various parameters actually did. The Intro and Tutorial article does a good job covering some of the details and tricks like the vertical flip trick, and I also recommend Tom’s session from AdobeMAX.

User Interaction Coolness

Last, we’ll add a little dash of coolness to our application with a simple rollover effect on our columns. Using an Axiis State, we modify a few properties of our drawingGeometries on the mouseOver event to create a rollover effect.

The State code:

<axiis:BaseLayout id="myLayout" ...>
    ...
    <axiis:states>
        <axiis:State enterStateEvent="mouseOver"
                exitStateEvent="mouseOut"
                targets="{[barFill,barStroke,myBarLabel]}"
                properties="{['alpha','weight','fontWeight']}"
                values="{[1,2,'bold']}"/>
    </axiis:states>
</axiis:BaseLayout>
Cool Colors

Using Degrafa geometry to build our chart gives us total control of the shape and design, but if we really want something cool, we need to use color. For our column chart, we’ll use an Axiis LayoutAutoPalette element to create a smooth color gradient for each bar.

Here is the code:

<axiis:LayoutAutoPalette id="myPalette" layout="{myLayout}"
        colorFrom="0xFF99FF"
        colorTo="0x6699FF"/>
 
<degrafa:SolidFill id="barFill" color="{myPalette.currentColor}" />

The LayoutAutoPalette interpolates from a starting color to an ending color for each data value in the Layout. We then feed the palette’s current color into a standard Degrafa SolidFill. Lastly, the fill is applied to the RegularRectangle in the drawingGeometries section of our Layout to create a pretty gradient of bars from left to right. Note that color is not proportional to the data value, but Axiis certainly provides the functionality to make a column chart with bars colored by height.

The Result

Here it is, rollover effect and all (view source enabled):

Flash is required. Get it here!
Files

Episode 19: Simeon Bateman MAX 2009 Wrap-up

Posted in Drunk On Software on October 25th, 2009 by admin

In this episode Simeon Bateman joins us at Adobe Max 2009 to chat about the highlights.

Resources:
- Simeon Bateman Blog

Adapt or Die Thinking You’re Right

Posted in Dave Rodenbaugh on October 22nd, 2009 by admin

From the late 1800s until the 1950s, railroads dominated the transportation landscape.  Want to go from LA to Chicago?  Chances were you did that by train.  It was the preferred choice of the traveler–cost effective, comfortable, and enjoyable.  In short, the railroads enjoyed a near monopoly on passenger movement for nearly 100 years.

When the automobile began to dominate the landscape, railroads simply ignored the threat.  “We are vastly superior, have a lock on many markets, and offer an experience you can’t touch!”  Unfortunately, the American consumer disagreed with them and railroads entered a period of decline.  Cars became the preferred mode of transportation, changing the way cities were built and how people spent their leisure time.  By 1966, railroads only carried 2% of all intercity passenger traffic.  And by 1970, only one major railroad carried passengers at all.  The railroads shrank, cut routes, and closed down wondering what happened.  This is now a classic example in business texts, MBA courses and lectures:  railroads failed to understand they were in the transportation business, not the passenger business.  They didn’t realize their core strengths causing certain death when their market shifted.

Back in the early 90s, my first job out of college was technical support at a GUI toolkit company.  This company’s claim to fame was a platform portable library(written in C, later adding a C++ framework) where you could build a user interface on say Windows and then move it to Motif, Mac, OS/2 or a litany of other unfamiliar and obscure platforms, recompile and BOOM, your app ran there too.  At the time, it was a novel concept and one folks were paying a mighty fine premium to obtain.  Licenses ran about $2000 a piece, plus annual maintenance for support.  Writing these kind of applications required a level of GUI expertise that wasn’t commonly available to many developers of the era which gave rise to a Consulting and Training Group that charged hefty rates for their highly sought-after services.  Life was good:  the company sold several million dollars of support, product and services each year.  ISVs writing C and C++ applications gobbled up the software as voraciously as their CFOs would approve the purchase orders, creating a very large and lucrative market during that time.  They were kings of the hill.

Fast forward about 3 years.  Java and HTML appear on the scene.  Younger developers in the company are checking these new technologies out and sending emails to the executives saying how cool Java is and how HTML is taking over the world.  The executives didn’t care.  “HTML?  Bah, that’s for children.  Java?  A toy language at best…all it can do is make Duke dance in an applet window.  Ignore them.  We have the Enterprise to worry about.”  They missed the point.  They were in the business of providing a platform-portable GUI development solution.  They forgot that technology doesn’t factor into their mission statement.  They were focused on getting new customers in their existing market.  They insisted everyone would use C++ forever because it sucked less than HTML and Java, instead of seeing how the market had changed.  Just like the railroads.

A few years later, the company shrank from the 100+ employees in 1994 to less than 5 by the Millennium.  Developers left in droves because Java was the hot new language and C++ developers were in demand.  Professional services was sold to another company because management wanted to “focus on product sales, not services”.  The product sales dried up slowly and only a few stubborn customers who couldn’t get off their C/C++ platforms paid the outrageous maintenance fees charged by the remaining shell company.  Java became the defacto language for the enterprise.  HTML is the lowest common denominator of every web framework today.

Seth Godin nailed this in a short post:  When you have a hammer, everything looks like a nail.  But making sure you have the right tool for the right market is about how quickly and easily you can switch hammers.  Not hitting the same nail again and again.

The lesson here is clear:  Understand your strengths because your market isn’t static.  When the market changes, be prepared to adapt to it with those strengths. Otherwise, you’ll die thinking your strategy was right.

No related posts.

Related posts brought to you by Yet Another Related Posts Plugin.

Episode 18: MAX 2009 Deep Thoughts

Posted in Drunk On Software on October 20th, 2009 by admin

In this episode Chet Haase joins us during the Adobe Max 2009 after party to discuss the highlights from the conference. Chet is a member of the Flex SDK team and Drunk on Software’s West Coast Correspondent.

Fail Fast, Learn Quickly

Posted in Dave Rodenbaugh on October 15th, 2009 by admin

Welcome to Lessons of Failure.  If you were looking for another blog about Dot Com Bazillionaires running around in limos post-IPO, well, sorry.  Try Google for someone else.  That’s not me.

I’ve spent the better part of two decades now as a professional computer geek (even longer as a rank amateur) and if there’s one thing I know about by now, it’s failure.  Everything from small fuse-popping, whoops-don’t-put-120V-on-an-electrolytic-capacitor failure, to Holy Sh*t! Dad-is-gonna-KILL-us-when-he-finds-out-about-this failure.

My background as a consultant gives me a unique perspective in the software industry.  Sort of like a bystander during an auto accident.  Or walking into the back of a bar mitzvah in a hotel.  You’re there, but at the same time, you’re also divested of the outcome to a certain degree.  Oh sure, you want success because it also happens to improve your chance of renewal at contract expiration time.  But when the company suddenly transforms into a smoking crater, you’re still standing on the side covered in a bit of soot, unlike your coworkers that are now atomized.  And hopefully a bit wiser, assuming you paid attention before the bomb went off.

Everyone knows the famous quote by George Santayana:

“Those who do not learn from history are doomed to repeat it”

And that’s what this blog is about…learning from failure.  Personal failure (like divorces).  Industry failure (like the dot-com bust).  Company failure (like Enron).  Learn or repeat.  Easy to say.  Hard to practice.

Having failed to learn a few times and, ahem, received a chance to repeat the mistake, this blog will explore failure on all those levels and more.  Fail fast, fail often, but for heaven’s sake, at least learn something.

No related posts.

Related posts brought to you by Yet Another Related Posts Plugin.

Refreshing Data in the UI

Posted in Bob Hedlund on October 13th, 2009 by admin
Once your application is up and running smoothly, all the data appears as it should, it may seem that all there is left to do is style it up and move on. But in high volume sites, or low volume sites with areas of high transaction, you need to ensure the user is seeing the latest information available. This needs to be done via XMLHttpRequests so that the page that the user is working on remains intact.

Lets first discuss the data is stored and retrieved.

In any web application, the user will request data and you present it. Often the state of the page is determined by the data that is present. So you want to limit the number of calls to the database for this information by caching it in your backing bean. This requires that you reset this data when appropriate. Once the page is loaded, the data remains flat on the page until the user interacts, or you cause an update. Thus we load the data on demand, or lazily, and then cache it until it needs refreshing.

Refresh from the UI is made by AJAX calls. The calls invoke backing bean actions based on the framework you are using. Apache Trinidad has a nice built in mechanism for making AJAX calls to the JSF.

In my backing beans, I add a PollListener method that resets the data I want to refresh in the UI. The method looks like this:

public void tableDataPoll(PollEvent ev) {
resetData();
}


When the bean gets the call from the AJAX event, it resets the underlying data so that when the page requests the data, it is pulled afresh. In the UI the call is made by adding a trinidad poll ( An AJAX call that runs at a certain interval) to the page:

tr:poll interval="30000" pollListener="{bean.tableDataPoll}" id="ajax1"

This causes an AJAX call to invoke my poll listener in the backing bean every thirty seconds. In order for the table of data to update, you need to add a partial trigger to the component that displays the data. This is done as follows:

tr:table value="{bean.backingData}" partialTriggers="::ajax1"

So the poll initiates an ajax call to the bean, resets the backingData in the bean, and the table refreshes by updating itself with the new value for the backing data.

It is incredibly easy to do.

On another project where I did not use Trinidad, we achieved the same by writing out the ajax calls. Basically, the pages would call your ajax javascript library with the ids of the objects to update, and your backing bean would change these values. I found that an extremely useful tool was a window within the page that showed the ajax calls. In the page, I added a div element such as:

div id = "div_ajax_log"
textarea id = "log_ajax" name = "status" rows = "25" cols = "55"
/div

I would have a javascript library for ajax, and in this library I would have a toggle to turn ajax logging on and off. I would also set the style for the div as none or block based on wheterh I was in debug /dev mode or not. That way if there was an issue in production, I could inspect the messages coming to and from the server to the page.

In my js file for ajax, I would specify whether we are logging, and the element to log to :
// Whether to log
var _logging = false;
// Where to log
var _log_elem;

I would then specify a logging function:

function logger(text, clear) {
if(!_log_elem) {
_log_elem=document.getEleemntById("log_ajax");
if(clear)
_log_elem.value="";
var old = _log_elem.value;
_log_elem.value = text + ((old) ? "\r\n" : "") + old;
}

You will need to add in some null checks and/or try blocks in the above basic version.

Then, in my ajax methods I would check to see if the logger was running and if so spit out information to the text area. For outgoing calls:

logger("AJAX Request: " + ((async) ? "Async" : "Sync") + " " + method + ": URL: " + url + ", Data: " + data);

Where the variables were passed in by the calling page. For outgoing responses, I would do the same - here the variable AJAX is the XMLHttpRequest generated in the original call.

logger(AJAX.status);

logger(AJAX.responseText);

The result is a conditional logger to the page with the information carried to and from the page in AJAX calls.

Hope that helps.