Export Image
Export Code

MrW's VizHub Experience 2020

Russell Watson

Last edited Mar 10, 2020
Created on Feb 05, 2020
Forked from MrW's VizHub Docu
<style> #blog { --corners: 3px; } #blog .aside { border:1px solid green; border-radius:var(--corners,6px); background-color:#ffeebb; padding:0px 10px; color:#333; } #blog .bgblk {background-color:black;} #blog .bgwht {background-color:white;} #blog pre { margin-left:36px; margin-right:36px; background-color:#eee; padding:6px; } #blog .embed { border:1px solid grey; border-radius:3px; background-color:#eee; padding:10px; } #blog .scale50 {transform: scale(0.5)} #blog .scale95 {transform: scale(0.95)} #blog .fl {float:left;margin-right:10px;margin-bottom:5px;} #blog .fr {float:right;margin-left:10px;margin-bottom:5px;} #blog .fs40 {font-size:40px;} #blog .fs80 {font-size:80px;} #blog .h40 {height:40px;} #blog .ha {height:auto;} #blog .m0 {margin:0px;} #blog .m10 {margin:10px;} #blog .mr10 {margin-right:10px;}
#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!

Prehistory

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:

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.

Early VizHub

I started the VizHub way ... by forking examples:

<svg height="40" viewBox="0 0 12 16"><path fill="currentcolor" d="M5.3 10.742A2.422 2.422 0 0 0 3.933 8.9C2.576 8.278 1.7 6.883 1.7 5.342V4.88C.716 4.568 0 3.618 0 2.494 0 1.116 1.075 0 2.4 0s2.4 1.116 2.4 2.494c0 1.124-.716 2.074-1.7 2.385v.463c0 .964.548 1.838 1.397 2.227.56.256 1.037.644 1.405 1.119a3.78 3.78 0 0 1 1.63-1.442c.85-.39 1.398-1.262 1.398-2.227v-.13c-1-.302-1.73-1.26-1.73-2.395C7.2 1.116 8.275 0 9.6 0S12 1.116 12 2.494c0 1.112-.702 2.055-1.67 2.376v.15c0 1.54-.876 2.935-2.233 3.557-.809.37-1.344 1.18-1.393 2.09.017.15.026.304.026.459v.004c.968.321 1.67 1.264 1.67 2.376C8.4 14.884 7.325 16 6 16s-2.4-1.116-2.4-2.494c0-1.124.716-2.074 1.7-2.385v-.318-.061zm-2.9-7.21c.552 0 1-.465 1-1.038 0-.574-.448-1.04-1-1.04s-1 .466-1 1.04c0 .573.448 1.038 1 1.038zm7.2 0c.552 0 1-.465 1-1.038 0-.574-.448-1.04-1-1.04s-1 .466-1 1.04c0 .573.448 1.038 1 1.038zM6 14.545c.552 0 1-.465 1-1.039 0-.573-.448-1.038-1-1.038s-1 .465-1 1.038c0 .574.448 1.04 1 1.04z"></path></svg>

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

HTML & CSS

Notes to pad out some time

  • Fill vs background-color
  • CSS nth-of-type
  • Text & box shadows
  • CSS-Animation!

:

[LINKS NEEDED HERE]

Observable vs VizHub

I also wanted to see how Observable and VizHub compare

  • can you embed them in other pages?
  • how performant are they?

2020-01-20 JetBrains Mono Font arrives

:

:

:

[LINKS NEEDED HERE]

Gaussian Primes

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

02•02•20•20

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

Notes to Self

2020-02-05

2020-02-05 I am very frustrated!

Can't get anything to work.

2020-02-06 Hooray! By Jove I've got it!

Everything has just fallen into place!

Breakthroughs =

  • Local modules need to be referenced with the "./" path prefix!
  • Got the hang of using .map(function) to munge data.
  • Got the hang of using a color scale's domain and range to map a value to a color.
  • Understood the use of .transition() and .duration() to animate
  • Understood the difficulties I was having moving
    • from a simple viz - with straightfoward method chaining
    • to a more complicated viz with animation, where method chaining needs to be augmented due to the change of current objects
      • thus the need to use .call()
      • or join (func,func,func)

(d3.)selection.join

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:

  1. selectAll("text")
  2. enter selection
  3. enter.transition
    
  4. update selection
  5. update.transition
    
  6. exit selection
  7. exit.transition
  8. merged selection (merged enter + update selections)
  9. merged.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
  

Learning Javascript - by having Fun

Along the way I came across some fun places to learn JavaScript.

  • JSFiddle For fiddling around with JavaScript online
  • 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, JSX, REDUX & Co. (Svelte)

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.

  • It uses custom tags backed by JavaScript functions, and
  • uses curly braces (in place of quotes) to allow dynamic calculation
      <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)

<svg height="1.5em" viewBox="-256 -256 1800 512" style="display:inline-block; margin:-.25em 0 0; vertical-align:middle;" title="Preact"><path d="M0,-256 221.7025033688164,-128 221.7025033688164,128 0,256 -221.7025033688164,128 -221.7025033688164,-128z" fill="white"></path><ellipse cx="0" cy="0" rx="75px" ry="196px" stroke-width="16px" stroke-dasharray="361.8741587987357 85.12584120126425" stroke-dashoffset="1386.2833677742738" fill="none" stroke="#673ab8" transform="rotate(52)"></ellipse><ellipse cx="0" cy="0" rx="75px" ry="196px" stroke-width="16px" stroke-dasharray="406.2097265927052 40.79027340729482" stroke-dashoffset="-1040.6223940690115" fill="none" stroke="#673ab8" transform="rotate(-52)"></ellipse><circle cx="0" cy="0" r="34" fill="#673ab8"></circle><path fill="white" d="M289.85 25.25L289.85 125L272 125L272-122.63L335.88-122.63Q379.45-122.63 401.59-103.55Q423.73-84.48 423.73-49.13Q423.73-32.85 417.69-19.20Q411.65-5.55 400.27 4.34Q388.90 14.22 372.63 19.74Q356.35 25.25 335.88 25.25L289.85 25.25M289.85 10.90L335.88 10.90Q352.33 10.90 365.27 6.35Q378.23 1.80 387.24-6.25Q396.25-14.30 401.06-25.24Q405.88-36.18 405.88-49.13Q405.88-77.65 388.29-93.05Q370.70-108.45 335.88-108.45L289.85-108.45L289.85 10.90ZM497.58 13.00L497.58 125L479.73 125L479.73-122.63L542.90-122.63Q585.78-122.63 606.95-106.09Q628.13-89.55 628.13-57.53Q628.13-43.35 623.23-31.63Q618.33-19.90 609.14-11.06Q599.95-2.23 587 3.46Q574.05 9.15 557.78 10.90Q561.98 13.52 565.30 17.90L650.53 125L634.95 125Q632.15 125 630.14 123.95Q628.13 122.90 626.20 120.45L546.93 20.00Q543.95 16.15 540.54 14.57Q537.13 13.00 529.95 13.00L497.58 13.00M497.58-0.30L540.63-0.30Q557.08-0.30 570.11-4.24Q583.15-8.18 592.16-15.53Q601.18-22.88 605.90-33.20Q610.63-43.53 610.63-56.48Q610.63-82.90 593.30-95.68Q575.98-108.45 542.90-108.45L497.58-108.45L497.58-0.30ZM843.73-122.63L843.73-107.75L713.35-107.75L713.35-7.65L821.85-7.65L821.85 6.87L713.35 6.87L713.35 110.13L843.73 110.13L843.73 125L695.33 125L695.33-122.63L843.73-122.63ZM1088.55 125L1074.73 125Q1072.28 125 1070.70 123.69Q1069.13 122.38 1068.25 120.28L1039.03 48.35L917.40 48.35L888.35 120.28Q887.65 122.20 885.90 123.60Q884.15 125 881.70 125L868.05 125L969.38-122.63L987.23-122.63L1088.55 125M922.83 35.05L1033.78 35.05L983.20-90.08Q981.98-93.05 980.75-96.81Q979.53-100.58 978.30-104.78Q977.08-100.58 975.85-96.81Q974.63-93.05 973.40-89.90L922.83 35.05ZM1302.40 83.35Q1304.15 83.35 1305.38 84.57L1312.38 92.10Q1304.67 100.33 1295.58 106.89Q1286.47 113.45 1275.71 118.09Q1264.95 122.72 1252.09 125.26Q1239.22 127.80 1223.83 127.80Q1198.10 127.80 1176.66 118.79Q1155.22 109.78 1139.91 93.24Q1124.60 76.70 1116.03 53.25Q1107.45 29.80 1107.45 1.10Q1107.45-27.08 1116.29-50.35Q1125.13-73.63 1141.14-90.34Q1157.15-107.05 1179.46-116.24Q1201.78-125.43 1228.72-125.43Q1242.20-125.43 1253.40-123.41Q1264.60-121.40 1274.31-117.64Q1284.03-113.88 1292.60-108.28Q1301.17-102.68 1309.40-95.33L1303.97-87.45Q1302.58-85.35 1299.60-85.35Q1298.03-85.35 1295.58-87.19Q1293.13-89.03 1289.36-91.74Q1285.60-94.45 1280.26-97.69Q1274.92-100.93 1267.58-103.64Q1260.22-106.35 1250.60-108.19Q1240.97-110.03 1228.72-110.03Q1206.15-110.03 1187.25-102.24Q1168.35-94.45 1154.70-80.01Q1141.05-65.58 1133.44-45.01Q1125.83-24.45 1125.83 1.10Q1125.83 27.35 1133.35 48.00Q1140.88 68.65 1154.17 82.91Q1167.47 97.17 1185.59 104.79Q1203.70 112.40 1224.88 112.40Q1238.17 112.40 1248.59 110.65Q1259 108.90 1267.75 105.40Q1276.50 101.90 1284.03 96.82Q1291.55 91.75 1298.90 84.92Q1299.78 84.22 1300.56 83.79Q1301.35 83.35 1302.40 83.35ZM1530.42-122.63L1530.42-107.40L1443.45-107.40L1443.45 125L1425.60 125L1425.60-107.40L1338.10-107.40L1338.10-122.63L1530.42-122.63Z"></path></svg>

If you need a small version of React, try Preact.

Virtual DOM vs Svelte

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

New webp image format

There is a new image format for the web: webp

  • lossless / lossy = 26% smaller / 25-34% smaller
  • Uses 'predictive coding' = predicts difference to neighbors.

Trends

Where to find out what is trending / changing in our world?

2020-02-09 Back to the future with vizhub

Due to some bug in the works somewhere, I've just had to retype most of this page, as the first version got sucked up by a black hole in the ether.

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)

Defining local CSS (or how to pimp your blog)

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.

SVG Paths

<svg width="30" height="30" viewBox="0 0 24 25" xmlns="http://www.w3.org/2000/svg"><path d="M11.47 24.75c6.833 0 12.376-5.542 12.376-12.375C23.846 5.543 18.303 0 11.47 0c-.271 0-.452.023-.588.045l12.33 12.33-12.33 12.33c.136.023.317.046.588.046zm-.995-2.533L.634 12.375l9.84-9.841a3.42 3.42 0 00-.587-.045C4.434 2.489 0 6.923 0 12.375c0 5.453 4.434 9.887 9.887 9.887.271 0 .452-.023.588-.045zm7.534-9.842c0-4.05-3.303-7.352-7.353-7.352-.272 0-.453.022-.588.045l7.307 7.307-7.307 7.308c.135.023.316.045.588.045 4.05 0 7.353-3.303 7.353-7.353zm-7.195 4.797l-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.842c.271 0 .452-.023.588-.045z" fill="#FFF" fill-rule="nonzero"></path></svg>

I've got a (kind-of) broken SVG:

Well, at least, …

  • it works in my browser,
  • it works in my svg viewer "Gaplin",
  • it breaks in my svg editor "Sketch",
  • it breaks when I import it into FileMaker as an svg-button icon!

=> 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)

# Cheatsheet for SVG Path Data

Straight line commands

+------------+-------------------+--------+
| *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)+   |
+------------+-------------------+--------+

Curve commands

+------------+----------------------------+--------------------+
| *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)+  |
+------------+----------------------------+--------------------+

Notes

Uppercase commands uses absolute positions, lowercase commands uses relative positions.

For further descriptions check: http://www.w3.org/TR/SVG/paths.html#PathDataClosePathCommand

Examples

Simple Triangle

<path fill="white" d="M 0,200 h 200 L 100,0 z" />

See http://codepen.io/spoike/pen/ogMGoJ

Cloud

<!-- 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" />

See http://codepen.io/spoike/pen/NPBbpN

...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)?

Help!
<?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>

Interesting stuff to check out later

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="164" height="40" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 164 40" data-icon="website-logo" data-height="40" class="iconify" data-inline="false"><g fill="none" fill-rule="evenodd"><g stroke="#979797" stroke-linecap="round" stroke-width="2"><path d="M8 13l-7 7M8 27l-7-7"></path><g><path d="M56 13l7 7M56 27l7-7"></path></g></g><g transform="translate(16 4)"><circle stroke="#307594" stroke-width="2" cx="16" cy="16" r="15"></circle><rect fill="#307594" x="9" y="10" width="3" height="5" rx="1.5"></rect><rect fill="#307594" x="20" y="10" width="3" height="5" rx="1.5"></rect><path d="M16 26c5 0 9.545-4.505 9.024-5.5C24.5 19.5 22 23 16 23c-6 0-8-3.5-8.5-2.5S11 26 16 26z" fill="#307594"></path></g><g transform="translate(76 1)"><rect fill="#E13E31" width="3" height="3" rx="1.5"></rect><path d="M1.5 6.5v12M18.596 7.404a6.5 6.5 0 1 0 0 9.192" stroke="#E13E31" stroke-width="3" stroke-linecap="round"></path><circle stroke="#E13E31" stroke-width="3" cx="30" cy="12" r="6.5"></circle><path d="M53.5 18.5V11a5.5 5.5 0 0 0-11 0v7.5" stroke="#E13E31" stroke-width="3" stroke-linecap="round"></path><g transform="translate(58)"><rect fill="#AEAEAE" width="3" height="3" rx="1.5"></rect><path d="M1.5 6.5v12" stroke="#AEAEAE" stroke-width="3" stroke-linecap="round"></path></g><g stroke="#AEAEAE" stroke-linecap="round" stroke-width="3"><path d="M73.5 1.5H70c-2.5 0-4.5 2-4.5 4.5v12.5M69 10.5h2.5"></path></g><g stroke="#AEAEAE" stroke-linecap="round" stroke-width="3"><path d="M78.5 21.5h4c2 0 4-2 4-4v-12"></path><path d="M77.5 5.5v5c0 2.5 1.5 4 4 4H83"></path></g></g><g transform="translate(73 24)"><circle fill="#307594" cx="1" cy="13" r="1"></circle><path d="M7 13A5 5 0 0 0 7 3H4v10h3z" stroke="#307594" stroke-width="2" stroke-linejoin="round"></path><g stroke="#307594" stroke-linecap="round" stroke-width="2"><path d="M22 13h-4c-1 0-2-1-2-2V5c0-1 1-2 2-2h4M18 8h3"></path></g><g stroke="#307594" stroke-linecap="round" stroke-width="2"><path d="M31 5.5A2.5 2.5 0 1 0 28.5 8M26 10.5A2.5 2.5 0 1 0 28.5 8"></path></g><g transform="translate(34 2)"><path d="M1 11V4" stroke="#307594" stroke-width="2" stroke-linecap="round"></path><circle fill="#307594" cx="1" cy="1" r="1"></circle></g><path d="M48 5c-.152-.18-.29-.362-.464-.536a5 5 0 1 0 .463 6.538V9H47M52 13V3l7 10V3" stroke="#307594" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></g></g></svg>

Icons

More CSS Stuff

CSS Selector-Fun

CSS Variables

At last, we can make our CSS modular using CSS var(--s) !

See Using CSS custom properties (variables) for detais.

How?

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;
}

'Standard' structures in d3?

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

VSCodium

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

Advanced Animation: JS, CSS, CPU or GPU?

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.

<svg xmlns="http://www.w3c.org/2000/svg" xmlns:xlink="http://www.w3c.org/1999/xlink" version="1.1" width="206" height="134" viewport="0 0 200 100"> <title>A RegEx Logo</title> <rect transform="translate(45, 1) skewX(-18)" width="156" height="130" fill="yellow"/> <rect transform="translate(55,10) skewX(-18)" width="130" height="70" fill="green"/> <rect transform="translate(60,20) skewX(-18)" width="82" height="50" fill="#900"/> <rect transform="translate(70,30) skewX(-18)" width="42" height="30" fill="blue"/> <text transform="translate(70,51)" stroke="#fff" stroke-opacity="0.2" fill="#fff" stroke-width="4" style="font-size:20px;font-family:sans-serif;">/^$/  g    \1</text> <text transform="translate(17,118) skewX(-18)" stroke="#000" stroke-opacity="0.2" fill="#000" stroke-width="4" style="font-size:44px;font-family:sans-serif;">RegEx</text> </svg>

More RegEx Stuff

More CSS Stuff

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/)

SVG Animation using SMIL <animate>, <animateMotion>

Tom Steeples just turfed up a great thing ... animation in SVG using the <animate> tag. See his animated smiley.

Munging data - some places to learn

2020-03-04 Getting started with VSCode and Node.js < 3 minutes

Visual Studio Code: Javascript, Node.js Hello World you tube

Wow - mermaid for markdown-like quick-charts

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

--

2020-03-09 Thoughts on further R&D

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.

2020-03-10 Latest CSS Grid Design breakthrough

Responsive Grid Magazine Layout in just 20 lines of css by ... my brother! (small world)

:

:

:

/Blog



MIT Licensed