Graphs & CHarts primer [was Re: Custom Multicolumn Reports broken]
plongstaff at rogers.com
Fri Apr 17 13:11:18 EDT 2009
On April 17, 2009 10:57:06 am Andrew Sackville-West wrote:
> On Thu, Apr 16, 2009 at 12:57:23PM -0400, Phil Longstaff wrote:
> > I've taken a quick look at this. I think I broke it when I split the
> > html stuff out of gnome-utils into a separate html library.
> Phil, can you give me a quick primer on the code path from a graph or
> chart to rendered html? Somewhere in there we are setting titles and
> not paying attention to how long they might be relative to the size of
> the figure resulting in truncated titles.
> I see where the title gets declared in the scheme code and assembled
> into an html string. What would control font size at that point? Do we
> need to use CSS for it (fonts within the graph proper, that is) or is it
> that rendered by something else?
> I guess the real question, now that I've thought this through, is what
> determines the font scaling within the graphs and what, if anything,
> controls line wrap as well? The hackish fix for this seems to be to
> force a </br> into that html string, but that's just, well, hackish,
> as it doesn't address the real problem of font scaling.
I haven't looked at how saved reports work, but for new reports, it is
something like this:
1) User clicks on menu entry to open a report
2) gnc-plugin-page-report creates new page, creates html engine, and asks it
to load the url "report:id=nnn" where nnn is an internal code based on the
3) gnc-html separates out URL type "report" and calls back report system to
provide the html.
4) Report system provides an html string.
5) gnc-html searches the string looking for "<object classid=" which indicates
an embedded graph.
6) If not found, the html string, which contains a report, is sent to the html
engine to be displayed. If found, the "</object>" end tag is found. The
string between <object> and </object> is removed, and the graphing code
callback is called based on the classid value.
7) In the graphing code, the <object> string is parsed. Display width and
height are sent as attributes of the <object> tag. Other parameters are sent
using '<param name="nnn" value="vvv">' tags. The graphing code assumes the
order of these parameters based on the current scm code. These parameters
provide title, subtitle, data, axis labels, etc.
8) The graphing code uses goffice to create a graph as a GdkPixbuf. This is
then saved to a buffer as a png, converted to base 64, and converted back to an
embedded html <img> element. This is then passed back to the gnc-html.
9) gnc-html inserts the <img> where the <object> used to be, and then passes
this html in to the html engine.
For the old gtkhtml engine, this is a bit different. Gtkhtml emits a signal
when it encounters an <object> tag. gnc-html catches this and calls the
graphing code. Gtkhtml provides a GtkhtmlEmbedded object which contains the
<object> parameters and also acts as a widget. The graphing code gets the
parameters from the GtkhtmlEmbedded, creates the graph as a GdkPixbuf, and
then creates a GtkImage widget from that which is added into thee
GtkhtmlEmbedded widget to be displayed.
BTW, while writing this, I realized why a custom multi-column report with more
than 1 graph doesn't work - gnc-html only looks for one <object> tag - it
would ignore a second one.
If you want more control, you would need to:
1) pass more information as part of a <param> i.e. instead of <param
name="title" value="My Chart Title"/>, use <param name="title" value="My Chart
Title" font="helvetica" fontsize="14" italic="yes" bold="no" ....>
2) Parse this in gnc-html-graph-gog-xxxxx.c (xxxxx = webkit or gtkhtml)
3) Each chart type has an info structure which is filled in with the parameter
info - this would need to be expanded for new info
4) Modify the code (gnc-html-graph-gog.c) which takes info from this info
structure and controls goffice.
One thing on my to-do list is to modify the older gnc-html-gtkhtml and how it
handles graphs to be identical to webkit (I haven't checked, but I assume it
can handle <img src="data:image/png;base64,...."> with embedded image pixels).
This would mean both html engines would use the same parameter handling code.
It would also be good to provide a way so that knowledge of how to create and
parse the parameter strings doesn't need to be spread around in both scm and c
code. Perhaps gnc-html-gog-html would supply some functions to scm like
"(gnc-html-graph-specify-title "My Title" "helvetica" 14 #t #f)" which would
return the string to add to the html.
More information about the gnucash-devel