Skip to content

Commit da51e2d

Browse files
committed
Fix ticks for EplusM and log
2 parents 6a4a657 + 7626e31 commit da51e2d

11 files changed

Lines changed: 257 additions & 316 deletions

File tree

.github/workflows/node.js.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
2+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs
3+
4+
name: Node.js CI
5+
6+
on:
7+
push:
8+
branches: [ "main" ]
9+
pull_request:
10+
branches: [ "main" ]
11+
12+
jobs:
13+
build:
14+
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
- name: Use Node.js
20+
uses: actions/setup-node@v4
21+
with:
22+
node-version: '20.x'
23+
- run: yarn --frozen-lockfile
24+
- run: yarn test

README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
# Implementation of the EpluM scale for d3.
2+
[![JS Tests](https://github.com/jdfekete/d3-eplusm/actions/workflows/node.js.yml/badge.svg?branch=main&event=push)](https://github.com/jdfekete/d3-eplusm/actions/workflows/node.js.yml)
23

3-
D3 provides several scales in [d3-scale](https://github.com/d3/d3-scale): quantitative, ordered, and categorical. EplusM is a quantitative scale, a good alternative to the logarithmic scale for values with orders of magnitude varying widely.
4+
D3 provides several scales in [d3-scale](https://github.com/d3/d3-scale): quantitative, ordered, and categorical. EplusM is a quantitative scale, an effective alternative to the logarithmic scale for values that span over multiple orders of magnitude.
45

56
![](./log-eplusm.png)
67

78

8-
See this publication for details:
9-
Katerina Batziakoudi, Florent Cabric, Stéphanie Rey, and Jean-Daniel Fekete. 2025. Lost in Magnitudes: Exploring Visualization Designs for Large Value Ranges. In Proceedings of the 2025 CHI Conference on Human Factors in Computing Systems (CHI '25). Association for Computing Machinery, New York, NY, USA, Article 1170, 1–18. https://doi.org/10.1145/3706598.3713487
9+
See these publications for details:
10+
- Katerina Batziakoudi, Stéphanie Rey, Jean-Daniel Fekete. Beyond Log Scales: Toward Cognitively Informed Bar Charts for Orders of Magnitude Values. IEEE Transactions on Visualization and Computer Graphics (TVCG). 2026 ⟨hal-05171203⟩
11+
- Katerina Batziakoudi, Florent Cabric, Stéphanie Rey, and Jean-Daniel Fekete. 2025. Lost in Magnitudes: Exploring Visualization Designs for Large Value Ranges. In Proceedings of the 2025 CHI Conference on Human Factors in Computing Systems (CHI '25). Association for Computing Machinery, New York, NY, USA, Article 1170, 1–18. https://doi.org/10.1145/3706598.3713487
1012

1113
## Using d3-eplusm
1214

13-
In JavaScript development, you can add the library in your `package.json` file with the following command:
15+
In JavaScript development, you can add the library to your `package.json` file with the following command:
1416
```
1517
npm i d3-eplusm
1618
```
@@ -25,7 +27,7 @@ You can also use it directly from `unpkg.com` by adding this line to your HTML f
2527
</script
2628
```
2729
28-
You can also use `d3-eplusm` in Observable, by using `scaleEplusM = require("d3-eplusm@0.0.6-dev")` as shown is [this example](https://observablehq.com/d/3e0c87451c4eeec0).
30+
You can also use `d3-eplusm` in Observable, by using `scaleEplusM = require("d3-eplusm@0.0.7-dev")` as shown is [this example](https://observablehq.com/d/3e0c87451c4eeec0).
2931
3032
## API
3133
@@ -60,7 +62,7 @@ import { bricksEplusM } from 'd3-eplusm';
6062
The library defines the following functions:
6163
6264
- `const bricks = bricksEplusM(brickColor)` returns an object to manage the bricks.
63-
- `bricks.declarePatterns(svg)` takes a D3 svg object and adds nine brick pattern declarations, called `#brick1` to `#brick9`.
65+
- `bricks.declarePatterns(svg)` takes a D3 svg object and adds ten brick pattern declarations, called `#brick0` to `#brick9`.
6466
- `bricks.barY(scale, v)` returns the bar chart Y value for a bar with value `v`.
6567
- `bricks.barHeight(scale, v)` returns the bar chart height value for a bar with value `v`.
6668
- `bricks.brickY(scale, v)` returns the bar chart Y value for the brick part of a bar with value `v`.

bricks.png

43.2 KB
Loading

bricks.svg

Lines changed: 7 additions & 4 deletions
Loading

examples/bar-chart.html

Lines changed: 82 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,11 @@
1-
<!doctype html>
2-
<meta charset="utf-8" />
3-
<title>Bar Chart using the EplusM scale</title>
4-
<link rel="preconnect" href="https://fonts.googleapis.com">
5-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
6-
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@500&family=Manrope:wght@200..800&family=Montserrat:ital,wght@0,100..900;1,100..900&family=Rubik:ital,wght@0,300..900;1,300..900&display=swap" rel="stylesheet">
7-
8-
9-
<style>
10-
11-
body, svg {
12-
font-family: 'Rubik', serif;
13-
margin: 0;
14-
padding: 0;
15-
overflow: hidden;
16-
}
17-
18-
.grid {
19-
color: black;
20-
opacity: 0.5;
21-
stroke-width: 0.5px;
22-
}
23-
24-
.grid-strong {
25-
color: rgb(20, 22, 76);
26-
stroke-width: 1px;
27-
}
28-
29-
.strongText {
30-
font-size: 16px;
31-
font-weight: bold;
32-
color: rgb(20, 22, 76);
33-
}
34-
35-
.strongSSBText {
36-
font-size: 16px;
37-
font-weight: bold;
38-
}
39-
40-
.lightText {
41-
font-size: 16px;
42-
color: grey;
43-
}
44-
45-
.dashed-line {
46-
stroke: grey;
47-
stroke-width: 2;
48-
stroke-dasharray: 4;
49-
}
50-
</style>
51-
52-
<div id="container"></div>
53-
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>Bar Chart using the EplusM scale</title>
6+
<link rel="preconnect" href="https://fonts.googleapis.com">
7+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
8+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@500&family=Manrope:wght@200..800&family=Montserrat:ital,wght@0,100..900;1,100..900&family=Rubik:ital,wght@0,300..900;1,300..900&display=swap" rel="stylesheet">
549
<script type="module">
5510
import * as d3 from 'https://cdn.jsdelivr.net/npm/d3@7/+esm';
5611
import { scaleEplusM } from 'd3-eplusm';
@@ -91,7 +46,7 @@
9146

9247
// Create the SVG container.
9348
const svg = d3
94-
.create('svg')
49+
.select('#barchartsvg')
9550
.attr('width', width)
9651
.attr('height', height)
9752
.attr('viewBox', [0, 0, width, height])
@@ -233,3 +188,76 @@
233188
// Append the SVG element.
234189
window['container'].append(svg.node());
235190
</script>
191+
</head>
192+
<body>
193+
<div id="container">
194+
<svg id="barchartsvg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
195+
<style>
196+
svg {
197+
font-family: 'Rubik', serif;
198+
margin: 0;
199+
padding: 0;
200+
overflow: hidden;
201+
}
202+
203+
.grid {
204+
color: black;
205+
opacity: 0.5;
206+
stroke-width: 0.5px;
207+
}
208+
209+
.grid-strong {
210+
color: rgb(20, 22, 76);
211+
stroke-width: 1px;
212+
}
213+
214+
.strongText {
215+
font-size: 16px;
216+
font-weight: bold;
217+
color: rgb(20, 22, 76);
218+
}
219+
220+
.strongSSBText {
221+
font-size: 16px;
222+
font-weight: bold;
223+
}
224+
225+
.lightText {
226+
font-size: 16px;
227+
color: grey;
228+
}
229+
230+
.dashed-line {
231+
stroke: grey;
232+
stroke-width: 2;
233+
stroke-dasharray: 4;
234+
}
235+
</style>
236+
</svg>
237+
238+
<script>
239+
function saveSvg(id, name) {
240+
const svgEl = document.getElementById(id);
241+
svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
242+
var svgData = svgEl.outerHTML;
243+
var preface = '<?xml version="1.0" standalone="no"?>\r\n';
244+
var svgBlob = new Blob([preface, svgData], {type:"image/svg+xml;charset=utf-8"});
245+
var svgUrl = URL.createObjectURL(svgBlob);
246+
var downloadLink = document.createElement("a");
247+
downloadLink.href = svgUrl;
248+
downloadLink.download = name;
249+
document.body.appendChild(downloadLink);
250+
downloadLink.click();
251+
document.body.removeChild(downloadLink);
252+
}
253+
254+
window.addEventListener(
255+
'keypress',
256+
function (evt) {
257+
if (evt.code == "KeyS")
258+
saveSvg('barchartsvg', 'bar-chart.svg')
259+
});
260+
</script>
261+
</div>
262+
</body>
263+
</html>

examples/bricks.html

Lines changed: 81 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,11 @@
1-
<!doctype html>
2-
<meta charset="utf-8" />
3-
<title>Bar Chart using the EplusM scale</title>
4-
<link rel="preconnect" href="https://fonts.googleapis.com">
5-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
6-
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@500&family=Manrope:wght@200..800&family=Montserrat:ital,wght@0,100..900;1,100..900&family=Rubik:ital,wght@0,300..900;1,300..900&display=swap" rel="stylesheet">
7-
8-
<style>
9-
body, svg {
10-
font-family: 'Rubik', serif;
11-
margin: 0;
12-
padding: 0;
13-
overflow: hidden;
14-
}
15-
16-
.grid {
17-
color: black;
18-
opacity: 0.5;
19-
stroke-width: 0.5px;
20-
}
21-
22-
.grid-strong {
23-
color: rgb(20, 22, 76);
24-
stroke-width: 1px;
25-
}
26-
27-
.strongText {
28-
font-size: 16px;
29-
font-weight: bold;
30-
color: rgb(20, 22, 76);
31-
}
32-
33-
.strongSSBText {
34-
font-size: 16px;
35-
font-weight: bold;
36-
}
37-
38-
.lightText {
39-
font-size: 16px;
40-
color: grey;
41-
}
42-
43-
.dashed-line {
44-
stroke: grey;
45-
stroke-width: 2;
46-
stroke-dasharray: 4;
47-
}
48-
</style>
49-
<div id="container"></div>
50-
<svg id="mainsvg" xmlns="http://www.w3.org/2000/svg"></svg>
51-
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>Bar Chart using the EplusM scale</title>
6+
<link rel="preconnect" href="https://fonts.googleapis.com">
7+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
8+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@500&family=Manrope:wght@200..800&family=Montserrat:ital,wght@0,100..900;1,100..900&family=Rubik:ital,wght@0,300..900;1,300..900&display=swap" rel="stylesheet">
529
<script type="module">
5310
import * as d3 from 'https://cdn.jsdelivr.net/npm/d3@7/+esm';
5411
import { scaleEplusM, bricksEplusM } from 'd3-eplusm';
@@ -91,7 +48,7 @@
9148

9249
// Create the SVG container.
9350
const svg = d3
94-
.select('#mainsvg')
51+
.select('#brickssvg')
9552
.attr('width', width)
9653
.attr('height', height)
9754
.attr('viewBox', [0, 0, width, height])
@@ -249,3 +206,75 @@
249206
// Append the SVG element.
250207
window['container'].append(svg.node());
251208
</script>
209+
</head>
210+
<body>
211+
<div id="container">
212+
<svg id="brickssvg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
213+
<style>
214+
svg {
215+
font-family: 'Rubik', serif;
216+
margin: 0;
217+
padding: 0;
218+
overflow: hidden;
219+
}
220+
221+
.grid {
222+
color: black;
223+
opacity: 0.5;
224+
stroke-width: 0.5px;
225+
}
226+
227+
.grid-strong {
228+
color: rgb(20, 22, 76);
229+
stroke-width: 1px;
230+
}
231+
232+
.strongText {
233+
font-size: 16px;
234+
font-weight: bold;
235+
color: rgb(20, 22, 76);
236+
}
237+
238+
.strongSSBText {
239+
font-size: 16px;
240+
font-weight: bold;
241+
}
242+
243+
.lightText {
244+
font-size: 16px;
245+
color: grey;
246+
}
247+
248+
.dashed-line {
249+
stroke: grey;
250+
stroke-width: 2;
251+
stroke-dasharray: 4;
252+
}
253+
</style>
254+
</svg>
255+
<script>
256+
function saveSvg(id, name) {
257+
const svgEl = document.getElementById(id);
258+
svgEl.setAttribute("xmlns", "http://www.w3.org/2000/svg");
259+
var svgData = svgEl.outerHTML;
260+
var preface = '<?xml version="1.0" standalone="no"?>\r\n';
261+
var svgBlob = new Blob([preface, svgData], {type:"image/svg+xml;charset=utf-8"});
262+
var svgUrl = URL.createObjectURL(svgBlob);
263+
var downloadLink = document.createElement("a");
264+
downloadLink.href = svgUrl;
265+
downloadLink.download = name;
266+
document.body.appendChild(downloadLink);
267+
downloadLink.click();
268+
document.body.removeChild(downloadLink);
269+
}
270+
271+
window.addEventListener(
272+
'keypress',
273+
function (evt) {
274+
if (evt.code == "KeyS")
275+
saveSvg('brickssvg', 'bricks.svg')
276+
});
277+
</script>
278+
</div>
279+
</body>
280+
</html>

examples/ticks-cdn.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<div id="container"></div>
55
<script type="module">
66
import * as d3 from 'https://cdn.jsdelivr.net/npm/d3@7/+esm';
7-
import { scaleEplusM, bricksEplusM } from 'https://unpkg.com/d3-eplusm?module';
7+
import { scaleEplusM } from 'https://unpkg.com/d3-eplusm?module';
88

99
// Declare the chart dimensions and margins.
1010
const width = 1024;

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "d3-eplusm",
3-
"version": "0.0.6-dev",
3+
"version": "0.0.8-dev",
44
"description": "Exponent plus Mantissa scale for d3.",
55
"keywords": [
66
"d3",

0 commit comments

Comments
 (0)