Since we are in process of evaluation and till now we have been pretty pleased with Infragistics.
One of the serious requirement we have is have a column range chart whereas each column is rendered over a range(just the two values, high and low)
Also can we have the same chart along with line chart on same chart area?
thanks
-S
You don't need to do anything quite so complicated to place text above a normal column series. This marker template should do:
<DataTemplate x:Key="textAboveMarker"> <Grid> <TextBlock Text="{Binding Item.Value}"> <TextBlock.RenderTransform> <TranslateTransform Y="-10" /> </TextBlock.RenderTransform> </TextBlock> </Grid> </DataTemplate>
Hope this helps!-Graham
not yet, but I notice you are using it with column series and it was designed for the range series, as per the original topic of the conversation. To use with regular column, it would need a few adjustments, I warrant. Will try to look at your sample as soon as I'm able.
Did you get a chance to take a look at the sample?
Thanks for the solution, was trying this solution on column series but it seems numbers are NOT correctly aligned i.e. either number show too close to upper bar or too far off.
Here is the sample code
<Window.Resources>
<local:TestData x:Key="data" />
<DataTemplate x:Key="hiloMarker">
<local:HiLowMarker
Context="{Binding}"
ValueMemberPath="Value"/>
</DataTemplate>
</Window.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<ig:XamDataChart x:Name="theChart" VerticalZoomable="True" HorizontalZoomable="True" Width="400" Height="300">
<ig:XamDataChart.Axes>
<ig:NumericYAxis x:Name="yAxis" ReferenceValue="0" />
<ig:CategoryXAxis
x:Name="xAxis"
ItemsSource="{StaticResource data}"
Label="{}{Label}"/>
</ig:XamDataChart.Axes>
<ig:XamDataChart.Series>
<ig:ColumnSeries
x:Name="series"
MarkerType="Circle"
MarkerTemplate="{StaticResource hiloMarker}"
XAxis="{Binding ElementName=xAxis}"
YAxis="{Binding ElementName=yAxis}"
ValueMemberPath="Value" >
</ig:ColumnSeries>
</ig:XamDataChart.Series>
</ig:XamDataChart>
</Grid>
Code Behind :
public class TestData : ObservableCollection<TestDataItem>
{
public TestData()
Add(new TestDataItem()
Label = "A",
Value = 3
});
Label = "B",
Value = 5
Label = "C",
Value = 6
Label = "D",
Value = 4
}
public class TestDataItem
public string Label { get; set; }
public double Value { get; set; }
public class HiLowMarker : ContentControl
public static readonly DependencyProperty ContextProperty =
DependencyProperty.Register("Context",
typeof(DataContext), typeof(HiLowMarker),
new PropertyMetadata(null, (o, e) => (o as HiLowMarker)
.OnContextChanged(e.OldValue, e.NewValue)));
public DataContext Context
get { return (DataContext)GetValue(DataContextProperty); }
set { SetValue(DataContextProperty, value); }
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value",
typeof(double), typeof(HiLowMarker),
new PropertyMetadata(0.0, (o, e) => (o as HiLowMarker)
.OnValueChanged((double)e.OldValue, (double)e.NewValue)));
private void OnValueChanged(double oldValue, double newValue)
UpdateContent();
public double Value
get { return (double)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
public static readonly DependencyProperty ValueMemberPathProperty =
DependencyProperty.Register("ValueMemberPath", typeof(string), typeof(HiLowMarker), new PropertyMetadata(null, (o, e) => (o as HiLowMarker)
.OnValueMemberPathChanged((string)e.OldValue, (string)e.NewValue)));
private void OnValueMemberPathChanged(string oldValue, string newValue)
public string ValueMemberPath
get { return (string)GetValue(ValueMemberPathProperty); }
set { SetValue(ValueMemberPathProperty, value); }
public static readonly DependencyProperty ItemProperty = DependencyProperty.Register("Item", typeof(object), typeof(HiLowMarker),
new PropertyMetadata(null, (o, e) => (o as HiLowMarker).OnItemChanged((object)e.OldValue, (object)e.NewValue)));
private void OnItemChanged(object oldValue, object newValue)
public object Item
get { return (object)GetValue(ItemProperty); }
set { SetValue(ItemProperty, value); }
private XamDataChart watchingChart = null;
private void UpdateContent()
if (!Valid())
return;
UpdateHandlers();
SetBinding(ItemProperty,
new Binding("Context.Item")
Source = this
SetBinding(ValueProperty,
new Binding("Context.Item." + ValueMemberPath)
if (!double.IsNaN(Value) && !double.IsInfinity(Value))
var rangeSeries = Context.Series as ColumnSeries;
var viewport =
new Rect(
0, 0,
rangeSeries.ActualWidth,
rangeSeries.ActualHeight);
double scaledLow = 0;
double scaledHigh = rangeSeries.YAxis.GetScaledValue(Value, rangeSeries.Chart.WindowRect, viewport);
double mid = (scaledLow + scaledHigh) / 2.0;
scaledLow += 10;
scaledHigh -= 10;
Grid grid = new Grid();
TextBlock tbHigh = new TextBlock()
Text = Value.ToString(),
RenderTransform =
new TranslateTransform()
Y = scaledHigh - mid
};
grid.Children.Add(tbHigh);
Content = grid;
private void UpdateHandlers()
if (watchingChart != null)
watchingChart.WindowRectChanged -= watchingChart_WindowRectChanged;
watchingChart.SizeChanged -= watchingChart_SizeChanged;
watchingChart = null;
if (Context.Series.Chart != null)
watchingChart = Context.Series.Chart;
watchingChart.WindowRectChanged += watchingChart_WindowRectChanged;
watchingChart.SizeChanged += watchingChart_SizeChanged;
void watchingChart_SizeChanged(object sender, SizeChangedEventArgs e)
void watchingChart_WindowRectChanged(object sender, Infragistics.RectChangedEventArgs e)
private bool Valid()
if (ValueMemberPath == null)
return false;
if (Context == null)
if (Context.Series == null)
return true;
private void OnContextChanged(object oldValue, object newValue)
ClearContent();
private void ClearContent()
Content = null;
produces result: