2016-01-19 4 views
5

Я ищу способ нарисовать линейную диаграмму с большим количеством точек (до 10 000) эффективно на iOS. График получает данные в реальном времени и нуждается в обновлении несколько раз в секунду. Я пытаюсь найти способ эффективно нарисовать график, чтобы он не максимизировал процессор и блокировал основной поток при рисовании.Рисунок диаграммы с большим количеством точек эффективно на iOS

В настоящее время я создаю UIBezierPath для линейной диаграммы, в фоновом потоке, добавляя все точки и рисуя ее в CALayer (с включенным асинхронным рисунком). Это не очень быстро, максимизирует процессор, и рисунок настолько медленный, что пользовательский интерфейс становится лагги. Я рисую данные в реальном времени, и теоретически я мог бы повторно использовать один и тот же UIBezierPath каждый раз и просто добавлять новые точки, однако старые значения отбрасываются через некоторое время, то есть точки для удаленных значений должны быть удалены из пути безье , что невозможно.

Я ничего не нашел в эффективном построении больших наборов данных на iOS, но я надеюсь, что есть способы использовать GPU для повышения производительности.

+0

вам нужно нарисовать все 10k точек? Даже на экране iPad это кажется чрезмерно чрезмерным ... (больше точек, чем горизонтальные пиксели). Рассматривали ли вы усреднение данных в меньший набор? – Hamish

+0

@ originaluser2 Я полностью согласен. Я делаю некоторые работы с клиентом и еще не смог выговорить их из идеи рисовать эти многочисленные моменты. – JonasG

+0

хорошо, если вы можете их убедить, усреднение - ваш лучший выбор! Я сомневаюсь, что вы сможете использовать большую часть графического процессора, не перейдя в Metal/Open GL. Я уверен, что 'UIBezierPath' в основном использует Core Graphics под капотом, и все работает на процессоре. – Hamish

ответ

0

я, наконец, нашел реализацию для рисования графа с OpenGL: https://github.com/syedhali/EZAudio/blob/master/EZAudio/EZAudioPlotGL.m

Это на самом деле довольно легко и улучшения производительности огромны.

Для устройств с чипом A7 (или новее), вероятно, будет еще быстрее рисовать график с металлом, что также должно быть довольно простым. Есть несколько руководств о том, как это сделать: https://www.raywenderlich.com/77488/ios-8-metal-tutorial-swift-getting-started

1

У меня была такая ситуация несколько лет назад (назад в iPhone 4 дня).

Я использовал , к которому я добавил баллы, используя CGPathMoveToPoint для первого пункта, и CGPathAddLineToPoint для последующих точек.

Чтобы получить приемлемую производительность, я сохранил точки данных в массиве C (не NSArray). Кроме того, при построении точки, если ее координаты отображения совпадают с последней нарисованной точкой, я просто пропустил вызов до CGPathAddLineToPoint. (Это часто случается, когда у вас больше точек данных, чем пикселей).

Я не помню точное время рисования, но это было удивительно быстро.

+0

, если вы не можете усреднить набор данных, это, безусловно, следующий лучший вариант. (без полного металла) – Hamish

0

Вместо того, чтобы нарисовать точки с помощью UIBezierPath, вы можете настроить CGBitmapContext, а затем нарисовать точки «вручную», например.

color = (0xFF << 24) | (blue << 16) | (green << 8) | (red); // AABBGGRR 
for (loop = 0; loop < count; loop++) 
{ 
    index = indices[loop]; 
    self.pixels[index] = color; 
} 

где self.pixels - это буфер, который вы использовали для создания CGBitmapContext. Тогда, в DrawRect:

CGContextRef c = UIGraphicsGetCurrentContext(); 

CGImageRef image = CGBitmapContextCreateImage(self.imageContext); 
CGContextDrawImage(c, self.bounds, image); 
CGImageRelease(image); 

Я думаю, вы найдете это будет значительно быстрее (и меньше), чем при использовании CGPath или UIBezierPath.

Смежные вопросы