Include x and y pixelratio in coordinfo

This commit is contained in:
Winston Chang
2018-07-10 14:22:33 -05:00
parent 5bbf2aa57a
commit ec12caaeba
2 changed files with 50 additions and 31 deletions

View File

@@ -249,14 +249,20 @@ nearPoints <- function(df, coordinfo, xvar = NULL, yvar = NULL,
x <- asNumber(df[[xvar]])
y <- asNumber(df[[yvar]])
# Get the pixel coordinates of the point
coordPx <- scaleCoords(coordinfo$x, coordinfo$y, coordinfo)
# Get the coordinates of the point (in img pixel coordinates)
point_img <- scaleCoords(coordinfo$x, coordinfo$y, coordinfo)
# Get pixel coordinates of data points
dataPx <- scaleCoords(x, y, coordinfo)
# Get coordinates of data points (in img pixel coordinates)
data_img <- scaleCoords(x, y, coordinfo)
# Distances of data points to coordPx
dists <- sqrt((dataPx$x - coordPx$x) ^ 2 + (dataPx$y - coordPx$y) ^ 2)
# Get x/y distances (in css coordinates)
dist_css <- list(
x = (data_img$x - point_img$x) / coordinfo$pixelratio$x,
y = (data_img$y - point_img$y) / coordinfo$pixelratio$y
)
# Distances of data points to the target point, in css pixels.
dists <- sqrt(dist_css$x^2 + dist_css$y^2)
if (addDist)
df$dist_ <- dists
@@ -298,50 +304,56 @@ nearPoints <- function(df, coordinfo, xvar = NULL, yvar = NULL,
# The coordinfo data structure will look something like the examples below.
# For base graphics, `mapping` is empty, and there are no panelvars:
# List of 7
# $ x : num 4.37
# $ y : num 12
# $ mapping: Named list()
# $ domain :List of 4
# $ x : num 4.37
# $ y : num 12
# $ pixelratio:List of 2
# ..$ x: num 2
# ..$ y: num 2
# $ mapping : Named list()
# $ domain :List of 4
# ..$ left : num 1.36
# ..$ right : num 5.58
# ..$ bottom: num 9.46
# ..$ top : num 34.8
# $ range :List of 4
# $ range :List of 4
# ..$ left : num 58
# ..$ right : num 429
# ..$ bottom: num 226
# ..$ top : num 58
# $ log :List of 2
# $ log :List of 2
# ..$ x: NULL
# ..$ y: NULL
# $ .nonce : num 0.343
# $ .nonce : num 0.343
#
# For ggplot2, the mapping vars usually will be included, and if faceting is
# used, they will be listed as panelvars:
# List of 9
# $ x : num 3.78
# $ y : num 17.1
# $ panelvar1: int 6
# $ panelvar2: int 0
# $ mapping :List of 4
# $ x : num 3.78
# $ y : num 17.1
# $ pixelratio:List of 2
# ..$ x: num 2
# ..$ y: num 2
# $ panelvar1 : int 6
# $ panelvar2 : int 0
# $ mapping :List of 4
# ..$ x : chr "wt"
# ..$ y : chr "mpg"
# ..$ panelvar1: chr "cyl"
# ..$ panelvar2: chr "am"
# $ domain :List of 4
# $ domain :List of 4
# ..$ left : num 1.32
# ..$ right : num 5.62
# ..$ bottom: num 9.22
# ..$ top : num 35.1
# $ range :List of 4
# $ range :List of 4
# ..$ left : num 172
# ..$ right : num 300
# ..$ bottom: num 144
# ..$ top : num 28.5
# $ log :List of 2
# $ log :List of 2
# ..$ x: NULL
# ..$ y: NULL
# $ .nonce : num 0.603
# $ .nonce : num 0.603

View File

@@ -334,13 +334,14 @@ imageutils.initPanelScales = function(coordmap) {
// 3. data: The coordinates in the data space. This is a bit more complicated
// than the other two, because there can be multiple panels (as in facets).
imageutils.initCoordmap = function($el, coordmap) {
var el = $el[0];
const el = $el[0];
const $img = $el.find("img");
// If we didn't get any panels, create a dummy one where the domain and range
// are simply the pixel dimensions.
// that we modify.
if (coordmap.length === 0) {
var bounds = {
let bounds = {
top: 0,
left: 0,
right: el.clientWidth - 1,
@@ -361,7 +362,6 @@ imageutils.initCoordmap = function($el, coordmap) {
// This returns the offset of the mouse in CSS pixels relative to the img,
// but not including the padding or border, if present.
coordmap.mouseOffsetCss = function(mouseEvent) {
const $img = $el.find("img");
const img_origin = findOrigin($img);
// The offset of the mouse from the upper-left corner of the img, in
@@ -378,7 +378,6 @@ imageutils.initCoordmap = function($el, coordmap) {
// img content is 1000 pixels wide, but is scaled to 400 pixels on screen,
// and the input is x:400, then this will return x:1000.
coordmap.scaleCssToImg = function(offset_css) {
const $img = $el.find("img");
const pixel_scaling = findImgToCssScalingRatio($img);
const result = mapValues(offset_css, (value, key) => {
@@ -400,7 +399,6 @@ imageutils.initCoordmap = function($el, coordmap) {
// wide, but is scaled to 400 pixels on screen, and the input is x:1000,
// then this will return x:400.
coordmap.scaleImgToCss = function(offset_img) {
const $img = $el.find("img");
const pixel_scaling = findImgToCssScalingRatio($img);
const result = mapValues(offset_img, (value, key) => {
@@ -417,6 +415,14 @@ imageutils.initCoordmap = function($el, coordmap) {
return result;
};
coordmap.cssToImgScalingRatio = function() {
const res = findImgToCssScalingRatio($img);
return {
x: 1 / res.x,
y: 1 / res.y
};
};
// Given an offset in css pixels, return an object representing which panel
// it's in. The `expand` argument tells it to expand the panel area by that
// many pixels. It's possible for an offset to be within more than one
@@ -428,7 +434,6 @@ imageutils.initCoordmap = function($el, coordmap) {
const y = offset_img.y;
// Convert expand from css pixels to img pixels
const $img = $el.find("img");
const imgToCssRatio = findImgToCssScalingRatio($img);
const expand_img = {
x: expand / imgToCssRatio.x,
@@ -517,6 +522,8 @@ imageutils.initCoordmap = function($el, coordmap) {
const coords = panel.scaleImgToData(coordmap.scaleCssToImg(offset_css));
coords.pixelratio = coordmap.cssToImgScalingRatio();
// Add the panel (facet) variables, if present
$.extend(coords, panel.panel_vars);
@@ -776,6 +783,8 @@ imageutils.createBrushHandler = function(inputId, $el, opts, coordmap, outputId)
// Add the panel (facet) variables, if present
$.extend(coords, panel.panel_vars);
coords.pixelratio = coordmap.cssToImgScalingRatio();
// Add variable name mappings
coords.mapping = panel.mapping;
@@ -984,11 +993,9 @@ imageutils.createBrushHandler = function(inputId, $el, opts, coordmap, outputId)
}
}
// This should be called when a resize event happens.
function onResize() {
brush.onResize();
// No need to call brushInfoSender.immediateCall() because all values
// should be unchanged.
brushInfoSender.immediateCall();
}
return {