swiftplot icon indicating copy to clipboard operation
swiftplot copied to clipboard

Frame selection on LineGraph and ScatterPlot

Open arguiot opened this issue 3 years ago • 12 comments

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!

arguiot avatar Aug 19 '20 13:08 arguiot

This is a good idea. Thanks for creating the issue! Would you be interested in contributing this feature @arguiot ?

KarthikRIyer avatar Aug 19 '20 13:08 KarthikRIyer

@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.

arguiot avatar Aug 19 '20 13:08 arguiot

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.

KarthikRIyer avatar Aug 19 '20 14:08 KarthikRIyer

Alright, thank you for the information. If I need more help I'll tell you.

arguiot avatar Aug 19 '20 14:08 arguiot

@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).

chart

LineGraph test with no modifications

chart

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.

arguiot avatar Aug 19 '20 15:08 arguiot

Do the tests pass before you make changes to the code?

KarthikRIyer avatar Aug 20 '20 14:08 KarthikRIyer

No they didn't... maybe this is a Xcode problem (I'm on macOS BigSur with Xcode 12)

arguiot avatar Aug 20 '20 14:08 arguiot

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.

KarthikRIyer avatar Aug 20 '20 23:08 KarthikRIyer

@arguiot did you try using docker?

KarthikRIyer avatar Sep 30 '20 19:09 KarthikRIyer

No I haven't but I could try

arguiot avatar Oct 02 '20 13:10 arguiot

@arguiot did you get a chance to try docker?

KarthikRIyer avatar Oct 05 '20 15:10 KarthikRIyer

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.

arguiot avatar Oct 05 '20 15:10 arguiot