Drawing huge graphs/trees

  • Continuing the discussion from Mafia: Theory:

    @Maciejasjmj said:

    apparently .NET has somewhere around 32768x32768 bitmap size limit

    So here's the thing - I want to be able to plot somewhat large decision trees from my C# programs. Things like this:


    For anything below the limit, simple drawing on bitmaps works fine - makes the application a bit memory-hungry, but the resulting file is rather small and easily compressible.

    Anything over the limit is just plain impossible to handle via standard .NET Bitmap - you can't even create a bitmap that big, much less stuff it into memory even if you could.

    So what's a good way to push it further? I want the results to be viewable without special handling - just any browser/image viewer the client should have installed. Some sort of vector format? Generating multiple bitmaps under the limit and then stitching them together somehow? Output this stuff to HTML and let the browser worry?

  • Also, nice job Discourse - left-clicking the image claims "the page does not exists", right click and open in new tab opens the image just fine.

  • Why does it have to be a bitmap and not a vector format?

    (Ignoring the obvious complication that I'm not sure if C# has any built-in support for vector formats-- SVG is about as easy as you get though.)

  • Use Graphivz? Not sure if it has a nice PNG/Image/PDF/Whatever output mechanism. I remember seeing something on Codeplex that used that or MSAGL to layout graphs and print them but I can't remember the project name.

  • D3 ( https://d3js.org/ ) is pretty good for turning data into (usually SVG) visualisations. There's a good number of examples on the site that can usually be adapted into something appropriate.

    edit: fecking forum not making that into a link, maybe if I put random spaces around it, OK CLOSE ENOUGH

  • I had to do something similar back in 2010, although I just shelled out the work to Graphviz - but that also has these limits on actual bitmaps. You pretty much have to go for vector graphics at this size, assuming you want a single file - while a number of image formats do technically allocate 4 bytes for specifying the size of each dimension, it might be a bit more difficult to find software which copes with it properly.

    What I did was ask it to output to SVG, which is pretty much your best bet for this, but note that when I did it, browsers had a lot of trouble coping with it - the SVG I generated with this sort of size (~40k by 30k pixels, I think? Might have been a bit more, actually...) caused both Firefox and Chrome to run out of memory when they tried to display it - only IE9 (which was in beta at the time!) could cope with it.

    EDIT: On further recollection, the browser problem might have been with massive PNGs, actually, which were scaled down versions of the SVGs (so they fit in 32k x 32k). Well, point is, if you do go for SVG, make sure you check if it works.

  • If you want to do the graph logic yourself, my approach would be to generate a SVG, which is a pretty simple XML format. Then you can pass it to a rendering program that can handle big bitmaps. There's many SVG rendering libraries, for example Batik.

    OR, you could just distribute the SVG! Every browser since IE9 supports it, so the vast majority of computers today can open it. But you might want to do a few tests to see if they handle big images right.

    But as other people are saying, there are many libraries for making graphs, and they might have tackled that problem already.

  • @blakeyrat said:

    Why does it have to be a bitmap and not a vector format?

    I don't care, as long as it's relatively easy to open/show on a webpage.

    @blakeyrat said:

    (Ignoring the obvious complication that I'm not sure if C# has any built-in support for vector formats-- SVG is about as easy as you get though.)

    May look into it... although AFAICT there's nothing in .NET framework, and I'm not sure how feasible it is to implement that bunch of features I need via direct XML output.

    @MathNerdCNU said:

    Not sure if it has a nice PNG/Image/PDF/Whatever output mechanism.

    Yeah, that's... kinda what I need. Besides, I can do the rendering myself, I just need a sensible output format that anyone can view and can handle large (in pixel size) images and zoom into portions of it without keeling over.

    SVG seems like a good bet, although I suppose I'd need to test it before going further with that.

  • @ydna said:

    D3 ( https://d3js.org/ ) is pretty good

    I am going to have to disagree there. D3 is obtuse as hell, impossible to debug, and has zero useful error messages. The only reason people use it is because it's performant for animations.

    You're not making an animation.

    ... in any case, it's a JavaScript library, and you're in C#.

  • Output the damn thing to HTML.
    Using an image for that little data is silly. Doing it in HTML will take up little to no space, is fast and is good for textual representation, searching might be nice you know.

  • Stupid question: in HTML, how do you do the arrows? AFAIK you can't just draw arbitrary angled lines without using SVG (or a canvas which would be mega-WTF.) I mean, it's not a bad idea, but.

    I still think SVG is the way to go here. For one thing, you'd be able to scale the SVG independent of the other HTML on the page. So if the user has to zoom-in, they can do it without affect the page's nav stuffs.

  • I'm thinking the HTML as a standalone file, with fixed positions - pretty much like an svg, except for the rendering problems.
    As you point out embedding is probably going to look weird/not work.
    The alternative is a tabular layout, or the JS thingie. But changing from fixed position png/jpeg to HTML should be very easy.

  • I think it would take something like a 2-d :minidisc: :horse:.

    (Just :trolleybus:...)

  • :belt_onion:

    Convert them to dot files and then svg, it works.

  • area_can

  • Not relevant to the request itself, but the specific graph you posted can be significantly compressed horizontally by merging equivalent subtrees. For example, all three 2/1 Day subtrees are equivalent; regardless of how you got there the odds on resolution are the same.

Log in to reply

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.