Arhn - архитектура программирования

Основной сюжет: как построить график с осью Y по среднему значению?

Я настроил график с основным сюжетом, который показывает анимацию при наличии новых данных для отображения. Я следовал примеру кода CorePlot, чтобы показать новые анимированные данные на графике.

Это ситуация:

  • Я должен показать тенденцию значения (например, скорость)
  • Ось X: значение скорости, которое я хочу нарисовать
  • Ось Y: значение времени, и я хочу, чтобы ось всегда центрировалась на среднем значении, доступном в настоящее время на диаграмме.
  • Каждое значение на графике должно быть видно, поэтому я должен расширить диапазон оси x, чтобы вместить все данные.

Теперь ось Y перемещается с каждым новым значением. без «заякоривания» посередине.

Это моя начальная установка для диаграммы:

- (void)configureHost {

    self.hostViewTop = [(CPTGraphHostingView *) [CPTGraphHostingView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height/3, 2*self.view.frame.size.width/5, self.view.frame.size.height/1.5)];
    self.hostViewTop.collapsesLayers = NO;
    [self.hostViewTop setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
    [self.hostViewTop setAutoresizesSubviews:YES];
    self.hostViewTop.allowPinchScaling = NO;
    [self.view addSubview:self.hostViewTop];
}

- (void) configurePlots{

    CPTGraph *graph = self.hostViewTop.hostedGraph;
    CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;

//    1 - Create the three plots

    ...  

//    2 - Set up plot space

    plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromUnsignedInteger(0) length:CPTDecimalFromUnsignedInteger(MAX_DATA_ON_CHART)];
    plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromUnsignedInteger(0) length:CPTDecimalFromUnsignedInteger(MAX_VALUE)];

//    4 - Create styles and symbols

    ...
}

- (void)configureAxes {

    // 1 - Create styles

    ...

    // 2 - Get axis set

    CPTXYAxisSet *axisSet = (CPTXYAxisSet *) self.hostViewTop.hostedGraph.axisSet;

    // X axis

    CPTXYAxis *x = axisSet.xAxis;
    x.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
    x.orthogonalCoordinateDecimal = CPTDecimalFromUnsignedInteger(0);
    x.minorGridLineStyle = minorGridLineStyle;
    x.majorGridLineStyle = majorGridLineStyle;
    x.minorTickLineStyle = minorTickLineStyle;
    x.majorTickLineStyle = majorTickLineStyle;
    x.minorTicksPerInterval = 9;
    x.axisLineStyle = axisLineStyle;
    x.labelTextStyle = clearTextStyle;
    x.axisConstraints = [CPTConstraints constraintWithUpperOffset:0.0];
    x.coordinate = CPTCoordinateX;
    x.tickDirection = CPTSignNegative;

    NSNumberFormatter *labelFormatter = [[NSNumberFormatter alloc] init];
    labelFormatter.numberStyle = NSNumberFormatterNoStyle;
    x.labelFormatter = labelFormatter;

    // Y axis

    CPTXYAxis *y = axisSet.yAxis;

    y.labelingPolicy = CPTAxisLabelingPolicyAutomatic;

    // Y Axis at the beginning is at MAX_VALUE/2

    y.orthogonalCoordinateDecimal = CPTDecimalFromUnsignedInteger(MAX_VALUE/2);

    y.minorGridLineStyle = minorGridLineStyle;
    y.majorGridLineStyle = majorGridLineStyle;
    y.minorTickLineStyle = minorTickLineStyle;
    y.majorTickLineStyle = majorTickLineStyle;

    y.majorIntervalLength = CPTDecimalFromInt(10);
    y.minorTicksPerInterval = 3;

    y.labelAlignment = CPTAlignmentRight;

    y.axisLineStyle = axisLineStyle;
    y.labelTextStyle = clearTextStyle;
    y.labelFormatter = labelFormatter;
    y.coordinate = CPTCoordinateY;
}

При наличии новых данных:

- (void)newData:(int)data {

    CPTGraph *graphTop = self.hostViewTop.hostedGraph;
    CPTPlot *plotTop = [graphTop plotWithIdentifier:@"ID"];

    if (plotTop) {

        if (dataArray.count > MAX_DATA) {
            NSRange range;
            range.location = 0;
            range.length = dataArray.count-MAX_DATA;
            [dataArray removeObjectsInRange:range];
            [plotTop deleteDataInIndexRange:range];
        }

        CPTXYPlotSpace *plotSpaceTop = (CPTXYPlotSpace *)graphTop.defaultPlotSpace;
        NSUInteger location = (currentIndex > MAX_DATA ? currentIndex - MAX_DATA + 1 : 0);

        CPTPlotRange *newYRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromUnsignedInteger(location)
                                                               length:CPTDecimalFromUnsignedInteger(MAX_DATA+MAX_DATA/4)];

        [plotSpaceTop setYRange:newYRange];

        currentIndex++;

        // minValue, maxVlue, avgValue calculated from al data visible in chart

        minValue = ...
        maxValue = ...
        avgValue = ...

        ...

        double delta;

        if (fabs(avgValue-minValue) > fabs(maxValue-avgValue)) {
            delta = fabs(avgValue-minValue);
        } else if (fabs(maxValue-avgValue)) {
            delta = fabs(maxValue-avgValue);
        }

        CPTPlotRange *newXRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(avgValue-delta) length:CPTDecimalFromDouble(avgValue+delta)];

        [plotSpaceTop setXRange:newXRange];

        [((CPTXYAxisSet *) graphTop.axisSet).yAxis setOrthogonalCoordinateDecimal:CPTDecimalFromDouble(avgValue)];

        ...

        [plotTop insertDataAtIndex:newData.count - 1 numberOfRecords:1];

        ...
    }
}

Заранее спасибо за помощь.

24.10.2015

  • Вы хотите, чтобы ось Y находилась в центре области графика в дополнение к пересечению оси x в среднем значении x? 24.10.2015
  • Правильно, и (для этого) мне нужно расширить диапазон оси x, чтобы пропорционально удерживать все значения, чтобы ось Y находилась в центре 25.10.2015

Ответы:


1

length нового xRange должно быть delta * 2, чтобы поместить среднее значение в центр.

CPTPlotRange *newXRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(avgValue-delta)
                                                       length:CPTDecimalFromDouble(delta * 2.0)];
25.10.2015
  • Да, правильно, много кода CorePlot, и я не видел этой детали. Теперь правильно. Большое спасибо ;) 30.10.2015
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..