Historian - Std Ed.

posted Jan 9, 2012, 5:54 AM by Sundew Shin   [ updated Mar 6, 2012, 9:43 AM ]

(cannot see the demo? click here )

Where it's from?

Few years ago, I was working for a group of General Motors engineers and realized they can be really mean if you don't track every single details of each events, such as where that's from and where it's ended during the whole project time..
After the first round, I eventually developed myself a tool called 'Issue Tracking Sheet.' It is a simple spreadsheet document w/ the list of on-going/completed issue items, and I recorded logs of all the related events and share the sheet every Friday with all, and I didn't get bothered ever since, plus, I found myself amazingly organized in terms of issue tracking.
It worked as charm, but it has only one problem. It works in only one direction. Since it was a simple spreadsheet file, it wasn't easy to absorb many people's voluntary status update or feedback. There were laid the classic 'version control' problem.

What is Historian?

We decided to call it, 'Historian.' It is a GAS-written program purposely mimic the functionality of the issue tracking spreadsheet. (The back-end spreadsheet is just look the same as my old tracking sheet) It has the front-face GUI which provides interface to receive feedback (cooperative update logging) more easily.

Long story short, you can use it, as it was originally designed for, as a task/log-oriented bulletin board with your team members or contractors. Or, you also can use it simply as your personal todo-list or task manager, or be more creative and impress me. =)

How to install on my Google Apps domain?
  1. Create a page on a Google Sites
  2. Insert a 'Apps Script Gadget'
  3. Paste the following URL for 'Select a script... Or paste the URL of your Apps Script already published as a service:'
    https://sites.google.com/a/macros/wednus.com/exec?service=AKfycbxyCZFoldG1INGh3AdcGKQKrauiPQJJ_1PTZTSkPA

That's it!
Historian will automatically prepare itself and run as if it's an unique copy for the page inserted, for you and the page visitors.
Please feel free to leave your comments at: ego@wednus.com 

[한국어 해설]

Version 1.2 (beta)

Version 1.1

Guest Map

posted Dec 18, 2011, 6:56 AM by Sundew Shin

(Under Testing)
The gadget spec URL could not be found

EGO Cashflow2

posted Jun 2, 2011, 10:24 AM by Sundew Shin

Today, we are excited to announce you Cashflow2, the new EGO engineered product.

As we briefly introduced at Cashflow1, EGO Cashflow products let users to manage and generate a cash flow on web using Google Apps tools. With users' brief input for each money transaction event, it generates a table with analyzed data which is readily consumable by various Google Chart APIs. 

The followings are the focus Chart APIs for now:
  • Bar Chart
  • Pie Chart
  • Time Series Chart
Each linked chart periodically updates itself and represents unique perspective for the series. By analyzing these trends, users can obtain concrete insight for the money flow, so they can make decisions properly.
Unlike Cashflow1 though, Cashflow2 provides a well-polished dedicated user interface and can directly talk to the data spreadsheet without redirects or refreshes.

This application is built on the newest Google Apps Script platform, and this means it is ready to deploy any of your existing Google Apps domains.
A new survey has created for your feedback.
Enjoy~

[Feedback & Requests]

[Live Demo]

tag:business | tag:script | tag:calendar | tag:demo | tag:visualization

GAS, Persistent Variable over Events

posted May 30, 2011, 11:06 AM by Sundew Shin

The GAS platform does not provide such as persistent runtime memory equipment during the lifetime of an app: from the UI initialization (, and user interactions, and) to the termination of application. (closing the browser)

It seems on the surface the global variable declaration looks valid over all local scopes (functions) as the standard JS defines, but in effect, it will not be for eventhandlers because each invocation will reload the entire code on a brand-new copy of runtime memory (this is probably why it is so slow..), and all the states of the previous run will be inaccessible, as the following sample code will display ‘2’ on the textbox for button clicks all the time:

(cannot see the demo? click here )

Code

var app = UiApp.createApplication();
app.add(app.loadComponent('MyGui'));
function doGet(){return app;};

var global = 1;
app.getElementById('txtResult').setText(global + '');

function add(e){
  var app = UiApp.getActiveApplication();
  global++;
  app.getElementById('txtResult').setText(global + '');
  return app;
};

I wish GAS team elaborates this and at least document it for saving any further brain burns.
One way-around I found for making any states (values or objects, stringified) persistent over events is that saving it somewhere on the active UI. It will make your code strange but it will be cheaper than backup/restore the values using a spreadsheet for each invokes.

(cannot see the demo? click here )

Code

var app = UiApp.createApplication();
app.add(app.loadComponent('MyGui'));
function doGet(){return app;};

var btnAdd = app.getElementById('btnAdd');
var txtResult = app.getElementById('txtResult').setName('txtResult');
var pnlContainer = app.getElementById('pnlContainer');
// forward the click event to its container
btnAdd.addClickHandler(app.createServerClickHandler('add').addCallbackElement(pnlContainer));

var global = 1;
app.getElementById('txtResult').setText(global +'');

function add(e){
  var app = UiApp.getActiveApplication();
  global = new Number(e.parameter.txtResult);
  global++;
  app.getElementById('txtResult').setText(global + '');
  return app;
};



Update:
As Johninio pointed out in the original post, the proposed method can be elaborated as the following:

The idea of saving some state in the UI using hidden fields is an excellent on and one which I have used. There is nothing strange about it. If you want to make it interesting, create TextBox and set its visibilty to false. Then save your state information to an object and use Utilities.jsonStringify() to turn that to text and set your hidden TextBox to that. To reload the state you do something like this in your handler:

Code

function handler(e) {
  ...
  // load state
  var myState = Utilities.jsonParse(e.parameter.hiddenState);
  ...
  // do stuff possibly changing state, e.g.
  myState.selectedTab = 2;
  myState.counter += 1;
  ...
  // now save state to UI before returning
  app.getElementById("hiddenState").setValue(Utilities.jsonStringify(myState));
  return app;
}

tag:script | tag:programming | tag:demo

GAS, Accessing Textbox Value in/out of Events

posted May 22, 2011, 5:57 AM by Sundew Shin

Since (component).getText() is not available *yet*, the basic component referencing often become too convoluted as the component count goes up. So the following use case proposes an unified component referencing method inside and outside of EventHandler.

(cannot see the demo? click here )

Code

var app = UiApp.createApplication();
app.add(app.loadComponent('MyGui'));
function doGet(){return app;};

// class for component reference
var Components = function(app){var self = this;
  this.source = app.getElementById('txtSource').setName('txtSource');                              
  this.target = app.getElementById('txtTarget').setName('txtTarget');
  this.container = app.getElementById('pnlContainer');
  this.button = app.getElementById('btnCopy');
  // add more..
                                  
  // forward click event to the container
  self.button.addClickHandler(app.createServerClickHandler('copy').addCallbackElement(self.container));
  // and more..
};

// outside referencing
var c = new Components(app);
c.target.setText('0');


/* eventhandlers */
function copy(e){
  var app = UiApp.getActiveApplication();
  // inside referencing
  var c2 = new Components(app);
  c2.target.setText(e.parameter.txtSource);
  return app;
};


Update: I revised this code after the Johninio's comment here.

(cannot see the demo? click here )

Code

function doGet(){
  var app = UiApp.createApplication();
  app.add(app.loadComponent('MyGui'));
  // outside (of eventhandler) referencing
  var c = new Components(app);
  c.target.setText('0');
  
  // forward click event to the container
  var handler = app.createServerClickHandler('copy');
  c.button.addClickHandler(handler.addCallbackElement(c.container));
  // and more..
  return app;
};


// class for component reference
var Components = function(app){var self = this;
  this.source = app.getElementById('txtSource').setName('txtSource');                              
  this.target = app.getElementById('txtTarget').setName('txtTarget');
  this.container = app.getElementById('pnlContainer');
  this.button = app.getElementById('btnCopy');
  // add more..
};


/* eventhandlers */
function copy(e){
  var app = UiApp.getActiveApplication();
  // inside referencing
  var c2 = new Components(app);
  c2.target.setText(e.parameter.txtSource);
  return app;
};


Update2: GAS team recently introduced the CacheService class, and now we can simplify our method as below:
(on GUI Builder, 'update' has registered as 'On Change' event handler of txtSource, and 'copy' for 'On Mouse Click' of btnCopy)

(cannot see the demo? click here )

Code

var cache = CacheService.getPrivateCache();

function doGet(e){
  var app = UiApp.createApplication();
  app.add(app.loadComponent('MyGui'));
  // init value  
  var value = 5;
  app.getElementById('txtSource').setText(value);
  cache.put('txtSource', value);
  return app;
};


/* eventhandlers */
function update(e){
  var source = e.parameter.source;
  cache.put(source, e.parameter[source]);  
};

function copy(e){
  var app = UiApp.getActiveApplication();
  // inside referencing
  app.getElementById('txtTarget').setText(cache.get('txtSource'));  
  return app;
};

GWT: 컴파일 시간 줄이기 (for debug)

posted May 11, 2011, 10:58 PM by Sundew Shin

GWT 소스 컴파일 시 걸리는 시간은 (개별 Permutation 컴파일시간 * 지원 브라우져 종류 수) 만큼이다.
여기서 반복적인 디버깅 작업효율을 위해, (임시) 컴파일시간을 최소화 하려면 지원 브라우져를 다음과 같이 명기하면 된다.
(선언 위치는 모듈속성을 지정 하는 'Module.gwt.xml'이다.)

    <set-property name='user.agent' value='gecko1_8' />

선택 가능한 값의 종류는 다음과 같다: ie6, ie8, gecko, gecko1_8, safari, opera
IE만을 사용하거나 여러개를 동시에 지원하려면 다음과 같이 중첩 선언 한다:

    <set-property name='user.agent' value='ie6' />
    <set-property name='user.agent' value='gecko1_8' />

tag:gwt | tag:programming

EGO Cashflow1

posted Apr 4, 2011, 6:50 PM by Sundew Shin

[STEP1: Preparing a Calender]
Since we use calender without any modification, there's nothing we specially need to do.
  1. Create a empty calendar
  2. Add money transaction events
    • Where: the money amount (e.g. 1000, -1000)
    • Description: event label on the chart
    • Guest can () invite others option: Cash (check), Non-cash (uncheck)
  3. Remember the start/end date of transaction entry

[STEP2: Creating Cashflow]
  1. Create a empty spreadsheet
  2. Find and insert the 'EGO Cashflow' script from the Apps Script Gallery View Code below.
  3. Specify three fields on the first row of the active (selected) sheet
    • A1: Calendar name in your calendar collection
    • A2: Start date
    • A3: End date
  4. From the top menu bar, click 'Cashflow' button and choose 'Build'
  5. Confirm the money transaction events were parsed and printed correctly
  6. Build a trend-type chart
    • datasource 1: Sheet1!C1:E100
    • datasource 2: Sheet1!F1:G100
    • datasource 3: Sheet1!H1:H100
  7. Populate a chart
That's all. Enjoy it~



tag:business | tag:script | tag:calendar | tag:demo | tag:visualization

EGO Cashflow - Demo


Wednus Timeline+

posted Jul 13, 2009, 8:44 AM by Sundew Shin

   

Features:
  • On-gadget event addition support
tag:script | tag:visualization | tag:demo | tag:gadget

Wednus Google Friend Connect

posted Jun 29, 2009, 8:15 AM by Sundew Shin

The gadget spec URL could not be found

Features:
  • Attach your domain FC anywhere you want.
tag:admin | tag:demo | tag:gadget

Gadget: Wednus Syntaxhighlighter for Google GE

posted Jun 25, 2009, 11:03 PM by Sundew Shin

The gadget spec URL could not be found

Features:
  • GGE, Google Gadget Editor, Back-end
    • Double-click the view area to get into the edit mode (GGE)
  • Synchronized w/ GGE Hosted files

1-10 of 14