Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

An example of r2d3 with shiny dashboard? #1

Open
alptaciroglu opened this issue Aug 25, 2020 · 0 comments
Open

An example of r2d3 with shiny dashboard? #1

alptaciroglu opened this issue Aug 25, 2020 · 0 comments

Comments

@alptaciroglu
Copy link

Hey, thanks for your work! I am trying to fit an "SVG" image into my shiny app but the plot is not in the intended place. I tried to solve this issue so far unsuccessfully. I would really appreciate it if you could help.

A very similar problem to mine is posted to the r2d3 GitHub issues page but there is no official answer. rstudio/r2d3#61

Here is a minimally reproducible example from my code.

server.R

shinyServer(function(input, output, session) {

output$d3 <- r2d3::renderD3({
  r2d3::r2d3(data = datd3,
       script = "code.js", options = list(r2d3.shadow = FALSE) 
  )
})

})

ui.R

library(r2d3)
library(rjson)

datd3 <<- rjson::fromJSON(file = 'data.json')

ui <- fluidPage(
    mainPanel(
      tabPanel(id = 'sumPanel', 'Summary',
                       wellPanel(
                         fluidRow(
                           column(12,
                                  div(style = 'overflow-y: scroll; overflow-x: scroll;', d3Output("d3"))
                           )
                         )
                       )
    ))
)

code.js

// Constants 
let kSvgHeight = 100
let kBackboneHeight = 10
let kDomainHeight = 40
let kDomainStrokeWidth = 3
let kPartialPixel = 3
let kTransmembraneHeight = 50
let kCoilsHeight = 45
let kLcrHeight = 45
let kUpHeight = 35
let kDomainTextMargin = 5
let kNameLengthToPixelFactor = 10
let kFontFamily = "Verdana"
let kFontSize = 12
let domainColors = {
  "domain": "rgb(255,255,255,0.8)",
  "domainStroke": "rgb(0,0,0,0.8)",
  "tm": "rgb(100,100,100,0.7)",
  "coils": "rgb(46,139,87,0.7)",
  "lcr": "rgb(199,21,133,0.7)",
  "uppin": "rgb(46,139,87,0.7)"

}

// Computed constants
let kMiddleY = kSvgHeight / 2
let kBackboneYstart = kMiddleY - (kBackboneHeight / 2)
let kDomainYstart = kMiddleY - (kDomainHeight / 2)
let kDomainYend = kMiddleY + (kDomainHeight / 2)
let kTransmembraneYstart = kMiddleY - (kTransmembraneHeight / 2)
let kCoilsYstart = kMiddleY - (kCoilsHeight / 2)
let kLcrYstart = kMiddleY - (kLcrHeight / 2)
let kUpYstart = kMiddleY - kDomainHeight

let Xscale = 1.0


function domainBorder(d, coverage = '[]') {
  partialPixelLeft = coverage[0] === '[' ? 0 : kPartialPixel
  partialPixelRight = coverage[1] === ']' ? 0 : kPartialPixel
  let kQuarterDomainHeight = kDomainHeight / 4

  pathList = [{
      "x": d.start,
      "y": kDomainYstart
    },
    {
      "x": d.end,
      "y": kDomainYstart
    },
    {
      "x": d.end - partialPixelRight,
      "y": kDomainYstart + kQuarterDomainHeight
    },
    {
      "x": d.end,
      "y": kDomainYstart + kQuarterDomainHeight * 2
    },
    {
      "x": d.end - partialPixelRight,
      "y": kDomainYstart + kQuarterDomainHeight * 3
    },
    {
      "x": d.end,
      "y": kDomainYstart + kDomainHeight
    },
    {
      "x": d.start,
      "y": kDomainYend
    },
    {
      "x": d.start + partialPixelLeft,
      "y": kDomainYend - kQuarterDomainHeight
    },
    {
      "x": d.start,
      "y": kDomainYend - kQuarterDomainHeight * 2
    },
    {
      "x": d.start + partialPixelLeft,
      "y": kDomainYend - kQuarterDomainHeight * 3
    },
    {
      "x": d.start,
      "y": kDomainYend - kDomainHeight
    }
  ]
  let path = ' M ' + pathList[0].x + ' ' + pathList[0].y +
    ' L ' + pathList[1].x + ' ' + pathList[1].y +
    ' L ' + pathList[2].x + ' ' + pathList[2].y +
    ' L ' + pathList[3].x + ' ' + pathList[3].y +
    ' L ' + pathList[4].x + ' ' + pathList[4].y +
    ' L ' + pathList[5].x + ' ' + pathList[5].y +
    ' L ' + pathList[6].x + ' ' + pathList[6].y +
    ' L ' + pathList[7].x + ' ' + pathList[7].y +
    ' L ' + pathList[8].x + ' ' + pathList[8].y +
    ' L ' + pathList[9].x + ' ' + pathList[9].y +
    ' L ' + pathList[10].x + ' ' + pathList[10].y +
    ' Z'
  return path
}

///////////////////////// Create the table ///////////////////////

// Create a table
let row = d3.select('body')
  .append('table')
  .selectAll()
  .data(data)
  .enter()
  .append('tr')
  

/////////////////////// Create the table end /////////////////////

/////////////////////// Create columns to place name ///////////////////////

// First column to place name
let nameColum = row.append('td')
  .append('p')
  .style('font-family', kFontFamily)
  .style('font-size', kFontSize)
  .text(function(d) {
    return d.name ? d.name : ''
  })

/////////////////////// Create columns to place name end ///////////////////////

/////////////////////// Create second columns for main architecture ///////////////////////

// Second column for the main architecture SVG
let architecture = row.append('td')
  .append('svg')
  .attr("height", kSvgHeight)
  .attr("width", function(d) {
    return (d.length ? d.length : 0 + 1) * Xscale
  })
  .append('g')

// Draw backbone
architecture.append('g')
  .filter(function(d) {
    return d.length && d.length > 0
  })
  .append('rect')
  .attr("x", 1)
  .attr("y", kBackboneYstart)
  .attr("width", function(d) {
    return (d.backbone == false ? 0 : d.length) * Xscale
  })
  .attr("height", kBackboneHeight)
  .attr("fill", "gray")

  
///////////////////// Create second columns for main architecture end /////////////////////

architecture.each(function(d, i) {

  // Draw coiled coils
  let coils = d3.select(this).selectAll('svg')
    .data(d.coils ? d.coils : [])
    .enter()
    .append('g')
    .filter(function(d) {
      return d.end - d.start > 0
    })
    .append('rect')
    .attr("x", function(d) {
      return d.start * Xscale
    })
    .attr("y", kCoilsYstart)
    .attr("width", function(d) {
      return (d.end - d.start) * Xscale
    })
    .attr("height", kCoilsHeight)
    .attr("fill", domainColors.coils)

  // Draw coiled low-complexity regions
  let lcr = d3.select(this).selectAll('svg')
    .data(d.lcr ? d.lcr : [])
    .enter()
    .append('g')
    .filter(function(d) {
      return d.end - d.start > 0
    })
    .append('rect')
    .attr("x", function(d) {
      return d.start * Xscale
    })
    .attr("y", kLcrYstart)
    .attr("width", function(d) {
      return (d.end - d.start) * Xscale
    })
    .attr("height", kLcrHeight)
    .attr("fill", domainColors.lcr)

  // Draw transmembrane regions
  let tm = d3.select(this).selectAll('svg')
    .data(d.tm ? d.tm : [])
    .enter()
    .append('g')
    .append('rect')
    .filter(function(d) {
      return d.end - d.start > 0
    })
    .attr("x", function(d) {
      return d.start * Xscale
    })
    .attr("y", kTransmembraneYstart)
    .attr("width", function(d) {
      return (d.end - d.start) * Xscale
    })
    .attr("height", kTransmembraneHeight)
    .attr("fill", domainColors.tm)


  // Draw protein domains
  let domain = d3.select(this).selectAll('svg')
    .data(d.domains ? d.domains : [])
    .enter()
    .append('g')

  domain.append('rect')
    .filter(function(d) {
      return d.end - d.start > 0
    })
    .attr("x", function(d) {
      return d.start * Xscale
    })
    .attr("y", kDomainYstart)
    .attr("width", function(d) {
      return (d.end - d.start) * Xscale
    })
    .attr("height", kDomainHeight)
    .attr("fill", function(d) {
      return 'fill' in d ? d.fill : domainColors.domain;
    })
    .attr("stroke", function(d) {
      return 'stroke' in d ? d.stroke : domainColors.domainStroke;
    })
    .attr("stroke-width", 0)

  // Draw domain borders
  domain.append('path')
    .filter(function(d) {
      return d.end - d.start > 0
    })
    .attr("d", function(d) {
      return domainBorder(d, d.coverage ? d.coverage : '[]')
    })
    .attr("stroke", function(d) {
      return 'stroke' in d ? d.stroke : domainColors.domainStroke;
    })
    .attr("stroke-width", function(d) {
      return 'strokeWidth' in d ? d.strokeWidth : kDomainStrokeWidth
    })
    .attr("fill", "none")
    .attr("stroke-linecap", "round")

  // Name the domain
  domain.append('text')
    .filter(function(d) {
      return d.end - d.start > 0
    })
    .attr("x", function(d) {
      return ((d.start + d.end) / 2) * Xscale
    })
    .attr("y", kMiddleY)
    .attr("text-anchor", "middle")
    .attr("alignment-baseline", "central")
    .attr("textLength", function(d) {
      return Math.min((d.name.length * kNameLengthToPixelFactor) * Xscale, (d.end - d.start - (kDomainTextMargin * 2)) * Xscale)
    })
    .attr("font-family", kFontFamily)
    .attr("font-size", kFontSize)
    .attr("lengthAdjust", "spacingAndGlyphs")
    .text(function(d) {
      return d.name
    })
    // Draw coiled low-complexity regions
    let uppin = d3.select(this).selectAll('svg')
		.data(d.uppin ? d.uppin:[])
		.enter()
		.append('g')
                   
		uppin.append('rect')
			.attr("x", function(d) { return d.start * Xscale })
			.attr("y", kUpYstart)
			.attr("width", function(d) { 
			return 1 * Xscale
		})
			.attr("height", kUpHeight)
			.attr("fill", function(d) {
				return 'fill' in d ? d.fill : domainColors.uppin;
		})           
		uppin.append('circle')
			.attr("cx", function(d) { return d.start * Xscale })
			.attr("cy", kUpYstart)
			.attr("r", 10 * Xscale)
			.attr("height", kUpHeight)
			.attr("fill", function(d) {
			return 'fill' in d ? d.fill : domainColors.uppin;
	})
})

data.json

[{
  "backbone": false,
  "length": 1000,
  "tm": [{
    "start": 0,
    "end": 1000
  }],
  "domains": [
{
"name": "I-set#5",
"start": 803,
"end": 883,
"coverage": "[]",
"fill": "#FC8D62",
"stroke": "grey",
"strokeWidth": 1
},
{
"name": "I-set#1",
"start": 110,
"end": 201,
"coverage": "[]",
"fill": "#4DAF4A",
"stroke": "grey",
"strokeWidth": 1
},
{
"name": "I-set#6",
"start": 892,
"end": 969,
"coverage": "[]",
"fill": "#F4CAE4",
"stroke": "grey",
"strokeWidth": 1
},
{
"name": "I-set",
"start": 10,
"end": 99,
"coverage": "[]",
"fill": "#CCCCCC",
"stroke": "grey",
"strokeWidth": 1
},
{
"name": "I-set#2",
"start": 241,
"end": 328,
"coverage": "[]",
"fill": "#6A3D9A",
"stroke": "grey",
"strokeWidth": 1
},
{
"name": "I-set#3",
"start": 333,
"end": 415,
"coverage": "[]",
"fill": "#E78AC3",
"stroke": "grey",
"strokeWidth": 1
},
{
"name": "fn3",
"start": 514,
"end": 600,
"coverage": "[]",
"fill": "#B2DF8A",
"stroke": "grey",
"strokeWidth": 1
},
{
"name": "I-set#4",
"start": 712,
"end": 784,
"coverage": "[]",
"fill": "#D9D9D9",
"stroke": "grey",
"strokeWidth": 1
}
  ]
}]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant