multiple d3 visualizations in one HTML document - svg

I want to have multiple d3 visualizations in one document. My idea is to store some configuration such as url of the RESTful service along with the SVG tag attributes. On document load d3 would read in the attributes and load the data from the server and create the visualization. In this way I could edit / rearrange the document while keeping the visualizations intact.
My question is whether there is already a standardized way (best practice) of doing this? Or is there some plugin or something I could use?
change: I realized that I should mention that I want to create different documents with the same code. Consequently the document defines the content of the visualization (not the code).
A sample document with SVG attributes:
...
<head>
...
<svg width="200"... src="localhost:8000/rest/host1/cpu" type="os.line">...</svg>
<svg width="200"... src="localhost:8000/rest/host1/memory" type="os.bar">...</svg>

in the end I decided to move the configuration into paragraphs (integrates well with redactor):
<p class="plot" src="localhost:8000/rest/host1/cpu" type="os.line">...</p>
<p class="plot" src="localhost:8000/rest/host1/memory" type="os.bar">...</p>
... here is my code:
define(['lib/d3.v3.min'], function(ignore) {
var visualise = function(plugins) {
var _host = function(src) {
return src.split("/")[4];
};
var _plot = function(type) {
var parts = type.split(".", 2);
return plugins[parts[0]][parts[1]];
};
d3.selectAll("p.plot")
.each(function() {
var div = d3.select(this);
var plot = _plot(div.attr("type"));
var url = div.attr("src");
var host = _host(url);
d3.csv(url, function(data) {
div.call(plot, data, host);
});
});
};
return {visualise: visualise};
});
comments, improvements are more than welcome.

Why not just append each visualization to a different div?

Related

angular return uploaded excel file in HTML grid

I am struggling to get my code to display in HTML. I know I am probably missing something really simple, but I am stuck.
I have an Angular 7 app. I want to retrieve the xlsx data (worksheet) and display it in HTML. Simple right? My issue is that all the examples are in browser js and I need to retrieve it from a component. Here's the kicker, I already have the method and can print out json and html via console. log, but cannot find how to return it to an editable grid in HTML.
component.ts
fileUpload() {
let fileReader = new FileReader();
fileReader.onload = (e) => {
this.arrayBuffer = fileReader.result;
var data = new Uint8Array(this.arrayBuffer);
var arr = new Array();
for (var i = 0; i != data.length; ++i) arr[i] = String.fromCharCode(data[i]);
var bstr = arr.join("");
var workbook = XLSX.read(bstr, { type: "binary" });
var first_sheet_name = workbook.SheetNames[0];
var worksheet = workbook.Sheets[first_sheet_name];
console.log(XLSX.utils.sheet_to_json(worksheet, { raw: true }));
console.log(XLSX.utils.sheet_to_html(worksheet));
}
fileReader.readAsArrayBuffer(this.file);
}
html
<input type="file" style="display: inline-block;" (change)="incomingfile($event)" placeholder="Upload file" accept=".xls,.xlsx,.ods">
Upload
Currently I can retrieve any workbook/worksheet, but I simply cannot find how to return it to a ui grid of some sort from the .ts file.
I have been through numerous tutorials including ui-grid, ng-grid and https://redstapler.co/sheetjs-tutorial-convert-excel-html-table/
I appreciate I am probably being a dumbass, but any help would be appreciated. I cannot use a commercial component and simply need to render this in an editable table on my html page. I will then look at changing column headers and exporting the file via the backend SpringBoot REST to Mongo (all working)
I am aware that there are numerous similar questions on SO, but the working examples do not seem to display the data(even without any errors). Could be a versioning error etc. I also tried ui-grid, but came up with this issue: 'readAsArrayBuffer' on 'FileReader': parameter 1 is not of type 'Blob'. The example here is however also in .js and not via a typescript component: parameter is not of type 'Blob'
I am simply not able to bind the output to the HTML

Why is svg generated by MathJax.js different than the svg generated by MathJax-node

I am writing an web app that saves html to onenote. In order to save math formulas, I plan to convert math formulas to svg by MathJax.js and then convert svg to png, because the html/css supported in onenote api is limited.
But it seems the svg generated by MathJax.js in browser is not a valid svg. I tested it with a simple math formula: $$a^2 + b^2 = c^2$$ (demo code) and copy the svg to jsfiddle and it displays nothing.
Then I tried to write a MathJax-node demo and copy the svg to jsfiddle again, it looks good. Here is my demo code, it's almost the same as the GitHub repo demo:
// a simple TeX-input example
const fs = require('fs')
var mjAPI = require("mathjax-node");
mjAPI.config({
MathJax: {
// traditional MathJax configuration
}
});
mjAPI.start();
var yourMath = String.raw`a^2 + b^2 = c^2`
mjAPI.typeset({
math: yourMath,
format: "TeX", // or "inline-TeX", "MathML"
svg: true, // or svg:true, or html:true
}, function (data) {
if (!data.errors) {console.log(data.svg)}
// will produce:
// <math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
// <mi>E</mi>
// <mo>=</mo>
// <mi>m</mi>
// <msup>
// <mi>c</mi>
// <mn>2</mn>
// </msup>
// </math>
fs.writeFile('math.txt', data.svg, (error) => {
console.log(error)
})
});
I also tested two svg with cloudconvert, it's the same result. Why are the two svg different? Do I miss something?
The difference is due to a specific setting: useGlobalCache
By default, MathJax (docs) sets this to true while mathjax-node (docs) sets this to false.
On the server MathJax-node does not have any document context and produces self-contained SVGs. On the client, MathJax has a full document context and thus can re-use the SVG paths across equations.

Customize the quick launch items for certain pages in sharepoint

I have requirement where client wants to customize the items in quick launch for only certain
pages.So, I want to change the items in the quick launch with some other items for a few pages.(Not about cahnging the style of quick launch. Its about the replacingthe content in quick launch)
I hope using CEWP, I can achive this.But I am not much aware how to do it.
You can have two approachs here:
1) creating a webpart to replace the quicklaunch: This way you can read the Navigation from SPWeb, and build it your own.
2) Using jQuery to change the html loading the page. In this approach, I would apply a 'display:none' to quicklaunch, make the changes in html, and then 'display:block' back. The con in this solution is that you must rely on the names/titles/urls of the items, so if an admin changes, it could break it.
I had followed following steps to achive the goal
1.. Added a CEWP in the page
Created a text file with Following script and added it to shared dcouments
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
function startClock(){
var div= document.getElementById('s4-leftpanel-content');
var spans= div.getElementsByTagName('span');
for (index = spans.length - 1; index >= 0; index--) {
spans[index].parentNode.removeChild(spans[index]);
}
var urls= div.getElementsByTagName('a');
for (index = urls.length - 1; index >= 0; index--) {
urls[index].parentNode.removeChild(urls[index]);
}
var pTag = document.createElement('p');
pTag.innerHTML = "HR Report";
div.appendChild(pTag);
var aTag = document.createElement('ul');
div.appendChild(aTag);
var newLi = document.createElement('li');
aTag.appendChild(newLi);
var a= document.createElement('a');
a.setAttribute('href',"url");
a.innerHTML = "report2";
newLi.appendChild(a);
//do onload work
}
if(window.addEventListener){
window.addEventListener('load',startClock,false); //W3C
}
else{
window.attachEvent('onload',startClock); //IE
}
</script>
enter code here
Paste the url text file in shared documents in CEWP as content link(Edit web part >>content link>>paste url)
Now, existing items in the Quick Launch is removed and new items are added

Set and get data like a raphaelJS

I'm working with RaphaelJS.
I've noticed that you can add dynamic data to the elements, for example:
to assign a value:
el.data("key",value);
to get a value:
el.data("key")
How can I copy this behaviour using JQuery or Javascript?
Hi I'm trying a wild guess here: as I understand correctly you'd like to communicate from Rapahel to jQuery.
The best I've come up so far is to keep references of both and use them accordingly as Raphael seems not to insert data into dom directly (apart from ID attribute):
$(document).ready(function () {
var paper = Raphael("div", 400, 150);
var circle = paper.circle(80, 80, 30).data('title', 'Red dot').attr({
fill: '#f00'
});
circle.node.id = 'my_circle';
$el_circle = $(circle[0]); // get DOM element out of Rapahel's object
$el_circle.on('click', function () {
// use Raphael reference:
alert("My is title: " + circle.data('title'));
});
});
http://jsfiddle.net/saxxi/Z35NV/
References.
the possibilities: raphael.js - custom attributes
the explanation: Where does Raphael.js store an element's data that is set with the element.data() method?
Combining Raphael and jQuery to achieve browser compatibility

How do I fill/stroke an SVG file on my website?

I Googled this issue for about 30 minutes and was surprised nobody has asked so maybe it's not possible.
I'm using this line to embed the SVG file that I made in AI (note that when I saved the SVG, I had no fill OR stroke on the paths):
<object type="image/svg+xml" data="example.svg" height=600px width=600px>Your browser does not support SVG</object>
This obviously comes up with no image because the SVG file has no fill or stroke.
I tried adding in
...fill=yellow>
or
...style="fill:yellow;">
but I'm not having any luck. Thanks!
Have a nice trick: Embed it as <img> and use javascript to convert it into inline <svg> with this code (that came from SO I think). Now you can manipulate this SVG object
CODE::
/*
* Replace all SVG images with inline SVG
*/
jQuery('img.svg').each(function(){
var $img = jQuery(this);
var imgID = $img.attr('id');
var imgClass = $img.attr('class');
var imgURL = $img.attr('src');
jQuery.get(imgURL, function(data) {
// Get the SVG tag, ignore the rest
var $svg = jQuery(data).find('svg');
// Add replaced image's ID to the new SVG
if(typeof imgID !== 'undefined') {
$svg = $svg.attr('id', imgID);
}
// Add replaced image's classes to the new SVG
if(typeof imgClass !== 'undefined') {
$svg = $svg.attr('class', imgClass+' replaced-svg');
}
// Remove any invalid XML tags as per http://validator.w3.org
$svg = $svg.removeAttr('xmlns:a');
// Replace image with new SVG
$img.replaceWith($svg);
});
});
Are you trying to add the fill or style on the object element? If so, that's not going to work. Those properties are not supported on the object element. You're going to have to add it into the SVG in the SVG file.

Resources