Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

### Experiment ### Use Litehtml instead of Webkit #1868

Open
wants to merge 16 commits into
base: stable
Choose a base branch
from

Conversation

Bob-IT
Copy link
Contributor

@Bob-IT Bob-IT commented Feb 16, 2024

This is just an experiment to see if it was possible to use Litehtml to display reports in the Gnucash application.

As I did not have a Litehtml package in Gentoo, I have added the source to borrowed but not correctly as the tests fail which will need to be fixed if this is worth continuing.

I used the Litehtml browser demo for Linux as a start point as this was based on Gtk. Litehtml is based on c++ and hence one of browser dependencies was gtkmm3 but I chose to convert the code to use Gtk which does away with that dependency. This conversion is done is html/conatiner-linux and html/html-widget.

Additional files were added to the html directory and these connect to Litehtml via the files above and with the use of a callback the web links open the appropriate register pages. I have not done much testing but I did notice that some of the style sheet properties did not work. This maybe down to the CSS not being recognised for a particular element but there maybe alternatives, I think one was the report text colour.
litehtml1

Unfortunately Litehtml does not support javascript so none of the chartjs reports display any thing, for that to work I think the canvas element would need to be added and the script element would need to plumbed to a javascript engine.

What I did find was cglib which creates an svg image of a chart. I added the source to borrowed and added a demo file, my-test-of-cglib which has hard coded paths to the /tmp directory. On every report creation, 5 svg files are created in /tmp directory and to view them I changed html-chart.scm to display them as seen below.
litehtml2
litehtml3
litehtml4

There is what appears to be an alignment issue for the labels and not sure what is causing it as opening the created report file in a browser looks OK. There maybe some changes to be made regarding colours, axis labls and maybe the legend box which hopefully is doable but I do not think links would be possible.

Also I added a javascript function, hideMyImage to hide these images when opened in a browser and then it would display the chartjs version, may be of use, not sure.

Looking at the configuration values for these charts, I think they could be obtained from the script tag, not sure how at the moment, and used to create the appropriate svg image in the temp directory along with updating the report with the correct path uri's.

Also while looking at this with a possible move to using pdf's, using libharu to create them I found libhpdftbl that makes creating tables easier. For viewing the glib version of poppler seems to fit the bill.

I am parking this for a while so people can decide if this is worth pursuing.

@jralls
Copy link
Member

jralls commented Feb 16, 2024

@Bob-IT

Nice work.

I'm not keen on the SVG approach, especially if it generates 5 files/chart. If it could be boiled down to a single file without the chartjs dependencies in the current export I'd be happier with it, but I think a <canvas> approach is overall cleaner.

Also there's a JavaScript dependency in new-owner-report.scm that's unrelated to charts. @christopherlam is there another way to implement that that doesn't use JS?

Meanwhile I've made progress with WebKit on Windows: I've got it building with CMake, Ninja, and Clang resulting in a 50-minute build (vs. ~30 hours using mingw-makepkg). It also makes small enough debug images that Win32 can load them, which the makepkg build doesn't. Javascript doesn't crash in this build but it also doesn't draw, so I've got a little more work to do. At least now I have a reasonable development cycle time.

@christopherlam
Copy link
Contributor

christopherlam commented Feb 17, 2024

https://chat.openai.com/share/762c3d6c-e4a6-411e-91b2-65c8dfc47da2

There's a few options which use pure css and hidden <a> or <input radio> elements. However the difficulty is that we need memory to store current ID to highlight. I am not sure css is possible then.

@christopherlam
Copy link
Contributor

Deleted comment in error. The option's include hidden a href elements, hidden radio buttons etc. Ultimately the table cells have an ID to denote linked cells and the HTML must remember the current ID being highlighted, and this may be difficult in pure CSS.

@christopherlam
Copy link
Contributor

christopherlam commented Feb 17, 2024

Re owner report-- if we forego the memory part I think we could avoid JavaScript and enable the table cells shading on CSS hover only. This was @gjanssens original proposal on the owner report.

@Bob-IT
Copy link
Contributor Author

Bob-IT commented Feb 17, 2024

@jralls

I'm not keen on the SVG approach, especially if it generates 5 files/chart. If it could be boiled down to a single file without the chartjs dependencies in the current export I'd be happier with it, but I think a approach is overall cleaner.

The 5 SVG files were my test showing the different charts available, in use there would only be one but I did notice that there is not a stacked bar chart so that would need to be created.

@Bob-IT
Copy link
Contributor Author

Bob-IT commented Feb 17, 2024

Some further things that would need to be considered...

Copying: There is no copy at the moment so data can not be copied to a spreadsheet.
Printing: Have no idea at the moment, it could just be a preview and leave printing via a browser.

This leaves the script tag with the chart json data
@jralls
Copy link
Member

jralls commented Feb 17, 2024

Copying and printing are both handled by the browser so they should work the same as the javascript charts.

@jralls
Copy link
Member

jralls commented Feb 17, 2024

There's a few options which use pure css and hidden or elements. However the difficulty is that we need memory to store current ID to highlight. I am not sure css is possible then.

The option's include hidden a href elements, hidden radio buttons etc. Ultimately the table cells have an ID to denote linked cells and the HTML must remember the current ID being highlighted, and this may be difficult in pure CSS.

Re owner report-- if we forego the memory part I think we could avoid JavaScript and enable the table cells shading on CSS hover only. This was @gjanssens original proposal on the owner report.

IIUC the javascript snippet elements have a linking ID and the function highlights all of the elements with the same ID when one of them is clicked. Is that right? What is it intended to show the report's user?

@christopherlam
Copy link
Contributor

christopherlam commented Feb 18, 2024

There's a few options which use pure css and hidden or elements. However the difficulty is that we need memory to store current ID to highlight. I am not sure css is possible then.

The option's include hidden a href elements, hidden radio buttons etc. Ultimately the table cells have an ID to denote linked cells and the HTML must remember the current ID being highlighted, and this may be difficult in pure CSS.

Re owner report-- if we forego the memory part I think we could avoid JavaScript and enable the table cells shading on CSS hover only. This was @gjanssens original proposal on the owner report.

IIUC the javascript snippet elements have a linking ID and the function highlights all of the elements with the same ID when one of them is clicked. Is that right? What is it intended to show the report's user?

Here's an $200 invoice clicked to highlight the assoc partial payment $150 and unpaid $50.
image

And the $150 payment clicked
image

And the second $200 invoice clicked
image

And you can click either the LHS transactions or the RHS "Link Details". When LHS=invoice, link-id is the invoice GUID. When LHS=payment_txn, the link-id is the payment transaction GUID.

@jralls
Copy link
Member

jralls commented Feb 18, 2024

Thanks. I don't think that kind of interactivity can be created on the browser side without javascript. You could do it server side with xmlhttprequest, but that requires GnuCash to be a server. Let's not go there.

I don't think it's doable in PDF at all.

So the next question is, is this something that users want or expect in something called a report? I guess the same question applies to the account and transaction links in other reports.

@christopherlam
Copy link
Contributor

without javascript

It would have been ok using CSS hover whereby each guid is a separate CSS class, and hovering it also highlights all similar class. However chatgpt tells me the css selector cannot target other elements outside the current dom subtree.

@christopherlam
Copy link
Contributor

So the next question is, is this something that users want or expect in something called a report? I guess the same question applies to the account and transaction links in other reports.

No answer from me for this one. There's also sub report links all over the place -- eg multi column income statement cells link to transaction report, expense barchart report links to subaccounts barchart or register, etc. We'd lose lots of functionality if we lose JavaScript.

@christopherlam
Copy link
Contributor

without javascript

PS mea culpa on the JavaScript dependency... I saw the vast playground afforded by the libgnucash API and JavaScript and thought hard how much bells and whistles can be added into reports! 😳

@jralls
Copy link
Member

jralls commented Feb 18, 2024

We'd lose lots of functionality if we lose JavaScript ... I saw the vast playground afforded by the libgnucash API and JavaScript and thought hard how much bells and whistles can be added into reports! 😳

So now I'm asking you to think hard about whether those bells and whistles even belong in reports or if they should be presented with views using the regular GUI, leaving reports to be reports.

@christopherlam
Copy link
Contributor

christopherlam commented Feb 19, 2024

whether those bells and whistles even belong in reports

I think many reports may be reengineered to export the html-table whereby the UI will present the data in a register. But I do not think I can do this part. No time, and no understanding of the register. Maybe something like gtksheet (EDIT: or GtkGridView)

@jralls
Copy link
Member

jralls commented Feb 19, 2024

I was thinking of something separate from the register in the Business menu, maybe call it Customer/Vendor View that would display similar to the report and would have the interactive behavior coded in C/C++.

I know that's outside your skill set. It's probably outside of mine.

@gjanssens
Copy link
Member

without javascript

It would have been ok using CSS hover whereby each guid is a separate CSS class, and hovering it also highlights all similar class. However chatgpt tells me the css selector cannot target other elements outside the current dom subtree.

That may be true, but that doesn't mean cross-table highlighting can't be done in CSS . Github won't take html files, so you'll have to remove the .txt extension if you want to look at this sample.

It will require very recent browsers or html rendering engines though as the technique depends on the very recent :has() pseudo class. Browser support can be found here. I doubt LightHtml would support this advanced feature so it wouldn't change much for our current report rendering problem.

@gjanssens
Copy link
Member

We'd lose lots of functionality if we lose JavaScript ... I saw the vast playground afforded by the libgnucash API and JavaScript and thought hard how much bells and whistles can be added into reports! 😳

So now I'm asking you to think hard about whether those bells and whistles even belong in reports or if they should be presented with views using the regular GUI, leaving reports to be reports.

If you ask me having some interactivity in reports is a plus. In the particular example of the Vendor report, I have had very complex payment histories in the past, which meant payments were not at all aligned to invoices and credit notes. Being able to highlight an invoice and then visually mark in which payments it was involved made it a lot easier to understand what was going on. That's both for me to simply remember what I did looking back after a while or to figure out what gnucash made of some mistake I made in the past while trying to fix that mistake.

In the same way the interactivity of the jquery plots is imo a boon. Moving the mouse cursor over the plot immediately gives more details. You can even zoom in.

I just think we have moved into an era where reports no longer are just that static thing you print to paper. Though that should obviously still remain possible as well...

Having said all that, if trying to keep this interactive experience means we get into a state of unreasonable maintenance burden, I would (sadly) agree to drop the extras. There's no point in ending up with an unmaintainable project just because of the nice to haves.

But it's a decision to weigh carefully. I personally think gnucash is already falling behind in user experience compared to what is today's norm. Dropping interaction from reports would be a step back IMO.

@gjanssens
Copy link
Member

I was thinking of something separate from the register in the Business menu, maybe call it Customer/Vendor View that would display similar to the report and would have the interactive behavior coded in C/C++.

I know that's outside your skill set. It's probably outside of mine.

I can conceptually imagine ways to do it in gtk widgets, but it would be extremely cumbersome compared to html/css/javascript. But I have not given it any hard and deep thought so I may be totally off. And most of all that would be waaaayyy more work than I could possibly contribute any time soon 😢 .

Unfortunately I have not seen any technology in which it's easier than html/css/javascript to build such flexible interactive representations of data.

@jralls
Copy link
Member

jralls commented Feb 20, 2024

Unfortunately I have not seen any technology in which it's easier than html/css/javascript to build such flexible interactive representations of data.

Hence (along with its extreme cross-platform support) the popularity of Electron.

@Bob-IT
Copy link
Contributor Author

Bob-IT commented Mar 6, 2024

I did some more testing with this, using glib-json and making some changes to cglib I was able to extract from the report the chartjs settings and use them to create a SVG file that the report loads which is below, this would need some work to do it properly. I am still unsure about how sizing would be affected.

SVG's can have links to area's of the image but it only works if the SVG commands are defined inline with the HTML file. They do not work when they are in a separate SVG file. Unfortunately litehtml does not support the SVG commands being inline so unless that can be added charts with links will not work.

The only other way I can see at the moment is if the legend is done as a table in HTML and only the chart, in this case the pie is done as SVG.

Just to clarify, links in the standard reports do work to open register pages, it is only the links on the charts that do not.

svg-test

I think I will leave this for now and ponder the other suggestion of using 'PDF's.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants