js-lang-aez-notes
Notes
I also have some notes on HTML and CSS, this includes some notes on SVG.
npm for package management
npm initto initialise a project, the important file is thepackage.jsonthat gets produced.npm run <xxx>will run the command called<xxx>as defined inpackage.json. There is an example below shows how to compile the typescript to javascript (of course, you need to have installed typescript first).
"scripts": {
"compile": "./node_modules/typescript/bin/tsc --target es5 bibread.ts"
},
npm install -Dto install packages needed for the development process.npm outdatedwill list any outdated packages in the current project.
D3 notes
- D3 for the Impatient is good.
- Because D3 generates figures by manipulating the DOM rather than operating on a canvas it can seem weird if you are coming from more traditional plotting libraries.
Selectionsare collections of DOM elements, they can be generated using CSS selectors.selectreturns the first match andselectAllreturns all matches.- You can iterate the
selectmethods to refine your query. Selectionobjects have an API similar to what you would expect for list handling, eg, sorting, searching, and insertion.
- The
datamethod of aSelectionis used to bind pieces of data to elements of the DOM. If there is a mismatch between the number of pieces of data or DOM elements, theenterandexitmethods are used to specify how to handle the extras. - Recall I have some notes on SVG.
gelements in SVG are groups of graphical elements. You will use one of these for each part of a figure.pathelements in SVG provide a way to draw lines and shapes.- Use
htl.htmland literal`<svg>...</svg>`to build up the figure.
Basic setup
The following steps will set up a single page using a server to simplify the process of incorporating data.
- Create a new directory for your project.
- Get a copy of
d3.jsord3.min.jsfrom the D3 website. - Create an
index.htmlpage similar to this.- Note the use of
onloadin thebody.
- Note the use of
- Create a
script.jswhich will construct the figure; here is a skeleton.- Data is read from a file
super-cool-data.tsv.
- Data is read from a file
- Start a server and point your browser at it.
function makeDemo() {
d3.tsv("super-cool-data.tsv")
.then(
function(data) {
var svg = d3.select("svg");
// do all the stuff to make the figure...
}
);
};
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Alex learns D3</title>
<script src="d3.js"></script>
<script src="script.js"></script>
</head>
<body onload="makeDemo()">
<svg id="demo" width="600" height="300"
style="background: lightgrey" />
</body>
</html>
busybox httpd -h <path/to/project> -p 8080
Examples
Example
Here is a very simple HTML file that can be used to make a visual library, just drag and drop your PDFs. It comes from Folk (Browser) Interfaces.
/* pdf-viewer.html */
<style>
html {
background-color: #fdf6e3;
margin: 20px
}
body {
display: flex;
flex-wrap: wrap;
}
</style>
<script>
const previewPdf = (name, url) => `
<div style="width: 300; height: 425; margin: 40px">
<embed width="100%" height="100%" type="application/pdf" src="${url}"></embed>
<p>${name}</p>
</div>
`;
window.addEventListener("dragover", e => e.preventDefault());
window.addEventListener("drop", e => {
e.preventDefault();
[...e.dataTransfer.items].forEach(item => {
if (item.type === "application/pdf") {
const file = item.getAsFile();
const url = URL.createObjectURL(file);
document.body.innerHTML += previewPdf(file.name, url);
}
});
});
</script>
Example
Here is the output of this example
The following describes how to generate this vega-lite chart with data specified client-side.
Start by including the UI which consists of couple of textarea for the user to input data, a button which we will use to re-generate the chart and a div for the actual chart.
<textarea id="xvals" rows="4" cols="50"> 1,3,2,4,3,5,1,2,3 </textarea> <textarea id="lvals" rows="4" cols="50"> 'a','b','c','d','e','f','g','h','i' </textarea> <button id="myButton">Click Me!</button> <div id="vis"></div>
Then we can load the relevant packages, where I've included lodash because it seems nice.
<script src="https://cdn.jsdelivr.net/npm/vega@5"></script> <script src="https://cdn.jsdelivr.net/npm/vega-lite@4"></script> <script src="https://cdn.jsdelivr.net/npm/vega-embed@6"></script> <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>
Finally we will write a little script which causes the chart to be updated when the button is clicked.
<script type="text/javascript">
<!-- Add the JavaScript code here! -->
</script>
where the actual JavaScript code that needs to be included here is the following
document.getElementById("myButton").addEventListener("click",
(event) => {
betas = document.getElementById("xvals").value.split(",").map((x) => parseInt(x))
alphas = document.getElementById("lvals").value.split(",")
var yourVlSpec = {
$schema: 'https://vega.github.io/schema/vega-lite/v2.0.json',
description: 'A simple bar chart with embedded data.',
data: {
values: dataValues(alphas,betas)
},
mark: 'bar',
encoding: {
x: {field: 'a', type: 'ordinal'},
y: {field: 'b', type: 'quantitative'}
}
};
vegaEmbed('#vis', yourVlSpec);
document.getElementById("myButton").innerHTML = "Woo!";
});
function dataValues(as, bs) {
return _.zipWith(as,bs, (a,b) => ({a:a,b:b}))
}
Note: if you are using org-mode you can use #+begin_export html ... #+end_export
to include all of this directly in the .org file.