mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-09-27 22:48:12 +08:00
joyplots working
This commit is contained in:
@@ -3,16 +3,55 @@ import _ from "lodash";
|
||||
import cells from "../../../data/GBM_metadata.js";
|
||||
import drawParallelCoordinates from "./drawParallelCoordinates";
|
||||
import createContinuousRanges from "./createContinuousRanges";
|
||||
import styles from './parallelCoordinates.css';
|
||||
|
||||
const Continuous = () => {
|
||||
import {
|
||||
margin,
|
||||
width,
|
||||
height
|
||||
} from "./util";
|
||||
|
||||
drawParallelCoordinates(cells)
|
||||
class Continuous extends React.Component {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h3> Continuous Metadata </h3>
|
||||
</div>
|
||||
)
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
ctx: null,
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
drawParallelCoordinates(cells)
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div id="parcoords_wrapper" style={{marginTop: 50}}>
|
||||
<h3> Continuous Metadata </h3>
|
||||
<div style={{marginBottom: 30}}>
|
||||
Color By:
|
||||
<button style={{marginLeft: 10}}>Cluster_2d_color</button>
|
||||
<button style={{marginLeft: 10}}>Cluster_CNV_color</button>
|
||||
<button style={{marginLeft: 10}}>Location.color</button>
|
||||
<button style={{marginLeft: 10}}>Sample.name.color</button>
|
||||
<button style={{marginLeft: 10}}>Sample.type.color</button>
|
||||
<button style={{marginLeft: 10}}>Selection.color</button>
|
||||
<button style={{marginLeft: 10}}>housekeeping_cluster_color</button>
|
||||
<button style={{marginLeft: 10}}>recluster_myeloid</button>
|
||||
<button style={{marginLeft: 10}}>recluster_myeloid_color</button>
|
||||
</div>
|
||||
<div
|
||||
className={styles.parcoords}
|
||||
id="parcoords"
|
||||
style={{
|
||||
width: width + margin.left + margin.right + "px",
|
||||
height: height + margin.top + margin.bottom + "px"
|
||||
}}></div>
|
||||
<pre id="parcoords_output" className={styles.pre}></pre>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
export default Continuous;
|
||||
|
||||
@@ -112,10 +112,7 @@ const drawParallelCoordinates = (data) => {
|
||||
******************************************
|
||||
******************************************/
|
||||
|
||||
var container = d3.select("body").append("div")
|
||||
.attr("class", "parcoords")
|
||||
.style("width", width + margin.left + margin.right + "px")
|
||||
.style("height", height + margin.top + margin.bottom + "px");
|
||||
var container = d3.select("#parcoords")
|
||||
|
||||
var svg = container.append("svg")
|
||||
.attr("width", width + margin.left + margin.right)
|
||||
@@ -131,18 +128,19 @@ const drawParallelCoordinates = (data) => {
|
||||
.style("margin-top", margin.top + "px")
|
||||
.style("margin-left", margin.left + "px");
|
||||
|
||||
|
||||
var ctx = canvas.node().getContext("2d");
|
||||
ctx.globalCompositeOperation = 'darken';
|
||||
ctx.globalAlpha = 0.15;
|
||||
ctx.lineWidth = 1.5;
|
||||
ctx.scale(devicePixelRatio, devicePixelRatio);
|
||||
|
||||
var output = d3.select("body").append("pre");
|
||||
var output = d3.select("#parcoords_output");
|
||||
|
||||
var axes = svg.selectAll(".axis")
|
||||
var axes = svg.selectAll(".parcoords_axis")
|
||||
.data(dimensions)
|
||||
.enter().append("g")
|
||||
.attr("class", "axis")
|
||||
.attr("class", `${styles.axis} parcoords_axis`)
|
||||
.attr("transform", function(d,i) { return "translate(" + xscale(i) + ")"; });
|
||||
|
||||
/*****************************************
|
||||
@@ -196,7 +194,8 @@ const drawParallelCoordinates = (data) => {
|
||||
|
||||
*/
|
||||
|
||||
ctx.strokeStyle = d["Cluster_2d_color"]; //"rgba(0,0,0,.4)" /* color(d.food_group); */
|
||||
ctx.strokeStyle = d["Sample.name.color"];
|
||||
// ctx.strokeStyle = "rgba(180,180,180,.4)";
|
||||
ctx.beginPath();
|
||||
var coords = project(d);
|
||||
coords.forEach((p,i) => {
|
||||
@@ -240,9 +239,8 @@ const drawParallelCoordinates = (data) => {
|
||||
render.invalidate();
|
||||
|
||||
var actives = [];
|
||||
svg.selectAll(".axis .brush")
|
||||
svg.selectAll(".parcoords_axis .parcoords_brush")
|
||||
.filter(function (d) {
|
||||
console.log('this', this)
|
||||
return d3.brushSelection(this);
|
||||
})
|
||||
.each(function(d) {
|
||||
@@ -263,12 +261,14 @@ const drawParallelCoordinates = (data) => {
|
||||
}
|
||||
});
|
||||
|
||||
/* Reset canvas */
|
||||
ctx.clearRect(0,0,width,height);
|
||||
ctx.globalAlpha = d3.min([0.85/Math.pow(selected.length,0.3),1]);
|
||||
|
||||
/* pass the result of the filter above to a fresh canvas, using RAF */
|
||||
render(selected);
|
||||
|
||||
output.text(d3.tsvFormat(selected.slice(0,24)));
|
||||
// console.log('fires brush', actives)
|
||||
output.text(d3.tsvFormat(selected.slice(0,22)));
|
||||
}
|
||||
|
||||
function brushstart() {
|
||||
@@ -297,13 +297,13 @@ const drawParallelCoordinates = (data) => {
|
||||
d3.select(this).call(renderAxis);
|
||||
})
|
||||
.append("text")
|
||||
.attr("class", "title")
|
||||
.attr("class", styles.title)
|
||||
.attr("text-anchor", "start")
|
||||
.text(function(d) { return "description" in d ? d.description : d.key; });
|
||||
|
||||
// Add and store a brush for each axis.
|
||||
axes.append("g")
|
||||
.attr("class", "brush")
|
||||
.attr("class", `${styles.brush} parcoords_brush`)
|
||||
.each(function(d) {
|
||||
d3.select(this).call(d.brush = d3.brushY()
|
||||
.extent([[-10,0], [10,height]])
|
||||
@@ -316,7 +316,7 @@ const drawParallelCoordinates = (data) => {
|
||||
.attr("x", -8)
|
||||
.attr("width", 16);
|
||||
|
||||
output.text(d3.tsvFormat(data.slice(0,24)));
|
||||
output.text(d3.tsvFormat(data.slice(0,22)));
|
||||
|
||||
function project(d) {
|
||||
return dimensions.map(function(p,i) {
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
|
||||
This code can be found: https://bl.ocks.org/syntagmatic/05a5b0897a48890133beb59c815bd953
|
||||
|
||||
body {
|
||||
min-width: 760px;
|
||||
}
|
||||
*/
|
||||
|
||||
.parcoords {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.parcoords svg,
|
||||
.parcoords canvas {
|
||||
font: 10px sans-serif;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.parcoords canvas {
|
||||
opacity: 0.9;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.axis .title {
|
||||
font-size: 10px;
|
||||
transform: rotate(-21deg) translate(-5px,-6px);
|
||||
fill: #222;
|
||||
}
|
||||
|
||||
.axis line,
|
||||
.axis path {
|
||||
fill: none;
|
||||
stroke: #ccc;
|
||||
stroke-width: 1px;
|
||||
}
|
||||
|
||||
.axis .tick text {
|
||||
fill: #222;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/*
|
||||
old, from reference bl.ocks
|
||||
.axis.manufac_name .tick text,
|
||||
.axis.food_group .tick text {
|
||||
opacity: 1;
|
||||
}
|
||||
*/
|
||||
|
||||
.axis:hover line,
|
||||
.axis:hover path,
|
||||
.axis.active line,
|
||||
.axis.active path {
|
||||
fill: none;
|
||||
stroke: #222;
|
||||
stroke-width: 1px;
|
||||
}
|
||||
|
||||
.axis:hover .title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.axis:hover .tick text {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.axis.active .title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.axis.active .tick text {
|
||||
opacity: 1;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.brush .extent {
|
||||
fill-opacity: .3;
|
||||
stroke: #fff;
|
||||
stroke-width: 1px;
|
||||
}
|
||||
|
||||
.pre {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
margin: 6px 12px;
|
||||
tab-size: 40;
|
||||
font-size: 10px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
export const margin = {top: 66, right: 110, bottom: 20, left: 188};
|
||||
export const width = document.body.clientWidth - margin.left - margin.right;
|
||||
const paddingRight = 120;
|
||||
|
||||
export const margin = {top: 66, right: 110, bottom: 20, left: 60};
|
||||
export const width = document.body.clientWidth - margin.left - margin.right - paddingRight;
|
||||
export const height = 340 - margin.top - margin.bottom;
|
||||
export const innerHeight = height - 2;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user