How do I save an svg node to a file using nodejs? - node.js

I'm using d3 through a small helper package: https://www.npmjs.com/package/d3-node
I created my svg file using d3-node, here's the code.
const D3Node = require('d3-node')
var d3n = new D3Node()
var svg = d3n.createSVG()
.style("width","1920px")
.style("height","1080px")
.attr("preserveAspectRatio","true")
.html(firstTemplate)
.append("myCustomTag")
Now after this, I have no idea how to save the output. The main problem is in myCustomTag.
console.log(d3n.d3Element.select("svg").node().innerHTML)
This line is supposed to output my svg, and it does, except that myCustomTag becomes mycustomtagand my svg gets corrupt.
I have tried select("svg").node().outerHTML, select("svg").html(), innerText, I just couldn't find anything.
I can't use the innerHTML in this case, is there a way to store the svg file directly from the d3 variable?

You could use xmlserializer since SVG is XML and XML is case sensitive. Something like this works for me:
const D3Node = require('d3-node');
const xmlserializer = require('xmlserializer');
const d3n = new D3Node();
var svg = d3n.createSVG()
.style("width","1920px")
.style("height","1080px")
.attr("preserveAspectRatio","true");
svg.append("myCustomTag");
console.log(xmlserializer.serializeToString(svg.node()));
HTML is not case sensitive so when you try to use HTML methods to serialize things you won't necessarily get what you want.

Related

How to set `invalidAttributeNamePrefix` value in Java?

Suppose I'm cleaning some html using HtmlCleaner (v2.18) and I want to set the property invalidAttributeNamePrefix (see section Cleaner parameters) to some value, i.e.: data-.
This way an attribute my-custom-attr="my-value" in the HTML will be transformed to data-my-custom-attr="my-value".
How can I do that? I wasn't able to find any example for the Java usage.
You can take as reference this piece of code:
HtmlCleaner cleaner = new HtmlCleaner();
CleanerProperties properties = cleaner.getProperties();
properties.setOmitComments(true);
// properties.setInvalidAttributeNamePrefix("data-"); there is no such method
// html is a declared variable which contains some html content
TagNode rootTagNode = cleaner.clean(html);
XmlSerializer xmlSerializer = new PrettyXmlSerializer(properties);
String cleanedHtml = xmlSerializer.getAsString(rootTagNode);
Upgrading to version 2.22 solves this.
Now it can be done
// ...
properties.setInvalidXmlAttributeNamePrefix("data-");
//...

How do I get the filename programmatically to use with this code?

The code below is the computed image source for an image control on my custom control. If I run it just like it stands it puts in photo.jpg and works fine. The problem is I want to pass that value programmatically. I have an upload control (fileUpload1) and a download control (fileDownload1) on the custom control as well. I've tried document1.photo which is where the jpg file is stored. I've tried several variations of currentdocument.getitemvalue, getitem, getattachments. But, so far, I have found no way to do this. In addition, I have tried setting the value of filename to the value of the upload control and the download control with no success.
I know this is probably simple, but, as a client developer, it's not simple to me.
Any help would be greatly appreciated.
var doc:NotesDocument = currentDocument.getDocument ();
var UID:string = doc.getUniversalID().toString();
var fp:string = database.getFilePath();
var filename = "photo.jpg"
return '/0/' + UID + '/$file/' + filename
Thanks,
MJ
There may be other ways to achieve this but here's what I usually do:
with image controls I need to be aware that computed resource URLs are in most cases prepended with the database's relative path ending with the database filename. So all I have to add is the usual file attachment URL as in
/0/docUnid/$File/imageFileName
If there is a chance that you have more than one file attached to your doc I need to find out which one of them is the one I wish to display. This can be done by looping through
currentDocument.getAttachmentList(fieldName)
which delivers a java.util.List of NotesEmbeddedObject elements. Using methods like .getName() I then can find the one file you're looking for.
EDIT:
quick example using a repeat to display multiple images sattached to a single richtext field (there may be better solutions esp. regarding the way to filter unwanted file types; I'm using file extensions, only allowing .jpg, .png and .gif). Images are displayed as simple html list elements:
<ul>
<xp:repeat id="repeat1" rows="30" var="pic">
<xp:this.value><![CDATA[#{javascript:
var att:java.util.List=docCar.getAttachmentList("Body");
var it=att.listIterator();
//new empty array, to be used as the repeater's datasource
var arr=[];
//build base path for each image file
var unid=docCar.getDocument().getUniversalID();
var p="/0/" + unid + "/$File/";
while(it.hasNext()){
var e:NotesEmbeddedObject=it.next();
if(e.getName().endsWithIgnoreCase(".png") ||
e.getName().endsWithIgnoreCase(".jpg") ||
e.getName().endsWithIgnoreCase(".gif")){
//push complete filepath + image filename to array
arr.push(p + e.getName());
}
}
return arr;}]]></xp:this.value>
<li>
<xp:image url="#{javascript:pic}" id="image1">
</xp:image>
</li>
</xp:repeat>
</ul>
Hope this helps
Well, I think I have it figured out. Here is the code that now works:
var doc:NotesDocument = currentDocument.getDocument ();
var UID:string = doc.getUniversalID().toString(); var fp:string =
database.getFilePath();
var filename = #AttachmentNames()
return '/0/' + UID + '/$file/' + filename
MJ

JSON.Net SerializeXnode excluding certain nodes

I have a xml string that i'm trying to convert to JSON using JSON.Net. The problem is that i want only certain part of this xml in my JSON string. Below is the code i use and what i need.
var x = XDocument.Parse(xmlString);
var json = JsonConvert.SerializeXNode(x);
This will convert the whole doc. This is how json string looks like in a JSON Viewer
What i want is ONLY the table (The Arrowed one in image 1) and its descendants to be inside string json.
Is it possible? How to achieve it? Can i use a custom ContractResolver with SerializeXnode?
You've got an XDocument, so why not simply select the part you want and then serialize just that part?
Try something like this:
var doc = XDocument.Parse(xmlString);
var table = doc.XPathSelectElement("//table[#class=\"form\"]");
var json = JsonConvert.SerializeXNode(table);
Note that XPathSelectElement is an extension method, so you will need using System.Xml.XPath; at the top of your code if you don't already have it.
EDIT
You can do it without XPath like this:
var doc = XDocument.Parse(xmlString);
var table = root.Descendants(XName.Get("table"))
.Where(e => e.Attributes(XName.Get("class"))
.Select(a => a.Value)
.FirstOrDefault() == "form")
.First();
var json = JsonConvert.SerializeXNode(table);
Both approaches give the same results, the table plus all descendants.

How to get reference to SVG (child) elements nested in another SVG element (parent) using D3?

I have several groups (SVG G elements) nested in another group and I would like to get their ID's. I used the D3 javascript library to create the SVG and the code looks similar to this.
var body = d3.select("body");
var svg = body.append("svg")
.attr("width", '100%')
.attr("height", '100%')
var outerG = svg.append("g")
.attr('id','outerG')
var innerG1 = outerG.append('g')
.attr('id','innerG1')
var innerG2 = outerG.append('g')
.attr('id','innerG2')
I tried to use childNodes attribute, but console.log(outerG[0].childNodes) gives me undefined. Could not find the right answer searching with google, could please someone give me a hint how to do that ?
This will work:
console.log(outerG[0][0].childNodes);
See jsFiddle here
The reason you need two nested indices is that all selections are grouped implicitly. If you'd like to know the deeper reasons for this, or want to understand selections better in general, see this article

Pass pdf url to pdf.js in query string

I'm new to node/pdf js. I just install node and run pdf.js.
Now I want know how can I open pdf files using pdf js by passing pdf file url as parameter in query string?
Try adding ?file=document.pdf to the viewer url. See also https://github.com/mozilla/pdf.js/issues/2496
It will require some changes in the viewer.js:
Move parseQueryString: function pdfViewParseQueryString(query) outside var PDFView so it's a standalone function: function pdfViewParseQueryString(query)
Replace all occurences of PDFView.parseQueryString(..) to pdfViewParseQueryString(..)
Change var DEFAULT_URL = '' to var urlParm = pdfViewParseQueryString(document.location.search.substring(1)); var DEFAULT_URL = urlParm.url;
You should now be able to call the viewer with somethin like $("actualViewer").src = 'pdfViewer?url=' + encodeURIComponent(pathToFile);
On a further note, it is important to know that the file=document.pdf argument must come before the hash sign:
http://myserver.com/web/viewer.html?file=test.pdf#page=6&zoom=page-fit,0,540
HTH

Resources