Диаграмма: ячейки с названиями серий [РЕШЕНО]

Автор JohnSUN, 2 марта 2011, 17:48

0 Пользователи и 1 гость просматривают эту тему.

JohnSUN

Коллеги, кто разбирал chart2 (или хотя бы устаревший chart)?
Проблема на картинке, зелеными рамками и стрелками.
Где и в каком виде диапазон категорий вешается на диаграмму?

Чтобы не возиться с тестовыми данными - образец во вложении.

[вложение удалено Администратором]
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

convas

#1
Примерно так?

Макрос для построения Chart в приложенном файле.

Ссылка на Wiki с примерами на Basic:
http://wiki.services.openoffice.org/wiki/Chart2

[вложение удалено Администратором]

JohnSUN

#2
Спасибо, друг мой! Очень похоже, но не совсем то. В этом макросе ключевой момент oChart.setRanges(aAddresses()) - присвоение сплошного прямоугольного диапазона с названиями категорий, серий и собственно данными. Если идти таким путём - получим что-то такое, как на рисунке. В моем-то случае данные сформированы именно так - с интервалами и разрывами.

Что досадно: если руками задать все ряды из пользовательского интерфейса, так чтобы получить требуемую диаграмму, то в "Диапазонах данных" генерируется последовательность вида $Дано.$C$2:$E$2;$Дано.$C$4;$Дано.$C$6;$Дано.$C$8;$Дано.$E$3:$E$5;$Дано.$E$6:$E$7;$Дано.$E$8:$E$9;$Дано.$D$3
то есть "ячейки с первой категорией и первой серией;ячейка со второй категорией; с третьей; с последней; прямоугольный диапазон с данными; ячейка со второй серией, последней".
Но если собрать эти адреса в массив и сунуть oChart'у через setRanges - результат будет совсем не такой как надо.

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

Народ предлагает не останавливаться на oChart и его getEmbeddedObject, а ковырять глубже - из EmbeddedObject выдернуть getFirstDiagram, для неё получить getCoordinateSystems, из неё - getChartTypes. Уже там получить getDataSeries, создать createDataSequenceByRangeRepresentation для каждого ряда данных с ролями  "label" и "values-y"... Всё это отлажено и работает. А вот подписи категорий - увы! - не могу найти где они размещаются.

Видимо, придется все-таки идти по первому пути.

[вложение удалено Администратором]
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

convas

Цитата: JohnSUN от  2 марта 2011, 20:54Всё это отлажено и работает.
Можно посмотреть твой готовый вариант? Интересно, я так глубоко не копал.
Хотя когда-то была идея построения графиков на основе массивов данных, формируемых в макросе, без обращения к данным на листах.
Но заглохла. ("All paid jobs absorb and degrade the mind." Aristotle.)

PS. Пример и ссылка выложены не столько для тебя (ты это и так знаешь), сколько для тех, кого эта проблема заинтересует впервые (или не впервые). Чтобы был предметный разговор.

JohnSUN

Можно, но чуть позже: сейчас программа в безобразном виде... Знаешь же как это бывает - начинаешь писать, четко представляешь что и где будет выполняться, пишешь ровно и вдохновенно, разбивая код на функциональные подпрограммы и функции... В какой-то момент очередной отладочный запуск показывает совсем не то, на что рассчитывал. Правишь, перезапускаешь, не то. Правишь, перечитываешь документацию, опять правишь, перезапускаешь - уже другое, но все-равно не то. Роешься на форумах, правишь, перезапускаешь... И внутри проекта образовывается одна такая большая Sub, которая на две трети состоит из заремленных строк кода, комментариев разной степени цензурности, иногда уже не имеющих отношения к оставшемуся коду, вызовов xRay и MRI...  Еще недавно эта Sub работала, хоть и делала не все, а сейчас она и то не делает, где то нужную строчку удалил...
Вот в такой вот Sub у меня и собрано все, что касалось построения графика по таблице на листе. Приведу в порядок - выложу.
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

JohnSUN

Причесал, более-менее связно откомментировал... Возможно, излишне многословно. Просто действительно учел, что пишу для "тех, кого эта проблема заинтересует впервые (или не впервые). Чтобы был предметный разговор."
Под LibreOffice 3.3.1 работает чуть более полно, чем под OOo 3.1.1.

На трех листах книги разбросаны данные. Макрос по некоторым из них строит гистограмму.
Правильно подписать категории так и не получилось.  :(

[вложение удалено Администратором]
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

convas

#6
Нужно макросом сделать вот так?

т.е. вставить такие Категории:
Цитировать$Друзья.$C$5;$Работа.$C$2;$Личное.$D$3

[вложение удалено Администратором]

JohnSUN

Вот-вот! Не точно эти самые, а произвольные, адреса которых можно задать такой строкой.
Тут ведь какая фишка: ООо, LO и XL будут по-разному отображать один и тот же график, если не потыкать каждый из них в полные данные... А крайне желательно добиться полной совместимости... Ну, о причинах можно не рассказывать, все и так в курсе  ;D
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

convas

#8
JohnSUN
Посмотри такой вариант:
Заменил твой кусок кода
REM В LibreOffice сработала бы и такая конструкция:
If verOOo >= "3.3" Then
oEmbed.getData().setRowDescriptions(oDataCat.getValues().TextualData())
REM Но в старых версиях ООо это вызовет вылет программы:
Else
REM НО КАК ЖЕ ЭТО СДЕЛАТЬ ПРАВИЛЬНО?!!!
End If

на
REM В LibreOffice сработала бы и такая конструкция:
If verOOo >= "3.3" Then
oEmbed.getData().setRowDescriptions(oDataCat.getValues().TextualData())
REM Но в старых версиях ООо это вызовет вылет программы:
Else
REM НО КАК ЖЕ ЭТО СДЕЛАТЬ ПРАВИЛЬНО?!!!

Dim catData(2)

catData(0) = "Одолжил"    'Получить строку из любой ячейки - не проблема, естественно.
catData(1) = "Вернул"
catData(2) = "Осталось"

oEmbed.getData().setRowDescriptions(catData())

End If


[вложение удалено Администратором]

convas

Это работает и в LO 3.3.1  и в OOo 3.2.1
Проверка If verOOo >= "3.3" Then ... End If не нужна.
Кусок кода работает в виде:
REM В LibreOffice сработала бы и такая конструкция:
' Все удалено
REM НО КАК ЖЕ ЭТО СДЕЛАТЬ ПРАВИЛЬНО?!!!

Dim catData(2)

catData(0) = "Одолжил"    'Получить строку из любой ячейки - не проблема, естественно.
catData(1) = "Вернул"
catData(2) = "Осталось"

oEmbed.getData().setRowDescriptions(catData())

JohnSUN

"Да... Да! ДА!!! Но - нет..." (с) За двумя зайцами

"Да" в смысле "Прямое присвоение строк работает"
"Но - нет" в смысле "Работает не так, как хотелось бы"

Например, если мы сформируем диаграмму, а затем в Друзья.B5 заменим "Леха" на, скажем, "Алексей Дмитриевич", то в легенде сразу же вместо несолидного "Лёхи" отобразится вполне респектабельный компаньон... А вот если надпись для категории "Вернул" мы при формировании графика выдернули, к примеру,  из ячейки Работа.G13, то даже вписав в эту ячейку слово "Прибыль" надпись на диаграмме мы уже автоматически не изменим.
Это потому, что для надписей рядов данных использованы реальные последовательности LabeledDataSequence, а для RowDescriptions используем просто строковые значения.

Если мы подсунем строку с адресами ячеек как параметр в createDataSequenceByRangeRepresentation (есть у DataProvider такой замечательный метод), то получим хитрый объект, который имеет свойство Role. В эту "Роль" вписываем одну из предопределенных строк ("label" - названия данных, "values-y" - значения Y) и chart2 будет знать, как с этими данными обращаться.
Среди этих предопределенных названий ролей есть и "categories" - названия категорий данных в диаграмме. То есть создать эту последовательность по всем правилам можно. Но вот в какое место объекта chart2 ее записать?
По логике вещей, точка, в которую нужно подвешивать LabeledDataSequence с ролью "категории", должна находиться или выше набора рядов данных (она ведь одна для всей группы рядов), или где-то немного ниже (поскольку детализирует по строкам значения внутри ряда)... Вот эту точку я и ищу уже больше двух недель (где у нас тут смайлик "башкой об стенку"?)
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

convas

Цитироватьнадпись на диаграмме мы уже автоматически не изменим

Посмотри теперь такой вариант, где можно менять.

[вложение удалено Администратором]

JohnSUN

#12
Супер! Класс! Сэнкс!
Я, когда расковыривал chart через xRay, обратил внимание, что самый первый элемент (который нулевой) содержит названия категорий. То есть просто:

oChart.setRanges(aAddresses())
и
oDataRow = oDiagram.getDataRowProperties(0)

Но у меня никак не получалось присвоить ему осмысленные значения... Теперь хотя бы понимаю причину, почему так получилось. А дело оказывается в версии офиса - под OpenOffice.org 3.1.1 эти строчки нормально выполняются и результат полностью соответствует твоему png.
А я-то отлаживал код под LO 3.3.1  :( А здесь уже такое нахальство не прокатит. Результат того же макроса выполненного под LO - на скриншоте.

PS. Кстати о версиях! Тот If с проверкой номера версии офиса я вставил именно поэтому: перед публикацией книги на форуме на всякий случай проверил как макрос отработает под ООо... А он взял, да и не отработал  :-[ Ну, чтобы народ не расстраивать ошибками на этапе выполнения, я на скорую руку и вставил ветвление...

PPS. Пока, видимо, придется использовать компромиссный вариант с запихиванием названий категорий живьем. Потому как куда приткнуть последовательность с этими адресами в новых версиях офиса все-равно не понятно

[вложение удалено Администратором]
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

JohnSUN

#13
Эврика! Нашёл! Еще в сентябре 2008 года Ingrid Halama :

1. Из системы координат выдергиваем главную ось Х - getAxisByDimension(0,0)
2. А в ней получим getScaleData (кто бы мог подумать, что ScaleData это то что надо?)
3. А уже в этой структуре находим XLabeledDataSequence "Categories"
Dim oAxisByDimension As Object
Dim aScaleData As New com.sun.star.chart2.ScaleData
Dim oCategories As Object

oAxisByDimension = oCoord.getAxisByDimension(0, 0)
aScaleData = oAxisByDimension.getScaleData()
aScaleData.Categories = oDataCat
aScaleData.AxisType = com.sun.star.chart2.AxisType.CATEGORY
oAxisByDimension.setScaleData(aScaleData)


Тему отмечаю [Решено], но некоторые вопросы еще остаются. Например, существует ли разница между строчками

"$Друзья.$C$5:$D$5;$Друзья.$E$3"
и
"$Друзья.$C$5;$Друзья.$D$5;$Друзья.$E$3"

Оказывается, для LO 3.3.1 - разница есть (см. картинки)

PS. А может [MEMO]?

PPS. Заметил на картинке опечатку в подписи ко второму графику - вместо точки с запятой имелось в виду двоеточие, конечно

[вложение удалено Администратором]
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

convas

Цитата: JohnSUN от  6 марта 2011, 19:01Эврика! Нашёл! Еще в сентябре 2008 года Ingrid Halama :
Примерчик для LO не подкинешь?