(Простой?) Размещение меток для линейных графиков - PullRequest
5 голосов
/ 23 июня 2009

Я рисую профили высот, показывающие выигрыш / убыток по трассе, аналогичный приведенному ниже:

Образец профиля высоты с размещенными вручную метками http://img38.imageshack.us/img38/4079/profilewithgoodlabels.png

Это в основном линейный график с расстоянием от начала по оси X и высотой по оси Y.

Я хотел бы предоставить необычные метки с точечными отметками в интересных точках вдоль трассы, подобно тем, которые я добавил вручную к образцу изображения. Я ищу идеи о том, как лучше разместить эти ярлыки, чтобы:

  • Они не пересекаются друг с другом
  • Они не пересекаются с самим профилем, или, по крайней мере, это происходит чисто на вид (кажется, что это может быть необходимо в середине крутой долины, например)
  • Они не выходят за рамки, ограничивающие общее изображение

Для достижения этих целей я полагаю (по крайней мере):

  • Перевернуть текст (см. Пример)
  • Выберите подходящую длину для лидеров
  • Выберите подходящие углы для лидеров (но минимизация отклонения может быть желательна по эстетическим соображениям)
  • Высотные отметки для менее важных мест в людных местах
  • Сокращайте названия в многолюдных местах (PlaceName s в моей среде уже поддерживают аббревиатуру действительно хорошим способом, поэтому переключение с "South Twin Mountain" на "S Twin Mtn" легко)
  • Оставляйте менее важные аннотации полностью в людных местах

Но я не знаю, как лучше структурировать этот алгоритм. Может быть, это проблема оптимизации? (Сведите к минимуму вонючность, связанную с аннотацией, и предоставьте числовое наказание за каждую из вещей, которые я пытаюсь избежать?) Но поскольку существует множество дискретных переменных, которые нужно оптимизировать, и меня не волнуют «лучшие» решение (просто хорошее и желательно стабильное) Я не уверен, что делать.

Как обычно решаются такие проблемы в графике? Динамическое программирование? Ветвь и связанный? Идея оптимизации вне базы? Есть ли какие-нибудь полезные библиотеки для .NET, которые я хотел бы посмотреть?

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

Ответы [ 3 ]

2 голосов
/ 23 июня 2009

Вот мой дубль:

  1. Отметьте точки, в которые вы хотите поместить метки
  2. Разделите их на группы с расстоянием не менее 2*size между ними
  3. Для каждой группы идите справа и попробуйте поставить метку.
  4. Попробуйте поставить метку вправо или влево. Посмотрите, что приводит к уменьшению длины вертикальной линии
  5. Если неважно, попробуйте поставить вправо
  6. Если это не конец группы, попробуйте поставить его слева

Теперь снова перейдите к меткам и посмотрите, можно ли их перевернуть с одной стороны на другую, сокращая при этом длину вертикальных линий.

Должен, по моему мнению, дать достойный результат.

1 голос
/ 23 июня 2009

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

Я вижу много параллелей с вашей проблемой. Текстовые поля - это узлы, а выносные линии - это края.

Это должно быть изменено. Например, должна быть положительная сила вверх, чтобы они не опускались ниже графика. Вы также должны были бы включить идею перелистывания текста влево или вправо. Но это должно дать разумный результат на большинстве входов.

Статья, на которую я ссылался для моего проекта, была здесь .

1 голос
/ 23 июня 2009

Я бы, вероятно, поместил один ярлык, затем разместил следующий, проверил, перекрывает ли он первый, и если это так, переверните его, если это не сработает, подтолкните его вверх, пока он больше не перекрывается ... отправная точка в любом случае. Может быть, добавить функцию стоимости как расстояние от идеального или стандартного размещения (если не было других меток, чтобы мешать), что должно быть минимизировано. Тогда найдите самое дешевое расположение этикеток. Может давать переворачивание, движение, вращение, аббревиатуру и опускание - разные цены.

...