Разрешить горизонтальную прокрутку только на гистограмме основного графика?
-
19-09-2019 - |
Вопрос
Я использую core-plot lib для рисования столбчатых диаграмм в моем приложении следующим образом
Моя проблема в том, что я хочу включить движение графика только в горизонтальном направлении, чтобы я мог видеть записи в течение длительного периода времени, Но проблема в том, что я просто не хочу, чтобы ось y была зафиксирована на своем месте,
Как я могу это сделать?
Ожидание помощи....
Решение
Только недавно на графиках Core Plot было включено элементарное взаимодействие с пользователем.Чтобы включить прокрутку в любом направлении, вы можете установить allowsUserInteraction
свойство площади участка равняться YES.
В настоящее время у нас нет средств зафиксировать это движение в одном направлении.Действие прокрутки происходит в -pointingDeviceDraggedAtPoint:
метод в CPXYPlotSpace, чтобы вы могли создать подкласс CPXYPlotSpace, скопировать его реализацию этого метода и изменить его, чтобы разрешить движение только в направлении X.Более того, мы были бы признательны за любой вклад в расширение функциональности CPXYPlotSpace для добавления поддержки однонаправленного перемещения.
Другие советы
Если вы используете Core-Plot 0.2.2 или выше (возможно, более раннюю версию), то вы можете добавить метод в делегат вашего пространства построения для обработки следующего:
-(CGPoint)plotSpace:(CPTPlotSpace *)space willDisplaceBy:(CGPoint)displacement {
return CGPointMake(displacement.x, 0);
}
Это ограничит перемещение графика только горизонтальным.Это предполагает, что вы разрешили взаимодействие с пространством графика, установив allowsUserInteraction = YES .
Ограничьте прокрутку, установив делегат (т. Е. 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
Я использовал простой способ "отключить" вертикальную прокрутку
CPPlotRange *globalYRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromDouble(minY) length:CPDecimalFromDouble(maxY)];
plotSpace.globalYRange = globalYRange;
Для, minY и maxY я ввел значения, которые я отобразил, например, что вертикальные границы - это то, что вы видите, поэтому вы не можете прокручивать по вертикали
У меня это сработало после того, как я увидел вашу тему, поэтому я хотел дополнить ваши ответы своими
Используя CorePlot 1.0 - Чтобы ограничить прокрутку только горизонтальной, а также масштабированием, я реализовал два метода CPTPlotSpaceDelegate:метод Стива Транби с модифицированным методом, предложенным 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;
}
я использую 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
Все, что вам нужно сделать, чтобы исправить ось y после ответа 4 с комментарием вкл.( newRange.doublePrecisionLocation
это сейчас newRange.locationDouble
) заключается в том, чтобы установить plotSpace.globalYRange = plotSpace.yRange;
благодаря supperAly
когда мой интерфейс реализует протокол "CPPlotSpaceDelegate"
и проект не может быть выполнен нормально, и показывает, что: your interface xxx doesn't implement 'CPLineStyleDelegate' protocol
, которые приводят меня в замешательство.итак, я добавляю метод : -(void)lineStyleDidChange:(CPLineStyle *)lineStyle { //empty }
для CPLineStyleDelegate и добавьте <CPLineStyleDelegate>
к моему интерфейсу, и проблемы исчезли.
Следующий код основан на Ответ Тома Дональдсона и был протестирован с 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;
}
Вы можете переопределить
-(void)scaleBy:(CGFloat)interactionScale aboutPoint:(CGPoint)plotAreaPoint`
выполните функцию в CPTXYPlotSpace и извлеките весь код, связанный с перемещением по оси y.
@Эндрю С:"Я получаю "назначение свойству, доступному только для чтения" в newRange.location = CPTDecimalFromFloat(0.0);"
У меня это тоже было, и, следуя примеру "CurvedScatterPlot" в приложении Core-Plot gallery, я использовал изменяемую копию newRange в plotSpace:willChangePlotRangeTo: forCoordinate:...
CPTMutablePlotRange *Измененный диапазон = [Изменяемая копия нового диапазона];
Изменен диапазон.местоположение = CPTDECIMALFROAT от CGFloat (0.0F);затем проходит проверка, и я использовал changedRange в блоке if ...else.