Skip to content

Commit 7a4387e

Browse files
author
Wolfgang Beyer
committed
update mini-example and README.md
1 parent a8d37a8 commit 7a4387e

9 files changed

+141
-95
lines changed

LICENSE.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2016 Wolfgang Beyer
3+
Copyright (c) 2017 Wolfgang Beyer
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

+53-44
Original file line numberDiff line numberDiff line change
@@ -41,68 +41,77 @@ There already exist various JavaScript tools for the visualization of graphs (se
4141

4242
The demo at [https://wolfib.github.io/sequenceTubeMap/](https://wolfib.github.io/sequenceTubeMap/) contains some example visualizations as well as a way to generate visalizations from custom data.
4343

44-
Another way to use this module is to include it in your own code. The whole visualization logic is contained in [`sequenceTubeMap.js`](https://github.com/wolfib/sequenceTubeMap/blob/master/sequenceTubeMap.js) and a handful of css rules are defined in [`sequenceTubeMapStyle.css`](https://github.com/wolfib/sequenceTubeMap/blob/master/sequenceTubeMapStyle.css). For the actual drawing the module uses [d3.js](https://d3js.org/), so this library has to be included as well. A minimal example would look like this:
44+
Another way to use this module is to include it in your own code. The whole visualization logic is contained in [`tubemap.js`](https://github.com/wolfib/sequenceTubeMap/blob/master/app/scripts/tubemap.js) and a handful of css rules are defined in [`tubemap.css`](https://github.com/wolfib/sequenceTubeMap/blob/master/app/styles/tubemap.css). tubemap.js is an ES6 module and importing it requires ES6's import command, which is not supported by most browsers natively at this time. The code therefore needs to be transpiled before it can be executed in the browser.
4545

46+
In addition, the module uses [d3.js](https://d3js.org/), [jQuery](https://jquery.com/) and [Bootstrap](https://getbootstrap.com/).
47+
48+
A minimal example would look like this:
49+
50+
miniExample.html
4651
```html
4752
<!DOCTYPE html>
4853
<html>
4954
<head>
50-
<title>sequenceTubeMap.js Minimal Example</title>
51-
<script type="text/javascript" src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
52-
<script src="sequenceTubeMap.js"></script>
53-
<link rel="stylesheet" type="text/css" href="sequenceTubeMapStyle.css">
55+
<title>Sequence Tube Map Minimal Example</title>
56+
<link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.css" />
57+
<link rel="stylesheet" href="styles/tubemap.css">
5458
</head>
5559
<body>
56-
<p>A minimal example created with sequenceTubeMap.js:</p>
57-
<div id="chart"></div>
58-
59-
<script type="text/javascript">
60+
<p>A minimal example created with the Sequence Tube Maps JavaScript Module:</p>
61+
<div id="legendDiv"></div>
62+
<div id="chart">
63+
<svg id="svg">
64+
</svg>
65+
</div>
66+
<script src="/bower_components/jquery/dist/jquery.js"></script>
67+
<script src="/bower_components/d3/d3.js"></script>
68+
<script src="scripts/miniExample.bundle.js"></script>
69+
</body>
70+
</html>
71+
```
6072

61-
var nodes = [
62-
{name: "A", width: 1},
63-
{name: "B", width: 2},
64-
{name: "C", width: 3}
65-
];
73+
miniExample.js
74+
```javascript
75+
import * as tubeMap from './tubemap';
6676

67-
var paths = [
68-
{id: 0, sequence: ["A", "B", "C"]},
69-
{id: 1, sequence: ["A", "B", "C"]},
70-
{id: 2, sequence: ["A", "C"]}
71-
];
77+
const nodes = [
78+
{ name: 'A', seq: 'AAAA' },
79+
{ name: 'B', seq: 'TTG' },
80+
{ name: 'C', seq: 'CC' },
81+
];
7282

73-
var svg = d3.select("#chart").append("svg");
83+
const paths = [
84+
{ id: 0, name: 'Track 1', sequence: ['A', 'B', 'C'] },
85+
{ id: 1, name: 'Track 2', sequence: ['A', '-B', 'C'] },
86+
{ id: 2, name: 'Track 3', sequence: ['A', 'C'] },
87+
];
7488

75-
sequenceTubeMap.create(svg, nodes, paths);
89+
tubeMap.create({
90+
svgID: '#svg',
91+
nodes,
92+
tracks: paths,
93+
});
94+
tubeMap.useColorScheme(0);
95+
```html
7696
77-
</script>
78-
</body>
79-
</html>
80-
```
8197
(See the result [here](https://wolfib.github.io/sequenceTubeMap/miniExample.html).)
8298
83-
[`sequenceTubeMap.js`](https://github.com/wolfib/sequenceTubeMap/blob/master/sequenceTubeMap.js) uses very simple custom JSON data structures for its input data:
99+
[`tubemap.js`](https://github.com/wolfib/sequenceTubeMap/blob/master/app/scripts/tubemap.js) uses very simple custom JSON data structures for its input data:
84100
85-
Nodes are defined by a `name` attribute (has to be unique) and either a `width` or a `sequenceLength` attribute. `width` determines the node's width directly whereas `sequenceLength` is used as input into a scaling function whose return value is the actual node `width` attribute to be used in the visualization.
101+
Nodes are defined by a `name` attribute (has to be unique) and a `seq` attribute which contains the node's sequence of bases.
86102
```javascript
87-
var nodes = [
88-
{name: "A", width: 1},
89-
{name: "B", width: 2},
90-
{name: "C", width: 3}
91-
];
92-
93-
var nodes = [
94-
{name: "A", sequenceLength: 1},
95-
{name: "B", sequenceLength: 2},
96-
{name: "C", sequenceLength: 3}
103+
const nodes = [
104+
{ name: 'A', seq: 'AAAA' },
105+
{ name: 'B', seq: 'TTG' },
106+
{ name: 'C', seq: 'CC' },
97107
];
98108
```
99-
100-
Paths each have a unique and consecutively numbered `id` attribute (starting with 0) and a `sequence` attribute which contains a array of node `name` attributes. If a node is traversed in reversed direction, the node `name` is prefixed by a `-`-symbol.
109+
Paths each have a unique and consecutively numbered `id` attribute (starting with 0), a `name` attribute and a `sequence` attribute which contains a array of node `name` attributes. If a node is traversed in reversed direction, the node `name` is prefixed by a `-`-symbol.
101110
```javascript
102-
var paths = [
103-
{id: 0, sequence: ["A", "B", "C"]},
104-
{id: 1, sequence: ["A", "-C", "-B"]},
105-
{id: 2, sequence: ["A", "C"]}
111+
const paths = [
112+
{ id: 0, name: 'Track 1', sequence: ['A', 'B', 'C'] },
113+
{ id: 1, name: 'Track 2', sequence: ['A', '-B', 'C'] },
114+
{ id: 2, name: 'Track 3', sequence: ['A', 'C'] },
106115
];
107116
```
108117

@@ -113,4 +122,4 @@ vg view -j filename.vg >filename.json
113122
JSON files generated in such a way can be parsed and displayed by the demo at [https://wolfib.github.io/sequenceTubeMap/](https://wolfib.github.io/sequenceTubeMap/).
114123

115124
## License
116-
Copyright (c) 2016 Wolfgang Beyer, licensed under the MIT License.
125+
Copyright (c) 2017 Wolfgang Beyer, licensed under the MIT License.

app/index.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="utf-8">
55
<meta name="description" content="">
66
<meta name="viewport" content="width=device-width, initial-scale=1">
7-
<title>sequenceTubeMap.js Demo</title>
7+
<title>Sequence Tube Map Demo</title>
88

99
<link rel="apple-touch-icon" href="apple-touch-icon.png">
1010
<!-- Place favicon.ico in the root directory -->
@@ -16,7 +16,7 @@
1616
<!-- endbuild -->
1717

1818
<!-- build:css styles/main.css -->
19-
<link rel="stylesheet" href="styles/tube-maps.css">
19+
<link rel="stylesheet" href="styles/tubemap.css">
2020
<!-- endbuild -->
2121

2222
</head>
@@ -189,7 +189,7 @@ <h4>Display Options</h4>
189189

190190
<!-- build:js scripts/main.js -->
191191
<!--<script src="scripts/main.js"></script>-->
192-
<script src="scripts/bundle.js"></script>
192+
<script src="scripts/main.bundle.js"></script>
193193
<!-- endbuild -->
194194
<!--<script src="exampleData/cactus-data.js"></script>-->
195195
</body>

app/miniExample.html

+12-26
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,19 @@
11
<!DOCTYPE html>
22
<html>
33
<head>
4-
<title>sequenceTubeMap.js Minimal Example</title>
5-
<script type="text/javascript" src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
6-
<script src="sequenceTubeMap.js"></script>
7-
<link rel="stylesheet" type="text/css" href="sequenceTubeMapStyle.css">
4+
<title>Sequence Tube Map Minimal Example</title>
5+
<link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.css" />
6+
<link rel="stylesheet" href="styles/tubemap.css">
87
</head>
98
<body>
10-
<p>A minimal example created with sequenceTubeMap.js:</p>
11-
<div id="chart"></div>
12-
13-
<script type="text/javascript">
14-
15-
var nodes = [
16-
{name: "A", width: 1},
17-
{name: "B", width: 2},
18-
{name: "C", width: 3}
19-
];
20-
21-
var paths = [
22-
{id: 0, sequence: ["A", "B", "C"]},
23-
{id: 1, sequence: ["A", "B", "C"]},
24-
{id: 2, sequence: ["A", "C"]}
25-
];
26-
27-
var svg = d3.select("#chart").append("svg");
28-
sequenceTubeMap.setNodeWidthOption(0);
29-
sequenceTubeMap.create(svg, nodes, paths);
30-
31-
</script>
9+
<p>A minimal example created with the Sequence Tube Maps JavaScript Module:</p>
10+
<div id="legendDiv"></div>
11+
<div id="chart">
12+
<svg id="svg">
13+
</svg>
14+
</div>
15+
<script src="/bower_components/jquery/dist/jquery.js"></script>
16+
<script src="/bower_components/d3/d3.js"></script>
17+
<script src="scripts/miniExample.bundle.js"></script>
3218
</body>
3319
</html>

app/scripts/miniExample.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import * as tubeMap from './tubemap';
2+
3+
const nodes = [
4+
{ name: 'A', seq: 'AAAA' },
5+
{ name: 'B', seq: 'TTG' },
6+
{ name: 'C', seq: 'CC' },
7+
];
8+
9+
const paths = [
10+
{ id: 0, name: 'Track 1', sequence: ['A', 'B', 'C'] },
11+
{ id: 1, name: 'Track 2', sequence: ['A', '-B', 'C'] },
12+
{ id: 2, name: 'Track 3', sequence: ['A', 'C'] },
13+
];
14+
15+
tubeMap.create({
16+
svgID: '#svg',
17+
nodes,
18+
tracks: paths,
19+
});
20+
tubeMap.useColorScheme(0);

app/scripts/tubemap.js

+11-3
Original file line numberDiff line numberDiff line change
@@ -1517,6 +1517,8 @@ function generateSVGShapesFromPath() {
15171517
} else {
15181518
xStart = getReadXStart(track);
15191519
}
1520+
maxYCoordinate = Math.max(maxYCoordinate, yStart + track.width);
1521+
minYCoordinate = Math.min(minYCoordinate, yStart);
15201522

15211523
// middle of path
15221524
for (let i = 0; i < track.path.length; i += 1) {
@@ -2169,24 +2171,30 @@ export function vgExtractNodes(vg) {
21692171

21702172
// calculate node widths depending on sequence lengths and chosen calculation method
21712173
function generateNodeWidth() {
2174+
nodes.forEach((node) => {
2175+
if (!node.hasOwnProperty('sequenceLength')) {
2176+
node.sequenceLength = node.seq.length;
2177+
}
2178+
});
2179+
21722180
switch (config.nodeWidthOption) {
21732181
case 1:
21742182
nodes.forEach((node) => {
2175-
if (node.hasOwnProperty('sequenceLength')) node.width = (1 + (Math.log(node.sequenceLength) / Math.log(2)));
2183+
node.width = (1 + (Math.log(node.sequenceLength) / Math.log(2)));
21762184
node.pixelWidth = Math.round((node.width - 1) * 8.401);
21772185
});
21782186
break;
21792187
case 2:
21802188
nodes.forEach((node) => {
21812189
// if (node.hasOwnProperty('sequenceLength')) node.width = (1 + Math.log(node.sequenceLength) / Math.log(10));
21822190
// node.pixelWidth = Math.round((node.width - 1) * 8.401);
2183-
if (node.hasOwnProperty('sequenceLength')) node.width = (node.sequenceLength / 100);
2191+
node.width = (node.sequenceLength / 100);
21842192
node.pixelWidth = Math.round((node.width - 1) * 8.401);
21852193
});
21862194
break;
21872195
default:
21882196
nodes.forEach((node) => {
2189-
if (node.hasOwnProperty('sequenceLength')) node.width = node.sequenceLength;
2197+
node.width = node.sequenceLength;
21902198

21912199
// get width of node's text label by writing label, measuring it and removing label
21922200
svg.append('text')
File renamed without changes.

gulpfile.js

+20-13
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ const browserify = require('browserify');
99
const babelify = require('babelify');
1010
const buffer = require('vinyl-buffer');
1111
const source = require('vinyl-source-stream');
12+
const rename = require('gulp-rename');
13+
const es = require('event-stream');
1214

1315
const $ = gulpLoadPlugins();
1416
const reload = browserSync.reload;
@@ -25,19 +27,22 @@ gulp.task('styles', () => {
2527
});
2628

2729
gulp.task('scripts', () => {
28-
// return gulp.src('app/scripts/**/*.js')
29-
30-
const b = browserify({
31-
entries: 'app/scripts/main.js',
32-
transform: babelify,
33-
debug: true,
34-
//alt// noParse: ['/Users/wolfgang/Dropbox/Websites/webappES6/app/scripts/cactus-data.js'],
35-
//exclude: [require.resolve('./app/scripts/cactus-data.js')],
36-
});
37-
// console.log(require.resolve('./app/scripts/cactus-data.js'));
38-
39-
return b.bundle()
40-
.pipe(source('bundle.js'))
30+
const files = [
31+
'app/scripts/main.js',
32+
'app/scripts/miniExample.js'
33+
];
34+
35+
const tasks = files.map((entry) => {
36+
return browserify({
37+
entries: [entry],
38+
transform: babelify,
39+
debug: true,
40+
})
41+
.bundle()
42+
.pipe(source(entry.substr(entry.lastIndexOf('/') + 1)))
43+
.pipe(rename({
44+
extname: '.bundle.js',
45+
}))
4146
.pipe($.plumber())
4247
// .pipe($.sourcemaps.init())
4348
// .pipe($.babel())
@@ -46,6 +51,8 @@ gulp.task('scripts', () => {
4651
.pipe($.sourcemaps.write('.'))
4752
.pipe(gulp.dest('.tmp/scripts'))
4853
.pipe(reload({ stream: true }));
54+
});
55+
return es.merge.apply(null, tasks);
4956
});
5057

5158
function lint(files, options) {

package.json

+21-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
"dependencies": {
1515
"body-parser": "^1.15.2",
1616
"cors": "^2.8.1",
17-
"express": "^4.14.0"
17+
"event-stream": "^3.3.4",
18+
"express": "^4.14.0",
19+
"gulp-rename": "^1.2.2"
1820
},
1921
"devDependencies": {
2022
"babel-core": "^6.4.0",
@@ -59,16 +61,30 @@
5961
},
6062
"extends": "airbnb",
6163
"rules": {
62-
"quotes": [2, "single"],
63-
"no-use-before-define": ["error", { "functions": false, "variables": true }],
64-
"no-mixed-operators": ["error", {"allowSamePrecedence": true}]
64+
"quotes": [
65+
2,
66+
"single"
67+
],
68+
"no-use-before-define": [
69+
"error",
70+
{
71+
"functions": false,
72+
"variables": true
73+
}
74+
],
75+
"no-mixed-operators": [
76+
"error",
77+
{
78+
"allowSamePrecedence": true
79+
}
80+
]
6581
},
6682
"parserOptions": {
6783
"ecmaVersion": 6,
6884
"sourceType": "module"
6985
},
7086
"globals": {
71-
"d3": true
87+
"d3": true
7288
}
7389
}
7490
}

0 commit comments

Comments
 (0)