Skip to content

Commit e305101

Browse files
committed
initial commit
1 parent d86551e commit e305101

File tree

7 files changed

+290
-50
lines changed

7 files changed

+290
-50
lines changed

.npmignore

Whitespace-only changes.

README.md

+43-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,50 @@
1-
# Genomic mutation lollipops
1+
<h1 align="center">
2+
G3-lollipop
3+
</h1>
24

3-
[demo1](https://bl.ocks.org/phoeguo/583a12e04c6b9d7ca1825cdbdc62f531)
5+
<h4 align="center" color="bluesteel">
6+
Easily generate interactive lollipop-style diagram to visulize genomic mutation data.
7+
</h4>
48

59
## Introduction
610

11+
G3-lollipop is a component of G3 (Gene|Genome|Genetics) javascirpt library, which generates an interactive lollipop-style diagram to visualize genomic mutation data.
12+
13+
### Quick start
14+
15+
Add library
16+
```html
17+
<link rel="stylesheet" href="https://g3js.github.io/lollipop/assets/css/g3-styles.min.css">
18+
<script src="https://d3js.org/d3.v4.min.js"></script>
19+
<script src="https://g3js.github.io/lollipop/assets/js/g3-lollipop.min.js"></script>
20+
21+
<svg></svg>
22+
```
23+
add lollipop chart
24+
25+
```javascript
26+
// new lollipop chart
27+
lollipop = g3.Lollipop("svg");
28+
29+
// add data
30+
lollipop.data.snvData = snvData;
31+
lollipop.data.domainData = domainData;
32+
33+
lollipop.draw(snvOpt, domainOpt);
34+
```
35+
36+
### Demo
37+
[Live demo](https://bl.ocks.org/phoeguo/583a12e04c6b9d7ca1825cdbdc62f531)
38+
39+
![Screenshot](./docs/assets/img/screenshot1.png)
740

841
## Features
42+
- Pop types: pie or circle
43+
- Rich chart options
44+
- Interactive chart legend
45+
- Zoom-in and zoom-out (using mouse or brush)
46+
- Label variation annotation (by clicking pops)
47+
- Save lollipop-plot in SVG or PNG format
48+
- Over 20 color schemes
949

50+
# Options

docs/assets/img/screenshot1.png

180 KB
Loading

package.json

+1-3
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,13 @@
2828
"dependencies": {
2929
"blob": "0.0.4",
3030
"d3": "^4.12.0",
31-
"file-saver": "git+https://github.com/eligrey/FileSaver.js.git",
32-
"xml-js": "^1.6.4"
31+
"file-saver": "git+https://github.com/eligrey/FileSaver.js.git"
3332
},
3433
"devDependencies": {
3534
"eslint": "4",
3635
"package-preamble": "0.1.0",
3736
"rollup": "^0.52.0",
3837
"rollup-plugin-node-resolve": "^3.3.0",
39-
"tape": "4",
4038
"uglify-es": "github:mishoo/UglifyJS2#harmony",
4139
"uglifycss": "0.0.29"
4240
}

test/lollipop_options.html

+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<link rel="shortcut icon" href="../favicon.ico">
6+
<link rel="stylesheet" media="screen" href="../css/style.min.css" />
7+
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4"
8+
crossorigin="anonymous">
9+
<style>
10+
.warp {
11+
margin-left: 40px;
12+
}
13+
14+
#svg-panel {
15+
border: 1px solid grey;
16+
}
17+
18+
.console {
19+
display: block;
20+
width: 900px;
21+
height: 200px;
22+
margin: 10px 0px;
23+
background-color: rgb(233, 233, 233);
24+
color: #4d4d4d;
25+
overflow-y: scroll;
26+
padding: 10px;
27+
font: normal 12px Arial;
28+
}
29+
</style>
30+
</head>
31+
32+
<body>
33+
<div class="wrap">
34+
<div id="ctrl-panel">
35+
<span class="btn-group">
36+
<button id="save-as-png">save PNG</button>
37+
<button id="save-as-svg">save SVG</button>
38+
<button id="next">Start</button>
39+
</span>
40+
</div>
41+
42+
<div class="console" id="info">
43+
</div>
44+
45+
<div id="plot-panel">
46+
<svg id="svg-panel">
47+
</svg>
48+
</div>
49+
</div>
50+
51+
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
52+
crossorigin="anonymous"></script>
53+
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js" integrity="sha384-cs/chFZiN24E4KMATLdqdvsezGxaGsi4hLGOzlXwp5UZB1LY//20VyM2taTB4QvJ"
54+
crossorigin="anonymous"></script>
55+
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm"
56+
crossorigin="anonymous"></script>
57+
58+
<script src="https://d3js.org/d3.v4.min.js"></script>
59+
<script src="../dist/g3-lollipop.min.js"></script>
60+
<script>
61+
var snvFile = "../data/snv/TP53-msk_impact_2017-parsed.tsv";
62+
var domainFile = "../data/domain/TP53_pfam.json";
63+
64+
var snvOpt = {
65+
x: "AA_Position",
66+
y: "Protein_Change",
67+
factor: "Mutation_Class",
68+
};
69+
70+
var domainOpt = {
71+
symbol: "hgnc_symbol",
72+
name: "protein_name",
73+
length: "length",
74+
domainType: "pfam",
75+
details: {
76+
start: "pfam_start",
77+
end: "pfam_end",
78+
ac: "pfam_ac",
79+
name: "pfam_id",
80+
},
81+
};
82+
83+
var q = d3.queue();
84+
q.defer(d3.tsv, snvFile);
85+
q.defer(d3.json, domainFile);
86+
87+
q.await(function (error, snvData, domainData) {
88+
snvData.forEach(function (d) {
89+
d[snvOpt.x] = +d[snvOpt.x];
90+
});
91+
92+
lollipop = g3.Lollipop("svg", "pie", 800);
93+
lollipop.data.snvData = snvData;
94+
lollipop.data.domainData = domainData;
95+
96+
next_btn.onclick = function (e) {
97+
if (idx == 0) {
98+
next_btn.innerHTML = "Next";
99+
}
100+
101+
if (idx < len_col) {
102+
lollipop.options.domainColorScheme = g3.scaleOrdinal(cols[idx]);
103+
lollipop.refresh(snvOpt, domainOpt);
104+
info = "Test " + (idx + 1) + "/" + len_col + ": color scheme = " +
105+
"<span style = \"color:firebrick;font-weight: bold;\">" + cols[idx] + "</span><br>";
106+
107+
info_box.innerHTML += info;
108+
info_box.scrollTop = info_box.scrollHeight;
109+
110+
idx++;
111+
if (idx == len_col) {
112+
next_btn.innerHTML = "Done";
113+
next_btn.disabled = true;
114+
}
115+
}
116+
};
117+
118+
document.getElementById("save-as-png").onclick = function (e) {
119+
g3.output("svg").toPNG('out_png');
120+
};
121+
122+
document.getElementById("save-as-svg").onclick = function (e) {
123+
g3.output('svg').toSVG('out_svg');
124+
};
125+
});
126+
</script>
127+
</body>
128+
129+
</html>

test/min_test.html

-45
This file was deleted.

test/test_data.html

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<link rel="shortcut icon" href="../favicon.ico">
6+
<link rel="stylesheet" media="screen" href="../css/style.min.css" />
7+
<style>
8+
.warp {
9+
margin-left: 40px;
10+
}
11+
12+
#svg-panel {
13+
border: 2px solid black;
14+
}
15+
</style>
16+
</head>
17+
18+
<body>
19+
<div class="wrap">
20+
<div id="ctrl-panel">
21+
<span class="btn-group">
22+
<button id="save-as-png">Save PNG</button>
23+
<button id="save-as-svg">Save SVG</button>
24+
<button id="next">Start</button>
25+
</span>
26+
</div>
27+
28+
<div class="console" id="info">
29+
</div>
30+
31+
<div id="plot-panel">
32+
<svg id="svg-panel">
33+
</svg>
34+
</div>
35+
</div>
36+
37+
<script src="https://d3js.org/d3.v4.min.js"></script>
38+
<script src="../dist/g3-lollipop.min.js"></script>
39+
<script>
40+
function csv2json(tsv, sep, header) {
41+
sep = sep || "\t";
42+
43+
if (header == undefined || header == null) {
44+
header = true;
45+
}
46+
47+
var result = [],
48+
headers = [];
49+
var lines = tsv.split("\n");
50+
if (lines[lines.length - 1] == "") {
51+
lines.pop();
52+
}
53+
54+
if (header) {
55+
headers = lines[0].split(sep);
56+
lines.shift();
57+
}
58+
59+
for (var i = 0; i < lines.length; i++) {
60+
var obj = {};
61+
var curLine = lines[i].split(sep);
62+
63+
if (header) {
64+
for (var j = 0; j < headers.length; j++) {
65+
obj[headers[j]] = curLine[j] || "";
66+
}
67+
} else {
68+
for (var j = 0; j < curLine.length; j++) {
69+
obj["V" + j] = curLine[j];
70+
}
71+
}
72+
73+
result.push(obj);
74+
}
75+
76+
return JSON.stringify(result);
77+
}
78+
79+
function uniprot(symbol, callback) {
80+
var url = "https://www.uniprot.org/uniprot/?query=gene_exact:" +
81+
symbol +
82+
"+AND+organism:9606+AND+reviewed:yes\&columns=id,length\&format=tab";
83+
84+
fetch(url, {
85+
cache: 'default', // *default, no-cache, reload, force-cache, only-if-cached
86+
method: 'GET',
87+
"Content-type": "text/plain",
88+
})
89+
.then(function (res) {
90+
if (res.status == 200) {
91+
return res.text();
92+
} else {
93+
console.log("something error code [" + res.status + "]");
94+
return "";
95+
}
96+
})
97+
.then(function (text) {
98+
return callback? callback(csv2json(text)) : csv2json(text);
99+
})
100+
}
101+
102+
function uniprot2(symbol){
103+
}
104+
105+
var _symbol = "tp53";
106+
107+
d3.queue()
108+
.defer(uniprot, _symbol)
109+
.await(function (error, json) {
110+
if (error) throw error;
111+
console.log("here");
112+
console.log(json);
113+
});
114+
</script>
115+
</body>
116+
117+
</html>

0 commit comments

Comments
 (0)