Skip to content

Commit

Permalink
Update to D3 v0.2
Browse files Browse the repository at this point in the history
Changes:

 - Added two new path drawing options, 'path1' and 'path2'
    based on d3-plugins PR #36 from @ghedamat and PR #40 by @cmorse.
    The standard bezier curve has difficulties when the thickness of the    path is large relative to the node distance. These paths are drawn with individual bezier curves, which may not give equal area along its width, but always works.
 - Added option showNodeValues to show node values above nodes
 - Added option nodeCornerRadius for rounded nodes
 - Added option title for titles in the upper-right corner of the plot
 - Added <sankey id>_hover event that is fired every 2 seconds
 - Added option doubleclickTogglesChildren to hide children/downstram
    nodes
 - Added option xScalingFactor to scale width between nodes
 - Added option xAxisDomain to make an x-axis
  • Loading branch information
fbreitwieser committed Oct 31, 2016
1 parent 9e8d65c commit 49b4553
Show file tree
Hide file tree
Showing 9 changed files with 476 additions and 121 deletions.
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ Package: sankeyD3
Type: Package
Title: D3 JavaScript Sankey Graphs from R
Description: Creates 'D3' 'JavaScript' Sankey graphs from 'R'.
Version: 0.1
Date: 2016-10-17
Version: 0.2
Date: 2016-10-30
Authors@R: c(
person("Christopher", "Gandrud", email = "[email protected]",
role = c("aut", "cre")),
Expand Down
38 changes: 38 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
sankeyD3 v0.2 (Release date: 2016-10-30)
==========

Changes:

- Added two new path drawing options, 'path1' and 'path2'
based on d3-plugins PR #36 from @ghedamat and PR #40 by @cmorse.
The standard bezier curve has difficulties when the thickness of the path is large relative to the node distance. These paths are drawn with individual bezier curves, which may not give equal area along its width, but always works.
- Added option showNodeValues to show node values above nodes
- Added option nodeCornerRadius for rounded nodes
- Added option title for titles in the upper-right corner of the plot
- Added <sankey id>_hover event that is fired every 2 seconds
- Added option doubleclickTogglesChildren to hide children/downstram
nodes
- Added option xScalingFactor to scale width between nodes
- Added option xAxisDomain to make an x-axis


sankeyD3 v0.1 (Release date: 2016-10-20)
========================================

Changes:

- ported to D3 v4
- based on https://github.com/d3/d3-sankey
- added several modifications from networkD3 sankey.js
- included fixes and features from unmerged pull requests:
- d3/d3-plugins#124: Fix nodesByBreadth to have proper ordering
- d3/d3-plugins#120: Added 'l-bezier' link type
- d3/d3-plugins#74: Sort sankey target links by descending slope
- d3/d3-sankey#4: Add horizontal alignment option to Sankey layout
- added option numberFormat, default being ",.5g" (see , fixes christophergandrud/networkD3#147)
- added option NodePosX, fixes christophergandrud/networkD3#108
- added option to force node ordering to be alphabetical along a path (only works well with trees with one parent for each node, but might fix christophergandrud/networkD3#153)
- zooming
- dragging both horizontally and vertically


30 changes: 22 additions & 8 deletions R/sankeyNetwork.R
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ NULL
#' @param nodeWidth numeric width of each node.
#' @param nodePadding numeric essentially influences the width height.
#' @param nodeStrokeWidth numeric width of the stroke around nodes.
#' @param numberFormat number format in toolstips - see https://github.com/d3/d3-format for options
#' @param nodeCornerRadius numberic Radius for rounded nodes.
#' @param numberFormat number format in toolstips - see https://github.com/d3/d3-format for options.
#' @param margin an integer or a named \code{list}/\code{vector} of integers
#' for the plot margins. If using a named \code{list}/\code{vector},
#' the positions \code{top}, \code{right}, \code{bottom}, \code{left}
Expand All @@ -74,19 +75,26 @@ NULL
#' to accomodate long text labels.
#' @param height numeric height for the network graph's frame area in pixels.
#' @param width numeric width for the network graph's frame area in pixels.
#' @param title character Title of plot, put in the upper-left corner of the Sankey
#' @param iterations numeric. Number of iterations in the diagramm layout for
#' computation of the depth (y-position) of each node. Note: this runs in the
#' browser on the client so don't push it too high.
#' @param align character Alignment of the nodes. One of 'right', 'left', 'justify', 'center', 'none'.
#' If 'none', then the labels of the nodes are always to the right of the node.
#' @param zoom logical value to enable (\code{TRUE}) or disable (\code{FALSE})
#' zooming
#' @param linkType character One of 'bezier', 'l-bezier', and trapezoid.
#' @param orderByPath Order the nodes vertically along a path - this layout only
#' @param xScalingFactor numeric Scale the computed x position of the nodes by this value.
#' @param xAxisDomain character[] If xAxisDomain is given, an axis with those value is
#' added to the bottom of the plot. Only sensible when also NodeXPos are given.
#' @param linkType character One of 'bezier', 'l-bezier', 'trapezoid', 'path1' and 'path2'.
#' @param orderByPath boolean Order the nodes vertically along a path - this layout only
#' works well for trees where each node has maximum one parent.
#' @param highlightChildLinks Highlight all the links going right from a node or
#' @param highlightChildLinks boolean Highlight all the links going right from a node or
#' link.
#' @param doubleclickTogglesChildren boolean Show/hide target nodes and paths to the left
#' on double-click. Does not hide incoming links of target nodes, yet.
#' @param curvature numeric Curvature parameter for bezier links - between 0 and 1.
#' @param showNodeValues boolean Show values above nodes. Might require and increased node margin.
#' @param scaleNodeBreadthsByString Put nodes at positions relatively to string lengths -
#' only work well currently with align='none'
#'
Expand Down Expand Up @@ -122,10 +130,13 @@ NULL
sankeyNetwork <- function(Links, Nodes, Source, Target, Value,
NodeID, NodeGroup = NodeID, LinkGroup = NULL, NodePosX = NULL, NodeValue = NULL,
units = "", colourScale = JS("d3.scaleOrdinal().range(d3.schemeCategory20)"), fontSize = 7, fontFamily = NULL,
nodeWidth = 15, nodePadding = 10, nodeStrokeWidth = 1, margin = NULL,
nodeWidth = 15, nodePadding = 10, nodeStrokeWidth = 1, nodeCornerRadius = 0,
margin = NULL, title = NULL,
numberFormat = ",.5g", orderByPath = FALSE, highlightChildLinks = FALSE,
doubleclickTogglesChildren = FALSE, xAxisDomain = NULL,
height = NULL, width = NULL, iterations = 32, zoom = FALSE, align = "justify",
linkType = "bezier", curvature = .5, scaleNodeBreadthsByString = FALSE)
showNodeValues = TRUE, linkType = "bezier", curvature = .5,
scaleNodeBreadthsByString = FALSE, xScalingFactor = 1)
{
# Check if data is zero indexed
check_zero(Links[, Source], Links[, Target])
Expand Down Expand Up @@ -187,11 +198,14 @@ sankeyNetwork <- function(Links, Nodes, Source, Target, Value,
options = list(NodeID = NodeID, NodeGroup = NodeGroup, LinkGroup = LinkGroup,
colourScale = colourScale, fontSize = fontSize, fontFamily = fontFamily,
nodeWidth = nodeWidth, nodePadding = nodePadding, nodeStrokeWidth = nodeStrokeWidth,
nodeCornerRadius = nodeCornerRadius,
numberFormat = numberFormat, orderByPath = orderByPath,
units = units, margin = margin, iterations = iterations,
zoom = zoom, linkType = linkType, curvature = curvature,
highlightChildLinks = highlightChildLinks,
align = align, scaleNodeBreadthsByString = scaleNodeBreadthsByString)
highlightChildLinks = highlightChildLinks, doubleclickTogglesChildren = doubleclickTogglesChildren,
showNodeValues = showNodeValues, align = align, xAxisDomain = xAxisDomain,
title = title,
scaleNodeBreadthsByString = scaleNodeBreadthsByString, xScalingFactor = xScalingFactor)

# create widget
htmlwidgets::createWidget(name = "sankeyNetwork", x = list(links = LinksDF,
Expand Down
28 changes: 20 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,35 @@
# D3 JavaScript Sankey Network Graphs from R

Version 0.1
Version 0.2

This project is based on the Sankey implementation in [networkD3](https://github.com/christophergandrud/networkD3) and [d3-sankey](https://github.com/d3/d3-sankey).

Changelog:
- ported to D3 v4
- based on https://github.com/d3/d3-sankey
- Based on D3 v4 / https://github.com/d3/d3-sankey
- added several modifications from networkD3 sankey.js
- included fixes and features from unmerged pull requests:
- d3/d3-plugins#124: Fix nodesByBreadth to have proper ordering
- d3/d3-plugins#120: Added 'l-bezier' link type
- d3/d3-plugins#36: Added 'path1' link type
- d3/d3-plugins#40: Added 'path2' link type
- d3/d3-plugins#74: Sort sankey target links by descending slope
- d3/d3-sankey#4: Add horizontal alignment option to Sankey layout
- added option numberFormat, default being ",.5g" (see , fixes christophergandrud/networkD3#147)
- added option NodePosX, fixes christophergandrud/networkD3#108
- added option to force node ordering to be alphabetical along a path (only works well with trees with one parent for each node, but might fix christophergandrud/networkD3#153)
- zooming
- dragging both horizontally and vertically
- Added option numberFormat, default being ",.5g" (see , fixes christophergandrud/networkD3#147)
- Added option NodePosX, fixes christophergandrud/networkD3#108
- Added option to force node ordering to be alphabetical along a path (only works well with trees with one parent for each node, but might fix christophergandrud/networkD3#153)
- Zooming
- Dragging both horizontally and vertically
- Added option showNodeValues to show node values above nodes
- Added option nodeCornerRadius for rounded nodes
- Added option title for titles in the upper-right corner of the plot
- Added <sankey id>_hover event that is fired every second
- Added option doubleclickTogglesChildren to hide children/downstram
nodes
- Added option xScalingFactor to scale width between nodes
- Added option xAxisDomain to make an x-axis




The `inst/examples/shiny` web-app exposes several of the features:
![image](https://cloud.githubusercontent.com/assets/516060/19533346/5af9a822-960d-11e6-984c-333d20f2451f.png)
Expand Down
15 changes: 14 additions & 1 deletion inst/examples/shiny/server.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,31 @@ shinyServer(function(input, output) {
Energy$links$target_name <- Energy$nodes[Energy$links$target+1, "name"]
sankeyNetwork(Links = Energy$links, Nodes = Energy$nodes, Source = "source",
Target = "target", Value = "value", NodeID = "name",
fontSize = 12, nodeWidth = 30,
fontSize = 12,
zoom = input$zoom, align = input$align,
scaleNodeBreadthsByString = input$scaleNodeBreadthsByString,
nodeWidth = input$nodeWidth,
nodeStrokeWidth = input$nodeStrokeWidth,
LinkGroup = ifelse(input$LinkGroup == "none", NA, input$LinkGroup),
NodeGroup = ifelse(input$NodeGroup == "none", NA, input$NodeGroup),
nodePadding = input$nodePadding,
nodeCornerRadius = input$nodeCornerRadius,
showNodeValues = input$showNodeValues,
linkType = input$linkType,
curvature = input$curvature,
numberFormat = input$numberFormat,
highlightChildLinks = input$highlightChildLinks,
doubleclickTogglesChildren = input$doubleclickTogglesChildren,
orderByPath = input$orderByPath,
xScalingFactor = input$xScalingFactor,
units = "kWh")
})

output$clicked_node <- renderPrint( {
input$sankey_clicked
})
output$hovered_node <- renderPrint( {
input$sankey_hover
})

})
64 changes: 46 additions & 18 deletions inst/examples/shiny/ui.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,55 @@ library(shiny)
library(sankeyD3)

shinyUI(fluidPage(

tags$head(
tags$style(HTML("
.form-group {
margin-bottom: 0px;
display: inline-block;
background: lightgreen;
padding-left: 10px;
padding-right: 10px;
padding-bottom: 2px;
margin-bottom: 2px;
}
.shiny-input-container:not(.shiny-input-container-inline) {
width: initial;
}
.irs {
width: 150px;
}
"))
),
titlePanel("Shiny sankeyD3 network"),
fluidRow(
column(4,radioButtons("LinkGroup", "LinkGroup", choices = c("source_name", "target_name", "none"), selected = "none", inline = TRUE)),
column(4,radioButtons("NodeGroup", "NodeGroup", choices = c("name", "none"), selected = "name", inline = TRUE)),
column(4,radioButtons("linkType", "linkType", selected = "bezier", choices = c("bezier", "l-bezier", "trapez"), inline = TRUE))
fluidRow(
radioButtons("LinkGroup", "LinkGroup", choices = c("source_name", "target_name", "none"), selected = "none", inline = TRUE),
radioButtons("NodeGroup", "NodeGroup", choices = c("name", "none"), selected = "name", inline = TRUE),
radioButtons("linkType", "linkType", selected = "bezier", choices = c("bezier", "l-bezier", "trapez", "path1", "path2"), inline = TRUE),
radioButtons("align", "align", choices = c("left", "right", "center", "justify", "none"), selected = "justify", inline = TRUE)
),
fluidRow(
column(4,radioButtons("align", "align", choices = c("left", "right", "center", "justify", "none"), selected = "justify", inline = TRUE)),
column(4,checkboxInput("scaleNodeBreadthsByString", "scaleNodeBreadthsByString", value = FALSE),
checkboxInput("zoom", "zoom", value = FALSE)),
column(4,checkboxInput("highlightChildLinks", "highlightChildLinks", value = FALSE),
checkboxInput("orderByPath", "orderByPath", value = FALSE))
fluidRow(
checkboxInput("orderByPath", "orderByPath", value = FALSE),
checkboxInput("scaleNodeBreadthsByString", "scaleNodeBreadthsByString", value = FALSE),
checkboxInput("zoom", "zoom", value = TRUE),
checkboxInput("highlightChildLinks", "highlightChildLinks", value = FALSE),
checkboxInput("doubleclickTogglesChildren", "doubleclickTogglesChildren", value = FALSE),
checkboxInput("showNodeValues", "showNodeValues", value = FALSE)
),
fluidRow(
column(4,sliderInput("nodeStrokeWidth","nodeStrokeWidth", value = 1, min = 0, max = 15)),
column(4,sliderInput("curvature","curvature", value = .5, min = 0, max = 1, step=.1)),
column(4,textInput("numberFormat", "numberFormat", value = ",.5g"))
fluidRow(
sliderInput("nodeWidth","nodeWidth", value = 30, min = 0, max = 50),
sliderInput("nodeStrokeWidth","nodeStrokeWidth", value = 1, min = 0, max = 15),
sliderInput("nodePadding","nodePadding", value = 10, min = 0, max=50, step = 1),
sliderInput("nodeCornerRadius","nodeCornerRadius", value = 5, min = 0, max = 15),
sliderInput("curvature","curvature", value = .5, min = 0, max = 1, step=.1),
sliderInput("xScalingFactor","xScalingFactor", value = 1, min = 0, max = 3, step=.1)

),
fluidRow(textInput("numberFormat", "numberFormat", value = ",.5g")),
fluidRow(verbatimTextOutput("clicked_node")),
fluidRow(verbatimTextOutput("hovered_node")),
fluidRow(
sankeyNetworkOutput("sankey")
)
))
)
)
)

Loading

0 comments on commit 49b4553

Please sign in to comment.