swiftplot
swiftplot copied to clipboard
Frame selection on LineGraph and ScatterPlot
It would be awesome to select the frame size and position, especially on LineGraph
and ScatterPlot
. For the moment, only minX
and maxX
exists, but you can't really define the maximum height/position of the frame.
The main benefit of this would be to enable an interactive graph that could respond to the touch/drag events. Of course, none of this has to be implemented inside SwiftPlot itself, but let the users (developer) create such behaviors could be great!
This is a good idea. Thanks for creating the issue! Would you be interested in contributing this feature @arguiot ?
@KarthikRIyer why not. I just have no idea how to do it or where to start. If you can give me some indication/help I think I could open a PR.
Building and running tests for SwiftPlot should be simple enough. Just clone the repo and run swift build
and swift test
from the project root directory. You might need to install freetype if it's not installed already. You can find the instructions to do that on your platform in the README.
Take a look at this section of the README for a brief intro to how stuff works, and let me know if you'd like me to elaborate about anything. Then we can try to land this feature for LineGraph first and then extend it to ScatterPlot. First try to read through the LineChart.swift code and try to get a feel of how it works.
It's been a while since I've seen the code but I think if we just scale all the points to the required range of points, it might just work. I don't think we need to worry about culling the points ourselves.
Let me know if I haven't been clear anywhere or you need further clarification.
Alright, thank you for the information. If I need more help I'll tell you.
@KarthikRIyer I just have a problem running the tests. All the tests are failing for no reason (I mean, yeah they're failing for a reason, but since I didn't change much of the code they shouldn't fail).
LineGraph test with no modifications
LineGraph test with modifications
All I've done was to add a binding of the following variables in the LineGraph
struct:
public var scaleX: Float = 1
public var scaleY: Float = 1
// The "origin" is just a known value at a known location,
// used for calculating where other points are located.
public var origin: Point = .zero
I then updated the layoutData
method:
// functions implementing plotting logic
public func layoutData(size: Size, renderer: Renderer) -> (DrawingData, PlotMarkers?) {
var results = DrawingData()
var markers = PlotMarkers()
guard !primaryAxis.series.isEmpty, !primaryAxis.series[0].values.isEmpty else { return (results, markers) }
results.primaryAxisInfo = AxisLayoutInfo(series: primaryAxis.series, size: size)
// Layout
results.primaryAxisInfo?.origin = self.origin
results.primaryAxisInfo?.scaleX = self.scaleX
results.primaryAxisInfo?.scaleY = self.scaleY
results.secondaryAxisInfo = secondaryAxis.map {
var info = AxisLayoutInfo(series: $0.series, size: size)
info.mergeXAxis(with: &results.primaryAxisInfo!)
// Layout
info.origin = self.origin
info.scaleX = self.scaleX
info.scaleY = self.scaleY
return info
}
(markers.xMarkers, markers.xMarkersText, markers.yMarkers, markers.yMarkersText) =
results.primaryAxisInfo!.calculateMarkers()
if let secondaryAxisInfo = results.secondaryAxisInfo {
(_, _, markers.y2Markers, markers.y2MarkersText) = secondaryAxisInfo.calculateMarkers()
}
return (results, markers)
}
Not sure what's wrong with the tests/my code. I decided to paste my changes here so in case you can make the tests work on your machine, you can test my changes.
Do the tests pass before you make changes to the code?
No they didn't... maybe this is a Xcode problem (I'm on macOS BigSur with Xcode 12)
I'll take a look. But I use Ubuntu so I might not be able to help on the macOS front. Also I'm a little preoccupied this week so my responses might not be prompt.
@arguiot did you try using docker?
No I haven't but I could try
@arguiot did you get a chance to try docker?
No. I had a pretty busy week (and more are coming) so I couldn't find some time to do it. I keep the idea in mind don't worry but I'm really not in a hurry. I don't care if this feature is added next week or in the next months.