Skip to content

Commit

Permalink
feat(examples): add svg-barchart demo
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Sep 22, 2018
1 parent 5ef9cf0 commit 86bdd06
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 0 deletions.
Binary file added assets/screenshots/svg-barchart.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions examples/svg-barchart/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# svg-barchart

[Live demo](http://demo.thi.ng/umbrella/svg-barchart/)

SVG bar chart component & one-off rendering.

![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/screenshots/svg-barchart.png)

```bash
git clone https://github.com/thi-ng/umbrella.git
cd umbrella/examples/svg-barchart
yarn install
yarn start
```

## Authors

- Karsten Schmidt

## License

© 2018 Karsten Schmidt // Apache Software License 2.0
16 changes: 16 additions & 0 deletions examples/svg-barchart/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>svg-barchart</title>
<link href="https://unpkg.com/tachyons@4.9.1/css/tachyons.min.css" rel="stylesheet">
<style>
</style>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="./src/index.ts"></script>
</body>
</html>
29 changes: 29 additions & 0 deletions examples/svg-barchart/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "svg-barchart",
"version": "0.0.1",
"repository": "https://github.com/thi-ng/umbrella",
"author": "Karsten Schmidt <k+npm@thi.ng>",
"license": "Apache-2.0",
"scripts": {
"clean": "rm -rf .cache build out",
"build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --detailed-report",
"start": "parcel index.html -p 8080 --open"
},
"devDependencies": {
"parcel-bundler": "^1.9.7",
"terser": "^3.8.2",
"typescript": "^3.0.1"
},
"dependencies": {
"@thi.ng/api": "latest",
"@thi.ng/atom": "latest",
"@thi.ng/rstream": "latest",
"@thi.ng/transducers-hdom": "latest"
},
"browserslist": [
"last 3 Chrome versions"
],
"browser": {
"process": false
}
}
97 changes: 97 additions & 0 deletions examples/svg-barchart/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { clearDOM, renderOnce } from "@thi.ng/hdom";
import { range } from "@thi.ng/transducers/iter/range";
import { map } from "@thi.ng/transducers/xform/map";
import { mapcat } from "@thi.ng/transducers/xform/mapcat";

// fit `x` from range (a,b) => (c,d)
const fit = (x, a, b, c, d) => (x - a) / (b - a) * (d - c) + c;

// iterator of range mapped tuples: `[mapped, orig]`
const mappedRange = (from, to, step, start, end) =>
map(
(n) => [fit(n, from, to, start, end), n],
range(from, to, step));

// syntax sugar to create SVG line
const line = (x1, y1, x2, y2) => ["line", { x1, y1, x2, y2 }];

// reusuable axis tick & label combo
const tick = (x1, y1, x2, y2, tx, ty, label) => [
line(x1, y1, x2, y2),
["text", { x: tx, y: ty, stroke: "none" }, label]
];

// mapping fn for x-axis ticks
const tickX = (y) => ([x, n]) => tick(x, y, x, y + 10, x, y + 20, n);

// mapping fn for y-axis ticks
const tickY = (x) => ([y, n]) => tick(x - 10, y, x, y, x - 15, y, n);

// x-axis with ticks as SVG group
const axisX = ({ axis: a, domain: d, range: r }) =>
["g", { "text-anchor": "middle" },
line(a[0], a[2], a[1], a[2]),
mapcat(tickX(a[2]), mappedRange(d[0], d[1], d[2], r[0], r[1]))];

// y-axis with ticks as SVG group
const axisY = ({ axis: a, domain: d, range: r }) =>
["g", { "text-anchor": "end" },
line(a[2], a[0], a[2], a[1]),
mapcat(tickY(a[2]), mappedRange(d[0], d[1], d[2], r[0], r[1]))];

// mapping fn to create a single bar from `[domainPos, value]`
const bar = ({ domain: xd, range: xr }, { domain: yd, range: yr }) =>
([xx, yy]) => {
const y = fit(yy, yd[0], yd[1], yr[0], yr[1]);
return ["rect", {
x: fit(xx, xd[0], xd[1], xr[0], xr[1]) - 5,
y,
width: 10,
height: yr[0] - y
}];
};

// complete bar chart component
const barChart = (_, opts, values) =>
["svg", opts.attribs,
["g", { stroke: opts.axis, fill: opts.axis },
axisX(opts.x),
axisY(opts.y)],
["g", { fill: opts.fill },
map(bar(opts.x, opts.y), values)]];


// one-off DOM creation
renderOnce(
["div.ma2.sans-serif",
["h1", "Bar chart example"],
[barChart,
{
attribs: {
width: 500,
height: 200,
"font-size": "10px",
"font-family": "Menlo, sans-serif"
},
x: {
axis: [40, 490, 170],
domain: [1980, 2021, 10],
range: [60, 480]
},
y: {
axis: [170, 10, 40],
domain: [0, 101, 25],
range: [160, 20]
},
axis: "#666",
fill: "#0cc"
},
map((year) => [year, Math.random() * 100], range(1980, 2020, 2))
]
]
);

if (process.env.NODE_ENV !== "production") {
const hot = (<any>module).hot;
hot && hot.dispose(() => clearDOM(document.getElementById("app")));
}
11 changes: 11 additions & 0 deletions examples/svg-barchart/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": ".",
"target": "es6",
"sourceMap": true
},
"include": [
"./src/**/*.ts"
]
}

0 comments on commit 86bdd06

Please sign in to comment.