Hello,
I am creating a chart for stock exchange data and there is a problem i can't solve for a few days already.
I have custom triangle and pyramid markers for ask and bid offers. They are positioned on the opposite side of Y-axis zero and work great until the distance from 0 become less than some value (close to 0). In such cases, they overlap and form a hexagon star-looking figure. What i need to make sure that pyramid's (bid, below 0 on Y) origin is its top corner, and for triangle everything is vice versa, i.e. origin is the bottom corner as it shows ask, always above 0 on Y.
I tried creating a rectangular template so the marker itself would occupy top/bottom half and it worked for triangle (ask) but doesn't work for pyramid (bid): legend and tooltip both loose the marker picture (that's clear why) and tooltip become visible when mouse is not exactly over the marker.
I assume the reason for the above is that all markers are aligned to center both on X and Y during layout phase so I need a way to amend that alignment.
Thanks, Alex
Hi Alex,
I'm having trouble following what the issue is. Can you provide a screenshot that shows the issue? This will help me understand it better.
This what I was looking for. Both markers has underlying value of 0, the difference should've been in the alignment.
\/ 0 --------- /\
By default, i was something like this:
0 ---><---
I have found two solutions for this problem, both are based on using RenderTransform set to Translate.
If set to marker, such approach ruins the legend.
If set to ScatterSeries, works almost as expected but it looks as scroll performance degradates.
So i wonder if there is any better solution.
I'm not sure why it would degrade scrolling performance but probably the simplest way to resolve this would be to apply a TranslateTransform to a custom marker template. You can keep it from translating in the legend by binding the RenderTransform property to a RelativeSource binding that looks for the Marker object as an ancestor. This binding will have a converter on it and when it finds a Marker, the converter will do the translation. If it doesn't find the marker, this means it's inside the legend so it won't apply the translation.
public class MarkerPositionConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { // the marker is not inside the legend so return an offset if (value != null) return new TranslateTransform { X = 0, Y = double.Parse(parameter.ToString()) }; return new TranslateTransform { X = 0, Y = 0 }; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } }
<local:MarkerPositionConverter x:Key="MarkerPositionConverter"/> <DataTemplate x:Key="MarkerTemplate"> <Rectangle Width="20" Height="20" Fill="Red" RenderTransform="{Binding RelativeSource={RelativeSource AncestorType={x:Type ig:Marker}}, Converter={StaticResource MarkerPositionConverter}, ConverterParameter=20}"> </Rectangle> </DataTemplate>
The converter parameter is what offset you want to apply to the marker. If you need both an X and Y offset then you can modify the converter paramter to accept two values (ConverterParameter='0,0') and then in the converter, parse the parameter argument for the X and Y values.
Hi Rob,
Thanks for the hint, it worked for me, yet perfomance is still crippled upon zooming in/out but i think its cause is elsewhere.
Alex
Was the performance bad before making the marker changes or did it occur after the fact? Would you be able to send me a sample that demonstrates the performance issue? I can take a look and see if there is anything that can be done to improve it.
Rob,
Thanks for the offer yet this is prop app so I can't expose the source code, and creating an additional sample is not an option for now. When time allows I will try to create a sample and if i manage to, a separate thread will be created. This thread can be closed - i got what i need.
Thanks.