Skip to content
Chris Wilson edited this page Aug 20, 2021 · 6 revisions

Developing the Interactive

As described in Getting Started, when you run time-interactive [my-app-id], it will generate a directory with a few items to get you started.

There are three main files that are often all that you need:

  • debug.js: Where all of your JavaScript lives.
  • src/styles.scss: All of your styling. It is automatically nested in a selector with the id you provided and the .time-interactive class, meaning everything inside will only apply to the interactive.
  • src/base.html: Any markup you need hard-coded.

The .time-interactive class, which is automatically added by the short code to the parent <div>, also contains some base styles in src/time-interactive.scss. While you can edit it if you really must, you can easily override it in styles.scss. We welcome all PRs for the base styling.

When you bootstrap a project, it also includes an index.html and embed.html that load the source-mapped and minified versions of your interactive, respectively. There are also empty directories for code, meant for calculations you need to make during development, and docs, for any public-domain source material you want to put somewhere where you can locate it.

Workflow

By default, the debug.js file will load the style sheets and, when the page is ready, place them on the page and assemble anything you have in base.html. It also imports three very common (and small) d3.js functions: select, selectAll, and event. These are for your convenience.

You can install any Node dependencies you like, bearing in mind that not every Node module is intended to work in the browser or properly shimmed. It is highly recommended that your import only the functions you'll want. While Webpack will ideally use tree shaking to eliminate unused functions in an external library, it's good practice to use Python import conventions.

It is also supremely important that any third-party modules installed from NPM be mature, vetted and properly licensed. In a vast number of cases, the function you need is already in D3 somewhere. See Safety First for more.

For anything you install, either for pre-production calculations or inclusion in the client code, make sure to save it to package.json for future reference and builds. E.g.

npm install node-nlp --save-dev # Maybe you need to run a little natural-language processing on some text ahead of time
npm install fast-levenshtein --save-prod # And you need a fast implementation of Levenshtein distance in the interactive for when users enter text.

As you'll see, the generated debug.js has some nice features:

/* importing basic dependencies and style sheets */
const time = require('time-interactive');
import { select, selectAll, event } from 'd3';
require("./src/time-interactive.scss");	// default styles for all interactives. Change if necessary.
require("./src/styles.scss");

/* this fires when the page is ready */
time("my_awesome_app_2020", function(interactive) {

	/* base.html is automatically added to the <div> */
	interactive.el.innerHTML = require("./src/base.html")();

	let el = select(interactive.el);
	/*
	this is an extremely useful d3 selection of the parent div.
	anytime you want to select an element, use `el.select` or `el.selectAll` so that
	you don't accidentally select something outside of the interactive
	*/
}

From here on out, this little world inside a single <div> is your oyster. You can bring in a lot of different types of files. Here's an incomplete list from https://www.npmjs.com/package/bundle-module, which Chris Wilson maintains:

  • Text: using raw-loader
  • .css: using css-loader. This currently does resolve paths in url() calls. It allows uses the autoprefixer plugin to ensure browser compatibility.
  • .less and .scss: You can import .less and .scss files as well using less-loader and sass-loader. These are also autoprefixed.
  • .html and .ejs: The ejs-loader handles both .ejs templates and raw .html.
  • .csv, .tsv, .dsv: The dsv-loader can handle any delimited file.
  • .png, .jpg, .jpg, .gif: The file-loader plug can import images.

Next: Parameters and Convenience Methods

Clone this wiki locally