These forums are now Read Only. If you have an Acrobat question, ask questions and get help from one of our experts.

Using Google Charts APIs with Adobe LiveCycle and ASP.NET !

tarekahf
Registered: May 1 2008
Posts: 91
Answered

Ok guys ... I am sorry that I am asking this question which has a lot of mix of technology.... I like to work with different platforms ...

Background:

I am using Adobe LiveCycle Designer 7.1 to work with secured forms, and generate PDF Reports on the fly (using XDP meaning XML Data Package). So far, I successfully used ASP.NET to generate LiveCycle Forms from the Server, and submit the PDF Form from the Server to ASPX Page, and process the form values on the server.

The Problem:
=========
I need now to include Charts and Analytical Data on the Generated PDF Forms by executing queries in ASP.NET on the server, generate DataSet Results which will be used to draw the Charts, and publish the charts on the PDF Form (LiveCycle Designer PDF).

Adobe LiveCycle Designer 7.1 Form has "Image Field" which is very similar to tab in HTML. It has Source URL Property, and if you assign to it the source of the chart as PNG or JPG then it will display the image on the PDF properly.

I am thinking to use some kind of tool or a method, where I can pass the DataSet/DataTable which has the graph data to be drawn, generate the Graph, Save the result as image file on a sub-folder under the Root Web Folder, assign the URL to the PDF Form Image Filed and that is all what needs to be done.

I found this link:

http://www.drflex.eu/category/livecycle/livecycle-output-es/

which talks about using LiveCycle ES (which is different that LiveCycle Designer) and Google Charts APIs (http://code.google.com/apis/chart/).

This is a sample of using Google Charts API:

The Image Source is:

http://chart.apis.google.com/chart?cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World

[img]http://chart.apis.google.com/chart?cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World[/img]

I tried to assign the above link to the PDF Image Field URL Peroperty, it did not work for some reason. I tried to used an absolute link to a Physical Image File, it worked. It looks like this is a limitation in LiveCycle Designer 7.1.

I think the workaround is to call the Google Chart API, retrieve the result as Binary, save the result to a file in the local web folder, and generate the URL to the Image, and assign it to the PDF Image Field URL Properly.

The Question:
========
- How I can use ASP.NET to execute a call to Google Chart API, and save the result image to a file locally ?

- Any other suggestions ?

Tarek.

My Product Information:
LiveCycle Designer, Windows
tarekahf
Registered: May 1 2008
Posts: 91
I hope someone can help !

In otherwords, I need to use an easy method to enable me add charts and graphs to my LiveCycle PDF Forms based on a Data Table or some other data sourse.

I did some search, and found out the Adobe Flex has super charting capabilities but I am not sure if it can be used with Adobe LiveCycle Desinger 7.1.

Any idea on how to add charting to PDF will be appreciated.

Tarek.
tarekahf
Registered: May 1 2008
Posts: 91
I will post update quickly.

I managed to use NGCharts (.NET Wrapper for Google Charts) to generate charts, download the file to a local web folder using HttpWebRequest Object as PNG Image File, and pass the relative URL of this Image File to Adobe LiveCycle Form, Image Field, using XDP.

All worked successfully. Very cool indeed.

Any one interested in the details, I can post the sample code.

Tarek.
keepitfrozen
Registered: Feb 20 2008
Posts: 8
I would be interested in how you did this. You've pretty much been talking over my head but it would be nice to see your results.

thanks,

Mark
tarekahf
Registered: May 1 2008
Posts: 91
keepitfrozen wrote:
I would be interested in how you did this. You've pretty much been talking over my head but it would be nice to see your results.thanks,

Mark
keepitfrozen ,

There you go:

Imports System.IOImports System.DrawingImports System.NetImports System.DataImports System.Data.CONNXImports NGChart

Partial Class TestGoogleChartInherits System.Web.UI.Page Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Dim strXML As StringDim myDataSet As New DataSetDim i As Integer'' Steps how to Draw Graph using Google Chart APIs'' 1. Open Database and Execute Query which needs to have a Graph' Fill result into DataSet.'Using cn As New OleDb.OleDbConnection(Database.AnalysisDB)Using cmd As OleDb.OleDbCommand = cn.CreateCommandcmd.CommandType = Data.CommandType.Textcmd.CommandText = "select * from qStaffCountByNationality02"Using da As New OleDb.OleDbDataAdapter(cmd)da.Fill(myDataSet)End Using

End Using

End Using

'' 2. Convert the DataSet/Table into Array of Data Items and Lables to be' used on the Graph.'Dim myArrayData() As IntegerDim myArrayLabels() As StringDim myArrayColors() As String = [Enum].GetNames(GetType(System.Drawing.KnownColor))Dim myChartColors() As System.Drawing.ColorReDim myArrayData(myDataSet.Tables(0).Rows.Count)ReDim myArrayLabels(myDataSet.Tables(0).Rows.Count)ReDim myChartColors(myDataSet.Tables(0).Rows.Count)Dim idxColor As IntegerDim idxColorStep As Integer'' StartColorIdx and ColorStep are used to generate different colors for the chart'If Not Request.QueryString("StartColorIdx") Is Nothing AndAlso Request.QueryString("StartColorIdx").Length <> 0 ThenIf IsNumeric(Request.QueryString("StartColorIdx").ToString) ThenidxColor = CInt(Request.QueryString("StartColorIdx"))Else

Response.Write("Error: The Parameter StartColorIdx must be numeric.")End If

Else

idxColor = 30

End If

If idxColor > myArrayColors.Length - 1 - myDataSet.Tables(0).Rows.Count ThenidxColor = myArrayColors.Length - 1 - myDataSet.Tables(0).Rows.Count - 10

End If

If idxColor < 0 ThenidxColor = 0

End If

If Not Request.QueryString("ColorStep") Is Nothing AndAlso Request.QueryString("ColorStep").Length <> 0 ThenIf IsNumeric(Request.QueryString("ColorStep").ToString) ThenidxColorStep = CInt(Request.QueryString("ColorStep"))Else

Response.Write("Error: The Parameter ColorStep must be numeric.")End If

Else

idxColorStep = 5

End If

If idxColorStep < 0 Or idxColorStep > 10 ThenidxColorStep = 5

End If

For i = 0 To myDataSet.Tables(0).Rows.Count - 1

myArrayData(i) = myDataSet.Tables(0).Rows(i).Item("TotalCount")myArrayLabels(i) = myDataSet.Tables(0).Rows(i).Item("Nationality").ToString.TrimmyChartColors(i) = Color.FromName(myArrayColors(idxColor))

idxColor = (idxColor + idxColorStep) Mod myArrayColors.Length

Next

'
' 3. Create PieChart as an Example and set the Data Items and Lables.' This sample uses NGChart wrapper for Google Charts APIs.'Dim PieData As New ChartData(myArrayData)

Dim pieLabels As New PieChartLabels(myArrayLabels)

Dim myPieChart As New PieChart(PieChartType.Pie3D, New ChartSize(625, 250), PieData)

myPieChart.Labels = pieLabels

myPieChart.Colors = New ChartColors(myChartColors)

'
' 4. Using the result of the Google Chart API URL, download the Image File using' HttpWebRequest Object.'' After Downloading the file, must save the file to a relative location and generate a' relative URL for the image.'SaveFileFromURL(myPieChart.ToString, Server.MapPath(".\images") & "\TarekChart.png", 5)'' 5. Generate the XDP LiveCycle Form Document as shown below.'Response.ContentType = "application/vnd.adobe.xdp+xml"'Response.ContentType = "text/html"'' Constant XDP Header'strXML = "<?xml version='1.0' encoding='UTF-8'?>"strXML = strXML & "<?xfa generator='AdobeDesigner_V7.0' APIVersion='2.2.4333.0'?>"strXML = strXML & "<xdp:xdp xmlns:xdp='http://ns.adobe.com/xdp/'>"strXML = strXML & "<xfa:datasets xmlns:xfa='http://www.xfa.org/schema/xfa-data/1.0/'>"strXML = strXML & "<xfa:data>"'' Values of the LiveCycle Form goes here' The relative location of the image file is:'' href="./images/TarekChart.png"'' The Image Fiels Name is "GoogleChart" in the PDF Form.'strXML = strXML & "<form1>"'strXML = strXML & "<GoogleChart xmlns:xfa=""http://www.xfa.org/schema/xfa-data/1.0/"" xfa:contentType=""image/png"" href=""http://blablabla/TarekChart.png""></GoogleChart>"strXML = strXML & "<GoogleChart xmlns:xfa=""http://www.xfa.org/schema/xfa-data/1.0/"" xfa:contentType=""image/png"" href=""./images/TarekChart.png""></GoogleChart>"strXML = strXML & "<TestField>Testing</TestField>"strXML = strXML & "</form1>"'''strXML = strXML & "</xfa:data>"strXML = strXML & "</xfa:datasets>"'' Point the XPD to the PDF Form created under Adobe LiveCycle Desinger'strXML = strXML & "<pdf href='http://blablabla/TestCharts.pdf' xmlns='http://ns.adobe.com/xdp/pdf/' />"'' Close the XPD File'strXML = strXML & "</xdp:xdp>"Response.Write(strXML)

Response.Flush()

Response.End()

End Sub

End Class

And ... following is the "SaveFileFromURL" function:

    Public Shared Function SaveFileFromURL(ByVal url As String, ByVal destinationFileName As String, ByVal timeoutInSeconds As Integer) As Boolean ' Create a web request to the URL Dim MyRequest As HttpWebRequest = CType(WebRequest.Create(url), HttpWebRequest)

MyRequest.Timeout = timeoutInSeconds * 1000

Try

 Dim MyProxy As New WebProxy()

'
MyProxy = CType(MyRequest.Proxy, WebProxy)MyProxy = New WebProxy("your.proxy.address", 8080)' Get the web response'MyRequest.Proxy = MyProxy'MyRequest.Proxy = WebRequest.DefaultWebProxyWebRequest.DefaultWebProxy.Credentials = CredentialCache.DefaultCredentials

'
MyRequest.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials'MyRequest.PreAuthenticate = True'MyRequest.AuthenticationLevel = Net.Security.AuthenticationLevel.MutualAuthRequested'MyRequest.Proxy.Credentials = New NetworkCredential("userid", "password", "domain")'MyRequest.Proxy.Credentials = CredentialCache.DefaultCredentialsDim MyResponse As HttpWebResponse = CType(MyRequest.GetResponse(), HttpWebResponse) ' Make sure the response is validIf (HttpStatusCode.OK = MyResponse.StatusCode) Then

 '
Open the response streamUsing MyResponseStream As Stream = MyResponse.GetResponseStream()' Open the destination fileUsing MyFileStream As FileStream = New FileStream(destinationFileName, FileMode.OpenOrCreate, FileAccess.Write)

 '
Create a 4K buffer to chunk the fileDim MyBuffer(4096) As ByteDim BytesRead As Integer' Read the chunk of the web response into the bufferBytesRead = MyResponseStream.Read(MyBuffer, 0, MyBuffer.Length)

While (0 < BytesRead)'
Write the chunk from the buffer to the fileMyFileStream.Write(MyBuffer, 0, BytesRead)BytesRead = MyResponseStream.Read(MyBuffer, 0, MyBuffer.Length)End Whileend using

End Using

End IfCatch err As ExceptionThrow New Exception("Error saving file from URL:" + err.Message, err)End TryReturn TrueEnd Function

And the last thing you may need to know is to download the NGChart Library from the related web site.

I hope this will be helpful.

(From the sound of your writing, it seems that you though that I was joking !!! )
Tarek.
tarekahf
Registered: May 1 2008
Posts: 91
Guys ...

Just to let you know that the above technique will not work properly if you upgrade to Acrobat 8.1 / LiveCycle Designer ES 8.1 or higher ...

Minor change will be required ...

When you compose the XML String Data, you must load the image into a memory stream, convert it to Base64 String, and assign this value to the Image Field Node Value of the XML String. In this case the "href" attribute must be empty string href="".

If more details are required, do not hesitate to ask me.

Tarek.
prateekbh
Registered: May 5 2010
Posts: 10
hi Tarek,
whould you please provied some sample xml code for using base 64 string as image field value
tarekahf
Registered: May 1 2008
Posts: 91
prateekbh,

Sure, check this link:

http://groups.google.com/group/livecycle/browse_thread/thread/4a5db82ceef9cabd/d804b26a38fee6a7?lnk=gst&q=image+base64#d804b26a38fee6a7Tarek.
prateekbh
Registered: May 5 2010
Posts: 10
Thanks Tarek for your quick response.Can you provied me the sample pdf also for reference which is having this xml data.

prateek
tarekahf
Registered: May 1 2008
Posts: 91
Do you want the sample PDF of the Staff Profile, or for Google Chart ?

Tarek.
prateekbh
Registered: May 5 2010
Posts: 10
I want the sample pdf in which you have the assigned the base 64 string to the Image Field as its value.I think your using this in Google Charts. so will you please provied me this pdf.


prateek
prateekbh
Registered: May 5 2010
Posts: 10
Hi Tarek,
I have implemented your xml code,but in that we are
embedding the image data(as base64 string),means its not at
all dynamic loading of images.I want to load images
dynamically,in adobe 7 its working fine with setting image
feild value as "href" but in version 8.1 or higher its not
working. Is there any java script or script is available for
convertin the image into base 64 string.so we can use it
within the pdf file.

What is my requirment is to send pdf throught email along with the
images in other folder or URL. and when user opne the pdf the images
should be loaded dynamically for the specified folder or url and if user
save that pdf then only these images should be embedd into the file.

Please reply if you have solution for this problem.

Thanks in advance.

Prateek
tarekahf
Registered: May 1 2008
Posts: 91
prateekbh wrote:
Hi Tarek,
I have implemented your xml code,but in that we are
embedding the image data(as base64 string),means its not at
all dynamic loading of images.I want to load images
dynamically,in adobe 7 its working fine with setting image
feild value as "href" but in version 8.1 or higher its not
working. Is there any java script or script is available for
convertin the image into base 64 string.so we can use it
within the pdf file.

What is my requirment is to send pdf throught email along with the
images in other folder or URL. and when user opne the pdf the images
should be loaded dynamically for the specified folder or url and if user
save that pdf then only these images should be embedd into the file.

Please reply if you have solution for this problem.

Thanks in advance.

Prateek
What you are asking for might be possible, but I have not done before.

But, why you want to do it that way ? You can have same result if you convert the images to Base64 on the server, and generate the XDP String accrodingly.

Note that once the form is loaded on the client, there are very limitted ways how the PDF can contact the outside world due to security restrictions.

Are you trying to save loading time and/or transmission speed ?

If you will have to convert the image from Binary to Base64 string on the Client using Javascript, then you are not saving anything in terms of speed or size, the net effect is the same, as a matter of fact, you are complicating you solution and making it more difficult to maintain.

In my openion, you should convert the images to Base64 String on the server and the client will only display the result.

See the Sample PDF for using Google Charts:

http://docs.google.com/fileview?id=0B97clwYte2SHNzRkOWI1ZWYtZDAxOC00ZmEzLWIzN2QtNmUxYjdmMDNjYThk&hl=en
prateekbh
Registered: May 5 2010
Posts: 10
Thanks for your suggestion tarek, why i want this is when we are sending pdf files with all images embedded in it the pdf file size becoming very large,so if we have some machenizm to send the images saparetly then when the user open the pdf file it will uplaod(show) the image from the remote location and after viewing if user want to embedd images into the pdf file permanently then he can save the pdf.

I also want to disable the images field from showing the image selection dialog box.so user will find this as a normal image.

But by converting the image to base64 string we are actully embedding the image data into the pdf file so we can not say that we are adding the images dynamically its just like the static image embedding into the file.

Please give me some suggestions if u have any idea about how can we achive this.



Prateek
tarekahf
Registered: May 1 2008
Posts: 91
Ok, I see your point.

The other method you want to try is to use a webservice that will return the image data as Base64 string.

Before you build the webservice, try to write a function inside PDF with a very small image converted to Base64 String. So, covert the image to Base64 and assign the result as a String Variable inside PDF JavaScript, for example:

var myImage = "asdjasldaklsjdhklasjhdlkasjdlkasjdlaksjdlkajsdlkajsdl"

Then, on click of a button, assign the value of the string to where it should be.

You can do that first manually, using Image Filed. Click on the Image Field, and assign a small image, then Export the result to XML File, see how it looks, the copy the Base64 String and put it inside JavaScript program.

If it works, then it should work by using webservice to get the Base64 String. The only problem here is the limits on the WebService Parameter Passing, I am not sure of this will be up to the job.

Another option it to try using the Message Passing between IE and PDF. There is a cool way to pass data between IE and PDF and there is a cool sample on this like:

http://www.windjack.com/WindJack/Browser2PDF/brwsr2acroJS.htm

Hope this helps.

Tarek.
prateekbh
Registered: May 5 2010
Posts: 10
Thanks Tarek, I have tried the first method which you suggest,I have executed this java script for base 64 conversion :

xfa.data.Document.base64.value= ((SOAP.stringFromStream(SOAP.streamEncode(myDoc.getDataObjectContents("c:\\1.jpeg"), "base64"))));


it works fine. I have got the converted Base64 string in "xfa.data.Document.base64.value" , but now my problem is to pas this value to the image field in data sets.

(ImageField1 xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/" href="" xfa:contentType="image/jpg"
)
............................................................... (Here i need to pas that value but i m not getting)
(/ImageField1)


Please suggest me some idea for work it out.


Note:: I am using "(" in place of "<" here because html tags are not allowed in this forum.Prateek
tarekahf
Registered: May 1 2008
Posts: 91
prateekbh wrote:
Thanks Tarek, I have tried the first method which you suggest,I have executed this java script for base 64 conversion :xfa.data.Document.base64.value= ((SOAP.stringFromStream(SOAP.streamEncode(myDoc.getDataObjectContents("c:\\1.jpeg"), "base64"))));


it works fine. I have got the converted Base64 string in "xfa.data.Document.base64.value" , but now my problem is to pas this value to the image field in data sets.

(ImageField1 xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/" href="" xfa:contentType="image/jpg"
)
............................................................... (Here i need to pas that value but i m not getting)
(/ImageField1)


Please suggest me some idea for work it out.


Note:: I am using "(" in place of "<" here because html tags are not allowed in this forum.Prateek
I am not sure if I understand what is the problem you are facing ?!

Did you try to assign the Base64 value of the image and the image is not showing ? Or you cannot assign this value ?

Try the following.

Create 2 image fields A and B. Image A is assigned manually, and B to be assigned by the program.

Try to assign the Base64 value of B inside javascript on click of a button. On click of another button, use console.println() to display the Base64 value of A and the Base64 value of B after it is assigned just to be sure. Compare the results.

If Image B is not showing, then this behavior is by design. It means Adobe does not allow this.

To try all possibilities, try to assign the Base64 value of the B on some Initialize Event of the document.

Let me know the result.

Also, it would be nice if you could post all the code you have developed for this exercise, including the one used to get the Base64 string.

Tarek.