They key piece is that: markers must only be shown when all the data points are visible.
There appears to be some hard-coded marker width that determines when to hide the markers. The attached code shows that a skinny line marker gets hidden at the same time as the circle markers (when resizing the width of the window).
The closeness of our data points (within our actual project) are barely out of the resolution of the chart for zooming in such that the points are sufficiently far enough apart that guarantees prevention of the chart hiding the data points.Therefore permanently preventing the points from ever being hidden is our best option. And this is viable because we are already doing our own down-sampling to a handful of points (the chart only ever sees 1000 points).
The second option 'brute-force' option would be to recompile the source with an adjusted hard-coded marker width which would fix the issue as well (given your help on locating this hard-coded constant).
Any ideas on how to accomplish this?
Hi Will,
I took a look at the source code to see if I could find out how we are handling marker hiding and I believe I've found the code in question. When the markers are being prepared, it looks through all the possible markers and runs them through a collision method to see if they collide with any other markers. If they do, it skips that marker and moves on to the next one. All markers that avoid collision are passed on for rendering. I didn't see any settings that would allow users to control this behavior so I don't think it's something you can disable without modifying the source code. I recommend that you add this as a new product idea for the chart here: http://ideas.infragistics.com.
If you are up for modifying the source code then the code in question is located in CategoryFramePreparer.cs inside the PrepareMarker method. You will see an if check and at the end you will see a collisionAvoider.TryAdd method. If this returns true, it will add the marker. If you want all markers to be visible regardless of whether they overlap with each other you should be able to remove that TryAdd method from the if check. Obviously there are disadvantages to modifying the source code, the main one being that you are now responsible for maintaining any changes you made as once we release a new patch, your changes will no longer be present when you update.
Is there no way to disable the behavior by inheriting from some kind of Series?I found a snippet of code on this forum that just happens to inherit HorizontalAnchoredCategorySeries and appears to allow the markers to overlap.
But the code seems like it is hacked together. I'll try to reference the post if I can find it.
Did you notice the initial project that was posted? The skinny lines should be collapsed later if based upon collision.
Inheriting from a series is an option like in the example you provided but I wanted to steer away from it at first because in order to control how the markers are rendered you will basically have to handle rendering of the series yourself. This will involve creating all the little components that make up the series in the plot area. If you use the default rendering the series provides, it's going to render the markers as it does now. It's definitely a viable option but it will require a decent amount of work. The CustomLineSeries in your example isn't really a hack though, if you want to create your own custom series that example is a way you can do it.
As for the marker size and collision, the calculation for determining collision is not using the markers visual size. Even if I adjust the marker's width and height to be the same as the content of the marker, line markers are still disappearing at the same time as circle markers. In the source code, this code is the reason why:
Rect markerRect = new Rect(x - 5, y - 5, 11, 11); if (!double.IsNaN(x) && !double.IsNaN(y) && !double.IsInfinity(x) && !double.IsInfinity(y) && collisionAvoider.TryAdd(markerRect)) { // add marker }
So you were right initially, the widths are being hard coded. At present the options are to either create your own series or modify the source code. I highly recommend submitting a product idea for this though so we can potentially add support to adjust this behavior in a future version. If you submit this, please reference this forum thread so the Product Management team can look back at it.
Hmm. It didn't seem to add a scrollbar to the code snippet from what I can see. At the end of this if check is collisionAvoider.TryAdd(markerRect).
I'll consider submitting the product idea piece. But in the meantime, I had a question about that last project that I had posted:
<Style TargetType="local:CustomLineSeries"> <Setter Property="Thickness" Value="2"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="local:CustomLineSeries"> <Canvas Name="RootCanvas"/> </ControlTemplate> </Setter.Value> </Setter> </Style>
I don't understand why this is needed and referenced in the custom series. Can I avoid this by setting the DefaultStyleKey to LineSeries to gain this? Is there no easy way to rid the xaml side such that it is consolidated into one piece? When attempting to use CustomLineSeries.cs in our code with that style placed in App.xaml resources, the series just simply does not show up. I'm having a hard time tracking down what is the actual issue as the code sample is sparse and incomplete for general usage. (But of course, its a sample).
--Whatever the style is doing it seems to related to this.Viewport getting set as well as this.RootCanvas. I guess for the custom series solution I figure out the connections between the style, series and the chart. Any useful information this would also be great.
Thanks for the quick responses.
At this time we have finally decided to modify the source to prevent the data point (marker) hiding.
Removing the collisionAvoider.TryAdd(..) check from CategoryFramePreparer.cs:PrepareMarker(..)still doesn't prevent the markers from being hidden.I'm not sure whether this is a bug or if there is simply more than one spot that needs to be modified.
Please advise.
Let me know if you have any further questions on this matter.
That's just the standard way we provide examples for creating custom series. You'll see this defined in our documentation as well.
I ran your newer sample though and set the DefaultStyle to LineSeries and it looked like it still worked. I made sure to remove the CustomLineSeries style xaml from the project as well just to make sure. So I don't see why you can't just do that. Now granted, even when I moved the CustomLineSeries style to the Application.Resources, it still rendered the series just fine with default style set to CustomLineSeries so I'm not really sure why you can't see it when you do the same thing.
The style only has to do with setting the RootCanvas I think, and for setting some default values for certain properties like Brush or Thickness. The Viewport should be set by the chart itself and passed to the series that way.