#blog .pal {position: absolute;left: 0;}
#blog .par {position: absolute;right: 0;}
#blog .prr {position: absolute;right: 0;}
#blog .p6 {padding:6px;}
#blog .psheet {padding:6px 40px;}
#blog .sheet {
box-shadow: 5px 10px rgba(0,0,0,0.1);
border-radius:var(--corners,6px);
background-color:white;
}
#blog .tac {text-align:center;}
#blog .this {font-weight: bold;}
/* FIXME */
#blog .vac {display: table;}
#blog .vac * {display: table-cell;vertical-align: middle;
/* /FIXME */
}
#blog .w130 {width:130px;}
#blog .w190 {width:190px;}
#blog .w40 {width:40px;}
#blog .w33pc {width:33%;}
#blog .w60 {width:60px;}
#blog .w90 {width:90px;}
#blog .wa {width:auto;}
#blog .z1 {z-index:1;}
#blog .z2 {z-index:2;}
/* EXPERIMENTAL */
#blog table,th,td {
border:1px solid green;
padding:3px 8px;
border-collapse:collapse;
}
</style>
This is my VizHub blog. Drop me a line, if you have any feedback on it!
I'm MrWatson of mrwatson.de, an age-old programmer and database developer, and work with the FileMaker / Claris platform.
Due to an up and coming closer integration of the platform with the web - and the general rise of the API-age - at the end of 2019 I realised the need to get up to speed with web technologies, and set myself the personal aim of learning how to programme in JavaScript and implement data visualisations in d3.
In summer 2019 I started looking at Node.js, learnt about npm, and the purpose of CDNs.
I discovered the awesome NODE-Red visual IoT workflow editor from Nick O'Leary, and realised the power, potential and importance of JavaScript, and the power of a visual interface.
I prepared the journey to text-based programming including installing Visual Studio Code towards the end of August - the #1 trending Editor in the GitHub State of the OctoVerse Top Project.
I had come across d3 several years ago, was totally awed by it, but did not have the time, nor motivation back then to 'get into it'.
In Sep. 2019 I rediscovered d3 (wow again!) and started experimenting.
Within a month I had discovered observablehq - awed again by Mike Bostock's genius ... but this time - with the help of the reactive envionment - I was able to quickly achieve some results ... but it soon became clear that my rusty JavaScript basics needed refreshing.
Things like:
stuff I had forgotten (Converting strings to numbers or Accessing Nested Objects)
doing old stuff, but in JS, (Regex in JS)
as well as getting up to speed on the state of JavaScript today (Gee! There sure has been some big changes in JS/ECMAScipt since 1999! Just a few ;-)), including:
Along the way my companions Google and StackOverflow have always helped!
At the start of Nov. 2019 I found a cool youtube d3 course from freecodecamp.
Three weeks later via the freecodecamp website I found Curran's marvellous 13-hour long Data Visualization with D3.js - Full Tutorial Course - which I watched from end to end over the following weeks! (Aside: desparately need to index that video!)
December was filled mostly with christmas preparations, a small excursion into tableau. Just at the turn of the year I then discovered vizhub - and from there everything is exploding! :-)
I've had the huge luck to have stumbled across vizhub just as Curran was starting the datavis-2020 course :D
Loving what Curran is doing, I immediately supported his Kickstarter Vizhub Launch Project.
…
I started the VizHub way ... by forking examples:
I followed the course materials and got to grips with SVG + React
:
:
I realised that if I am going to get this code under my skin, I need to get my rusty HTML + CSS back up to scratch
Notes to pad out some time
:
[LINKS NEEDED HERE]
I also wanted to see how Observable and VizHub compare
2020-01-20 JetBrains Mono Font arrives
:
:
:
[LINKS NEEDED HERE]
I found a very interesting(*) viz about Gaussian Primes by Jason Davies and was very happy to port this to Vizhub.
I adapted my gaussian primes visualisation from the fruit bowl, and tried to do too much at once, so after a long while I mananged to get it working at all.
It still needs animating, which I hope to do at a later date.
(*) OK, so I'm a bit of a mathemetician, who's interested in such things as Primes, Gaussian Primes and likes nothing better than a bit of mathematical youtubing with Numberphile, Matt Parker or Mathologer
2020-02-02 A very special viz for a very special date! (It wasn't just a palindrome day, but a whirligig day!) // The animation will be (extensively) extended as I develop the skills :D
2020-02-05
Can't get anything to work.
Everything has just fallen into place!
Breakthroughs =
./
" path prefix!.map(function)
to munge data..transition()
and .duration()
to animate.call()
join (func,func,func)
Yep, the crux if the problem is explained in the selection.join observable documentation.
The last paragraph says (my highlighting)
The return value of the enter and update function is important—it specifies the selections to merge and return by selection.join. To avoid breaking the method chain, use selection.call to create transitions. Or, return an undefined enter or update selection to prevent merging.
Here is the code with my current understanding of the method-chaining in the comments:
{
const svg = d3.create("svg")
.attr("width", width)
.attr("height", 33)
.attr("viewBox", `0 -20 ${width} 33`);
while (true) {
const t = svg.transition()
.duration(750);
svg.selectAll("text") // method chain 1 START
.data(randomLetters(), d => d) // method chain 1
.join(
enter => enter.append("text") // method chain 2 START
.attr("fill", "green") // method chain 2
.attr("x", (d, i) => i * 16) // method chain 2
.attr("y", -30) // method chain 2
.text(d => d) // method chain 2
.call( // .call branches method chain 2
enter => enter.transition(t) // method chain 3 START
.attr("y", 0) // method chain 3 END
) // method chain 2 END
,
update => update // method chain 4 START
.attr("fill", "black") // method chain 4
.attr("y", 0) // method chain 4
.call( // .call branches method chain 4
update => update.transition(t) // method chain 5 START
.attr("x", (d, i) => i * 16) // method chain 5 END
) // method chain 4 END
,
exit => exit // method chain 6 START
.attr("fill", "brown") // method chain 6
.call( // .call branches method chain 6
exit => exit.transition(t) // method chain 7 START
.attr("y", 30) // method chain 7
.remove() // method chain 7 END
) // method chain 6 END
) // method chain 8 START (& 1 END)
.attr("foo","bar") // method chain 8
.call( // .call branches method chain 8
merge => merge.transition(t) // method chain 9 START
.attr("foo", "baz") // method chain 9 END
) // method chain 8 END
yield svg.node();
await Promises.tick(2500);
}
}
The method chains:
enter.transition
update.transition
Maybe we can picture it like this:
selectAll("text").data().join()
.------------------------´
|`- enter selection
| `- enter.transition ---.
|`- update selection |
| `- update.transition --+
`- exit selection |
`- exit.transition |
.--------------------------´
`- merged selection
`- merged.transition
Along the way I came across some fun places to learn JavaScript.
WarriorJS A game to develop your JavaScript 'sword' by programming your warrior-bot to fight against foe ... and stuff.
CodeWars is a ninja-like place to pit your coding skills against others
CodeWars offers small focussed tasks, which really help you to hone your skills by forcing you to APPLY any half-baked knowledge you have. I can really recommend it.
2020-02-25 RW: Note: CodeWars ranks place 7 in The 10 most popular coding challenge websites for 2020 AND in The Top 20 Websites to Learn Coding for Free
React is currently the leading JavaScript Framework
JSX is a markup syntax - a mix of HTML+Javascript - which makes it possible to calculate attributes + code on the fly.
<MyTag attr={JavaScriptCode}>foo-bar</MyTag>
Checkout the JSX-intro.
In larger React projects, you might want to use Redux to (centrally) manage application state. (React Redux is the official React bindings for Redux)
If you need a small version of React, try Preact.
React uses a virtual DOM to decide what to change in the real DOM.
While making it possible to update just the necessary DOM elements, the virtual DOM method represents a heavy CPU-load on the device. https://twitter.com/0xca0a/status/1199997552466288641 and there are moves to counter this new programming language Svelte
There is a new image format for the web: webp
Where to find out what is trending / changing in our world?
That reminds me of my first experiences of programming back in the early 80s on a ZX Spectrum and Atari 400 ...
2020-02-13 Time to start going through the Svelte tutorial
You could only save to cassette back then and the only validation method to check if it had saved correctly was just to reload it, and if didn't load, that confirmed it hadn't saved properly ... and you just stayed up half the night and programmed it again (and crossed your fingers a litle harder)
2020-02-13 After a long conversation with Curran about the development of vizhub, one of the topics that was raised, was how to make CSS which is local to this readme - so I went searching…
Apparently, for a while (in the history of HTML) it was possible to scope styles to the current containing element using <style scoped>
... but the scoped attribute has now been dropped.
This Stackoverflow answer presented the following method to localize styles for a given div:
<div id="blog">
<style>
#blog .bgblk {background-color:black;}
#blog .bgwht {background-color:white;}
#blog .fl {float:left;margin-right:10px;margin-bottom:0px;}
#blog .fr {float:right;margin-left:10px;margin-bottom:5px;}
#blog .m0 {margin:0px;}
#blog .p6 {padding:6px;}
</style>
PUT YOUR BLOG TEXT HERE
</div>
Need to check my CSS against this cool list of methods to organize your css
…and if you look at the README file, you will see that this is exactly how I have implemented styles in this blog.
I've got a (kind-of) broken SVG:
Well, at least, …
=> Time to learn about SVG Paths
... and before I summarize it myself check out this ideal gist
I've just used the CSS scale() transform function to reduce the size of the embedded page.
(but the SPACE it occupies is NOT scaling = problem for later)
+------------+-------------------+--------+
| *M* or *m* | moveto | (x y)+ |
+------------+-------------------+--------+
| *Z* or *z* | close path | (none) |
+------------+-------------------+--------+
| *L* or *l* | lineto | (x y)+ |
+------------+-------------------+--------+
| *H* or *h* | horizontal lineto | (x)+ |
+------------+-------------------+--------+
| *V* or *v* | vertical lineto | (y)+ |
+------------+-------------------+--------+
+------------+----------------------------+--------------------+
| *C* or *c* | Bézier curveto | (x1 y1 x2 y2 x y)+ |
+------------+----------------------------+--------------------+
| *S* or *s* | Shorthand Bézier curveto | (x2 y2 x y)+ |
+------------+----------------------------+--------------------+
| *Q* or *q* | Quadratic bézier curveto | (x1 y1 x y)+ |
+------------+----------------------------+--------------------+
| *T* or *t* | Shorthand/Smooth Quadratic | |
| | bézier curveto | (x y)+ |
+------------+----------------------------+--------------------+
| *A* or *a* | Elliptical arc | (rx ry |
| | | x-axis-rotation |
| | | large-arc-flag |
| | | sweep-flag x y)+ |
+------------+----------------------------+--------------------+
Uppercase commands uses absolute positions, lowercase commands uses relative positions.
For further descriptions check: http://www.w3.org/TR/SVG/paths.html#PathDataClosePathCommand
<path fill="white" d="M 0,200 h 200 L 100,0 z" />
See http://codepen.io/spoike/pen/ogMGoJ
<!-- Note: Needs to be scaled up because it is 2x4 px -->
<path
fill="#333333"
d="M 1,2
h 2
c 1,0,1,-1.4,0,-1.4
a 1.075,1.1,1,0,0,-2,0.3
c -0.8,0,-0.8,1.1,0,1.1
z" />
...and now I need to understand the error
...which I think is something to do with the last path in the SVG
... maybe it's turning (clockwise/anti-clockwise)?
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 25" class="fm_fill">
<path d="M11.47 24.75
c6.833 0 12.376-5.542 12.376-12.375C23.846 5.543 18.303 0 11.47 0
c-.271 0-.452.023-.588.045
l12.33 12.33-12.33 12.33
c.136.023.317.046.588.046z
m-.995-2.533L.634 12.375
l9.84-9.841a3.42 3.42 0 00-.587-.045C4.434 2.489 0 6.923 0 12.375
c0 5.453 4.434 9.887 9.887 9.887.271 0 .452-.023.588-.045z
m7.534-9.842
c0-4.05-3.303-7.352-7.353-7.352-.272 0-.453.022-.588.045
l7.307 7.307-7.307 7.308
c.135.023.316.045.588.045 4.05 0 7.353-3.303 7.353-7.353z
m-7.195 4.797
l-4.796-4.797 4.796-4.796a3.424 3.424 0 00-.588-.045 4.847 4.847 0 00-4.842 4.841 4.847 4.847 0 004.842 4.842
c.271 0 .452-.023.588-.045z
"
fill="#FFF" fill-rule="nonzero"/>
</svg>
At last, we can make our CSS modular using CSS var(--s) !
See Using CSS custom properties (variables) for detais.
You can define a custom property using a double-dash like this:
#blog {
--corners: 4px;
}
[or - if you want it defined globally - use the :root pseudo-class (and a longer name!)]
and then reference it like this
var(--variable-name, default-value);
For example:
#blog .aside {
border:1px solid green;
border-radius:var(--corners,6px);
background-color:#ffeebb;
padding:0px 10px;
color:#333;
}
#blog .embed {
border:1px solid grey;
border-radius:var(--corners,6px);
background-color:#eee;
padding:10px;
}
#blog .sheet {
box-shadow: 5px 10px rgba(0,0,0,0.1);
border-radius:var(--corners,6px);
background-color:white;
}
Q. asked by Mark Hughes on the D3 help slack channel & Curran replied:
Struture | represented as |
---|---|
A record | An Object , where each property corresponds to a column |
A table | An Array of Object records |
…with metadata | The Array returned by d3.csvParse includes a property array.columns which returns an Array of column-names. |
A network | See d3-force |
A tree | See d3-hierarchy |
There are also ways to get "from here to there" (e.g. from database to JS), such as https://github.com/d3/d3-dsv and https://github.com/d3/d3-hierarchy#stratify
A less sinister version of VSCode!
Free/Libre Open Source Software Binaries of VSCode
Removes telemetry but needs somw workarounds to get all features working
2020-02-17 GPU Animation: Doing it right - a very interesting article about (pros and cons of) getting the GPU (Graphics Processor Unit) to do the animation rather than the CPU.
For example, here the upper square is animated via CSS by the GPU, the lower square by JS + the CPU.
Whilst a couple of heavy JS-functions steal the CPU time from the lower square, the GPU-animation is smooth.
Need to consider the BEM CSS model.
The HTML & CSS Is Hard website appears to have great tutorials about:
CSS positioning
☝ THIS ☝
"Float-based layouts have mostly been replaced with Flexbox in modern websites."
- [Advanced Positioning](https://internetingishard.com/html-and-css/advanced-positioning/)<animate>
, <animateMotion>
Tom Steeples just turfed up a great thing ... animation in SVG using the <animate>
tag. See his animated smiley.
Visual Studio Code: Javascript, Node.js Hello World you tube
See mermaid-js or [mermaid githubgithub] (https://github.com/mermaid-js/mermaid)
This text…
sequenceDiagram
VizHub User-->>VizHub:Looks at
Note right of VizHub User: Impressed, but...
VizHub User->>Curran: What about XYZ?
Curran->>VizHub User: XYZ sounds cool!
Curran->>User Forum: Proposes Feature XYZ
VizHub User->>User Forum: Like
Note right of User Forum: Idea discussed and refined
User Forum-->>Curran: Uses details
Curran-->>VizHub: Implements Feature XYZ
Curran-->>VizHub User: Announces cool new Feature XYZ!
produces this cool SVG:
(Open the VizHubFeatureProposalAndImplementationSequence.svg file, which I can't embed here)
Have a look at the results on this gist
-- Embedded Gist-Script doesn't work
<script src="https://gist.github.com/mrwatson-de/6a259e2217cbd01bb7c08e4f9ca6cfec.js"></script>-- img with svg-source doesn't work
--So, I'm getting on well with JavaScript, D3, VizHub and Observable. I shall keep on learning in these areas.
However, I am aware that D3 is a nuts and bolts technology. You need to learn quite a lot of stuff to get things working.
Vega and Vega-Lite seem to simplify things and provide a lot more sensible logic out of the bag.
Responsive Grid Magazine Layout in just 20 lines of css by ... my brother! (small world)
:
:
:
/Blog