结合 ggplot2 和 d3(gridSVG 教程生成非交互式图像)
Combining ggplot2 and d3 (gridSVG tutorial results in non-interactive image)
我正在学习一个关于集成 ggplot2 和 d3 的简单教程。我专门研究本教程站点 (http://timelyportfolio.github.io/gridSVG_intro/) 上的方法 2。我正在尝试复制交互式图(这是该页面上的最后一个图)。
我使用了他们相同的语法,并将其插入到.R文件中,如下所示:
library(gridSVG)
library(ggplot2)
library(XML)
library(rjson)
set.seed(955)
dat <- data.frame(cond = rep(c("A", "B"), each=10), xvar = 1:20 + rnorm(20,sd=3), yvar = 1:20 + rnorm(20,sd=3))
g4 = ggplot(dat, aes(x=xvar, y=yvar)) + geom_smooth() + geom_point(shape=19, aes(color = cond), size=5)
g4
g4.svg <- grid.export("plot1.svg",addClasses=TRUE)
cat(saveXML(g4.svg$svg))
cat(
'<script> ourdata=',
rjson::toJSON(apply(g4$data,MARGIN=1,FUN=function(x)return(list(x)))),
'</script>'
)
cat(
'<script> dataToBind = ',
'd3.entries(ourdata.map(function(d,i) {return d[0]}))',
'</script>'
)
cat(
'<script>\n',
'scatterPoints = d3.select(".points").selectAll("use");\n',
'scatterPoints.data(dataToBind)',
'</script>\n'
)
cat('<script>\n',
'scatterPoints
.on("mouseover", function(d) {
//Create the tooltip label
var tooltip = d3.select(this.parentNode).append("g");
tooltip
.attr("id","tooltip")
.attr("transform","translate("+(d3.select(this).attr("x")+10)+","+d3.select(this).attr("y")+")")
.append("rect")
.attr("stroke","white")
.attr("stroke-opacity",.5)
.attr("fill","white")
.attr("fill-opacity",.5)
.attr("height",30)
.attr("width",50)
.attr("rx",5)
.attr("x",2)
.attr("y",5);
tooltip.append("text")
.attr("transform","scale(1,-1)")
.attr("x",5)
.attr("y",-22)
.attr("text-anchor","start")
.attr("stroke","gray")
.attr("fill","gray")
.attr("fill-opacity",1)
.attr("opacity",1)
.text("x:" + Math.round(d.value.xvar*100)/100);
tooltip.append("text")
.attr("transform","scale(1,-1)")
.attr("x",5)
.attr("y",-10)
.attr("text-anchor","start")
.attr("stroke","gray")
.attr("fill","gray")
.attr("fill-opacity",1)
.attr("opacity",1)
.text("y:" + Math.round(d.value.yvar*100)/100);
})
.on("mouseout", function(d) {
d3.select("#tooltip").remove();
});',
'</script>'
)
我从此脚本得到的唯一输出是 plot1.svg 文件。但是,当我在浏览器中打开它时(尝试过 Safari 和 Google Chrome),它是图像的停滞版本。
我会给作者发电子邮件 him/herself。但该联系信息不可用。这是一个简单的教程,所以我希望它是一个简单的解决方案!
我对这个交互式组件还很陌生。然而,我一步一步地按照说明操作,不确定我可能忽略了什么。非常感谢任何与解决此问题相关的支持或信息!
编辑
所以,我最终安装了 R 以查看我原来的答案哪里出了问题。我很接近。我错过了一个 saveXML
电话,正如@arvi1000 指出的那样,我没有找到 d3
的来源。这是一个完整的固定示例。我只是 运行 它与 R 3.2.3 它会在你的工作目录中产生一个 myAwesomePlot.html
:
library(gridSVG)
library(ggplot2)
library(XML)
library(rjson)
set.seed(955)
dat <- data.frame(cond = rep(c("A", "B"), each=10), xvar = 1:20 + rnorm(20,sd=3), yvar = 1:20 + rnorm(20,sd=3))
g4 = ggplot(dat, aes(x=xvar, y=yvar)) + geom_smooth() + geom_point(shape=19, aes(color = cond), size=5)
# what does this line do? It writes the SVG to the file "plot1.svg"?
g4.svg <- grid.export("", addClasses=TRUE)
# create a valid html file
cat("<html><head><script src='http://d3js.org/d3.v3.min.js'></script></head><body>", file="myAwesomePlot.html")
# I'm assuming this gets the svg content and can write it to a file
cat(saveXML(g4.svg$svg), file="myAwesomePlot.html", append=TRUE)
cat(
'<script> ourdata=',
rjson::toJSON(apply(g4$data,MARGIN=1,FUN=function(x)return(list(x)))),
'</script>', file="myAwesomePlot.html", append=TRUE
)
cat(
'<script> dataToBind = ',
'd3.entries(ourdata.map(function(d,i) {return d[0]}))',
'</script>'
, file="myAwesomePlot.html", append=TRUE)
cat(
'<script>\n',
'scatterPoints = d3.select(".points").selectAll("use");\n',
'scatterPoints.data(dataToBind)',
'</script>\n'
, file="myAwesomePlot.html", append=TRUE)
cat('<script>\n',
'scatterPoints
.on("mouseover", function(d) {
//Create the tooltip label
var tooltip = d3.select(this.parentNode).append("g");
tooltip
.attr("id","tooltip")
.attr("transform","translate("+(d3.select(this).attr("x")+10)+","+d3.select(this).attr("y")+")")
.append("rect")
.attr("stroke","white")
.attr("stroke-opacity",.5)
.attr("fill","white")
.attr("fill-opacity",.5)
.attr("height",30)
.attr("width",50)
.attr("rx",5)
.attr("x",2)
.attr("y",5);
tooltip.append("text")
.attr("transform","scale(1,-1)")
.attr("x",5)
.attr("y",-22)
.attr("text-anchor","start")
.attr("stroke","gray")
.attr("fill","gray")
.attr("fill-opacity",1)
.attr("opacity",1)
.text("x:" + Math.round(d.value.xvar*100)/100);
tooltip.append("text")
.attr("transform","scale(1,-1)")
.attr("x",5)
.attr("y",-10)
.attr("text-anchor","start")
.attr("stroke","gray")
.attr("fill","gray")
.attr("fill-opacity",1)
.attr("opacity",1)
.text("y:" + Math.round(d.value.yvar*100)/100);
})
.on("mouseout", function(d) {
d3.select("#tooltip").remove();
});',
'</script>'
, file="myAwesomePlot.html", append=TRUE)
# close out file
cat("</body></html>", file="myAwesomePlot.html", append=TRUE)
原答案
自从我完成任何 R
编程以来已经有一段时间了,但是那些 cat
函数看起来不正确。他们将写入标准输出,而不是写入文件。我的猜测是 grid.export
只写入 svg
文件,其他所有内容都被删除。乍一看,我假设您打算 运行 此代码为:
R myRCode.R > outPutFile.svg
以便标准输出重定向到一个文件。
我会尝试稍微重组代码并将所有内容显式写入 html
文件:
library(gridSVG)
library(ggplot2)
library(XML)
library(rjson)
set.seed(955)
dat <- data.frame(cond = rep(c("A", "B"), each=10), xvar = 1:20 + rnorm(20,sd=3), yvar = 1:20 + rnorm(20,sd=3))
g4 = ggplot(dat, aes(x=xvar, y=yvar)) + geom_smooth() + geom_point(shape=19, aes(color = cond), size=5)
g4
// what does this line do? It writes the SVG to the file "plot1.svg"?
g4.svg <- grid.export("plot1.svg",addClasses=TRUE)
// create a valid html file
cat("<html><head></head><body>", file="myAwesomePlot.html")
// I'm assuming this gets the svg content and can write it to a file
cat(g4.svg$svg, file="myAwesomePlot.html")
cat(
'<script> ourdata=',
rjson::toJSON(apply(g4$data,MARGIN=1,FUN=function(x)return(list(x)))),
'</script>', file="myAwesomePlot.html"
)
// etc, rest of JavaScript
// close out file
cat("</body></html>", file="myAwesomePlot.html")
- 您 D3.js 图书馆缺少 link!
cat
,如您所见,在普通的 R 脚本中,就像@Mark 所说的那样,只输出到控制台。
要解决 1) 您的最终 html 文档必须包含:<script src="http://d3js.org/d3.v3.min.js"></script>
或同等内容。
要解决 2),您可以使用 Rmarkdown .Rmd 文件并将所有内容放入一个块中。
在扩展名为 .Rmd 的文件中,块的开头为:
```{r, echo=FALSE, results='asis', warning=FALSE, message=FALSE}
接下来,请确保将 D3 库包含在这一行中:
cat('<script src="http://d3js.org/d3.v3.min.js"></script>')
然后在上面添加所有代码,然后结束块:
```
如果您在 Rstudio 中执行此操作,则可以点击 'Knit HTML'。否则,您可以在控制台或另一个 .R 脚本中使用 knitr::knit2html
或 rmarkdown::render
)
如果您不喜欢@arvi1000 使用 knitr
的建议(这是一个很好的建议),您可以在第一个 cat()
语句之前使用 sink(file = "myfile.html")
来编写所有输出到 myfile.html
。最后,只需添加语句 sink()
即可开始写回标准输出。
如@arvi1000 所说,您还缺少 link 到 D3.js 库。按照他们的指示,将 cat('<script src="http://d3js.org/d3.v3.min.js"></script>')
作为您的第一个 cat()
语句。您可能还需要遵循@Mark 关于创建有效 HTML 文件的建议。
老实说,最简单的方法是使用 knitr
。我已经包含了一个有效的 .Rmd 文件的内容,它将产生 D3.js 图。只需 运行 knitr::knit2html()
包含以下代码的 .Rmd 文件。我添加了一些评论和我对正在发生的事情的最佳解释(我从来没有对 D3.js 做过 ggplot,所以这对我来说是一次很酷的学习经历!)
```{r echo = FALSE, message = FALSE, fig.keep = 'none'}
library(gridSVG)
library(ggplot2)
library(XML)
library(rjson)
# create a plot with some fake data
set.seed(955)
dat <- data.frame(cond = rep(c("A", "B"), each=10), xvar = 1:20 + rnorm(20,sd=3), yvar = 1:20 + rnorm(20,sd=3))
g4 = ggplot(dat, aes(x=xvar, y=yvar)) + geom_smooth() + geom_point(shape=19, aes(color = cond), size=5)
# you need to print the plot in order to capture it with grid.export
g4
# exporting the plot to a .svg file
g4.svg <- grid.export("plot1.svg",addClasses=TRUE)
```
```{r, echo=FALSE, results='asis', warning=FALSE, message=FALSE}
# load the d3.js script
cat('<script src="http://d3js.org/d3.v3.min.js"></script>')
# convert the svg file to an XML string and print it
cat(saveXML(g4.svg$svg))
# looks like you convert the ggplot object data to JSON for use by d3.js
# looks like the aesthetics are included here? I don't seem them defined
# anywhere else
cat(
'<script> ourdata=',
rjson::toJSON(apply(g4$data,MARGIN=1,FUN=function(x)return(list(x)))),
'</script>'
)
# d3.js data definition
cat(
'<script> dataToBind = ',
'd3.entries(ourdata.map(function(d,i) {return d[0]}))',
'</script>'
)
# d3.js scatter plot
cat(
'<script>\n',
'scatterPoints = d3.select(".points").selectAll("use");\n',
'scatterPoints.data(dataToBind)',
'</script>\n'
)
# d3.js code to support the hover tooltips (hover over a point on the plot)
# this is apparently ALL for the tooltip
cat('<script>\n',
'scatterPoints
.on("mouseover", function(d) {
//Create the tooltip label
var tooltip = d3.select(this.parentNode).append("g");
tooltip
.attr("id","tooltip")
.attr("transform","translate("+(d3.select(this).attr("x")+10)+","+d3.select(this).attr("y")+")")
.append("rect")
.attr("stroke","white")
.attr("stroke-opacity",.5)
.attr("fill","white")
.attr("fill-opacity",.5)
.attr("height",30)
.attr("width",50)
.attr("rx",5)
.attr("x",2)
.attr("y",5);
tooltip.append("text")
.attr("transform","scale(1,-1)")
.attr("x",5)
.attr("y",-22)
.attr("text-anchor","start")
.attr("stroke","gray")
.attr("fill","gray")
.attr("fill-opacity",1)
.attr("opacity",1)
.text("x:" + Math.round(d.value.xvar*100)/100);
tooltip.append("text")
.attr("transform","scale(1,-1)")
.attr("x",5)
.attr("y",-10)
.attr("text-anchor","start")
.attr("stroke","gray")
.attr("fill","gray")
.attr("fill-opacity",1)
.attr("opacity",1)
.text("y:" + Math.round(d.value.yvar*100)/100);
})
.on("mouseout", function(d) {
d3.select("#tooltip").remove();
});',
'</script>'
)
```
我正在学习一个关于集成 ggplot2 和 d3 的简单教程。我专门研究本教程站点 (http://timelyportfolio.github.io/gridSVG_intro/) 上的方法 2。我正在尝试复制交互式图(这是该页面上的最后一个图)。
我使用了他们相同的语法,并将其插入到.R文件中,如下所示:
library(gridSVG)
library(ggplot2)
library(XML)
library(rjson)
set.seed(955)
dat <- data.frame(cond = rep(c("A", "B"), each=10), xvar = 1:20 + rnorm(20,sd=3), yvar = 1:20 + rnorm(20,sd=3))
g4 = ggplot(dat, aes(x=xvar, y=yvar)) + geom_smooth() + geom_point(shape=19, aes(color = cond), size=5)
g4
g4.svg <- grid.export("plot1.svg",addClasses=TRUE)
cat(saveXML(g4.svg$svg))
cat(
'<script> ourdata=',
rjson::toJSON(apply(g4$data,MARGIN=1,FUN=function(x)return(list(x)))),
'</script>'
)
cat(
'<script> dataToBind = ',
'd3.entries(ourdata.map(function(d,i) {return d[0]}))',
'</script>'
)
cat(
'<script>\n',
'scatterPoints = d3.select(".points").selectAll("use");\n',
'scatterPoints.data(dataToBind)',
'</script>\n'
)
cat('<script>\n',
'scatterPoints
.on("mouseover", function(d) {
//Create the tooltip label
var tooltip = d3.select(this.parentNode).append("g");
tooltip
.attr("id","tooltip")
.attr("transform","translate("+(d3.select(this).attr("x")+10)+","+d3.select(this).attr("y")+")")
.append("rect")
.attr("stroke","white")
.attr("stroke-opacity",.5)
.attr("fill","white")
.attr("fill-opacity",.5)
.attr("height",30)
.attr("width",50)
.attr("rx",5)
.attr("x",2)
.attr("y",5);
tooltip.append("text")
.attr("transform","scale(1,-1)")
.attr("x",5)
.attr("y",-22)
.attr("text-anchor","start")
.attr("stroke","gray")
.attr("fill","gray")
.attr("fill-opacity",1)
.attr("opacity",1)
.text("x:" + Math.round(d.value.xvar*100)/100);
tooltip.append("text")
.attr("transform","scale(1,-1)")
.attr("x",5)
.attr("y",-10)
.attr("text-anchor","start")
.attr("stroke","gray")
.attr("fill","gray")
.attr("fill-opacity",1)
.attr("opacity",1)
.text("y:" + Math.round(d.value.yvar*100)/100);
})
.on("mouseout", function(d) {
d3.select("#tooltip").remove();
});',
'</script>'
)
我从此脚本得到的唯一输出是 plot1.svg 文件。但是,当我在浏览器中打开它时(尝试过 Safari 和 Google Chrome),它是图像的停滞版本。
我会给作者发电子邮件 him/herself。但该联系信息不可用。这是一个简单的教程,所以我希望它是一个简单的解决方案!
我对这个交互式组件还很陌生。然而,我一步一步地按照说明操作,不确定我可能忽略了什么。非常感谢任何与解决此问题相关的支持或信息!
编辑
所以,我最终安装了 R 以查看我原来的答案哪里出了问题。我很接近。我错过了一个 saveXML
电话,正如@arvi1000 指出的那样,我没有找到 d3
的来源。这是一个完整的固定示例。我只是 运行 它与 R 3.2.3 它会在你的工作目录中产生一个 myAwesomePlot.html
:
library(gridSVG)
library(ggplot2)
library(XML)
library(rjson)
set.seed(955)
dat <- data.frame(cond = rep(c("A", "B"), each=10), xvar = 1:20 + rnorm(20,sd=3), yvar = 1:20 + rnorm(20,sd=3))
g4 = ggplot(dat, aes(x=xvar, y=yvar)) + geom_smooth() + geom_point(shape=19, aes(color = cond), size=5)
# what does this line do? It writes the SVG to the file "plot1.svg"?
g4.svg <- grid.export("", addClasses=TRUE)
# create a valid html file
cat("<html><head><script src='http://d3js.org/d3.v3.min.js'></script></head><body>", file="myAwesomePlot.html")
# I'm assuming this gets the svg content and can write it to a file
cat(saveXML(g4.svg$svg), file="myAwesomePlot.html", append=TRUE)
cat(
'<script> ourdata=',
rjson::toJSON(apply(g4$data,MARGIN=1,FUN=function(x)return(list(x)))),
'</script>', file="myAwesomePlot.html", append=TRUE
)
cat(
'<script> dataToBind = ',
'd3.entries(ourdata.map(function(d,i) {return d[0]}))',
'</script>'
, file="myAwesomePlot.html", append=TRUE)
cat(
'<script>\n',
'scatterPoints = d3.select(".points").selectAll("use");\n',
'scatterPoints.data(dataToBind)',
'</script>\n'
, file="myAwesomePlot.html", append=TRUE)
cat('<script>\n',
'scatterPoints
.on("mouseover", function(d) {
//Create the tooltip label
var tooltip = d3.select(this.parentNode).append("g");
tooltip
.attr("id","tooltip")
.attr("transform","translate("+(d3.select(this).attr("x")+10)+","+d3.select(this).attr("y")+")")
.append("rect")
.attr("stroke","white")
.attr("stroke-opacity",.5)
.attr("fill","white")
.attr("fill-opacity",.5)
.attr("height",30)
.attr("width",50)
.attr("rx",5)
.attr("x",2)
.attr("y",5);
tooltip.append("text")
.attr("transform","scale(1,-1)")
.attr("x",5)
.attr("y",-22)
.attr("text-anchor","start")
.attr("stroke","gray")
.attr("fill","gray")
.attr("fill-opacity",1)
.attr("opacity",1)
.text("x:" + Math.round(d.value.xvar*100)/100);
tooltip.append("text")
.attr("transform","scale(1,-1)")
.attr("x",5)
.attr("y",-10)
.attr("text-anchor","start")
.attr("stroke","gray")
.attr("fill","gray")
.attr("fill-opacity",1)
.attr("opacity",1)
.text("y:" + Math.round(d.value.yvar*100)/100);
})
.on("mouseout", function(d) {
d3.select("#tooltip").remove();
});',
'</script>'
, file="myAwesomePlot.html", append=TRUE)
# close out file
cat("</body></html>", file="myAwesomePlot.html", append=TRUE)
原答案
自从我完成任何 R
编程以来已经有一段时间了,但是那些 cat
函数看起来不正确。他们将写入标准输出,而不是写入文件。我的猜测是 grid.export
只写入 svg
文件,其他所有内容都被删除。乍一看,我假设您打算 运行 此代码为:
R myRCode.R > outPutFile.svg
以便标准输出重定向到一个文件。
我会尝试稍微重组代码并将所有内容显式写入 html
文件:
library(gridSVG)
library(ggplot2)
library(XML)
library(rjson)
set.seed(955)
dat <- data.frame(cond = rep(c("A", "B"), each=10), xvar = 1:20 + rnorm(20,sd=3), yvar = 1:20 + rnorm(20,sd=3))
g4 = ggplot(dat, aes(x=xvar, y=yvar)) + geom_smooth() + geom_point(shape=19, aes(color = cond), size=5)
g4
// what does this line do? It writes the SVG to the file "plot1.svg"?
g4.svg <- grid.export("plot1.svg",addClasses=TRUE)
// create a valid html file
cat("<html><head></head><body>", file="myAwesomePlot.html")
// I'm assuming this gets the svg content and can write it to a file
cat(g4.svg$svg, file="myAwesomePlot.html")
cat(
'<script> ourdata=',
rjson::toJSON(apply(g4$data,MARGIN=1,FUN=function(x)return(list(x)))),
'</script>', file="myAwesomePlot.html"
)
// etc, rest of JavaScript
// close out file
cat("</body></html>", file="myAwesomePlot.html")
- 您 D3.js 图书馆缺少 link!
cat
,如您所见,在普通的 R 脚本中,就像@Mark 所说的那样,只输出到控制台。
要解决 1) 您的最终 html 文档必须包含:<script src="http://d3js.org/d3.v3.min.js"></script>
或同等内容。
要解决 2),您可以使用 Rmarkdown .Rmd 文件并将所有内容放入一个块中。
在扩展名为 .Rmd 的文件中,块的开头为:
```{r, echo=FALSE, results='asis', warning=FALSE, message=FALSE}
接下来,请确保将 D3 库包含在这一行中:
cat('<script src="http://d3js.org/d3.v3.min.js"></script>')
然后在上面添加所有代码,然后结束块:
```
如果您在 Rstudio 中执行此操作,则可以点击 'Knit HTML'。否则,您可以在控制台或另一个 .R 脚本中使用 knitr::knit2html
或 rmarkdown::render
)
如果您不喜欢@arvi1000 使用 knitr
的建议(这是一个很好的建议),您可以在第一个 cat()
语句之前使用 sink(file = "myfile.html")
来编写所有输出到 myfile.html
。最后,只需添加语句 sink()
即可开始写回标准输出。
如@arvi1000 所说,您还缺少 link 到 D3.js 库。按照他们的指示,将 cat('<script src="http://d3js.org/d3.v3.min.js"></script>')
作为您的第一个 cat()
语句。您可能还需要遵循@Mark 关于创建有效 HTML 文件的建议。
老实说,最简单的方法是使用 knitr
。我已经包含了一个有效的 .Rmd 文件的内容,它将产生 D3.js 图。只需 运行 knitr::knit2html()
包含以下代码的 .Rmd 文件。我添加了一些评论和我对正在发生的事情的最佳解释(我从来没有对 D3.js 做过 ggplot,所以这对我来说是一次很酷的学习经历!)
```{r echo = FALSE, message = FALSE, fig.keep = 'none'}
library(gridSVG)
library(ggplot2)
library(XML)
library(rjson)
# create a plot with some fake data
set.seed(955)
dat <- data.frame(cond = rep(c("A", "B"), each=10), xvar = 1:20 + rnorm(20,sd=3), yvar = 1:20 + rnorm(20,sd=3))
g4 = ggplot(dat, aes(x=xvar, y=yvar)) + geom_smooth() + geom_point(shape=19, aes(color = cond), size=5)
# you need to print the plot in order to capture it with grid.export
g4
# exporting the plot to a .svg file
g4.svg <- grid.export("plot1.svg",addClasses=TRUE)
```
```{r, echo=FALSE, results='asis', warning=FALSE, message=FALSE}
# load the d3.js script
cat('<script src="http://d3js.org/d3.v3.min.js"></script>')
# convert the svg file to an XML string and print it
cat(saveXML(g4.svg$svg))
# looks like you convert the ggplot object data to JSON for use by d3.js
# looks like the aesthetics are included here? I don't seem them defined
# anywhere else
cat(
'<script> ourdata=',
rjson::toJSON(apply(g4$data,MARGIN=1,FUN=function(x)return(list(x)))),
'</script>'
)
# d3.js data definition
cat(
'<script> dataToBind = ',
'd3.entries(ourdata.map(function(d,i) {return d[0]}))',
'</script>'
)
# d3.js scatter plot
cat(
'<script>\n',
'scatterPoints = d3.select(".points").selectAll("use");\n',
'scatterPoints.data(dataToBind)',
'</script>\n'
)
# d3.js code to support the hover tooltips (hover over a point on the plot)
# this is apparently ALL for the tooltip
cat('<script>\n',
'scatterPoints
.on("mouseover", function(d) {
//Create the tooltip label
var tooltip = d3.select(this.parentNode).append("g");
tooltip
.attr("id","tooltip")
.attr("transform","translate("+(d3.select(this).attr("x")+10)+","+d3.select(this).attr("y")+")")
.append("rect")
.attr("stroke","white")
.attr("stroke-opacity",.5)
.attr("fill","white")
.attr("fill-opacity",.5)
.attr("height",30)
.attr("width",50)
.attr("rx",5)
.attr("x",2)
.attr("y",5);
tooltip.append("text")
.attr("transform","scale(1,-1)")
.attr("x",5)
.attr("y",-22)
.attr("text-anchor","start")
.attr("stroke","gray")
.attr("fill","gray")
.attr("fill-opacity",1)
.attr("opacity",1)
.text("x:" + Math.round(d.value.xvar*100)/100);
tooltip.append("text")
.attr("transform","scale(1,-1)")
.attr("x",5)
.attr("y",-10)
.attr("text-anchor","start")
.attr("stroke","gray")
.attr("fill","gray")
.attr("fill-opacity",1)
.attr("opacity",1)
.text("y:" + Math.round(d.value.yvar*100)/100);
})
.on("mouseout", function(d) {
d3.select("#tooltip").remove();
});',
'</script>'
)
```