ChartDirector Graphs Retina Apps

Hello – I have to following code for a polar chart that displays wind speed and direction. The canvas it paints into is 200x200. I would like to figure out how to increase the resolution to sharpen up the text, lines, labels, etc to look good on a Retina mac. I found how you can do this with images, but not with graphs. I have line graphs as well that I need to figure this out. But I thought I would start with the polar graph. Here is the code:


  dim wind as double = val(dataArray(10))
  
  dim winddir as double = val(NthField(TextFieldWindDir.Text, ",", 1))
    
  // Create a PolarChart object of size 200 x 200 pixels which is the Canvas.Wind size, with a silver background
  // and a 1 pixel 3D border
  dim c as new CDPolarChartMBS(CanvasWind.Width, CanvasWind.height, CDPolarChartMBS.silverColor)
    
  // set wallpaper from folder image
  c.setWallpaper(f)
  
  // Set plot area center at (102, 100) with radius 80 pixels and white background
  c.setPlotArea(102, 100, 80)', &hF2F2F2)
  
  // Set the grid style to circular grid
  c.setGridStyle(false)
  c.setGridColor(&h000080)
  
  // Set angular axis as 0 - 360, with a spoke every 30 units
  c.angularAxis.setLinearScale(0, 360, 30)
  c.angularAxis.setLabelStyle.setFontSize(7)
  c.angularAxis.setLabelStyle.setFontColor(&h000080)
  call c.radialAxis.setLabelStyle "",7
  c.angularAxis.setLabelGap 3
  
  
  // Add sectors to the chart as sector zones
  c.angularAxis.addZone(winddir - 5, winddir + 5, 0, wind, &h33ff33, &h008000)
  
  If wind = 0 Then 
   
    //Add another layer to to capture wind direction as bubble
    dim layer0 as CDPolarLineLayerMBS
    layer0 = c.addLineLayer(array(wind+100),&h33ff33)
    layer0.setAngles(array(winddir))
  
  // Disable the line by setting its width to 0, so only the symbols are visible
    layer0.setLineWidth(0)
  
  // Use a circular data point symbol
    layer0.setDataSymbol(CDPolarChartMBS.kCircleSymbol, 6)
    
  Else
  end
  
  // Add layer to ensure the axis is auto-scaled using the
  // data
  call c.addLineLayer(array(wind), &h000080)
  
  // Output the chart
  CanvasWind.Backdrop=c.makeChartPicture

Any help/ideas would be greatly appreciated. I’m running this on my 15" MacBook Pro Retina with Mavericks (OSX 10.9.2).

Thanks
JP

This might be me oversimplifying it, but why don’t you draw it as 2x the width and height and place it in the original position? This is what would be done with an image .

We have some high res examples which show how to make high res images.
You need to increase all sizes by a given factor (2 for you).

Thanks Christian – I’ve tried this a few times, but I am missing something. I did the scale factor by 2. The plot now centers on the lower right corner of the canvas. The wind speed labels look OK, but are large. The lines and the spoke labels are still blurry. Here is the code:

 
  const f = 2   // for retina

  dim wind as double = val(dataArray(10))
  
  dim winddir as double = val(NthField(TextFieldWindDir.Text, ",", 1))
    
  // Create a PolarChart object of size 200 x 200 pixels which is the Canvas.Wind size, with a silver background
  // and a 1 pixel 3D border
  dim c as new CDPolarChartMBS(f*CanvasWind.Width, f*CanvasWind.height, CDPolarChartMBS.silverColor)
    
  // set wallpaper from folder image
  c.setWallpaper(fi)
  
  // Set plot area center at (102, 100) with radius 80 pixels and white background
  c.setPlotArea(f*102, f*100, f*80)', &hF2F2F2)
  
  // Set the grid style to circular grid
  c.setGridStyle(false)
  c.setGridColor(&h000080)
  
  // Set angular axis as 0 - 360, with a spoke every 30 units
  c.angularAxis.setLinearScale(0, 360, 30)
  c.angularAxis.setLabelStyle.setFontSize(7*f)
  c.angularAxis.setLabelStyle.setFontColor(&h000080)
  call c.radialAxis.setLabelStyle "",7*f
  c.angularAxis.setLabelGap 3*f
  
  
  // Add sectors to the chart as sector zones
  c.angularAxis.addZone(winddir - 5, winddir + 5, 0, wind, &h33ff33, &h008000)
  
  If wind = 0 Then 
   
    //Add another layer to to capture wind direction as bubble
    dim layer0 as CDPolarLineLayerMBS
    layer0 = c.addLineLayer(array(wind+100),&h33ff33)
    layer0.setAngles(array(winddir))
  
  // Disable the line by setting its width to 0, so only the symbols are visible
    layer0.setLineWidth(0)
  
  // Use a circular data point symbol
    layer0.setDataSymbol(CDPolarChartMBS.kCircleSymbol, 6)
    
  Else
  end
  
  // Add layer to ensure the axis is auto-scaled using the
  // data
  call c.addLineLayer(array(wind), &h000080)
  
  // Output the chart
  CanvasWind.Backdrop=c.makeChartPicture

In summary I did the f* … in the following locations:

new CDPolarChartMBS
setPlotArea
setFontSize
setLabelStyle
setLabelGap

I run this in a method called GraphWind, then output the chart via CanvasWind.Backdrop – if that makes a difference. Do you see anything I am missing?

Thanks for your assist.
JP

So what these high res examples seem to do is double the size of the chart when using a factor of 2 – which is too large for my canvas, hence the center of the plot rests on the lower right corner. The canvas size is 200x200. The above code makes the chart 400x400. How do I scale it back down to fit the canvas and keep it sharp?

I really don’t know what I’m doing here …
JP

you can’t use backdrop property. You have to use paint event and there draw the 400x400 picture in a 200x200 rectangle.

Hmmm … so save the 400x400 chartpicture as an image, then use g.drawpicture() in the canvas paint event? How do I keep or save as a transparent background?

Appreciate the help.
JP

Well, it should stay transparent of course.

I made myself an example for surface chart with retina.
The difficulty is that you need to apply the factor all default values, so set all the label sizes bigger.

Thanks Christian – you’ve been a great help.

I still can not get the spoke labels to increase in size for the PolarChart. Do you see something in the code that is not correct?


  const s = 2
  
  Dim windrose As Picture
  
  DIm f As FolderItem

  f =SpecialFolder.Documents.Child("jpweather").Child("rainwise").Child("windrose.png")
 
 // Data for the chart
  
  dim wind as double = val(dataArray(10))
  
  dim winddir as double = val(NthField(TextFieldWindDir.Text, ",", 1))
  
  
  // Create a PolarChart object of size 200 x 200 pixels, with a transparent background

  dim c as new CDPolarChartMBS(s*CanvasWind.Width, s*CanvasWind.Width, CDPolarChartMBS.kTransparent)
  
  // Set plot area center at (102, 100) with radius 80 pixels and white background
  c.setPlotArea(s*102, s*100, s*80)
  
  // Set the grid style to circular grid
  c.setGridStyle(false)
  c.setGridColor(&h000080)
  
  // Set angular axis as 0 - 360, with a spoke every 30 units
  c.angularAxis.setLinearScale(0, 360, 30)
  c.angularAxis.setLabelStyle.setFontSize(7*s)
  c.angularAxis.setLabelStyle.setFontColor(&h000080)
  call c.radialAxis.setLabelStyle "",7*s
  c.angularAxis.setLabelGap 3*s
  
  
  // Add sectors to the chart as sector zones
  c.angularAxis.addZone(winddir - 5, winddir + 5, 0, wind, &h33ff33, &h008000)
 
  If wind = 0 Then 

    //Add another layer to to capture wind direction as bubble
    dim layer0 as CDPolarLineLayerMBS
    layer0 = c.addLineLayer(array(wind+100),&h33ff33)
    layer0.setAngles(array(winddir))

    // Disable the line by setting its width to 0, so only the symbols are visible
    layer0.setLineWidth(0)

    // Use a circular data point symbol
    layer0.setDataSymbol(CDPolarChartMBS.kCircleSymbol, 6*s)
    
  Else
  end
  
  // Add an Transparent invisible layer to ensure the axis is auto-scaled using the
  // data
  call c.addLineLayer(array(wind), &h000080)' kTransparent)
 
  // Output the chart
  
  windrose = c.makeChartPicture
  
  windrose.Save(f, windrose.SaveAsPNG)
  
  CanvasWind.Refresh

Somehow the font does not increase for the spoke label at each 30 degree point.

The wind label (which is wind speed) does increase in size (call c.radialAxis.SetLabelStyle “”, 7*s).

When I use the transparent background on the CDPolarChartMBS the background is black. I was having this this problem before scaling the chart, so I used a wallpaper to get the desired outcome. I would rather do a transparent background as the wallpaper is hosed when scaling the graph.

Also, you will notice I use the canvas.refresh to fire the paint event. I had read somewhere that using canvas.refresh was not an efficient way to do this. Is there another alternative?

Thanks
JP

Well, I can only fix an example I have.
You may need to call setLabelStyle and other functions to apply a bigger font size.

Thanks Christian – call setLabelStyle did the trick – call c.angularAxis.setLabelStyle “”, 7*s, &h000080 …

Any hint on the CDPolarChartMBS transparent background? When I do:

dim c as new CDPolarChartMBS(sCanvasWind.Width, sCanvasWind.Width, CDPolarChartMBS.kTransparent)

It is a black background.

Lastly – when I have several canvas’ on my window, is using canvas.refresh for each one a bad idea?

OK – the real last questions – how do I stop the canvas paint from firing on the app startup before the method is called? Currently I am using a static tic count to skip the paint code if it is less than 1 … kinda crude, but it works.

Thanks again, this has been a great help. Sorry for all the questions.
JP

Well, the transparency can only survive if you get the chart picture with transparency. So export to PNG for example will do it.

Thanks Christian – I started another thread to work the transparency question as it really is not a Retina/HIgh Resolution graph issue.

JP