Allow horizontal scrolling only in the core-plot barchart?
Asked Answered
V

11

9

I am using core-plot lib to draw bar charts in my app like this ......

My problem is that i want the enabling of grapgh movement only in horizontal direction so that I can see the records for a long period of time, But the problem is that i just wnt to keep the y axis fixed to its place,

How can i do this?

Waiting for help....

Vitascope answered 12/12, 2009 at 6:18 Comment(1)
I don't know why you rolled back my edit last time. Imgur is a lot faster than FreeImageHosting.net, which times out whenever I try to load the image as part of this page.Disband
O
11

Only recently has rudimentary user interaction been enabled in Core Plot graphs. To enable scrolling in any direction, you can set the allowsUserInteraction property of the plot space to YES.

We currently have no means of locking that movement to one direction. The scrolling action takes place in the -pointingDeviceDraggedAtPoint: method on CPXYPlotSpace, so you could subclass CPXYPlotSpace, copy over its implementation of that method, and alter it to only allow movement in the X direction. Even better, we'd appreciate any contributions to extend the functionality of the CPXYPlotSpace to add support for unidirectional movement.

Overweight answered 12/12, 2009 at 16:10 Comment(2)
Hi Brad, I implemented the solution as you said at #1900053 But still I am not able to fix the originVitascope
@BradLarson is there built in support added for this yet, or not?Carbonic
P
22

If you are using Core-Plot 0.2.2 or greater (possibly earlier) then you can add a method on your plot space's delegate to handle the following:

-(CGPoint)plotSpace:(CPTPlotSpace *)space willDisplaceBy:(CGPoint)displacement {
    return CGPointMake(displacement.x, 0);
}

This will restrict the plot movement to horizontal only. This assumes you have allowed interacting with the plot space by setting allowsUserInteraction = YES.

Perjury answered 29/12, 2010 at 23:42 Comment(2)
I was only able to get this to work after doing a hg clone of the repository. I did not have any luck using the installers.Hellenism
Works fine on CorePlot v1.1Lexicostatistics
M
16

Limit scrolling by setting a delegate (i.e., CPPlotSpaceDelegate) on the plot space and implement the willChangePlotRangeTo method. You can do other cool things at the same time. Here's how I limit the display to quadrant one:

- (CPPlotRange *)plotSpace:(CPPlotSpace *)space
    willChangePlotRangeTo:(CPPlotRange *)newRange
            forCoordinate:(CPCoordinate)coordinate {

    // Display only Quadrant I: never let the location go negative.
    //
    if (newRange.locationDouble < 0.0F) {
        newRange.location = CPDecimalFromFloat(0.0);
    }

    // Adjust axis to keep them in view at the left and bottom;
    // adjust scale-labels to match the scroll.
    //
    CPXYAxisSet *axisSet = (CPXYAxisSet *)self.graph.axisSet;
        if (coordinate == CPCoordinateX) {
            axisSet.yAxis.orthogonalCoordinateDecimal = newRange.location;
            axisSet.xAxis.titleLocation = CPDecimalFromFloat(newRange. newRange.locationDouble +
                                                             (newRange.lengthDouble / 2.0F));
        } else {
            axisSet.xAxis.orthogonalCoordinateDecimal = newRange.location;
            axisSet.yAxis.titleLocation = CPDecimalFromFloat(newRange.locationDouble +
                                                             (newRange.lengthDouble / 2.0F));
        }

    return newRange;
}

See: CPPlotSpace.h

Mindamindanao answered 5/4, 2010 at 19:28 Comment(4)
newRange.doublePrecisionLocation is now newRange.locationDoubleUrena
newRange.doublePrecisionLength is now newRange.lengthDoubleHellenism
I'm getting assignment to read only property on: newRange.location = CPTDecimalFromFloat(0.0);Cycling
I've added the updated code that works with CorePlot 1.5.1 here: https://mcmap.net/q/1115656/-allow-horizontal-scrolling-only-in-the-core-plot-barchartZeigler
B
13

I used a simple way to "disable" the vertical scroll

    CPPlotRange *globalYRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromDouble(minY) length:CPDecimalFromDouble(maxY)];
    plotSpace.globalYRange = globalYRange;

For, minY and maxY I put the values I displayed, like that the vertical limits are what you see, so you can't vertical scroll

It worked for me, after I saw your topic, so I wanted to complete your answers with mine

Blemish answered 3/1, 2011 at 13:58 Comment(1)
Is it possible to limit the scrolling to the negative x-axis?Irvingirwin
O
11

Only recently has rudimentary user interaction been enabled in Core Plot graphs. To enable scrolling in any direction, you can set the allowsUserInteraction property of the plot space to YES.

We currently have no means of locking that movement to one direction. The scrolling action takes place in the -pointingDeviceDraggedAtPoint: method on CPXYPlotSpace, so you could subclass CPXYPlotSpace, copy over its implementation of that method, and alter it to only allow movement in the X direction. Even better, we'd appreciate any contributions to extend the functionality of the CPXYPlotSpace to add support for unidirectional movement.

Overweight answered 12/12, 2009 at 16:10 Comment(2)
Hi Brad, I implemented the solution as you said at #1900053 But still I am not able to fix the originVitascope
@BradLarson is there built in support added for this yet, or not?Carbonic
R
11

Using CorePlot 1.0 -- To restrict scrolling to just horizontal and scaling as well, I implemented the two CPTPlotSpaceDelegate methods: method by Steve Tranby with a modified method suggested by supperAly/edo42.

-(CGPoint)plotSpace:(CPTPlotSpace *)space willDisplaceBy:(CGPoint)displacement
{
    return CGPointMake(displacement.x, 0);
}

-(CPTPlotRange *)plotSpace:(CPTPlotSpace *)space willChangePlotRangeTo:(CPTPlotRange *)newRange forCoordinate:(CPTCoordinate)coordinate
{
    if (coordinate == CPTCoordinateY) {
    newRange = ((CPTXYPlotSpace*)space).yRange;
    }
    return newRange;
}
Rosa answered 15/3, 2012 at 14:25 Comment(2)
Would you mind also share the code of how to setup graph? i mean the start point of setup the CPTPlotSpace at the beginning. I followed your solution, but my one is still not working. Please help! >.<Hypsography
You are the man... Thanks for the wonderful answer Jay... :) Voted upShadchan
E
3

All you have to do to fix the y axis after Answer 4 with the comment incl. ( newRange.doublePrecisionLocation is now newRange.locationDouble ) is to set plotSpace.globalYRange = plotSpace.yRange;

Excavate answered 10/9, 2010 at 5:35 Comment(0)
S
3

i am using CorePlot 0.2.2

-(CPPlotRange *)plotSpace:(CPPlotSpace *)space willChangePlotRangeTo:(CPPlotRange *)newRange forCoordinate:(CPCoordinate)coordinate;
{
    CPXYPlotSpace * plot_space = (CPXYPlotSpace*)space;
    plot_space.globalYRange = plot_space.yRange;
    return newRange;
}

u will need to add CPPlotSpaceDelegate,CPLineStyleDelegate protocols to your controller

and add (for CPLineStyleDelegate)

-(void)lineStyleDidChange:(CPLineStyle *)lineStyle
{
//empty
}

the system will keep the original range of y axis

Sahara answered 24/1, 2011 at 12:32 Comment(0)
C
2

thanks to supperAly when my interface implements "CPPlotSpaceDelegate" protocol and the project can not be complied normally , and shows that: your interface xxx doesn't implement 'CPLineStyleDelegate' protocol, which make me confuse. so i add the method : -(void)lineStyleDidChange:(CPLineStyle *)lineStyle { //empty } for CPLineStyleDelegate and add <CPLineStyleDelegate> to my interface and the problems have gone.

Cutin answered 27/4, 2011 at 7:40 Comment(0)
Z
2

The following code is based on Tom Donaldson's answer and has been tested with CorePlot 1.5.1:

- (CPTPlotRange *)plotSpace:(CPTPlotSpace *)space
      willChangePlotRangeTo:(CPTPlotRange *)newRange
              forCoordinate:(CPTCoordinate)coordinate
{
    CPTMutablePlotRange *range = [CPTMutablePlotRange plotRangeWithLocation:newRange.location length:newRange.length];

    // Display only Quadrant I: never let the location go negative.
    //
    if (range.locationDouble < 0.0F)
    {
        range.location = CPTDecimalFromFloat(0.0);
    }

    // Adjust axis to keep them in view at the left and bottom;
    // adjust scale-labels to match the scroll.
    //
    CPTXYAxisSet *axisSet = (CPTXYAxisSet *) space.graph.axisSet;
    if (coordinate == CPTCoordinateX)
    {
        axisSet.yAxis.orthogonalCoordinateDecimal = range.location;
        axisSet.xAxis.titleLocation               = CPTDecimalFromDouble(range.locationDouble + (range.lengthDouble / 2.0F));
    }
    else
    {
        axisSet.xAxis.orthogonalCoordinateDecimal = range.location;
        axisSet.yAxis.titleLocation               = CPTDecimalFromDouble(range.locationDouble + (range.lengthDouble / 2.0F));
    }

    return range;
}
Zeigler answered 2/7, 2014 at 7:46 Comment(0)
L
0

You can override the

-(void)scaleBy:(CGFloat)interactionScale aboutPoint:(CGPoint)plotAreaPoint`

function in CPTXYPlotSpace and take out all the code related to the movement for y axis.

Lachrymal answered 19/9, 2011 at 20:55 Comment(0)
N
0

@Andrew S: "I'm getting 'assignment to read-only property' on newRange.location = CPTDecimalFromFloat(0.0);"

I had that, too, and, following the "CurvedScatterPlot" example in the Core-Plot gallery app, used a mutable copy of newRange in plotSpace:willChangePlotRangeTo:forCoordinate: ...

CPTMutablePlotRange *changedRange = [newRange mutableCopy];

changedRange.location = CPTDecimalFromCGFloat(0.0F); then passes muster and I used changedRange in the if...else block.

Neoclassicism answered 14/4, 2013 at 2:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.