Skip to content
This repository has been archived by the owner on Mar 12, 2024. It is now read-only.

Commit

Permalink
Hack-fix labels on safari when scrolling
Browse files Browse the repository at this point in the history
  • Loading branch information
danthe3rd committed Nov 4, 2021
1 parent eaa37fc commit 6659c28
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 6 deletions.
7 changes: 5 additions & 2 deletions src/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { ErrorDisplay, HeaderBar } from "./header";
import { HiPlotPluginData, DataProviderClass } from "./plugin";
import { StaticDataProvider } from "./dataproviders/static";
import { uncompress } from "./lib/compress";

import { setupBrowserCompat } from "./lib/browsercompat";

//@ts-ignore
import LogoSVG from "../hiplot/static/logo.svg";
Expand Down Expand Up @@ -152,6 +152,7 @@ export function createDefaultPlugins(): PluginsMap {
export class HiPlot extends React.Component<HiPlotProps, HiPlotState> {
// React refs
contextMenuRef = React.createRef<ContextMenu>();
rootRef = React.createRef<HTMLDivElement>();

plugins_window_state: {[plugin: string]: any} = {};

Expand Down Expand Up @@ -322,6 +323,8 @@ export class HiPlot extends React.Component<HiPlotProps, HiPlotState> {
this.callFilteredUidsHooks.cancel();
}
componentDidMount() {
setupBrowserCompat(this.rootRef.current);

// Setup contextmenu when we right-click a parameter
this.contextMenuRef.current.addCallback(this.columnContextMenu.bind(this), this);

Expand Down Expand Up @@ -532,7 +535,7 @@ export class HiPlot extends React.Component<HiPlotProps, HiPlotState> {
};
}.bind(this);
return (
<div className={`hip_thm--${this.state.dark ? "dark" : "light"}`}>
<div ref={this.rootRef} className={`hip_thm--${this.state.dark ? "dark" : "light"}`}>
<div className={style.hiplot}>
<SelectedCountProgressBar {...controlProps} />
<HeaderBar
Expand Down
29 changes: 29 additions & 0 deletions src/lib/browsercompat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

export const IS_SAFARI = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);

export function redrawObject(fo: SVGForeignObjectElement) {
const parent = fo.parentNode;
parent.removeChild(fo);
parent.appendChild(fo);

}
export function redrawAllForeignObjectsIfSafari() {
if (!IS_SAFARI) {
return;
}
const fo = document.getElementsByTagName("foreignObject");
Array.from(fo).forEach(redrawObject);
}

export function setupBrowserCompat(root: HTMLDivElement) {
/**
* Safari has a lot of trouble with foreignObjects inside canvas. Especially when we apply rotations, etc...
* As it considers the parent of the objects inside the FO to be the canvas origin, and not the FO.
* See https://stackoverflow.com/questions/51313873/svg-foreignobject-not-working-properly-on-safari
* Applying the fix in the link above fixes their position upon scroll - we don't want that, so we
* manually force-redraw them upon scroll.
*/
if (IS_SAFARI) {
root.addEventListener("wheel", redrawAllForeignObjectsIfSafari);
}
}
4 changes: 2 additions & 2 deletions src/lib/svghelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { ParamDef } from "../infertypes";
import style from "../hiplot.scss";
import { ContextMenu } from "../contextmenu";


function leftPos(anchor: string, w: number, minmax?: [number, number]): number {
var left = {
end: -w,
Expand Down Expand Up @@ -51,8 +52,7 @@ export function foCreateAxisLabel(pd: ParamDef, cm?: React.RefObject<ContextMenu
var fo = document.createElementNS('http://www.w3.org/2000/svg',"foreignObject");
const span = d3.select(fo).append("xhtml:div")
.classed(style.tooltipContainer, true)
.classed(style.label, true)
.style("position", "fixed"); // BUGFIX for transforms in Safari (https://stackoverflow.com/questions/51313873/svg-foreignobject-not-working-properly-on-safari)
.classed(style.label, true);
span.append("xhtml:span")
.attr("class", pd.label_css)
.classed("label-name", true)
Expand Down
15 changes: 13 additions & 2 deletions src/parallel/parallel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { HiPlotPluginData } from "../plugin";
import { ResizableH } from "../lib/resizable";
import { Filter, FilterType, apply_filters } from "../filters";
import { foDynamicSizeFitContent, foCreateAxisLabel } from "../lib/svghelpers";
import { IS_SAFARI, redrawAllForeignObjectsIfSafari } from "../lib/browsercompat";

interface StringMapping<V> { [key: string]: V; };

Expand Down Expand Up @@ -152,10 +153,11 @@ export class ParallelPlot extends React.Component<ParallelPlotData, ParallelPlot
this.xscale.domain(this.state.dimensions);
this.dimensions_dom.filter(function(this: ParallelPlot, p) { return this.state.dimensions.indexOf(p) == -1; }.bind(this)).remove();
this.dimensions_dom = this.dimensions_dom.filter(function(this: ParallelPlot, p) { return this.state.dimensions.indexOf(p) !== -1; }.bind(this));
if (!this.state.dragging) {
if (!this.state.dragging && !IS_SAFARI) {
g = g.transition();
}
g.attr("transform", function(this: ParallelPlot, p) { return "translate(" + this.position(p) + ")"; }.bind(this));
redrawAllForeignObjectsIfSafari();
this.update_ticks();
this.updateAxisTitlesAnglesAndFontSize();
}
Expand Down Expand Up @@ -349,14 +351,19 @@ export class ParallelPlot extends React.Component<ParallelPlotData, ParallelPlot
me.setState({dimensions: new_dimensions});
}
me.dimensions_dom.attr("transform", function(d) { return "translate(" + me.position(d) + ")"; });
redrawAllForeignObjectsIfSafari();
})
.on("end", function(d: string) {
if (!me.state.dragging.dragging) {
// no movement, invert axis
var extent = invert_axis(d);
} else {
// reorder axes
d3.select(this).transition().attr("transform", "translate(" + me.xscale(d) + ")");
var drag: any = d3.select(this);
if (!IS_SAFARI) {
drag = drag.transition();
}
drag.attr("transform", "translate(" + me.xscale(d) + ")");
var extents = brush_extends();
extent = extents[d];
}
Expand Down Expand Up @@ -612,6 +619,7 @@ export class ParallelPlot extends React.Component<ParallelPlotData, ParallelPlot
.each(function(d: string) {
d3.select(this).call(me.axis.scale(me.yscale[d]));
});
me.updateAxisTitlesAnglesAndFontSize();

// render data
this.setState(function(prevState) { return { brush_count: prevState.brush_count + 1}; });
Expand Down Expand Up @@ -682,6 +690,9 @@ export class ParallelPlot extends React.Component<ParallelPlotData, ParallelPlot
));
this.style.fontSize = newFontSize + "px";
this.style.transform = "rotate(" + (360 - ROTATION_ANGLE_RADS * 180 / Math.PI) + "deg)";
if (IS_SAFARI) {
this.parentElement.style.position = "fixed";
}
const fo = this.parentElement.parentElement as any as SVGForeignObjectElement;
fo.setAttribute("y", -newFontSize + "");
});
Expand Down

0 comments on commit 6659c28

Please sign in to comment.