`LineAnnotation` `X` and `Y` are ignored for sloped lines
Steps to reproduce
- Add an annotation as per below.
- Observe it ignoring
Xand passing through(0, 0).
ChartModel.Annotations.Add(new LineAnnotation
{
Slope = 2,
X = 5,
});
Expected behaviour
Setting X and Slope will give me an offset line.
Actual behaviour
It doesn't. I get a line with the correct slope, but passing through (0, 0), not (X, 0).
The documentation even mentions this issue by saying that X is ignored unless the line is Type == Vertical, and Y is ignored unless Type == Horizontal.
I see I can do Type = LinearEquation, but I think the system could be simplified. If you want a horizontal line, set Slope to 0, and if you want a vertical one, set it to double.PositiveInfinity.
@colejohnson66 you need to use the Intercept property in combination with Slope to specify the intercept for a linear LineAnnotation
Yeah. I figured that out. I still think it'd be nice to have a line annotation where I go, "Here's X, Y, and Slope. Figure out what line gives b in Y = Slope * X + b"
It doesn't seem too hard. I'd be willing to make a patch that would allow that, but I don't think it'd be wise to break the API of LineAnnotation. Any ideas?
(hurried thoughts) I could image that as a convenience method somewhere; OxyPlot doesn't have a whole lot of such convenience methods, but I don't think it would suffer if there were a few more.
My main concern with baking this into the class itself would be that it will create even more confusion than the current design, as we'll need to spec what happens when e.g. Intercept and X or Y are non-NaN, and that's going to be messy. Personally I don't like using infinity for this sort of thing, but that's probably just me.
The existing API has another issue: the terms Horizontal and Vertical are a bit fuzzy now anyway, given they really mean X or Y aligned.
I think infinity is ugly too, but that's how it was taught to me in school: a vertical line is just one with an infinite slope.
As for a convenience function, where would it go and what would it be called?
As for a convenience function, where would it go and what would it be called?
I don't know; I'm afraid my imagination is pretty limited. I feel like AnnotationHelpers could be a thing, but probably not justifiable for a single static method.
An overhaul of LineAnnotation might be a reasonable thing for 3.0, but my instinct is that the current API isn't bad enough to break or otherwise convolute it. Might be worth looking at other packages to see what is generally expected. My inclination at the moment is to leave it as-is.
I wonder if it could be reworked so Type == LinearEquation could use either Intercept or X and Y? So initially, all would be double.NaN, then when rendering, if the type is LinearEquation, it figures out what to use?
double intercept = Intercept;
if (double.IsNaN(yIntercept))
{
if (double.IsNaN(Slope) || double.IsNaN(X) || double.IsNaN(Y))
{ /* error? */ }
intercept = Y - Slope * X;
}
I don't think initializing to NaN would break the API, but I'm probably wrong. If you feel it's not worth it, feel free to close this issue.