Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • mdm-lab/wiki
  • hvaysset/wiki
  • jsousa/wiki
  • tclabby/wiki
4 results
Show changes
Commits on Source (6)
---
layout: article
navigation:
---
# test
\ No newline at end of file
......@@ -7,6 +7,7 @@
"dependencies": {
"@observablehq/plot": "^0.6.11",
"@pinia/nuxt": "^0.4.11",
"d3": "^7.8.5",
"d3-dsv": "^3.0.1",
"d3-fetch": "^3.0.1",
"meilisearch": "^0.35.0",
......@@ -2661,7 +2662,8 @@
},
"node_modules/d3": {
"version": "7.8.5",
"license": "ISC",
"resolved": "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz",
"integrity": "sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA==",
"dependencies": {
"d3-array": "3",
"d3-axis": "3",
......
......@@ -20,6 +20,7 @@
"dependencies": {
"@observablehq/plot": "^0.6.11",
"@pinia/nuxt": "^0.4.11",
"d3": "^7.8.5",
"d3-dsv": "^3.0.1",
"d3-fetch": "^3.0.1",
"meilisearch": "^0.35.0",
......
<script setup lang="ts">
import * as d3 from "d3";
import { useDisplay } from 'vuetify'
import { useElementSize } from '@vueuse/core'
const { width } = useDisplay()
const height = ref(150)
const color = d3.scaleOrdinal([-1, 1], d3.schemeSet1);
const data = ref([
{ start: 20, end: 30, strand: 1, name: "toto" },
{ start: 40, end: 80, strand: -1, name: "tata moins" },
{ start: 38, end: 59, strand: 1, name: "tata plus" },
{ start: 65, end: 95, strand: 1, name: "foo" }
])
const gbContainer = ref(null)
const gbContainerWidth = ref(useElementSize(gbContainer, { width: 500, height: 0 }, { box: 'border-box' }).width)
const computedWidth = computed(() => {
return gbContainerWidth.value
})
const marginLeftGb = ref(10)
const marginRightGb = ref(10)
const marginBottomGb = ref(10)
const innerWidth = computed(() => {
return computedWidth.value - marginLeftGb.value - marginRightGb.value
})
const innerHeigth = computed(() => {
return height.value - marginBottomGb.value
})
const minRange = ref(0)
const maxRange = ref(innerWidth.value)
const svgRef = ref(null)
const domain = ref([0, 100])
// const range = ref()
const xScale = ref(d3.scaleLinear()
.domain(domain.value)
.range([minRange.value, maxRange.value])
);
const yScale = ref(d3.scaleLinear()
.domain([-1, 1])
.range([0, innerHeigth.value]));
const computedData = computed(() => {
const newData = data.value.filter(gene => {
const { start, end } = gene
const [scaleStart, scaleEnd] = xScale.value.domain()
return start <= scaleEnd || end >= scaleStart
}).map(gene => {
const width = xScale.value(gene.end) - xScale.value(gene.start)
const height = yScale.value(-0.5)
const x = xScale.value(gene.start) + marginLeftGb.value
const y = gene.strand < 0 ? yScale.value(0.25) - marginBottomGb.value : yScale.value(-0.75) - marginBottomGb.value
return {
...gene,
width,
height,
x,
y
}
})
return newData
})
function drawGene({ width, height, strand }) {
const context = d3.path()
const halfHeight = height / 2
const isWidthLonger = halfHeight < width
if (strand < 0) {
context.moveTo(0, halfHeight)
if (isWidthLonger) context.lineTo(halfHeight, 0)
context.lineTo(width, 0)
context.lineTo(width, height)
if (isWidthLonger) context.lineTo(halfHeight, height)
context.closePath()
} else {
context.moveTo(0, 0)
if (isWidthLonger) context.lineTo(width - halfHeight, 0)
context.lineTo(width, halfHeight)
if (isWidthLonger) context.lineTo(width - halfHeight, height)
context.lineTo(0, height)
context.closePath()
}
return context
}
function positionText(selection) {
selection.each(function (d) {
const textWidth = this.clientWidth
if (textWidth >= d.width - 10) {
d3.select(this)
.text('')
} else {
const halfW = d.width / 2
const halfTw = textWidth / 2
const k = d.height / 8
const x = d.strand > 0 ? halfW - halfTw - k : halfW - halfTw + k
d3.select(this)
.attr("transform", `translate(${x},${d.height / 2})`)
}
})
}
function drawGenes(genesSelection) {
genesSelection
.selectAll("g.gene") // get all "existing" lines in svg
.data(computedData.value) // sync them with our data
.join(
enter => {
const g = enter.append("g")
.classed("gene", true);
g.append("path")
g.append("text")
// .attr("fill", "white")
.attr("fill", "currentColor")
.attr("dominant-baseline", "middle")
g.append("title")
},
update => {
update
.attr("transform", d => `translate(${d.x},${d.y})`)
update.select("path").attr("d", d => drawGene(d).toString()).attr("fill", d => color(d.strand))
update.select("title").text(d => d.name)
update.select("text").attr("transform", d => `translate(${5},${d.height / 2})`).text(d => d.name).call(positionText)
},
exit => exit.remove()
)
}
function draw() {
const svg = d3.select(svgRef.value);
const zoom = d3.zoom()
.scaleExtent([0.5, 32])
.on("zoom", zoomed);
const xAxis = d3.axisBottom(xScale.value)
let gx = svg.select("g.xaxis")
if (gx.empty()) {
gx = svg.append("g").classed("xaxis", true)
}
gx
.attr("transform", `translate(${marginLeftGb.value},${height.value - 18})`)
.call(xAxis)
let gGenes = svg.select("g.genes")
if (gGenes.empty()) {
gGenes = svg.append("g").classed("genes", true)
}
gGenes.call(drawGenes, xScale, yScale)
svg.call(zoom).call(zoom.transform, d3.zoomIdentity);
function zoomed(event) {
const { transform } = event
const zx = transform.rescaleX(xScale.value);
domain.value = zx.domain()
minRange.value = zx.range()[0]
maxRange.value = zx.range()[1]
}
}
onMounted(() => {
console.log(gbContainer.value)
draw()
})
watchEffect(() => {
xScale.value = d3.scaleLinear()
.domain(domain.value) // input values...
.range([minRange.value, innerWidth.value])
draw()
})
</script>
<template>
<div ref="gbContainer">
<v-card title="D3 GB">
<svg ref="svgRef" :width="computedWidth" :height="height">
<g class="x-axis" />
</svg>
</v-card>
</div>
</template>
\ No newline at end of file
<script setup lang="ts">
import { csv as d3Csv } from 'd3-fetch';
import { csvParse } from 'd3-dsv'
import * as Plot from "@observablehq/plot";
import PlotFigure from "~/components/PlotFigure";
import { useDisplay } from "vuetify";
......