Adding Background Image to SVG Circles

Flattr this!

If you want to create nifty Graphics and Animation in the web, you cannot avoid d3.js. D3.js uses SVG as the basic Displaying Technologie. And sometimes you know, why SVG had such a hard time persuading developers.

It is a simple task:
Creating a Circle with an image as a background. The everyday Web-Developer would just create a Circle Element and would try to add the Background Image via CSS.
But that did not work at all.
After asking friend Google for a while, i found the answer to this question over at stackoverflow.
So you need SVG patterns (never heard about them before). And reference the image-pattern via the ID.

So here is a brief example:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
    "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" 
    xmlns:ev="http://www.w3.org/2001/xml-events" width="400" height="400">

    <defs>
        <pattern id="image" x="-32" y="-32" patternUnits="userSpaceOnUse" height="64" width="64">
            <image x="0" y="0" height="64" width="64" xlink:href="http://0.gravatar.com/avatar/902a4faaa4de6f6aebd6fd7a9fbab46a?s=64"/>
        </pattern>
    </defs>

    <line class="link" style="stroke: #9ecae1; stroke-width: 1;" x1="200" y1="0" x2="200" y2="400"/>
    <text dy=".35em" transform="translate(0 , 190)">0,200</text>
    <line class="link" style="stroke: #9ecae1; stroke-width: 1;" y1="200" x1="0" y2="200" x2="400"/>
    <text dy=".35em" transform="translate(200 , 10)">200,0</text>
    <circle id="top" transform="translate(200,200)" r="32" fill="url(#image)"/>
</svg>
test

We used that in our small project GitHubble (you may find the sources here).

IMHO: Differences between a mobile Web-Page and a mobile Web-Application

Flattr this!

About

Since i did some Web-Development for Mobile Device for my last projects, i would like to cover some of my thoughts and expierences i had during these months.

To come straight to the point, it is not really easy to develop stuff for mobile Devices these days, exspecially if you want to support older ones like Android <=2.3, since there are a lot of vendor specific hoops you have to jump through (and althought a lot of testing).

But i would like to start from the other site: the users site (the so called user experience).

 

mobile Web-Page

For a User, a mobile Web-Page is just a different view to a common know Homepage.
He can use saved or received links to access a specific resource.
He can rapidly change the Page Location while changing the URL in the address bar.
The Page opens in the Mobile Web-Browser (or an Browser like environment like WebView, hybrid App, etc.)
The Page need online Access to work.
The Page needs some time to load, although the content has been adjusted to mobile use (responsiveness, minifying, image optimazation, aggrssive Caching, CND, etc.)
Every Action will use a Request and will go through the Web-Page and will receive a Response for Displaying.
The User can add a Bookmark to Homescreen/Browser Favorites to have fast and easy access to that URL.

To summarize all this, a mobile Web-Page is the result of a web-optimized Web-Development Project, so e.g. you start with your common (Desktop-) Web-Flows using mobile agnostic CSS (if you must bootstrap or foundation) and modify Navigation, Javascript and Content-size to work with the mobile devices display.

In most cases you will find something like this on your screen:

Ohne Titel.002

You have a fitting View, on top your URL (that might be scrolled up via JS) and on the bottom your Browsers controls (that might be hidden by the Browsers default – e.g. Landscape view on iOS).

 

mobile Web-Application

A mobile Web-Application is specially developed for a mobile Device. You won’t start with already existing views or other assets. Do a App-Like Design (e.g. Views instead of Pages).
You should think about different Behaviour for this one (like more Icons instead of Full-Tested Links), hidden Menus that appear via slide. To be clear: use gestures and icons, your device has a touch sensor, so use it.
Use the availble Devices Settings to adjust your Applications appearance.
The User has to add the Application to her/his Homescreen to enter “App-Mode” (although the first Start uses the mobile Browser).
The App starts alway Full-Screen, so no URL is present at all, so the URL and Links are less relevant, although the Application my use a specific Model Routing like Backbone.js.
The App uses local storage (up to 10 megs) – if it has to store Data – first, then uses the Servers persistence logic.
The App should use the availible Device specific JavaScript Methods
An Action does not trigger a request automatically back to the Server (Backend).
A common use-case might be: Load Data from Backend, do something with the Data, save it locally, user other local Data, save the Data, close the App, …, restart the App, continue working, …, send the Data back to the Backend.
The App should work Offline (you have to implement some kind for update Logic – e.g. using a manifest file).
You should use a less Request/Response Cycles as possible to save Battery Time and Bandwidth.
You should use optimzied Resources (e.g. pack the structe of a survey in on JSON Feed instead of using Links to appending resources – with usefull exeption like sounds or images).
Consider using alternative Communications ways (like Websockets).

Ohne Titel.003

You will find a common Menu with Icons at the Bottom of the Page. Some Apps also using hidden Menus (that appear via swipe or a small Button).
You also will need some Kind of Activity Indicator (like a progress bar), if you need to fetch Data from or send Data to the Backend (or doing other operations that might use some time).

 

Disclaimer 🙂

That’s for the moment. It really needs some more clearifications and examples. Of course you can argue a lot about some statements here. This i just my personal opinion, first of all to differentiate between the two things.

Most of the Links go to iOS Resources, since i had to do Web Devlopment mostly for iOS and since iOS was first planed as a Web-Application only Platform, it has a pretty good documenation of all availible features. But i am sure, there are similar Documentations for (at least the common) Android and Windows Phone Devices.

1. GUI und die Sicherheit

Flattr this!

Die letzte Zeit habe ich mehr mit Schreiben verbracht. Nachdem ein JavaScript-Unterbau soweit lauffähig ist, habe ich angefangen, meine GUI-Skizzen soweit wie möglich einzubauen:

Ich bin dazu übergangen, anstatt statischen HTML-Code als String zusammen zu bauen (was eh langsam ist), alle Inhalte aus DOM Objekte zusammen zu setzen. Das hat den großen Vorteil, dass ich Elemente auch im Nachhinein per JavaScript mit Hilfe von Callback-Funktionen verändern kann.

Bisher muss man den Benutzer noch “per Hand” abrufen. Ich hoffe, dass ich bald mit einem laufenden Login aufwarten kann, sodass dem Client quasi ein User gesetzt wird.

Hierbei bin ich jetzt davon weg, eine der eingebauten Funktionen von Tomcat/Glassfish zu nutzen. Letztendlich habe ich meine Benutzerdaten in meiner Datenbank und kann diese ja auch ohne weiteres überprüfen. Ich möchte also die Sicherheitsfragen von der Serverebene auf die Applikationsebene verschieben.

Ich habe nun zwei Probleme zu lösen:

  1. Alle Abfragen, die nicht über HTTPS laufen, sollen umgeleitet werden (klassischer Redirekt) – wenn möglich könnte ich das noch nach Mime Type filtern (weil z.B. Bilder und CSS/JS ruhig über normales HTTP laufen können).Es gibt dafür die Methode response.isSecure(). Ich habe jetzt aber mehrmals gelesen, dass man das tunlichst nicht mit einem Scriptlet in JSP machen soll, sondern das ganze über ein Servlet abhandeln sollte. Es wäre ja auch notwendig, die alte Anfrage so um zubauen, dass der Inhalt (welche Datei angefragt wird), gleich bleibt, aber der Empänger auf SSL gelenkt wird. (und ggf. auf einen anderen Port).
  2. Es soll vor jeder Anfrage geprüft werden, ob die SSL-Verbindung einem angemeldeten Benutzer gehört. So dies nicht der Fall ist, soll auf eine Loginseite weitergeleitet werden.

Beide Probleme haben gemeinsam, dass die Überprüfung(en) abgehandelt werden müssen, bevor überhaupt etwas anderes passiert.

Ich hatte jetzt überlegt, dass ich ein Servlet einfach auf /* mappe – also ALLE Anfragen an die Applikation über dieses Servlet laufen.

Ich muss jetzt nur rausfinden, wie ich die “guten” Anfragen (die, von eine autorisierten User) an geeignete Stelle weiterleite.

Dazu müsste ich ja u.a. direkt mein Servlet aufrufen, welches für Jersey/REST meine Anfragen abhandelt. Ein HTTP-konformes Redirect würde ja irgendwie eine Endlosschleife verursachen. Ich lese grade EJB3 in Action und bin auch schon auf ein paar interessante Stellen gestoßen. Was fehlt ist einfach noch der “Aha-Effekt”.
Nachbemerkung zu JavaScript:

Durch die ganzen – notwendigen – Callbacks und die Nutzung von DOM-Komponenten, kommt es mir langsam vor, als würde ich Java programmieren. Letztendlich sehr zweischneidig:

  1. Man hat Schemata, die funktionieren (weil aus Java bekannt)
  2. JavaScript verliert so ein bisschen den Charme einer leichten und schnellen Scriptsprache.

Die Nebenläufigkeit

Flattr this!

Ich sitze nun schon seit einiger Zeit an meinem Client und bin dabei, die Funktionalität soweit zu verwirklichen, dass ein einfaches Arbeiten (CRUD), mit jeweils User, Task und Group möglich ist. Ich habe bemerkt, dass die Oberfläche die wenigsten Probleme macht, was eine Herausforderung ist, sind die vielen nebenläufigen Request-Abfragen.
Ich habe (hatte) mich dazu entschlossen (hier mal anhand eines Users), jeweils per JS ein User Objekt (welches von den Attributen her meinem JPA Objekt entspricht), sowie ein User-Service Objekt, welches den Zugriff (Ändern/Laden/Speichern/Cachen) meiner User-Objekte.
Liegt ein Objekt nicht im lokalen Cache (ein Array aus User-Objekten) vor, so soll es Remote vom Server geholt werden.
Das klappt auch soweit alles. Leider handelt es sich bei dem Request (AJAX-typisch) um einen asynchronen Request,so dass die Daten im Hintergrund geladen werden, während die Verarbeitung im Vordergrund weiter läuft. Es passiert dann des öfteren, dass auf Daten zugegriffen werden soll, die noch nicht vollständig geladen sind. Dies passiert zum Beispiel auch, wenn innerhalb eines Task-Objektes ein User-Objekt abgefragt wird, welches noch nicht lokal im Cache vorhanden ist. Nach einiger Literatur (u.a. auch auf den Developer Seite bei Yahoo) und ein wenig Austausch mit Willem (vielen Danke noch mal hierfür) bin ich nun zu dem Ergebnis gekommen, dass ich meine Architektur so abändere, sodass diese stärker mit Callbacks arbeiten.
YUI sieht hierbei ein Callback-Objekt vor, welches jeweils eine Methode bei Erfolg und eine Methode bei Misserfolg zur Verfügung stellt.
Ein großes Problem ist hierbei aber auch die Übergabe der Referenzen.
Da zum Beispiel meine UserService Klasse distanziert wird und das Cache Array dann ein Attribut des Objektes ist.
So ist es dann notwendig, dass einer Callback-Klasse diese Referenz ebenfalls zur Verfügung gestellt wird.
Dies kann man u.a. durch ein “Zwischen referenzieren des this-Pointers machen:

COTODO.UserService.prototype.getRemoteAndCallback = function(id, callback) {
    function failureHandler(o){
        var out = "COTODO.UserService.getRemote: id="+id;
        //Referenz steht normalerweise im UserAttribute
        var rUrl = "resources/users/"+id+"/"; 
        var self = this;
        YAHOO.log("Failure handler called; http status: " + o.status, "warn", "User.js");
    }
    YAHOO.util.Connect.asyncRequest('GET', sUrl, { success:callback, failure:failureHandler });
};

Da self in diesem Fall im Bezug auf eine mögliche Callback-Methode innerhalb der Methode getRemoteAndCallback im globalen Kontext steht, ist es ohne weiteres möglich, auf die Methoden von self zu zugreifen.
Im Moment bin ich dabei so Dinge wie:

//US = UserService Instanz
COTODO.TaskService.prototype.getCreatedBy = function(){
    return US.get(this.created_by);
}

Auf eine Callback-Variante um zubauen. Letztendlich sah meine get Methode bisher wie folgt aus:

COTODO.UserService.prototype.get = function(id){
    if(!this.exists(id)){
        return this.getRemote(id);
    }
    COTODO.debug(this.list[id],"get");
    return this.list[id];
};

Da aber in getRemote ein nebenläufiger Request abgesetzt wird, muss ich das so umbauen, dass die Methodenaufrufe quasi von der “anderen Richtung” her ausgelöst werden, also nach Abschluss des Requestes erst aktiviert wird. Andernfalls kommt es des öfteren zu einem NULL Objekt.
Meine erste – zugegebenermaßen naive Idee – eine Art globales Wait-Flag im User-Objekt zu hinterlegen, um die nebenläufigen Threads zu synchronisieren, habe ich wieder begraben, weil so Dinge wie:

while(!US.get(this.created_by).done){}

Sich nur schwer bis gar nicht kontrollieren lassen. Und entweder den Status ändern (also auf TRUE gesetzt werden), obwohl das Objekt noch nicht geladen ist oder einfach in Endlosschleifen verenden.
Eine weitere interessante Möglichkeit wäre die Nutzung von XML-Inseln. Also die Möglichkeit, dass jedes Objekt (und in diesem Objekt dann jeweils eine Callback-Methode) dafür verantwortlich ist, dass seine eigene Daten in den DOM Tree der Seite gesetzt werden.
D.h. jedes User-Objekt würde sicher selber – bei Bedarf – als li – Node in ein ul Element auf der Seite setzen und so auch tatsächlich in der GUI die Userliste  füllen. Alle User Attribute könnte man entweder als li Attribute setzen (den Tag in dieser Hinsicht “verschmutzen”) oder aber halt in einen versteckten Layer packen. Sicherlich eine interessante Idee, aber letztendlich halt nicht wirklich 100% MVC, aber durchaus gängige Praxis im AJAX Umfeld.
Mein User-Service  würde dann auch kein  internes Cache Array haben – sondern direkt auf  den DOM-Knoten zugreifen.
Um den Zugriff zu vereinfachen habe ich mir schon ein paar Ersatz-Methoden geschrieben, um die Dinge zu verkürzen. Wer Prototype kennt, wird sich zuhause fühlen.

Object.prototype.$V = function(id, num){
    var num = num || 0;
    try{
        return this.$E(id)[num].firstChild.nodeValue;
    }catch(error){
        return null;
    }
};

Object.prototype.$E = function(id){
    return this.getElementsByTagName(id);
};

Letztendlich werden hier aber noch alle JS-Objekte verändert, sodass auch ein Array besagte Methoden enthält.
Ich werde mal schauen ob sich das irgendwie noch verfeinern lässt.

users REST

Flattr this!

GET http://localhost:8080/cotodo/users

gibt mir:

Weiterhin habe ich mir eine kleine Testanwendung geschrieben. Im Moment arbeite ich noch daran, per ajax meine GET/POST/PUT/DELETEs abzusetzen.

Als nächstes werde ich mich jetzt den unterschiedlichen Ausgabeformaten zuwenden und der Behandlung von POST/PUT Inputs

es geht voran

Flattr this!

Nach der gestrigen Ernüchterung habe ich es dann heute einfach noch mal mit ner aktuellen Eclipse Version versucht. Auf der Eclipse Homepage gibt es ja den “Europa Build”. Und siehe da: es ging plötzlich. War zwar erst immer noch etwas absturzfreudig das ganze, aber nachdem ich Java wieder auf Version 6 umgestellt habe, konnte ich sogar damit arbeiten.
Das hat zu folge, dass ich mittlerweile in wenig weiter mit JSP gekommen bin (allerdings immer noch auf bekanntem Gebiet 😀 – siehe dazu auch die Quelltexte).
Zudem habe ich dann heute mal mein erstes Script als JSP/YUI Kombination geschrieben. Und das schönste: es geht sogar.
Nachfolgend also eine Tabelle, die sehr simpel durch 2 Schleifen erstellt wurde.
Zudem habe ich Schleifen benutzt, um das JavaScript fürs YUI zu erstellen.
(für die Sortierfunktion muss man alle Table Headers als Array angeben – das war mir ein wenig zu mühselig um es per Hand zu machen 🙂 )
Tabelle ohne YUI:

Tabelle mit YUI:

(durch Klick auf den Tabellenkopf kann man die einzelnen Spalten jeweils sortieren)
allererstes Panel:

Letzendlich gibt es bei YUI immer zwei (okay eigentlich drei) Möglichkeiten, um den Inhalt zu erstellen.

  1. durch Veränderung von vorhandenem HTML Code (sog. Markup)
  2. durch reine JavaScript Befehle
  3. durch JavaScript und eine externe Quelle (sei es nun ein XML Feed oder JSON)

Das eröffnet einem einen relativ großen Bereich an Möglichkeiten.
Zudem fand ich heute eine weitere, interessant Seiten, auf der die verschiedenen Möglichkeiten des YUI Frameworks demonstriert werden. [1][2]
Der Code für die obigen Beispiele ist folgender:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello Client <%=request.getRemoteHost() %>!</title>
<style type="text/css">
    .grey{
        background: grey;
    }
    .black{
        background: black;
        color: white;
    }
    td, th{
        font-size: xx-small;
    }
</style>
<link rel="stylesheet" type="text/css" href="yui/fonts/fonts-min.css" />
<link rel="stylesheet" type="text/css" href="yui/datatable/assets/skins/sam/datatable.css" />

<script type="text/javascript" src="yui/utilities/utilities.js"></script>
<script type="text/javascript" src="yui/datasource/datasource-beta.js"></script>
<script type="text/javascript" src="yui/datatable/datatable-beta.js"></script>
<script type="text/javascript" src="yui/yahoo-dom-event/yahoo-dom-event.js"></script> 
<script type="text/javascript" src="yui/element/element-beta-min.js"></script> 

</head>
<body>
<a href="menu.jsp">Men&uuml;</a>
<h2>THIS is a JSP/YUI TEST TABLE!</h2>
<%
    int _cols = 20;
    int _rows = 30;
%>

<div id="myContainer">
<table  id="accounts">
<%
    out.println("t<thead><tr>");
    for(int j=0; j<_cols; j++){
        out.println("tt<th class="black">"+j+"</th>");
    }
    out.println("t</tr></thead>");
    String css_class = "";
    out.println("t<tbody>");
    for(int i=0; i<_rows;i++){
        out.println("t<tr>");
        if(i % 2 == 0)
            css_class = "white";
        else
            css_class = "grey";
        for(int j=0; j<_cols; j++){
            out.println("tt<td class=""+css_class+"">"+i+","+j+"</td>");
        }
        out.println("t</tr>");
    }
    out.println("t</tbody>");
%>
</table>
</div>

<script type="text/javascript">

YAHOO.util.Event.addListener(window, "load", function() {
    YAHOO.example.EnhanceFromMarkup = new function() {
        var myColumnDefs = [
            <%
            for(int j=0; j<_cols; j++){
                out.print("t{key:""+j+"",label:"No "+j+"", sortable:true}");
                if(j != (_cols-1))
                    out.println(",");
                else
                    out.println("");
            }
            %>
        ];

        this.myDataSource = new YAHOO.util.DataSource(YAHOO.util.Dom.get("accounts"));
        this.myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
        this.myDataSource.responseSchema = {
            fields: [

                    <%
                    for(int j=0; j<_cols; j++){
                        out.print("t{key:""+j+""}");
                        if(j != (_cols-1))
                            out.println(",");
                        else
                            out.println("");
                    }
                    %>
            ]
        };

        this.myDataTable = new YAHOO.widget.DataTable("myContainer", myColumnDefs, this.myDataSource,
                {caption:"Example: This is just the Table Title ;-)",
                sortedBy:{key:"0",dir:"desc"}});
        };

        this.parseNumberFromCurrency = function(sString) {
            // Remove dollar sign and make it a float
            return parseFloat(sString.substring(1));
        };
});

</script>

</body>
</html>

index.jsp (für die Tabelle)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Panel Demo</title>
<link rel="stylesheet" type="text/css" href="yui/fonts/fonts-min.css" />
<link rel="stylesheet" type="text/css" href="yui/container/assets/skins/sam/container.css" />
<script type="text/javascript" src="yui/yahoo-dom-event/yahoo-dom-event.js"></script>
<script type="text/javascript" src="yui/container/container.js"></script>
</head>
<body>
Simple Panel

<div id="myPanel">
	<div>my little Demo Panel</div>
	<div>
	<ul>
	<li><a href="index.jsp">item one</a></li>
	<li><a href="index.jsp">item two</a></li>
	<li><a href="index.jsp">item tree</a></li>
	</ul>
	</div>
	<div>&copy; by me :-)</div>
</div>

<script type="text/javascript">
myPanel = new YAHOO.widget.Panel("myPanel", {
	width:"240px", 
	height:"480px", 
	fixedcenter: true, 
	constraintoviewport: true, 
	underlay:"shadow", 
	close:false, 
	visible:true, 
	draggable:true } );
myPanel.render();
myPanel.show();
</script>

</body>
</html>

menu.jsp (für das Panel)

Hierbei ist zu beachten, dass jeweils zwischen der JSP Code zu finden ist. Von der Syntax ist JSP sehr an Java angelehnt.
Ich werde die restlichen Tage der Woche benutzen, um das ganze auch auf meinem Laptop zum Laufen zu kriegen und dann schon mal versuchen, eine Verbindung zu einer MySQL Datenbank herzustellen.