After reviewing the documentation, specifically http://www.telerik.com/help/silverlight/radchartview-styles-and-templates-customizing-scatter-points.html, I am exploring ways to scale a custom scatter point based on values of the underlying data.
I know there is an old post in this forum relating to bubble plots in RadChartView (where the bubble is sized based on the underlying data) which is not currently supported. This was 2012.
Looking at the source code for the Candlestick object (as part of the Candlestick series) as a reference, clearly the Candlestick uses sizing (scale) information to determine how big it should be based on the underlying data object. In particular, it uses the layout and size information in the LayoutSlot to draw itself accordingly which is exactly what I need to do. So, clearly the Candlestick has the mechanisms to do this internally (and in fact, it would be very nice if the classes were not declared Internal so they could easily be inherited and the issue would be easily solved for me just using a custom Candlestick object to draw what I want.
The scatter point template doesn't seem to get that information (the layout height and width is 0, only the X, Y coordinates are valid).
What I'm trying to do here is to write a custom point template which, using the load event on the template, can get scale information. I do this in code-behind instead of defining the template in XAML so bear with me. The template simply is a grid object with a handler attached to its loaded event, which causes the handler to be called whenever the chart renders the custom point template the first time the series is rendered. In the loaded event of the grid, we simply create content based on the underlying data point. This is very similar to the concept in the documentation where color and shape is changed. What I want to do however is SIZE the object based on the underlying data. Sizing is trivial, however, the sizing should match the current scale of the chart so the dimensions match the axis data, so I need a way to scale the axis information to the pixel. ChartView does provide a conversion API (http://www.telerik.com/help/silverlight/radchartview-features-conversion.html) but I haven't found a good way to hook that in.
What I have to date is this:
The handler code is:
The layout slot width and height are always 0 for a scatter point so I can't derive the scale from the layout box. This is not true of the Candlestick object where it uses the layout information to size itself.
My custom point will be rendered at the X and Y locations correctly on the chart, what I'm missing is the ratio of pixel/value for the chart to allow me to compute the scale of the object so it matches the axes.
For simplicity, I'm using linear axes on both X and Y.
So what I'd like to do is to compute the scale value in the handler code above. I can easily get a reference to the chart object in the handler if needed, but I have no idea where to fish the plot scale data from right now.
Alternatively, I can use a CandlestickSeries instead of a ScatterSeries and accomplish the same thing but changing the rendering of the candlestick so what I need to make it do. I haven't found of a way to do that via templates as the relevant overrides are all marked "internal".
Thanks!
E.
I know there is an old post in this forum relating to bubble plots in RadChartView (where the bubble is sized based on the underlying data) which is not currently supported. This was 2012.
Looking at the source code for the Candlestick object (as part of the Candlestick series) as a reference, clearly the Candlestick uses sizing (scale) information to determine how big it should be based on the underlying data object. In particular, it uses the layout and size information in the LayoutSlot to draw itself accordingly which is exactly what I need to do. So, clearly the Candlestick has the mechanisms to do this internally (and in fact, it would be very nice if the classes were not declared Internal so they could easily be inherited and the issue would be easily solved for me just using a custom Candlestick object to draw what I want.
The scatter point template doesn't seem to get that information (the layout height and width is 0, only the X, Y coordinates are valid).
What I'm trying to do here is to write a custom point template which, using the load event on the template, can get scale information. I do this in code-behind instead of defining the template in XAML so bear with me. The template simply is a grid object with a handler attached to its loaded event, which causes the handler to be called whenever the chart renders the custom point template the first time the series is rendered. In the loaded event of the grid, we simply create content based on the underlying data point. This is very similar to the concept in the documentation where color and shape is changed. What I want to do however is SIZE the object based on the underlying data. Sizing is trivial, however, the sizing should match the current scale of the chart so the dimensions match the axis data, so I need a way to scale the axis information to the pixel. ChartView does provide a conversion API (http://www.telerik.com/help/silverlight/radchartview-features-conversion.html) but I haven't found a good way to hook that in.
What I have to date is this:
public
static
DataTemplate CreatePointTemplate(
[NotNull]RoutedEventHandler pointLoadedHandler,
string
selectedBooleanField =
null
,
string
notSelectedBooleanField =
null
)
{
var template =
new
DataTemplate();
var gridFactory =
new
FrameworkElementFactory(
typeof
(Grid));
gridFactory.AddHandler(Control.LoadedEvent, pointLoadedHandler);
template.VisualTree = gridFactory;
return
template;
}
The handler code is:
private
void
HandlePointCreated(
object
sender, RoutedEventArgs e)
{
var grid = (Grid)sender;
var scatterDataPoint = (ScatterDataPoint)((FrameworkElement)sender).DataContext;
var data = (HistoricalMarketDataPoint)scatterDataPoint.DataItem;
var layoutSlot = scatterDataPoint.LayoutSlot;
var bubble =
new
Ellipse();
var scale = !Equals(layoutSlot.Height, 0.0) ? data.PriceAverage/layoutSlot.Height : 1.0;
var scaleSize =
new
Size(scale*layoutSlot.Width, scale*layoutSlot.Height);
bubble.Width = scaleSize.Width;
bubble.Height = scaleSize.Height;
var chartPointBrush =
new
SolidColorBrush(Colors.Red);
bubble.Fill = chartPointBrush;
grid.Children.Add(bubble);
}
The layout slot width and height are always 0 for a scatter point so I can't derive the scale from the layout box. This is not true of the Candlestick object where it uses the layout information to size itself.
My custom point will be rendered at the X and Y locations correctly on the chart, what I'm missing is the ratio of pixel/value for the chart to allow me to compute the scale of the object so it matches the axes.
For simplicity, I'm using linear axes on both X and Y.
So what I'd like to do is to compute the scale value in the handler code above. I can easily get a reference to the chart object in the handler if needed, but I have no idea where to fish the plot scale data from right now.
Alternatively, I can use a CandlestickSeries instead of a ScatterSeries and accomplish the same thing but changing the rendering of the candlestick so what I need to make it do. I haven't found of a way to do that via templates as the relevant overrides are all marked "internal".
Thanks!
E.