Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frame selection on LineGraph and ScatterPlot #125

Open
arguiot opened this issue Aug 19, 2020 · 12 comments
Open

Frame selection on LineGraph and ScatterPlot #125

arguiot opened this issue Aug 19, 2020 · 12 comments

Comments

@arguiot
Copy link
Contributor

arguiot commented Aug 19, 2020

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!

@KarthikRIyer
Copy link
Owner

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

@arguiot
Copy link
Contributor Author

arguiot commented Aug 19, 2020

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

@KarthikRIyer
Copy link
Owner

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.

@arguiot
Copy link
Contributor Author

arguiot commented Aug 19, 2020

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

@arguiot
Copy link
Contributor Author

arguiot commented Aug 19, 2020

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

@KarthikRIyer
Copy link
Owner

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

@arguiot
Copy link
Contributor Author

arguiot commented Aug 20, 2020

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

@KarthikRIyer
Copy link
Owner

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
Copy link
Owner

@arguiot did you try using docker?

@arguiot
Copy link
Contributor Author

arguiot commented Oct 2, 2020

No I haven't but I could try

@KarthikRIyer
Copy link
Owner

@arguiot did you get a chance to try docker?

@arguiot
Copy link
Contributor Author

arguiot commented Oct 5, 2020

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants