Skip to content

Instantly share code, notes, and snippets.

@AWKruijt
Last active December 3, 2018 17:52
Show Gist options
  • Save AWKruijt/366e50ca4be86ec68317a8cd7092a6fc to your computer and use it in GitHub Desktop.
Save AWKruijt/366e50ca4be86ec68317a8cd7092a6fc to your computer and use it in GitHub Desktop.
MyFirstR2D3
#
# This is a Shiny web application incorporating a D3 graph, called with R2D3().
# You can run the application by clicking the 'Run App' button above.
#
# Find out more about building applications with Shiny here:
#
# http://shiny.rstudio.com/
#
# Find out more about R2D3 here:
#
# https://rstudio.github.io/r2d3/
#
library(shiny)
library(r2d3)
# Define UI for application that shows the D3 plot and returns the updated correlation:
ui <- fluidPage(
fluidRow(
h3("corr:"),
verbatimTextOutput("corrComputed")),
fluidRow(
d3Output("d3"),
h4("drag the dots..."))
)
# Define server
server <- function(input, output) {
n_p <- 5
mn <- 20
sd <- 5
t1 <- rnorm(n_p, mn, sd)
t2 <- t1 + 5
df <- data.frame(id = rep(c(1:n_p), each = 2),
tt = rep(c(1, 2), n_p),
val = c(rbind(t1, t2)) )
df2 <<- df
output$corrComputed <- renderText({
cor(df$val[df$tt=="1"] , df$val[df$tt=="2"])
})
output$d3 <- renderD3({
r2d3(data=df, d3_version = 4, script = "dragmultilinechart.js")
})
observeEvent(input$dataD3Adjusted, {
dataD3Adjusted <<- input$dataD3Adjusted
df$val <- as.numeric(dataD3Adjusted [names(dataD3Adjusted) == "val"])
output$corrComputed <- renderText({
cor(df$val[df$tt=="1"] , df$val[df$tt=="2"])
})
})
}
# Run the application
shinyApp(ui = ui, server = server)
// !preview r2d3 data= data.frame(id = c(1,1,2,2,3,3,4,4,5,5), tt = c(1, 2, 1, 2, 1, 2, 1, 2, 1, 2), val = c(14.4, 19.3, 22.0, 27.0, 20.7, 25.74, 16.9, 21.9, 18.6, 23.6))
var dById = d3.nest()
.key(function(d) {
return d.id;
})
.entries(data);
var margin = {
top: 40,
right: 40,
bottom: 40,
left: 40
},
width = 450 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
var color = d3.scaleOrdinal()
.range(["#a6cee3", "#1f78b4", "#b2df8a", "#33a02c", "#fb9a99"]);
var x = d3.scaleLinear()
.range([0.25 * width, 0.75 * width])
.domain([1, 2]);
// I think that a continuous scale is required for the drag to work, but
// add a second ordinal x axis scale to show instead of the linear one:
var xOrd = d3.scaleOrdinal()
.range([0.25 * width, 0.75 * width])
.domain(["t1", "t2"]);
var yrange = d3.max(data, function(d) {return d.val;}) - d3.min(data, function(d) {return d.val;});
var y = d3.scaleLinear()
.rangeRound([height, 0])
.domain([d3.min(data, function(d) {return d.val;}) - .3*yrange, d3.max(data, function(d) {return d.val;}) + .3*yrange ]);
var xAxis = d3.axisBottom(xOrd), // use the Ordinal x scale
yAxis = d3.axisLeft(y);
// Define the line by data variables
var connectLine = d3.line()
.x(function(d) {
return x(d.tt);
})
.y(function(d) {
return y(d.val);
});
svg.append('rect')
.attr('class', 'zoom')
.attr('cursor', 'move')
.attr('fill', 'none')
.attr('pointer-events', 'all')
.attr('width', width)
.attr('height', height)
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
var focus = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
focus.selectAll('lines')
.data(dById)
.enter().append("path")
.attr("class", "line")
.attr("d", function(d) {
return connectLine(d.values);
})
.attr("stroke", function(d) {
return color(d.key);
})
.attr('stroke-width', 4);
focus.selectAll('circles')
.data(dById)
.enter().append("g")
.attr("class", "dots")
.selectAll("circle")
.data(function(d) {
return d.values;
})
.enter().append("circle")
.attr("cx", function(d) {
return x(d.tt);
})
.attr("cy", function(d) {
return y(d.val);
})
.attr("r", 6)
.style('cursor', 'pointer')
.attr("fill", function(d) {
return color(d.id);
})
.attr("stroke", function(d) {
return color(d.id);
});
focus.append('g')
.attr('class', 'axis axis--x')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);
focus.append('g')
.attr('class', 'axis axis--y')
.call(yAxis);
/// drag stuff:
let drag = d3.drag()
.on('start', dragstarted)
.on('drag', dragged)
.on('end', dragended);
focus.selectAll('circle')
.call(drag);
// focus.selectAll('line')
// .call(drag);
function dragstarted(d) {
d3.select(this).raise().classed('active', true);
}
function dragged(d) {
dragNewY = y.invert(d3.event.y);
d.val = dragNewY;
d3.select(this)
.attr('cx', d => x(d.tt))
.attr('cy', d => y(d.val));
focus.selectAll('path').attr("d", function(d) {
return connectLine(d.values);
});
// How do I select only the line associated with the dragged circle?
}
function dragended(d) {
Shiny.setInputValue(
"dataD3Adjusted",
//dById,
data,
{priority: "event"}
);
d3.select(this).classed('active', false);
//.attr("d", function(d) {return d; });
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment