Sunday, November 25, 2007

Grafici flash in Asp.Net 2.0

. Sunday, November 25, 2007

Se si vogliono inserire nelle proprie pagine asp.net grafici flash, esistono diverse library free e non. Fra le tante segnalo:

  • FusionCharts Free: può essere usata con diversi linguaggi, non solo con Asp.Net, ma anche ASP, PHP, JSP, Ruby on Rails, con la possibilità di generare grafici a barre, linee, torta, aree.
  • amCharts: 4 tipi di grafici: torta, linee & area, barre, bolle. Costo della licenza: da 85 a 275 euro.
  • Open Flash Chart: 35 tipi differenti, con una serie di effetti di mouse-over applicati sul grafico flash. Il progetto è rilasciato in GNU General Public License.

Ho fatto qualche esperimento usando proprio Open Flash Chart.
Per implementare il tutto basta:

  1. Scaricare la library.
  2. Compilare il progetto contenuto nella cartella dot-net-ofc-library.
  3. Referenziare la OpenFlashChart.dll generata con il passo 2.
  4. Nella vostra applicazione web creare una cartella aspnet_client, con una sottodirectory OpenFlashChart, in cui bisogna copiare il file open-flash-chart.swf e la cartella js( si trovano al seguente path: dot-net-ofc-library\WebTest\aspnet_client\OpenFlashChart).

Adesso si può iniziare a scrivere un pò di codice.
Per usare OFC.NET bisogna registrare la library attraverso il comando:

<%@Register TagPrefix="ofc" Namespace="OpenFlashChart" Assembly="OpenFlashChart" %>

e creare il controllo chart tramite il tag:



   1: <ofc:Chart Width="200" Height="200" Url="pageData.aspx" runat="Server" />

Il parametro più importante è senza ombra di dubbio Url che indica la risorsa dati per il grafico. Può essere sia un file html statico oppure generare il tutto dinamicamente tramite la library.
Nel caso specifico la pagina pageData.aspx contiene il codice per generare un chart a barre 3D:


   1: Dim graph As OpenFlashChart.Graph = New OpenFlashChart.Graph()
   2: graph.LegendX = New LegendX("Chart Test", 12, "#FF0000")
   3: graph.StepsY = 5
   4: graph.MaxY = 50
   5: Dim chart As OpenFlashChart.Charts.Bar3D = _
      New OpenFlashChart.Charts.Bar3D(10, "#001100", "Legend", 10)
   6: chart.Data.Add(20)
   7: chart.Data.Add(30)
   8: chart.Data.Add(40)
   9: chart.Data.Add(10)
  10: graph.Data.Add(chart)
  11: Response.Write(graph.ToString())
  12: Response.End()


Il codice è molto semplice, infatti tramite l'uso della library possiamo settare una serie di property per definire l'aspetto grafico del controllo chart, settare testo e formattazione di varie etichette, ecc.
Ora possiamo compilare ed osservare il risultato, ma qui son sorti i primi problemi.
Se visualizzo il tutto con Firefox, nessun problema ma se provo a lanciare la pagina aspx con il browser Internet Explorer 6 SP2(con la versione 7 non ho ancora avuto modo di fare un test a proposito) il grafico viene generato ma compare un errore javascript:
ofc1Ho pensato banalmente di aver dimenticato di settare la property ID del controllo chart.
Il risultato con mia grande sorpresa non cambia, ma peggiora Angry.
Sono così andato a spulciare il codice della library, in particolar modo la classe Chart.cs che contiene il metodo RenderContents attraverso il quale viene appunto renderizzato il controllo nella pagina aspx.
Dall'analisi del codice, si può notare che se si tratta di un SWFObject(di default è true) viene iniettato nella pagina uno script.
Perchè l'inserimento di questo script nella pagina?
Lo script SWFObject consente di rilevare il plugin flash, quindi ci consente di aggiungere contenuto flash con pochissime righe di codice, ma soprattutto evita sul browser Internet Explorer l'attivazione dei controlli ActiveX.
Proprio in questa porzione di codice ho fatto una "piccola modifica" cioè:


  1. l'id del div contenitore è dato da ClientID del controllo chart più il carattere "_" più il valore della property SequenceId
  2. l'id passato a new SWFObject è dato dal value della property ClientID( non ofc annegato nel codice).

In questo modo l'errore javascript non compare più e gira perfettamente anche su Internet Explorer:
ofc2

16 commenti:

Flatlineato said...

Ciao io ho modificato la libreria ed embendato il javascript e il flash nella dll, sotto firefox tutto ok ma explorer 7 addirittura quando inserisco il controllo in una pagina mi da un errore assurdo dicendo che la pagina non è raggiungibile.
Tu hai provato?

Sign In said...

Ciao Flat, dopo la tua indicazione ho voluto fare qualche prova anche sul browser Explorer 7 posso dirti che sembra funzionare tutto correttamente.
Verifica come prima cosa se non l'hai ancora fatto, che la pagina non raggiungibile sia imputabile al controllo graph ed inoltre se riesci a provare lo stesso codice anche su Explorer 6 SP2 per vedere se ci sono comportamente diversi.

Flatlineato said...

Grazie per l'aiuto ma dopo che ti ho scritto il messaggio ci ho lavorato un altro pò ed ho trovato l'errore, nella costruzione del javascript in questo punto dove fa il write non avevo aggiornato l'assegnazione dell'id.
Non capisco perchè desse quell'errore assurdo e non un semplice errore javascript.
Se può interessarti ti segnalo anche che nella libreria quando fa il to string per costruire le flash vars si sono scordati di mettere le label dell'assex.
Io ho aggiunto questo pezzo di codice:

if (this.LabelsX.Count > 0)
{
sb.Append("&x_labels=");
foreach (String labx in this.LabelsX)
{
sb.Append(labx + ",");
}
sb.Append("&\r\n");
}

nella classe Graph nel metodo ToString.

Info said...

Grazie a te per la segnalazione ;)

Anonymous said...

http://eden/open-flash-chart/dot-net.php

Thank you for the tutorial :-)

monk.e.boy

Anonymous said...

http://teethgrinder.co.uk/open-flash-chart/dot-net.php

ooops!!

monk.e.boy

Anonymous said...

ciao, io sto utilizzando OFC con asp.net 3.5 e non riesco in nessun modo a visualizzare due grafici nella stessa pagina aspx.

grosso modo la pagina è strutturatata così

-----------------
div id="container1"
ofc:Chart ID="Chart1" Width="300" Height="400" Url="datagraph2.aspx" runat="Server"

div id="container2"
ofc:Chart ID ="Chart2" runat ="server" width="300" Height = "400" url = "datagraph.aspx"

-----------------

Quando vado a vedere l'html della pagina trovo che

vengono renderizzati sia i div container che gli oggetti flash ma viene generato solamente il javascript relativo al primo oggetto.

Sai da cosa può dipendere?
grazie

Pierluca Petragallo said...

..ma il grafico del primo oggetto compare?

Anonymous said...

si, il primo grafico appare correttamente.
Analizzando l'hmtl ho notato che viene generato questo

>div<
>span id="Chart1" style="display: inline-block;"<
>div id="Chart1_014949" /<
>noscript<
>object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0"
width="300px" height="400px" id="chart_0" align="middle"<
>param name="allowScriptAccess" value="sameDomain" /<
>param name="movie" value="/test/aspnet_client/OpenFlashChart/open-flash-chart.swf?width=300px&height=400px&data=datagraph2.aspx" /<
>param name="quality" value="high" /<
>param name="bgcolor" value="#FFFFFF" /<
>embed src="/test/aspnet_client/OpenFlashChart/open-flash-chart.swf?data=datagraph2.aspx"
quality="high" bgcolor="#FFFFFF" width="300px" height="400px" name="open-flash-chart"
align="middle" allowscriptaccess="sameDomain" type="application/x-shockwave-flash"
pluginspage="http://www.macromedia.com/go/getflashplayer" id="embed_0" /<>/object<>/noscript<>/span<
>/div<
>div<
>span id="Chart2" style="display: inline-block;"<
>div id="Chart2_014949" /<
>noscript<
>object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0"
width="300px" height="400px" id="chart_1" align="middle"<
>param name="allowScriptAccess" value="sameDomain" /<
>param name="movie" value="/test/aspnet_client/OpenFlashChart/open-flash-chart.swf?width=300px&height=400px&data=datagraph.aspx" /<
>param name="quality" value="high" /<
>param name="bgcolor" value="#FFFFFF" /<
>embed src="/test/aspnet_client/OpenFlashChart/open-flash-chart.swf?data=datagraph.aspx"
quality="high" bgcolor="#FFFFFF" width="300px" height="400px" name="open-flash-chart"
align="middle" allowscriptaccess="sameDomain" type="application/x-shockwave-flash"
pluginspage="http://www.macromedia.com/go/getflashplayer" id="embed_1" /<>/object<>/noscript<>/span<
>/div<

>script type="text/javascript" src="/test/aspnet_client/OpenFlashChart/js/swfobject.js"<>/script<

>script type="text/javascript"<
var so = new SWFObject("/test/aspnet_client/OpenFlashChart/open-flash-chart.swf", "Chart1_014949", "300px", "400px", "9", "#FFFFFF");
so.addVariable("width", "300px");
so.addVariable("height", "400px");
so.addVariable("data", "datagraph2.aspx");
so.addParam("allowScriptAccess", "sameDomain");
so.write("Chart1_014949");
>/script<

(perdona il casino con i tag :-) )
Come puoi vedere, alla fine c'è il javascript relativo al primo grafico ma manca quello per il secondo.

Anonymous said...

tra l'altro... se aggiungo a mano il presunto javascript mancante

semplicemente copiando quello per il primo grafico e cambiando a mano i riferimenti(chart1 in chart2 etc...)

il grafico compare quindi a questo punto penso sia un bachetto...

Pierluca Petragallo said...

...potrebbe anche essere. Se riesco a ripescare il progetto usato per il post faccio qualche prova.

Anonymous said...

adesso provo a dare un'occhiata anche io nel codice sperando di capirci qualcosa...
Grazie per l'interessamento

Pierluca Petragallo said...

Purtroppo non avendo tempo per fixare nuovamente la dll( vedi post) ho eseguito il test solo su FF(firefox).
Ho inserito nella pagina due controlli ofc con le rispettive property url settate su due pagine differenti(quello che praticamente hai fatto te). Conclusione vedo i due grafici. Hai eseguito delle prove anche su FF.

Anonymous said...

no ma ci provo subito... (che piccione che sono)

Anonymous said...

test fatto e vedo sempre solo il primo grafico

Pierluca Petragallo said...

..a questo punto inviami un email con un progetto di test con l'essenziale( pagina per il grafico, ecc). Appena ho un attimo vedo di dargli uno sguardo

Post a Comment