Taking an example that Graham had posted awhile back, I am using a DataTemplate to bind the Width/Height of an Ellipse marker based on the underlying data. Something like this:
<UserControl.Resources>
<DataTemplate x:Key="bubbleTemplate" >
<Ellipse Stretch="Fill"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Fill="{Binding ActualItemBrush}"
Stroke="{Binding Series.ActualMarkerOutline}"
StrokeThickness="0.5"
MinWidth="10" MinHeight="10"
Width="{Binding Item.Width}"
Height="{Binding Item.Width}"/>
</DataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<igChart:XamDataChart x:Name="theChart">
<igChart:XamDataChart.Axes>
<igChart:NumericXAxis x:Name="xAxis"
MinimumValue="0" MaximumValue="15"/>
<igChart:NumericYAxis x:Name="yAxis"
</igChart:XamDataChart.Axes>
<igChart:XamDataChart.Series>
<igChart:ScatterSeries x:Name="scatter"
MarkerTemplate="{StaticResource bubbleTemplate}"
ItemsSource="{Binding}"
XMemberPath="XValue"
YMemberPath="YValue"
XAxis="{Binding ElementName=xAxis}"
YAxis="{Binding ElementName=yAxis}"/>
</igChart:XamDataChart.Series>
</igChart:XamDataChart>
</Grid>
and in the code behind I have a class with the Width property.
I've got some code that does the hit test on a series left mouse button up and set's the Selected property on the item. Something like this:
if (hitItems.Count ==1)
{
var item = e.Item
MyDataPoint dp = e.Item as MyDataPoint;
dp.Selected = !dp.Selected;
}
In the MyDataPoint class, I've the Selected and Width properties look like so:
public class MyDataPoint : INotifyPropertyChanged
public event PropertyChangedEventHander PropertyChanged;
public double Width
get { return _width; }
set
_width = value;
OnPropertyChanged("Width");
private bool _selected = false;
public bool Selected
get { return _selected; }
_selected = value;
if (_selected)
Width = SELECTEDSIZE;
else
Width = UNSELECTEDSIZE;
Now, the idea is that if I a point to Selected, the corresponding marker will change size. This does work but the behavior that I'm seeing is as follows:
I set point 1 to selected and it resizes but it's center isn't correct.
I set point 2 to selected and now it resizes but it's center isn't correct either. But point 1 has now adjusted its center to be correct.
Ideas on how to force the series to adjust the point?
Thanks,
Matt
Matt,
Currently the chart repositions the markers based on their desired size when it "refreshes". It could be that the changes that you are making when the marker is selected are not causing a chart refresh, or that there is an issue with the timing such that your change doesn't take effect in time for the refresh to pick up the new desired size. I believe more recent versions of the chart are only listening to the properties that are bound to the x and y to determine if it should refresh, so changes to the Width property won't force a refresh to occurr. We are evaluating different ways of approaching the reaction to the marker sizes changing.
In either case, the safer method is to resize the marker in a way that doesnt effect its layout size or position (RenderTransform).
-Graham
A modification I'll need to make for my own personal needs is to create multiple DataTemplates to allow for different shaped markers on the chart (square, star, etc.). Might be able to minimize the number of templates I have to create since they all rely on the same idea of applying a scale transform. Of course any thoughts you might have on this would be good to hear.
Regards,
To make this work correctly, did the following:
I created a DataTemplate as follows:
<DataTemplate x:Key="bubbleTemplate">
RenderTransform="{Binding Item.RenderTransform}"/>
And then in the code behind I have the Selected property drive the RenderTransform property to adjust the size of the ellipse:
RenderTransform = new ScaleTransform(2.0, 2.0, UNSELECTEDSIZE/2.0, UNSELECTEDSIZE/2.0);
RenderTransform = null;
The RenderTransform property then just uses the property changed event to adjust the shape associated with this data point:
private Transform _renderTransform;
public Transform RenderTransform
get { return _renderTransform; }
_renderTransform = value;
OnPropertyChanged("RenderTransform");
protected void OnPropertyChanged(string name)
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(name));
Seems to work pretty well. Note that I don't directly change the Width/Height of the shape, rather I use the ScaleTransform to do this. There may be different/better ways to do this. I'd be interested in hearing others' thoughts on this.