Skip to content

Commit

Permalink
move axes in separated file and complet axe document
Browse files Browse the repository at this point in the history
  • Loading branch information
nicgirault committed Mar 11, 2017
1 parent eaf9bcd commit 0dcb9e8
Show file tree
Hide file tree
Showing 9 changed files with 300 additions and 84 deletions.
18 changes: 18 additions & 0 deletions demo/axes/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang='en'>

<head>
<title>circosJS</title>
<meta charset='utf-8'></meta>
<script src='../../dist/circos.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/d3-queue/3.0.3/d3-queue.js'></script>
</head>

<body>
<div id='chart1'></div>
<div id='chart2'></div>
<div id='chart3'></div>
<script src='./index.js'></script>
</body>
</html>
96 changes: 96 additions & 0 deletions demo/axes/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
var main = function(error, snp250) {

snp250 = snp250
.filter(function (d) {
return d.chromosome === 'chr2'
})
.map(function (d) {
return {
block_id: d.chromosome,
position: (parseInt(d.start) + parseInt(d.end)) / 2,
value: d.value
}
})

buildCircos('#chart1', snp250, [
{
color: 'red',
position: 0.002
},
{
color: 'green',
position: 0.013
}
])

buildCircos('#chart2', snp250, [
{
color: '#333333',
spacing: 0.001,
opacity: 0.3,
}
])

buildCircos('#chart3', snp250, [
{
color: 'red',
opacity: 0.3,
spacing: 0.001,
end: 0.004
},
{
color: 'green',
opacity: 0.3,
spacing: 0.001,
start: 0.011
},
{
color: '#333333',
opacity: 0.3,
spacing: 0.002,
thickness: 2,
start: 0.004,
end: 0.011
},
{
color: '#333333',
opacity: 0.3,
spacing: 0.001,
thickness: 1,
start: 0.004,
end: 0.011
}
])
}

var buildCircos = function (container, snp250, axes) {
var circos = new Circos({
container: container,
width: 1000,
height: 1000
})

circos
.layout(
[{id: "chr2", color: '#03a9f4', len:243199373}],
{
innerRadius: 400,
outerRadius: 400,
labels: {display: false},
ticks: {display: false}
}
)
.line('snp-250', snp250, {
innerRadius: 0.5,
outerRadius: 0.8,
min: 0,
max: 0.015,
color: '#222222',
axes: axes,
})
.render()
}

d3.queue()
.defer(d3.csv, '../data/snp.density.250kb.txt')
.await(main)
Binary file added doc/axes-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/axes-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/axes-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
93 changes: 93 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
- [Scatter](#scatter)
- [Stack](#stack)
- [Text](#text)
- [Colors](#colors)
- [Axes](#axes)

## Introduction

Expand Down Expand Up @@ -519,7 +521,98 @@ The default min and max values are computed according to the dataset. You can ov

## Axes

To render axes on a track, you can specify an `axes` attribute in the configuration. By default, the value of this attribute is an empty array:

```javascript
{
axes: []
}
```

You can add items to this array to render an axis or a group of axes. You can give axes a `color` (default: '#d3d3d3'), `thickness` (default: 1) and `opacity` (default: track opacity):

```javascript
{
axes: [
{
color: 'black',
thickness: 2, // in pixel
opacity: 0.3 // between 0 and 1
}
]
}
```

Then you have to specify where to place the axes.

You can either define single axis by defining a `position` attribute with a value between the min and max value of the track:

```javascript
{
axes: [
{
color: 'red',
position: 4
},
{
color: 'green',
position: 15
}
]
}
```

<p align="center">
<img src="doc/axes-1.png" width="60%" alt="axes-1">
<br/>
<i><a href="demo/axes">source</a></i>
</p>


Or define a range of axes with a `spacing` attribute and optionnally a `start` and `end` attributes.

<p align="center">
<img src="doc/axes-2.png" width="60%" alt="axes-2">
<br/>
<i><a href="demo/axes">source</a></i>
</p>

Here is an advanced example:

```javascript
{
axes: [
{
color: 'red',
spacing: 2,
end: 4
},
{
color: 'green',
spacing: 2,
start: 16
},
{
spacing: 2,
start: 4,
end: 16,
thickness: 2
},
{
spacing: 1,
start: 4,
end: 16,
thickness: 1
}
]
}
```

<p align="center">
<img src="doc/axes-3.png" width="60%" alt="axes-3">
<br/>
<i><a href="demo/axes">source</a></i>
</p>

## Radius

Expand Down
74 changes: 74 additions & 0 deletions src/axes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import range from 'lodash/range'
import reduce from 'lodash/reduce'
import {arc} from 'd3-shape'

const buildAxesData = (conf) => {
return reduce(conf.axes, (aggregator, axesGroup) => {
if (axesGroup.position) {
aggregator.push({
value: axesGroup.position,
thickness: axesGroup.thickness || 1,
color: axesGroup.color || '#d3d3d3',
opacity: axesGroup.opacity || conf.opacity
})
}
if (axesGroup.spacing) {
const builtAxes = range(
axesGroup.start || conf.cmin,
axesGroup.end || conf.cmax,
axesGroup.spacing
)
.map((value) => {
return {
value: value,
thickness: axesGroup.thickness || 1,
color: axesGroup.color || '#d3d3d3',
opacity: axesGroup.opacity || conf.opacity
}
})
return aggregator.concat(builtAxes)
}
return aggregator
}, [])
}

export const renderAxes = (parentElement, conf, layout, scale) => {
const axes = buildAxesData(conf)

const axis = arc()
.innerRadius((d) => {
return conf.direction === 'in'
? conf.outerRadius - scale(d.value)
: conf.innerRadius + scale(d.value)
})
.outerRadius((d) => {
return conf.direction === 'in'
? conf.outerRadius - scale(d.value)
: conf.innerRadius + scale(d.value)
})
.startAngle(0)
.endAngle((d) => d.length)

return parentElement
.selectAll('.axis')
.data((blockData) => {
const block = layout.blocks[blockData.key]
return axes.map((d) => {
return {
value: d.value,
thickness: d.thickness,
color: d.color,
opacity: d.opacity,
block_id: blockData.key,
length: block.end - block.start
}
})
})
.enter()
.append('path')
.attr('opacity', (d) => d.opacity)
.attr('class', 'axis')
.attr('d', axis)
.attr('stroke-width', (d) => d.thickness)
.attr('stroke', (d) => d.color)
}
34 changes: 18 additions & 16 deletions src/tracks/Line.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,24 +90,26 @@ export default class Line extends Track {
}
}

const selection = parentElement.selectAll('.line')
.data((d) => conf.maxGap ? splitByGap(d.values, conf.maxGap) : [d.values])
.enter().append('g')
.attr('class', 'line')
const selection = parentElement
.selectAll('.line')
.data((d) => conf.maxGap ? splitByGap(d.values, conf.maxGap) : [d.values])
.enter()
.append('g')
.attr('class', 'line')
.append('path')
.datum((d) => {
return d.map((datum) => {
const height = this.scale(datum.value)
return assign(datum, {
angle: this.theta(datum.position, layout.blocks[datum.block_id])
}, buildRadius(height))
.datum((d) => {
return d.map((datum) => {
const height = this.scale(datum.value)
return assign(datum, {
angle: this.theta(datum.position, layout.blocks[datum.block_id])
}, buildRadius(height))
})
})
})
.attr('d', generator)
.attr('opacity', conf.opacity)
.attr('stroke-width', conf.thickness)
.attr('stroke', conf.colorValue)
.attr('fill', 'none')
.attr('d', generator)
.attr('opacity', conf.opacity)
.attr('stroke-width', conf.thickness)
.attr('stroke', conf.colorValue)
.attr('fill', 'none')

if (conf.fill) { selection.attr('fill', conf.fillColor) }

Expand Down
Loading

0 comments on commit 0dcb9e8

Please sign in to comment.