Thursday, November 4, 2010

Html5 Canvas Drawing -- Draw dotted or dashed line





This post is for those who want to use html5 canvas for drawing. Canvas have methods to draw lines of different widths but not for different styles. Like if you want to draw dotted lines or dashed line there is no such stroke style. But fortunately there is a way to achieve this. Following is a description about how I achieved this.

You can set the stroke pattern on canvas context. Stroke pattern can be any canvas pattern. So here I created an image of 1 pixel height and 6 pixel width. First three pixels were black and other three were white. Now I created the image to create a repeating pattern.

       var linePattern;
       imageToUsedAsPattern.onload = function() {
               linePattern = context.createPattern(
imageToUsedAsPattern, "repeat");
               context.strokeStyle=linePattern;
        }
        var imageToUsedAsPattern = new Image();

        imageToUsedAsPattern.src = "images/linePatterns.jpg";    

Now all the calls to context.stroke will use the pattern to draw strokes. Like if you create a line from the top left corner of the canvas to the bottom right corner it will be a dashed line.

         context.moveTo(0,0);
         context.lineTo(canvas.width,canvas.height);
         context.stroke();


You can achieve dotted line in similar way by creating an image may be two pixel wide. First pixel of white color and second of black color.


A limitation of this is that you can create lines of only white and black color or only of those colors for which you have already created the images. To provide lines of any color you may create another image on the fly using canvas element and doing pixel mainpulation.

Wednesday, March 31, 2010

GWT-EXT Read nested JSON object

Here is my JSON.

{
 "pk": 9990,
"title": "World Event",
"description": "Description of World Event",
"idea": {
     "ideafk": "9840",
      "ideastring": "World"
           },
 "streetAddress": "World Event's street ad"
 }

You can see it is has nested attributes. The attribute idea has sub-attributes ideafk and ideastring. I wanted to read the value of ideastring in a column and wanted to keep the value of ideafk in the recordDef for further references. Following is the solution.

final RecordDef recordDef = new RecordDef(new FieldDef[] {
new IntegerFieldDef("pk"),
new StringFieldDef("idea", "idea.ideaString"),  // here you name ideaString as idea in recordDef.
new StringFieldDef("title"),
new StringFieldDef("ideapk", "idea.ideapk"),

ColumnConfig ideaStr = new ColumnConfig("Idea", "idea", 45, true);  // In recordDef ideaString was called idea.
ColumnConfig eventTitle = new ColumnConfig("Title", "title", 45, true);

Sunday, January 10, 2010

Handling Simile Timeline in GWT application.

During a project I had to use Simile Timeline with GXT. I handled mouse wheel zoomin, scrolling, event click handling, dynamically loading events as timeline scrolls etc in GWT-EXT application. I was difficult task and took lot of time to handle these things. Here I am pasting my code for some of the solutions.

How did I change the font size
timeline.css

.timeline-container {
position: relative;
overflow: hidden;
font-size:10;
font-color:red;
}

Added these two lines
font-size:10;
font-color:red;

This style is applied to the div element in which timeline is rendered.


How did I cleare the timeline events to re-render the events on prevously rendered dates.
$wnd.Timeline.timelines[0].getBand(0).getEventSource().clear();

If you want to clear band number 2 the it becomes
$wnd.Timeline.timelines[0].getBand(1).getEventSource().clear();

Handling scroll events

public native static void addScrollListener(int index,
CustomTimeLine timeLine)/*-{
timeLine.getBand(index).addOnScrollListener($wnd.bandScroll);
}-*/;

public static void bandScroll(double startDate, double endDate) {

MessageBox.alert("scroll Event recieved");

}



Handling zoom events

import com.google.gwt.core.client.JavaScriptObject;

public class ZoomStepOptions extends JavaScriptObject {
protected ZoomStepOptions() {
super();
}

public static ZoomStepOptions create() {
return ZoomStepOptionsImpl.create();
}

/**
* required, start date
*
* @param value
*/
public final void setPixelsPerInterval(int value) {
JavaScriptObjectHelper.setAttribute(this, "pixelsPerInterval", value);
}

/**
* required, Unit
*
* @param value
*/
// value =
// Timeline.DateTime.HOUR,Timeline.DateTime.DAY,Timeline.DateTime.MONTH
public final void setUnit(int value) {
JavaScriptObjectHelper.setAttribute(this, "unit", value);
}

}


class ZoomStepOptionsImpl {
public static native ZoomStepOptions create()/*-{
return new Object;
}-*/;
}


import java.util.List;

import com.google.gwt.core.client.JavaScriptObject;

class JavaScriptObjectHelper {

private JavaScriptObjectHelper() {

}

public static native String getAttribute(JavaScriptObject elem, String attr) /*-{
var ret = elem[attr];
return (ret === undefined) ? null : String(ret);
}-*/;

public static native void setAttribute(JavaScriptObject elem, String attr,
String value) /*-{
elem[attr] = value;
}-*/;

public static native JavaScriptObject getAttributeAsJavaScriptObject(
JavaScriptObject elem, String attr) /*-{
var ret = elem[attr];
return (ret === undefined) ? null : ret;
}-*/;

public static native JavaScriptObject[] getAttributeAsJavaScriptObjectArray(
JavaScriptObject elem, String attr) /*-{
var ret = elem[attr];
return (ret === undefined) ? null : ret;
}-*/;

public static native void setAttribute(JavaScriptObject elem, String attr,
JavaScriptObject[] value) /*-{
elem[attr] = value;
}-*/;

public static native void setAttribute(JavaScriptObject elem, String attr,
JavaScriptObject value) /*-{
elem[attr] = value;
}-*/;

public static native void setAttribute(JavaScriptObject elem, String attr,
int value) /*-{
elem[attr] = value;
}-*/;

public static native void setAttribute(JavaScriptObject elem, String attr,
boolean value) /*-{
elem[attr] = value;
}-*/;

public static native void setDateAttribute(JavaScriptObject elem,
String attr, String value) /*-{
var dateValue=new Date(value);
elem[attr] = dateValue;
alert("dateValue="+dateValue);
alert(elem.id + " " + elem.start);
}-*/;

public static native void setAttribute(JavaScriptObject elem, String attr,
float value) /*-{
elem[attr] = value;
}-*/;

public static native int getAttributeAsInt(JavaScriptObject elem,
String attr) /*-{
var ret = elem[attr];
return (ret === undefined) ? null : ret;
}-*/;

public static native float getAttributeAsFloat(JavaScriptObject elem,
String attr) /*-{
var ret = elem[attr];
return (ret === undefined) ? null : ret;
}-*/;

public static int[] getAttributeAsIntArray(JavaScriptObject elem,
String attr) {
int[] rtn = null;
JavaScriptObject hold = getAttributeAsJavaScriptObject(elem, attr);
if (hold != null) {
rtn = new int[getJavaScriptObjectArraySize(hold)];

for (int i = 0; i < rtn.length; i++) {
rtn[i] = getIntValueFromJavaScriptObjectArray(hold, i);
}
}

return rtn;
}

public static native int getJavaScriptObjectArraySize(JavaScriptObject elem) /*-{
if (elem) return elem.length;
return 0;
}-*/;

public static native int getIntValueFromJavaScriptObjectArray(
JavaScriptObject elem, int i) /*-{
return elem[i];
}-*/;

public static native void setAttributeAsIntArray(JavaScriptObject elem,
String attr, int[] value) /*-{
elem[attr] = value;
}-*/;

public static native boolean getAttributeAsBoolean(JavaScriptObject elem,
String attr) /*-{
var ret = elem[attr];
return (ret === undefined) ? null : ret;
}-*/;

/**
* Helper function to create [] array from List.
*
* @param list
*
* @return array of objects
*/
public static JavaScriptObject[] listToArray(List list) {
JavaScriptObject[] array = new JavaScriptObject[list.size()];

for (int i = 0; i < array.length; i++) {
array[i] = (JavaScriptObject) list.get(i);
}

return array;
}

public static JavaScriptObject arrayConvert(Object[] array) {
JavaScriptObject result = newJSArray(array.length);
for (int i = 0; i < array.length; i++) {
arraySet(result, i, array[i]);
}
return result;
}

public static JavaScriptObject arrayConvert(JavaScriptObject[] array) {
JavaScriptObject result = newJSArray(array.length);
for (int i = 0; i < array.length; i++) {
arraySet(result, i, array[i]);
}
return result;
}

private static native JavaScriptObject newJSArray(int length) /*-{
if (length < 0)
{
return new Array();
}
else
{
return new Array(length);
}
}-*/;

public static native int arrayLength(JavaScriptObject array) /*-{
return array.length;
}-*/;

public static native Object arrayGetObject(JavaScriptObject array, int index) /*-{
return array[index];
}-*/;

public static native void arraySet(JavaScriptObject array, int index,
Object value) /*-{
array[index] = value;
}-*/;

public static native void arraySet(JavaScriptObject array, int index,
JavaScriptObject value) /*-{
array[index] = value;
}-*/;
}