Several weeks ago I have been asked to upgrade a web application based on a very old version of MXGraph library (version 2.4). The application integrated also the 'grapheditor' a sort of demo application evolved later in Diagramly
and then in Draw.io). Recently I completed the more problematic step, the transition from old "grapheditor" to Draw.io, so I am now able to open all the previous diagrams (saved as plain XML), modify and save them consistently.
Ok, this is the nice part. The bad side is the 'read-only' section of the application ,where the users can more or less, only view the graph.
This page is based on the mxClient.js that renders the graph described in the xml through this code:
var graph = new mxGraph(container);
var diagram = mxUtils.parseXml(xml);
var codec = new mxCodec(diagram);
codec.decode(diagram.documentElement, graph.getModel());
graph.fit();
Upgrading the MX library to the last version (3.9.10) the same code works but some shapes are not rendered properly, they appears as squares instead of
circles, ellipses, etc. The two following images are an example of this misbehavior
Graph in the draw.io:
Same graph rendered by mxClient:
After some tries I discovered that the old mxClient is able to render the same graph perfectly (as draw.io does) so I think there have to be something wrong (or missing) in my code or mxGraph installation/configuration.
As a temporary workaround I can keep in place the old version of mxGraph but obviously I'd like to use the new one.
Can someone give me an hint on this? Any help would be very appreciated.
The tape shape isn't part of core mxGraph, it's part of the GraphEditor example, in the additional shapes JavaScript.
If you look at the style of the ellipse, it's probably not the one in the core, most likely another one from Shapes.js.
Either pull in shapes.js, or use the viewer in draw.io.
Related
I've got a customised instance of GraphEditor in a view in an ASP.NET MVC app and I've got it set to use a database for diagram persistence. When opening, I've programmed it to create a new model to initialise the graph using the model data stored in the database. This works, except that vertexes and edges that were black and white when saved become blue when loaded. I'm guessing there's some default mxGraph style variable that's responsible for this, but I'm not sure. Anyone have any ideas? Thanks!
So, in case it's useful to anyone else, I actually found the solution. The default colours are defined in mxClient as hexadecimals and can be replaced with whatever you want to use.
First, a quick description of the end-goal:
I'm building a cross-platform, .NET Core-based, printing app. This app will be able to print all sorts of file types with custom page settings, such as headers, footers, and margins. A key feature is it supports multiple-pages-up (e.g. a landscape sheet of paper with two portrait pages rendered side by side...called "2up").
Printing HTML is important not just because of printing HTML, but I want to use all the great HTML-based syntax-highlighting out there for source code (e.g. www.prismjs.com).
The app is basically done but for one major problem: I can't get the HTML to render well enough. So far I've implemented source code printing three ways:
1) As plain text with my own line-numbering and line-wrap engine. This works wonderfully for everything I can throw at it, but it does not support syntax highlighting.
2) Using Html-Renderer (https://github.com/ArthurHub/HTML-Renderer/issues) an OSS .NET-based Html Renderer. This implementation is the weakest because Html-Renderer's CSS support is really weak. It can't handle hardly anything prismjs or highlightjs' generate.
3) Usinglitehtml' (www.litehtml.com) via LiteHtmlSharp. This was very promising and I almost have it working with some major hacks, but litehtml also does not support key, modern, HTML/CSS features.
Neither Html-Renderer or litehtml support the CSS page-break-before feature that, when combined with media print would let me ensure lines are not split between pages.
What I really want to use is the Chromium rendering engine. litehtml provides a fantastic API for this sort of problem: It calls me whenever it needs to render, and I draw (text, table borders, images, etc...) using GDI+. My dream is to find something in Chromium (CEF, Puppeteer, ???) that provides a similar API.
Or, an alternative, an API that will let me pass in a GDI+ Graphics (or HDC) and the renderer will render to that surface.
With Html-Renderer I measure calculate # pages like this.
SizeF size = HtmlRender.MeasureGdiPlus(g, html, containingSheet.GetPageWidth());
int numPages = (int)(size.Height / containingSheet.GetPageHeight());
My page rendering code (e.g. OnPaint) looks like this:
SizeF size = new SizeF(containingSheet.GetPageWidth(), containingSheet.GetPageHeight());
HtmlRender.RenderGdiPlus(g, html, PointF(0, 0), size );
With htmllite the OnPaint code looks like this:
// Set the clip such that any extraLines are clipped off bottom
g.SetClip(new Rectangle(0, 0, (int)Math.Round(PageSize.Width), (int)Math.Round(PageSize.Height - remainingPartialLineHeight)));
LiteHtmlSize size = new LiteHtmlSize(Math.Round(PageSize.Width), Math.Ceiling(PageSize.Height));
litehtml.Document.Draw((int)-0, (int)-yPos, new position {
x = 0,
y = 0,
width = (int)size.Width,
height = (int)size.Height
});
And in this case the call to litehtml.Document.Draw causes a bunch of callbacks into my app that I process using the same Graphics the OnPaint is called with.
Most discussions of CEF and Chromium point to ScreenshotAsync etc... which will not do because I need to be rendering to a PRINTERS HDC (or GDI+) and blitting bitmaps will loose quality.
I have poured over the Chromium source and I cannot find the obvious way to say to CEF/Chromium "render page 1 (defined as Height/Width) to this GDI+ Graphics object" then "render page 2..." etc... The printing support (and how pdfium is integrated come close!).
Chromium issue 311308 indicates I'm hosed until this work gets picked up again.
Note: I have full access to nodejs w/in my app. I have built a dotnet/nodejs bridge, which is how I convert the raw text file of a source code file to richly formatted, line-numbered, syntax-highlighted html via prismjs. This means I could easily use puppeteer/Headless Chrome if I could just figure out the right APIs.
Does anyone have a suggestion that might help? I'm willing to contribute to Chromium if it's not major heart surgery.
Please bear in mind that I have never used Web Workers before and I'm having some trouble wrapping my head around them.
Here's an explanation of a simplified version of what I'm doing.
My page has links to various files - some are text, some are images, etc. Each file has an image showing a generic file icon.
I want the script to replace each generic icon with a preview of the file's contents.
The script will request the file from the server (thereby adding it to the cache, like a preloader), then create a canvas and draw the preview onto it (a thumbnail for images, an excerpt of text for text files, a more specific icon for media files...) and finally replace the generic icon's source with the canvas using a data URL.
I can do this quite easily. However, I would prefer to have it in the background so that it doesn't interfere with the UI while it's working.
Before I dive right in to this, I need to know: can Workers work with a canvas, and if so how would I create one? I don't think document.createElement('canvas') would work because Workers can't access the DOM, or am I misunderstanding when all the references I've found say they "can't access the DOM"?
You cannot access the DOM from web workers. You cannot load images. You cannot create canvas elements and draw to them from web workers. For now, web workers are pretty much limited to doing ajax calls and doing compute intensive things. See this related question/answer on web workers and canvas objects: Web Workers and Canvas and this article about using webworkers to speed up image manipulation: http://blogs.msdn.com/b/eternalcoding/archive/2012/09/20/using-web-workers-to-improve-performance-of-image-manipulation.aspx
Your simplest bet is to chunk your work into small chunks (without web workers) and do a chunk at a time, do a setTimeout(), then process the next chunk of work. This will allow the UI to be responsive while still getting your work done. If there is any CPU consuming computation to be done (like doing image analysis), this can be farmed out to a web worker and the result can be sent via message back to the main thread to be put into the DOM, but if not, then just do your work in smaller chunks to keep the UI alive.
Parts of the tasks like loading images, fetching data from servers, etc... can also be done asynchronously so it won't interfere with the responsiveness of the UI anyway if done properly.
Here's the general idea of chunking:
function doMyWork() {
// state variables
// initialize state
var x, y, z;
function doChunk() {
// do a chunk of work
// updating state variables to represent how much you've done or what remains
if (more work to do) {
// schedule the next chunk
setTimeout(doChunk, 1);
}
}
// start the whole process
doChunk();
}
Another (frustrating) limitation of Web Workers is that it can't access geolocation on Chrome.
Just my two cents.
So as others have stated, you cannot access the DOM, or do any manipulations on the DOM from a web worker. However, you can outsource some of the more complete calculations on the web worker. Then once you get your return message from the web worker inside of your main JS thread, you can extract the values you need and use them on the DOM there.
This may be unrelated to your question, but you mentioned canvas so i'll share this with you.
if you need to improve the performance of drawling to canvas, I highly recommend having two canvas objects. One that's rendered to the UI, the other hidden. That way you can build everything on the hidden canvas, then draw the hidden canvas on the displayed one. It may not sound like it will do much if anything, but it will increase performance significantly.
See this link for more details about improving canvas performance.
I am rendering an image to a Sprite inside of an Iterator. I'd like each render (iteration) to remain on the canvas indefinitely, so that each successive render layers on top of the previous ones. How can I do this?
There are no Clears or any other layers in my composition.
In Quartz Composer, you'll almost always want to use a Clear patch — don't assume that you can rely on the prior contents of the framebuffer. So, to accomplish this, you'll need to load all of your images into a structure (probably by using JavaScript to feed an Image Loader patch and build a Queue from that), and then display all of the images each frame using an Iterator.
Check out Apple's "Image TV" sample composition, available in the OS X Developer Library in the Quartz Composer Conceptual Compositions bundle. This example demonstrates how to load a series of images into a structure and then display them.
Okay, so I've been busting my hump the last week or so on this project for my OOP/AS3 course and this past Sunday I realized that my approach wasn't going to work so I scrapped the better part of it and started over.
Our assignment is to create an XML based flash menu that demonstrates an understanding of the OOP patterns we've just learned. It was kind of a 'test the waters' project where he gave us a ton of tutorials and information and told us to make our best attempt at making sense of it so I'm certain there are more efficient ways to do what I'm doing, but that's a moot point.
We need to employ at least two patterns in our menu, though at the moment I'm just focusing on MVC so that I can get the mainUI working before I finalize the second part of the UI. It essentially flows like so:
MainUI has 4 menus that slide out.
Each slider has 3 thumbnails on it.
Clicking on any of the thumbnails will move to the next part of the UI. This functionality is currently disabled.
The program runs with 0 compiler errors, but the images are not being placed on the stage correctly and I can't figure out why. All the image paths are being pulled and stored from the XML properly. The main background image is pulled once and is supposed to be only placed once (if statement that uses a count to determine whether to run the placement function or not), but it is being placed 4 times with the sliding menu image. The sliders are being placed in the correct positions (switch statement that iterates through the mainUI function in the View class and creates a separate loader for each one), but the thumbnails are not all showing up. So here is what I'm seeking help with:
The mainPanel image should only be placed once, rather than 4 times with each slider.
The sliders, while being placed correctly, must be tweened in different directions through the as (using TweenMax), but each instance is unidentifiable from the other so right now they all have an eventListener that calls the same tween method. How can I distinguish them in a way that lets me apply a different tween to each (This will likely be a concern with the thumbnail functionality later as I will need to load different XML data based on which thumb is clicked).
I have added what I hope are very informative comments to each script so hopefully people can help. Also included are images of what I want the mainUI to eventually look like and how it's coming out currently.
pastebin with all 3 classes and XML (2 hyperlink limit) - http://pastebin.com/u/crookedparadigm
top image is how the stage is outputting, bottom image is what I'd like to to be - http://imgur.com/a/bOmsS
Last quick note, stage is currently set to 600x480 with a black background. Ideally, to reinforce OOP principles, our professor wants us to avoid using the timeline or library if possible.
Any advice at all will be greatly appreciated! Thanks!
Install FlexPMD This is a very good add on( sometimes hard to install ) It basically is used to show areas of your code that you are not following standards. For example your classes lack the use of "this". And you should avoid passing parameters in constructors. It would be good practice to develop standardized writing skills while you are still new.
Looking at your code I see you are calling buildUI from within a loop.
buildUI is assigning a MainView object to mainUI.
So each time you go through a loop iteration you are reassigning mainUI.
In the end mainUI will only be the last iteration of that loop.
Not sure this is your issue but is an issue.
[EDIT]
Excellent Singleton guide for Flex SDK
Part 1
Part 2
Some Good writing on pure AS3 Singletons.
I would prolly start from scratch as your XML data is miss formatted.
your XML should resemble something like this.
<MainProject>
<MainUI>
<Thumbnail Name="Spring">
<Destination Name="Spring" Price="99" ratingPath="images/SP1/SP1rating.png" />
</Thumbnail>
<Thumbnail Name="Winter">
<Destination Name="Winter" Price="152" ratingPath="images/SP1/SP2rating.png" />
</Thumbnail>
</MainUI>
</MainProject>
Then you should have the following structure on your stage. These movieclips should be empty and already placed inside on your stage with instance name.
Stage
MenuUI MovieClip
ThumbNail1 MovieClip <- feed it thumbnail from the XML
ThumbNail2 MovieClip <- feed it thumbnail from the XML
ThumbNail3 MovieClip <- feed it thumbnail from the XML
ThumbNail4 MovieClip <- feed it thumbnail from the XML
This might be a bit too vague, just tell me if you need more details.
Hope this helps !