-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Plot title additions #2337
Plot title additions #2337
Changes from 2 commits
81ba7f9
5933ada
23edd85
e87eb2a
c46b6d4
273d70a
789a4a0
9659652
5f0d434
35aea89
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
"use client"; | ||
|
||
import { Component, PropsWithChildren } from "react"; | ||
|
||
type State = { | ||
error?: Error; | ||
}; | ||
|
||
export class ErrorBoundary extends Component<PropsWithChildren, State> { | ||
public state: State = {}; | ||
|
||
public static getDerivedStateFromError(error: Error): State { | ||
return { error }; | ||
} | ||
|
||
componentDidCatch() {} | ||
|
||
public render() { | ||
if (this.state.error) { | ||
return ( | ||
<div className="m-2 p-4 bg-red-300 rounded"> | ||
<header className="mb-2 font-semibold">Fatal Error</header> | ||
<div className="mb-2">{this.state.error.message}</div> | ||
<div className="mb-2">Try reloading the browser.</div> | ||
<pre className="text-xs overflow-auto">{this.state.error.stack}</pre> | ||
</div> | ||
); | ||
} | ||
|
||
return this.props.children; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,8 @@ interface DrawAxesParams { | |
yTickCount?: number; | ||
xTickFormat?: string; | ||
yTickFormat?: string; | ||
xAxisTitle?: string; | ||
yAxisTitle?: string; | ||
} | ||
|
||
export function drawAxes({ | ||
|
@@ -46,6 +48,8 @@ export function drawAxes({ | |
yTickCount = Math.max(Math.min(Math.floor(height / 100), 12), 3), | ||
xTickFormat: xTickFormatSpecifier = defaultTickFormatSpecifier, | ||
yTickFormat: yTickFormatSpecifier = defaultTickFormatSpecifier, | ||
xAxisTitle, | ||
yAxisTitle, | ||
}: DrawAxesParams) { | ||
const xTicks = xScale.ticks(xTickCount); | ||
const xTickFormat = xScale.tickFormat(xTickCount, xTickFormatSpecifier); | ||
|
@@ -56,6 +60,12 @@ export function drawAxes({ | |
const tickSize = 2; | ||
|
||
const padding: Padding = { ...suggestedPadding }; | ||
if (xAxisTitle) { | ||
padding.bottom = padding.bottom + 20; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a potential problem, more important than the one about 4px in my other comment. I'm not proposing any immediate changes here, just flagging a potential technical debt. By design, This is a problem because we determine the height of canvas first, then try to draw on it and increase padding, which decreases the chart's main area. If I made this experiment, because AFAIK Inner height there is still positive, but dangerously close to zero. Ideally, we should always respect inner height ( The circular dependency that needs to be untangled to fix this is a bit complex:
So this is solvable, but would require significant changes or additions to the APIs that we have ( |
||
if (yAxisTitle) { | ||
padding.left = padding.left + 35; | ||
} | ||
|
||
// measure tick sizes for dynamic padding | ||
if (!hideYAxis) { | ||
|
@@ -70,6 +80,27 @@ export function drawAxes({ | |
}); | ||
} | ||
|
||
if (xAxisTitle) { | ||
const titleX = width / 2; // center the title | ||
const titleY = height - 8; // adjust this value based on desired distance from x-axis | ||
context.textAlign = "center"; | ||
context.textBaseline = "bottom"; | ||
context.font = "bold 12px Arial"; | ||
context.fillText(xAxisTitle, titleX, titleY); | ||
} | ||
if (yAxisTitle) { | ||
const titleY = height / 2; // center the title vertically | ||
const titleX = 0; | ||
context.save(); // save the current context state | ||
context.translate(titleX, titleY); | ||
context.rotate(-Math.PI / 2); // rotate 90 degrees counter-clockwise | ||
context.textAlign = "center"; | ||
context.textBaseline = "top"; | ||
context.font = "bold 12px Arial"; // adjust font size and style as needed | ||
context.fillText(yAxisTitle, 0, 0); | ||
context.restore(); // restore the context state to before rotation and translation | ||
} | ||
|
||
const frame = new CartesianFrame({ | ||
context, | ||
x0: padding.left, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a slight discrepancy (4px) with the old behavior.
Before: https://www.squiggle-language.com/playground?v=dev#code=eNqrVkpJTUsszSlxzk9JVbJSqlCwVQiuzNUrzctMyy%2FK1TDSMTTQVKoFAAjgDIc%3D
After: https://squiggle-website-git-plot-additions-quantified-uncertainty.vercel.app/playground?v=dev#code=eNqrVkpJTUsszSlxzk9JVbJSqlCwVQiuzNUrzctMyy%2FK1TDSMTTQVKoFAAjgDIc%3D
In both versions, canvas is 84px tall:
So previously chart height itself was exactly as was requested, 50px, but it's 54px now.
Of course this doesn't matter much, but to avoid future confusion about what's right, I'd suggest:
suggestedPadding
outside ofdraw
functionconst height
based on it,const height = innerHeight + suggestedPadding.top + suggestedPadding.bottom
, then we'd be confident that they match and thatinnerHeight
is correctThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a messy area, thanks for explaining!
For one thing, I imagine we'll later just want the labels to be in HTML, which would change the constraints here.
We'd also want it underneath the samples toolbar, as discussed in my PR description.