amCharts for Charting

Exploring the use of WPF (Windows Presentation Foundation - part of Microsoft's .NET), there's a surprising void in the abssent shape of anything to do with (business) charting.  After writing more than enough charting code from the ground up it seemed that there was at least entertainment value in trying to hook up to something pre-written.  An inexhaustive list of what's available includes...


There are more, anyone with positive experiences to share is more than welcome.  My bias towards software I can use for free may not be the most rational selection criterion.

amCharts Options

amCharts offers a bewildering range of products all aimed at putting (business) charts into applications, two seemed worth exploring.

The website is - as the saying went - a "twisty little maze", which foretells the problems to come...

Let's dispose of the Quick Charts alternative; wasted several hours trying to make sense of it - couldn't get a chart to display.

More success with amCharts Bundle for WPF, first thing to note is the easy install, just unzip and put the DLL wherever suits you.  Downloading the documentation (a .chm file) seemed like a good idea, but wasn't - trying to look at it locally just produces "page not found" errors - so you have to navigate online.  And navigating through the pages is a nightmare, taking the reader round in endless circles and/or off to who-knows-where.  I think what we're seeing here is the peril of programmers believing that running code through an automated documentation-generator is how to create documentation.  Coupled with a rather take-it-or-leave-it attitude in their "support" forums.  I would be very reluctant to pay for this product.

Still, I can use it for free, so...

Making a DataView

We could (an earlier draft showed how) put everything - including data values - into XAML.  But it's a bit classier if we keep the XAML generic and push the data in through object properties - to achieve this we need to have something to turn APL matrices into .NET DataViews...

    ∇ z←MakeDataView(titles types data);⎕IO;⎕ML;dt
     ⍝ Make a .NET DataView from a matrix
      ⎕IO ⎕ML ⎕USING←0 3('System' 'System.Data,System.Data.dll')
      dt←⎕NEW DataTable
      ⍎'{}dt.Columns.Add¨',∊titles{'(''',⍺,'''',⍵,')'}¨types
      2010⌶dt data
      z←⎕NEW DataView dt
    ∇

Simple enough to use, three elements to the argument...
This function gets tucked away in a utility namespace  (it's useful for other .NET stuff besides charting)

PieChart Example

Tweaking ⎕USING

First we need to let APL know where to find all the amCharts stuff (I've put the DLL into a folder named in #.GLOBALS.homefolder), this function is used to add an entry to ⎕USING...

 ∇ use←UsingAmChart opt;chartpath
    ⍝ Add Charting namespaces
      use←''
      :If (⊂'AmChart')∊opt
          chartpath←#.GLOBALS.homefolder
          use,←⊂'AmCharts.Windows,',chartpath,'AmCharts.Windows.dll'
      :EndIf
    ∇

The PieChart Function


  ∇ PieChart(title columns values);⎕IO;⎕ML;f;⎕USING;xaml;n;dv
  ⍝ Display piechart
      ⎕IO ⎕ML←0 3
      ⎕USING←#.UTIL.WPF.Using⊂'AmChart'
      xaml←PieChartXAML title values
      f←#.UTIL.WPF.LoadXaml xaml(⊂'AmChart')
      n←1⊃#.UTIL.XAML.ExtractNames xaml
      f←n #.UTIL.WPFTOOLS.SetObjects f
      f.chartwindow.Title←title
      dv←#.UTIL.WPFTOOLS.MakeDataView columns('String' 'Int32')values
      f.piechart.SlicesSource←dv
      f.piechart.(TitleMemberPath ValueMemberPath)←columns
      {}f.ShowDialog
    ∇

Which is pretty routine, build a XAML definition of the window, get the object references we need, make a DataView out of our matrix, set properties appropriately, admire the chart...

The PieChart XAML


  ∇ xaml←PieChartXAML(title values);⎕IO;⎕ML
⍝ XAML to defime PieChart window
      ⎕IO ⎕ML←0 3
      xaml←' <Window'
      xaml,←'     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"'
      xaml,←'     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"'
      xaml,←'     xmlns:am="http://schemas.amcharts.com/charts/wpf/2009/xaml"'
      xaml,←'     Name="chartwindow" Height="350" Width="600">'
      xaml,←'     <Grid>'
      xaml,←'         <am:PieChart Name="piechart"/>'
      xaml,←'     </Grid>'
      xaml,←' </Window>'
    ∇

Maybe data binding might make it easier - haven't tried that yet.

In Action

   ]displayr title columns values
┌3────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ┌17───────────────┐ ┌2───────────────┐ ┌2─────────────────────────────────────────────────────────────┐ │
│ │Count for Browser│ │ ┌4───┐ ┌5────┐ │ 3 ┌54────────────────────────────────────────────────────┐     │ │
│ └─────────────────┘ │ │Item│ │Count│ │ │ │Baiduspider+(+http://www.baidu.com/search/spider.htm)"│ 3   │ │
│                     │ └────┘ └─────┘ │ │ └──────────────────────────────────────────────────────┘     │ │
│                     └2───────────────┘ │ ┌20──────────────────┐                                       │ │
│                                        │ │Googlebot-Image/1.0"│                                   122 │ │
│                                        │ └────────────────────┘                                       │ │
│                                        │ ┌11─────────┐                                                │ │
│                                        │ │Mozilla/5.0│                                            281 │ │
│                                        │ └───────────┘                                                │ │
│                                        └¯2────────────────────────────────────────────────────────────┘ │
└¯3───────────────────────────────────────────────────────────────────────────────────────────────────────┘

 #.UTIL.AMCHART.PieChart title columns values

Showing us...



BarChart Example

Following pretty much the same agenda (but property names are different); note also the AmCharts offers Bar and Column charts with a trivial property change...
   ∇ BarChart w
    ⍝ Display Barchart in a window
      'Vertical'XYChart w
    ∇
    ∇ ColumnChart w
    ⍝ Display Columnchart in a window
      'Horizontal'XYChart w
    ∇
    ∇ orientation XYChart(title legend columns values);⎕IO;⎕ML;f;n;c;⎕USING;xaml;dt;dv
  ⍝ Display barchart or columnschart
      ⎕IO ⎕ML←0 3
      ⎕USING←#.UTIL.WPF.Using⊂'AmChart'
      xaml←XYChartXAML orientation
      f←#.UTIL.WPF.LoadXaml xaml(⊂'AmChart')
      n←1⊃#.UTIL.XAML.ExtractNames xaml
      f←n #.UTIL.WPFTOOLS.SetObjects f
      f.chartwindow.Title←title
      f.xychart.Title←legend
      dv←#.UTIL.WPFTOOLS.MakeDataView columns('String' 'Int32')values
      f.xychart.DataItemsSource←dv
      f.xychart.(SeriesIDMemberPath ValueMemberPath)←columns
      {}f.ShowDialog
    ∇
    ∇ xaml←XYChartXAML orientation;⎕IO;⎕ML
⍝ Generate XAML for a barchart or columnchart
      ⎕IO ⎕ML←0 3
      xaml←'<Window'
      xaml,←'    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"'
      xaml,←'    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"'
      xaml,←'    xmlns:am="http://schemas.amcharts.com/charts/wpf/2009/xaml"'
      xaml,←'    Height="400" Width="640" Name="chartwindow" >'
      xaml,←'    <Grid>'
      xaml,←'        <am:ColumnChart Orientation="',orientation,'">'
      xaml,←'            <am:ColumnChart.Graphs>'
      xaml,←'                <am:ColumnChartGraph Name="xychart"/>'
      xaml,←'            </am:ColumnChart.Graphs>'
      xaml,←'        </am:ColumnChart>'
      xaml,←'    </Grid>'
      xaml,←'</Window>'
    ∇

  ]displayr title legend columns values
┌4──────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ┌17───────────────┐ ┌7──────┐ ┌2───────────────┐ ┌2─────────────────────────────────────────────────────────────┐ │
│ │Count for Browser│ │Browser│ │ ┌4───┐ ┌5────┐ │ 3 ┌54────────────────────────────────────────────────────┐     │ │
│ └─────────────────┘ └───────┘ │ │Item│ │Count│ │ │ │Baiduspider+(+http://www.baidu.com/search/spider.htm)"│ 3   │ │
│                               │ └────┘ └─────┘ │ │ └──────────────────────────────────────────────────────┘     │ │
│                               └2───────────────┘ │ ┌20──────────────────┐                                       │ │
│                                                  │ │Googlebot-Image/1.0"│                                   122 │ │
│                                                  │ └────────────────────┘                                       │ │
│                                                  │ ┌11─────────┐                                                │ │
│                                                  │ │Mozilla/5.0│                                            281 │ │
│                                                  │ └───────────┘                                                │ │
│                                                  └¯2────────────────────────────────────────────────────────────┘ │
└¯3─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

 #.UTIL.AMCHART.BarChart title legend columns values



Summing Up

At present my trials have been limited to the chart types above - there are a heap more properties to explore/use (and it seems that trial and error is going to be more forthcoming than the documentation).

What's here isn't particularly pretty (I need to try and extract more sense from the documentation and examples), or sophisticated  - but it does appear to be something I can drop thoughtlessly into applications which need these sorts of charting.  And it does seem to be more reliable than WPF Toolkit (although still not 100% - from time to time I see spurious DOMAIN ERROR elsewhere in application code with good arguments after drawing some charts).  It also demonstrates (again) that we're way out of the APL comfort zone (and APL's rationality).

Hopefully something better will turn up soon.

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

Page updated 10 November 2011; Copyright © Dogon Research 2011