Ask Your Question
0

Inserting Chart using pyuno

asked 2017-12-05 06:03:36 +0200

omars gravatar image

Hi all,

Is there any references/example of inserting chart using python (through pyuno) for Libreoffice writer ?

edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted
1

answered 2017-12-06 06:25:47 +0200

Ratslinger gravatar image

Hello,

Your question had me revisit converting my Base charts to complete some of the conversion to Python. Since Base Forms are basically Writer documents, I thought I would produce a sample for you. What started out to be a small project has taken up more than my entire day! First, here is the code I present:

#!/usr/bin/env
import uno
import sys
import os
import time
from array import array
from com.sun.star.awt import Point
from com.sun.star.awt import Size
from com.sun.star.text.TextContentAnchorType import AT_PAGE
from com.sun.star.text.VertOrientation import NONE
from com.sun.star.text.HoriOrientation import NONE

def create_chart(*args):
    doc = XSCRIPTCONTEXT.getDocument()
    textFrame = doc.createInstance( "com.sun.star.text.TextFrame" )
    text = doc.Text
    textFrame.Width = 11000
    textFrame.Height = 7500
    textFrame.AnchorType = AT_PAGE
    textFrame.RelativeWidthRelation = 1
    textFrame.RelativeWidth = 100
    textFrame.SizeType = 1
    textFrame.VertOrient = NONE
    textFrame.HoriOrient = NONE
    cursor = text.createTextCursor()
    text.insertTextContent(doc.Text.End,textFrame,0)
    textFrame.Text.String = chr(13)
    textObject = doc.createInstance( "com.sun.star.text.TextEmbeddedObject" )
    textObject.setPropertyValue("CLSID","12dcae26-281f-416f-a234-c3086127382e")
    textObject.Name = "ChartID"
    textFrame.getText().insertTextContent(textFrame.Text.End, textObject, False)
    docChart = textObject.EmbeddedObject.Component
    docChart.Diagram = docChart.createInstance("com.sun.star.chart.BarDiagram")
#problem area in follow:    
    rowDesc = ["a","b","c","d","e","f","g"]
    docChart.Data.setRowDescriptions(rowDesc)
    colDesc = ["First", "Second"]
    colDesc[0] = "Third"
    colDesc[1] = "Fourth"
    docChart.Data.setColumnDescriptions(tuple(colDesc))
    myData = [[100,150],[200,50],[300,270],[400,63],[500,82],[600,645]]
    docChart.Data.Data = tuple(myData)
#problem area above
    chartTitle = docChart.getTitle()
    chartTitle.String = "Sample Python Chart"
    docChart.Diagram.getAxis(0).getAxisTitle().String = "Some Stuff Here"
    docChart.Diagram.getAxis(1).getAxisTitle().String = "Maybe Distance"
    docChart.HasLegend = 1
    myDoc = XSCRIPTCONTEXT.getDocument()
    embeddedObjects = doc.getEmbeddedObjects()
    chartObject = embeddedObjects.getByName("ChartID")
    chartSize = Size(15000,6500)
    chartObject.setSize(chartSize)

g_exportedScripts = create_chart,

This code works without a problem in a Base Form. However, there are problems in a Writer document. The code will finally work, but when first executed it starts out as:

image description

Now I like to use charts inside frames because it is easier to manipulate, so that is what is seen. When the inside of the frame is clicked on (where the chart actually is) Writer crashes. When recovered through the normal recovery process the Chart appears complete. Here is the chart in both Base & Writer:

image description

The frame on the Base chart is harder to see since it goes to the edge of the screen. Both were done using the same code. Base appeared instantly & writer crashes but can recover to successful display. The problem area is indicated in the code; The Row/Column descriptions & the actual data. Even if only one (any one) is present - crash. Been trying all day with searches & not finding anything. This may be why you only find Python code for Calc. I actually never found any for Base. Devised this over a long period.

You can find my post here regarding charts in Base forms. It contains samples and the ... (more)

edit flag offensive delete link more

Comments

As a further note, just tried creating chart in Writer using code in Basic. Same results. Got to be some problem but lost as to what it is.

Ratslinger gravatar imageRatslinger ( 2017-12-06 06:56:37 +0200 )edit

I was not aware that this could be done outside of Calc (and I mistakenly overlooked the writer tag in the question). I wonder if a chart can use a Base table as the data source?

Jim K gravatar imageJim K ( 2017-12-06 15:44:31 +0200 )edit

@Jim K I don't see any reason why not. I do this all the time in Base. You can see this in the post I mentioned near the end of my answer. There I use Queries to retrieve data for display within the charts. The samples include a number of variations.

Note: I should clarify '..as the data source..". The data is obtained from the tables thru SQL and must be re-done if table data changes. There is no 'Live' connection to the tables.

Ratslinger gravatar imageRatslinger ( 2017-12-06 15:51:49 +0200 )edit

To avoid the crash in Writer, append the following code.

ctx = XSCRIPTCONTEXT.getComponentContext()
smgr = ctx.ServiceManager
frame = doc.getCurrentController().getFrame()
dispatcher = smgr.createInstanceWithContext(
    "com.sun.star.frame.DispatchHelper", ctx)
dispatcher.executeDispatch(frame, ".uno:Save", "", 0, ())
dispatcher.executeDispatch(frame, ".uno:Reload", "", 0, ())
Jim K gravatar imageJim K ( 2017-12-06 20:07:46 +0200 )edit

Thanks. Now works as expected. Thought there was a solution but because Base worked had gone in wrong direction for too many hours.

Ratslinger gravatar imageRatslinger ( 2017-12-06 20:26:32 +0200 )edit

Apparently, these charts are different from those in Calc in that they use an internal data table rather than an external data source. So the data must either be entered manually in the chart table or come from a macro, such as the query in your example.

Jim K gravatar imageJim K ( 2017-12-06 20:30:19 +0200 )edit

Not completely certain of that. For example, in both Base and Writer you can have Text Tables Which an inserted chart can be based upon. I believe this is also possible with this code but haven't tried yet. There are some other possibilities I have thought of but again time and necessity get in the way. Just not a priority yet.

Ratslinger gravatar imageRatslinger ( 2017-12-06 20:41:58 +0200 )edit

One more idea regarding the crash: Perhaps when resizing, it would help to call https://www.openoffice.org/api/docs/c....

Jim K gravatar imageJim K ( 2017-12-06 21:01:16 +0200 )edit
1

Thanks for this last link. Although your fix worked, I wasn't thrilled with it. I have now replaced your fix with:

extendedChartControl = chartObject.getExtendedControlOverEmbeddedObject()
extendedChartControl.changeState(4)

Still not the best but works. So much more can be done. Searching API becomes tiresome.

Ratslinger gravatar imageRatslinger ( 2017-12-07 01:52:22 +0200 )edit

@Jim K Got one more for you on this subject. Your comment about using external data source. See my answer here. I try to look at this every once in a while. Gets sheet in doc but haven't gotten actual live links working. Actually its' what led me to charts in Base. Had to laugh when I looked at it just now cause I used extendedControl there. This may revive my interest to get it working.

Ratslinger gravatar imageRatslinger ( 2017-12-07 02:21:02 +0200 )edit
0

answered 2017-12-05 10:05:47 +0200

Jim K gravatar image

There is a python example at https://wiki.openoffice.org/wiki/Pyth....

However, it may be better to start with Andrew Pitonyak's macro document section 6.27. Add a chart and translate it from Basic to Python.

edit flag offensive delete link more

Comments

ok, thank you for the answer.

omars gravatar imageomars ( 2017-12-07 07:30:50 +0200 )edit
Login/Signup to Answer

Question Tools

1 follower

Stats

Asked: 2017-12-05 06:03:36 +0200

Seen: 413 times

Last updated: Dec 06 '17