Google Chart Images, VBA, and the ESRI Map Web Part

Microsoft SharePoint lets you display hyperlink fields in a list as images, so the same batch URL generation technique I discussed in a previous post can be used if you have a set of hosted images that correspond to the items in a list, provided that those images have a standard URL format.  And because the Map Web Part fully supports hyperlink fields that are formatted as images, these images will be shown right in each feature's pop-up.

One popular source for images that relate to a set of data is Google Charts.  Through the Google Charts REST API, you can pass a URL that specifies your data and some formatting information and receive a chart image in return.  Since the URLs are data-driven and must be specified in a standardized format, they are a natural candidate for batch URL generation.  So first, write an Excel formula to generate a Google chart based on your data.  In the sample workbook, you can use the following:
=CONCATENATE("http://chart.apis.google.com/chart?chs=425x175&cht=p3&chco=FFFFFF,
FEFF01,03FF11,028088,80FF09,0201FF,810181,4101C0,FF0003,C00042,FEAA02,
FF5502&chl=Jan: $",CONCATENATE(G2, "|Feb: $", H2, "|Mar: $", I2, "|Apr: $",
J2, "|May: $", K2, "|Jun: $", L2,"|Jul: $", M2, "|Aug: $", N2, "|Sep: $", O2,
"|Oct: $", P2, "|Nov: $", Q2,"|Dec: $", R2),"&chf=bg,s,FFFFFF00&chd=t:",
ROUND(G2/S2 * 100, 0), ",", ROUND(H2/S2 * 100, 0), ",", ROUND(I2/S2 * 100, 0),
",", ROUND(J2/S2 * 100, 0),",",ROUND(K2/S2 * 100, 0),",",ROUND(L2/S2 * 100, 0),
",", ROUND(M2/S2 * 100, 0), ",", ROUND(N2/S2 * 100, 0), ",", 
ROUND(O2/S2 * 100, 0), ",", ROUND(P2/S2 * 100, 0),",", ROUND(Q2/S2 * 100, 0),
",", ROUND(R2/S2 * 100, 0))

This generates a URL that will create a labeled pie chart showing sales for each month.  Once you have the formula, follow steps 2-4 above.  When you create the hyperlink field in SharePoint, be sure to select the option to format it as a picture.

Now, there is one small issue with the Google Chart URLs.  SharePoint only supports URLs up to 255 characters in length, but the Google Chart URLs are much longer than this.  Fortunately, there are many free URL shortening services that expose REST APIs, and we can use VBA to call these in batch fashion.  In the code behind for the sample workbook, notice the methods shown below.  If you are using your own data, you should copy these methods into the code-behind for your workbook.

Private Sub ConvertLinksToShortUrls(sourceColumn As String, targetColumn As String, 
 startRow As Integer, endRow As Integer)
    Dim i As Integer
    Dim sourceCell As String
    Dim targetCell As String
    Dim shortUrl As String
    For i = startRow To endRow
        sourceCell = sourceColumn + CStr(i)
        shortUrl = ShortenURL(Range(sourceCell).Value)
        
        targetCell = targetColumn + CStr(i)
        Call Worksheets(1).Hyperlinks.Add(Range(targetCell), shortUrl)
        DoEvents
    Next i
End Sub

Private Function ShortenURL(longUrl As String)
    'Encode passed-in URL
    Dim encodedUrl As String
    encodedUrl = URLEncode(longUrl, True)
    
    'Construct URL to shortening service
    Dim requestUrl As String
    requestUrl = "http://ur.ly/new.xml?href=" + encodedUrl
    
    'Execute request to URL
    Dim net As Inet
    Set net = New Inet
    Call net.Execute(requestUrl)
    Do While net.StillExecuting
        DoEvents
    Loop
    
    'Get length of response
    Dim contentLength As Long
    contentLength = net.GetHeader("content-length")
    
    'Get response's XML content and escape ampersands
    Dim urlXml As String
    urlXml = net.GetChunk(contentLength)
    urlXml = Replace(urlXml, "&", "&")
    
    'Load response into DOM doc object
    Dim xml As DOMDocument60
    Set xml = New DOMDocument60
    Call xml.LoadXML(urlXml)
        
    'Extract short Url info from xml and construct short url
    Dim shortUrl As String
    shortUrl = "http://ur.ly/" + xml.getElementsByTagName("urly")
      (0).Attributes.NextNode.NodeValue
    
    ShortenURL = shortUrl
End Function

Public Function URLEncode( _
   StringToEncode As String, _
   Optional UsePlusRatherThanHexForSpace As Boolean = False _
) As String

  Dim TempAns As String
  Dim CurChr As Integer
  CurChr = 1

  Do Until CurChr - 1 = Len(StringToEncode)
    Select Case Asc(Mid(StringToEncode, CurChr, 1))
      Case 46 To 57, 65 To 90, 97 To 122
        TempAns = TempAns & Mid(StringToEncode, CurChr, 1)
      Case 32
        If UsePlusRatherThanHexForSpace = True Then
          TempAns = TempAns & "+"
        Else
          TempAns = TempAns & "%" & Hex(32)
        End If
      Case Else
        TempAns = TempAns & "%" & Hex(Asc(Mid(StringToEncode, CurChr, 1)))
    End Select

    CurChr = CurChr + 1
  Loop

  URLEncode = TempAns
End Function

The key here is the ConvertLinksToShortURLs method.  All you need to do to convert links in one range of cells to short URLs and copy them as hyperlinks to another range is call this method.  For the sample uncomment the call to this method and comment the call to CopyHyperlinks so that the AddUrlsToTable method appears as:
Private Sub AddUrlsToTable()
    'Call CopyHyperlinks("V", "T", 2, 79)
    Call ConvertLinksToShortUrls("W", "U", 2, 79)
    MsgBox "Operation Complete"
End Sub

Run this method to generate the shortened Google Chart URLs and synchronize the list with SharePoint.  Then load the list in your Map Web Part, hover over a feature, and see the chart show up in the pop-up:


Rich Zwaap
ESRI Product Engineer
ArcGIS Server .NET, Silverlight/WPF, MapIt

Published Thursday, October 29, 2009 3:08 PM by rexhansen
Filed under: , , ,

Comments

No Comments
Anonymous comments are disabled