Skip to content

Commit 6fb231f

Browse files
Merge pull request #82 from timelyportfolio/feature/margins
more robust margin control for diagonalNetwork and radialNetwork
2 parents 2bad283 + 12621d9 commit 6fb231f

File tree

5 files changed

+93
-12
lines changed

5 files changed

+93
-12
lines changed

R/diagonalNetwork.R

+9-3
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@
1717
#' be before they are clicked. Multiple formats supported (e.g. hexadecimal).
1818
#' @param opacity numeric value of the proportion opaque you would like the
1919
#' graph elements to be.
20-
#' @param margin integer value of the plot margin. Set the margin
21-
#' appropriately to accomodate long text labels.
20+
#' @param margin an integer or a named \code{list}/\code{vector} of integers
21+
#' for the plot margins. If using a named \code{list}/\code{vector},
22+
#' the positions \code{top}, \code{right}, \code{bottom}, \code{left}
23+
#' are valid. If a single integer is provided, then the value will be
24+
#' assigned to the right margin. Set the margin appropriately
25+
#' to accomodate long text labels.
2226
#'
2327
#'
2428
#' @examples
@@ -94,12 +98,14 @@ diagonalNetwork <- function(
9498
nodeStroke = "steelblue",
9599
textColour = "#111",
96100
opacity = 0.9,
97-
margin = 0)
101+
margin = NULL)
98102
{
99103
# validate input
100104
if (!is.list(List))
101105
stop("List must be a list object.")
102106
root <- List
107+
108+
margin <- margin_handler(margin)
103109

104110
# create options
105111
options = list(

R/radialNetwork.R

+9-3
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@
1717
#' be before they are clicked. Multiple formats supported (e.g. hexadecimal).
1818
#' @param opacity numeric value of the proportion opaque you would like the
1919
#' graph elements to be.
20-
#' @param margin integer value of the plot margin. Set the margin
21-
#' appropriately to accomodate long text labels.
20+
#' @param margin an integer or a named \code{list}/\code{vector} of integers
21+
#' for the plot margins. If using a named \code{list}/\code{vector},
22+
#' the positions \code{top}, \code{right}, \code{bottom}, \code{left}
23+
#' are valid. If a single integer is provided, then the value will be
24+
#' assigned to the right margin. Set the margin appropriately
25+
#' to accomodate long text labels.
2226
#'
2327
#'
2428
#' @examples
@@ -94,12 +98,14 @@ radialNetwork <- function(
9498
nodeStroke = "steelblue",
9599
textColour = "#111",
96100
opacity = 0.9,
97-
margin = 0)
101+
margin = NULL)
98102
{
99103
# validate input
100104
if (!is.list(List))
101105
stop("List must be a list object.")
102106
root <- List
107+
108+
margin <- margin_handler(margin)
103109

104110
# create options
105111
options = list(

R/utils.R

+39
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,42 @@ toJSONarray <- function(dtf){
5959
read_file <- function(doc, ...){
6060
paste(readLines(doc, ...), collapse = '\n')
6161
}
62+
63+
64+
#' Utility function to handle margins
65+
#' @param margin an \code{integer}, a named \code{vector} of integers,
66+
#' or a named \code{list} of integers specifying the margins
67+
#' (top, right, bottom, and left)
68+
#' in \code{px}/\code{pixels} for our htmlwidget. If only a single
69+
#' \code{integer} is provided, then the value will be assumed to be
70+
#' the \code{right} margin.
71+
#' @return named \code{list} with top, right, bottom, left margins
72+
#' @noRd
73+
margin_handler <- function(margin){
74+
# margin can be either a single value or a list with any of
75+
# top, right, bottom, left
76+
# if margin is a single value, then we will stick
77+
# with the original behavior of networkD3 and use it for the right margin
78+
if(!is.null(margin) && length(margin) == 1 && is.null(names(margin))){
79+
margin <- list(
80+
top = NULL,
81+
right = margin,
82+
bottom = NULL,
83+
left = NULL
84+
)
85+
} else if(!is.null(margin)){
86+
# if margin is a named vector then convert to list
87+
if(!is.list(margin) && !is.null(names(margin))){
88+
margin <- as.list(margin)
89+
}
90+
# if we are here then margin should be a list and
91+
# we will use the values supplied with NULL as default
92+
margin <- modifyList(
93+
list(top = NULL, right = NULL, bottom = NULL, left = NULL),
94+
margin
95+
)
96+
} else {
97+
# if margin is null, then make it a list of nulls for each position
98+
margin <- list(top = NULL, right = NULL, bottom = NULL, left = NULL)
99+
}
100+
}

inst/htmlwidgets/diagonalNetwork.js

+15-3
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,21 @@ HTMLWidgets.widget({
3434

3535
var s = d3.select(el).selectAll("svg");
3636

37-
s.attr("margin", x.options.margin);
38-
var margin = {top: 20, right: 20 + parseInt(s.attr("margin")), bottom: 20,
39-
left: 20};
37+
// margin handling
38+
// set our default margin to be 20
39+
// will override with x.options.margin if provided
40+
var margin = {top: 20, right: 20, bottom: 20, left: 20};
41+
// go through each key of x.options.margin
42+
// use this value if provided from the R side
43+
Object.keys(x.options.margin).map(function(ky){
44+
if(x.options.margin[ky] !== null) {
45+
margin[ky] = x.options.margin[ky];
46+
}
47+
// set the margin on the svg with css style
48+
s.style(["margin",ky].join("-"), margin[ky]);
49+
});
50+
51+
4052
width = s.attr("width") - margin.right - margin.left;
4153
height = s.attr("height") - margin.top - margin.bottom;
4254

inst/htmlwidgets/radialNetwork.js

+21-3
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,27 @@ HTMLWidgets.widget({
3232
// JSON array with the d3Tree root data
3333

3434
var s = d3.select(el).selectAll("svg");
35-
var diameter = Math.min(parseInt(s.attr("width")),parseInt(s.attr("height")));
36-
s.attr("margin", x.options.margin);
37-
tree.size([360, diameter/2 - parseInt(s.attr("margin"))])
35+
36+
// margin handling
37+
// set our default margin to be 20
38+
// will override with x.options.margin if provided
39+
var margin = {top: 20, right: 20, bottom: 20, left: 20};
40+
// go through each key of x.options.margin
41+
// use this value if provided from the R side
42+
Object.keys(x.options.margin).map(function(ky){
43+
if(x.options.margin[ky] !== null) {
44+
margin[ky] = x.options.margin[ky];
45+
}
46+
// set the margin on the svg with css style
47+
s.style(["margin",ky].join("-"), margin[ky]);
48+
});
49+
50+
var diameter = Math.min(
51+
parseInt(s.attr("width")) - margin.right - margin.left,
52+
parseInt(s.attr("height")) - margin.top - margin.bottom
53+
);
54+
55+
tree.size([360, diameter/2])
3856
.separation(function(a, b) { return (a.parent == b.parent ? 1 : 2) / a.depth; });
3957

4058
// select the svg group element and remove existing children

0 commit comments

Comments
 (0)