【问题标题】:Allow horizontal scrolling only in the core-plot barchart?仅在核心图条形图中允许水平滚动?
【发布时间】:2010-12-25 22:33:02
【问题描述】:

我正在使用 core-plot lib 在我的应用程序中绘制条形图,如下所示

我的问题是我希望仅在水平方向上启用 grapgh 移动,以便我可以长时间查看记录,但问题是我只想将 y 轴固定在其位置,

我该怎么做?

等待帮助....

【问题讨论】:

  • 我不知道你上次为什么回滚我的编辑。 Imgur 比 FreeImageHosting.net 快得多,每当我尝试将图像作为此页面的一部分加载时,它就会超时。

标签: iphone cocoa-touch core-graphics core-plot bar-chart


【解决方案1】:

以下代码基于Tom Donaldson's answer,并已使用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;
}

【讨论】:

    【解决方案2】:

    如果您使用的是 Core-Plot 0.2.2 或更高版本(可能更早),那么您可以在绘图空间的委托上添加一个方法来处理以下内容:

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

    这会将绘图移动限制为仅水平移动。这假设您已通过设置allowUserInteraction = YES 来允许与绘图空间进行交互。

    【讨论】:

    • 我只能在对存储库进行 hg 克隆后才能使其正常工作。我没有使用安装程序。
    • 在 CorePlot v1.1 上运行良好
    【解决方案3】:

    在答案 4 之后,您需要做的就是修复 y 轴,并附上注释。 (newRange.doublePrecisionLocation 现在是newRange.locationDouble)是设置plotSpace.globalYRange = plotSpace.yRange;

    【讨论】:

      【解决方案4】:

      @Andrew S:“我正在接受‘分配给只读属性’ newRange.location = CPTDecimalFromFloat(0.0);"

      我也有,并且按照 Core-Plot 画廊应用程序中的“CurvedScatterPlot”示例,在 plotSpace:willChangePlotRangeTo:forCoordinate: 中使用了 newRange 的可变副本:...

      CPTMutablePlotRange *changedRange = [newRange mutableCopy];

      changedRange.location = CPTDecimalFromCGFloat(0.0F);然后通过集合,我在 if...else 块中使用了 changedRange。

      【讨论】:

        【解决方案5】:

        你可以覆盖

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

        在 CPTXYPlotSpace 中调用函数,取出所有与 y 轴运动相关的代码。

        【讨论】:

          【解决方案6】:

          使用 CorePlot 1.0 -- 为了将滚动限制为水平和缩放,我实现了两个 CPTPlotSpaceDelegate 方法:Steve Tranby 的方法和 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;
          }
          

          【讨论】:

          • 你介意分享一下如何设置图表的代码吗?我的意思是在开始时设置 CPTPlotSpace 的起点。我遵循了您的解决方案,但我的解决方案仍然无法正常工作。请帮忙! >.
          • 你是男人...感谢杰伊的精彩回答... :) 投票
          【解决方案7】:

          感谢 supperAly 当我的接口实现“CPPlotSpaceDelegate”协议时 项目无法正常编译,显示: your interface xxx doesn't implement 'CPLineStyleDelegate' protocol,这让我很困惑。 所以我添加了方法:-(void)lineStyleDidChange:(CPLineStyle *)lineStyle { //empty } 对于 CPLineStyleDelegate 并将&lt;CPLineStyleDelegate&gt; 添加到我的界面,问题就消失了。

          【讨论】:

            【解决方案8】:

            我正在使用 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;
            }
            

            您需要将 CPPlotSpaceDelegate、CPLineStyleDelegate 协议添加到您的控制器

            并添加(用于 CPLineStyleDelegate)

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

            系统将保持y轴的原始范围

            【讨论】:

              【解决方案9】:

              通过在绘图空间上设置一个委托(即 CPPlotSpaceDelegate)来限制滚动并实现 willChangePlotRangeTo 方法。你可以同时做其他很酷的事情。以下是我如何将显示限制在第一象限:

              - (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;
              }
              

              参见:CPPlotSpace.h

              【讨论】:

              • newRange.doublePrecisionLocation 现在是 newRange.locationDouble
              • newRange.doublePrecisionLength 现在是 newRange.lengthDouble
              • 我正在分配只读属性:newRange.location = CPTDecimalFromFloat(0.0);
              • 我在此处添加了适用于 CorePlot 1.5.1 的更新代码:stackoverflow.com/a/24525631/607
              【解决方案10】:

              我使用了一种简单的方法来“禁用”垂直滚动

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

              对于,minY 和 maxY 我把我显示的值,就像垂直限制是你看到的那样,所以你不能垂直滚动

              在我看到你的主题后,它对我有用,所以我想用我的来完成你的答案

              【讨论】:

              • 是否可以限制滚动到负x轴?
              【解决方案11】:

              直到最近才在 Core Plot 图表中启用了基本的用户交互。要启用任意方向的滚动,您可以将绘图空间的allowsUserInteraction 属性设置为YES。

              我们目前无法将该运动锁定在一个方向。滚动动作发生在 CPXYPlotSpace 上的 -pointingDeviceDraggedAtPoint: 方法中,因此您可以子类化 CPXYPlotSpace,复制其对该方法的实现,并将其更改为仅允许在 X 方向上移动。更好的是,我们非常感谢您对扩展 CPXYPlotSpace 的功能以增加对单向移动的支持的任何贡献。

              【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-04-05
              • 2015-02-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多