Skip to content

Commit

Permalink
feat(RulerBubble): added an option to scale their size to fit in the …
Browse files Browse the repository at this point in the history
…axis
  • Loading branch information
Quacken8 committed Nov 18, 2024
1 parent e09321b commit 7cafa8a
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 26 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
"@fortawesome/free-solid-svg-icons": "^6.6.0",
"@risai/bim": "^1.4.2",
"@tanstack/svelte-virtual": "^3.10.8",
"@typek/signalhead": "npm:@jsr/typek__signalhead@^0.0.39",
"@typek/signalhead": "npm:@jsr/typek__signalhead@^0.0.40",
"@typek/typek": "npm:@jsr/typek__typek@^0.10.0",
"@types/lodash-es": "^4.17.12",
"@types/seedrandom": "^3.0.8",
Expand All @@ -86,7 +86,7 @@
},
"peerDependencies": {
"fraction.js": "^4.3.7",
"unitlib": "^0.8.11"
"unitlib": "^0.9.0"
},
"packageManager": "pnpm@9.1.1+sha256.9551e803dcb7a1839fdf5416153a844060c7bce013218ce823410532504ac10b",
"browserslist": [
Expand Down
20 changes: 10 additions & 10 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 12 additions & 3 deletions src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@
],
}),
);
const fullscreen$ = mut(false);
</script>

<main>
Expand All @@ -175,6 +176,8 @@
legendPosition="bottom"
hoverPointsInterpolation="nearest"
{commonXRange$}
{fullscreen$}
class={$fullscreen$ ? "bg" : ""}
>
<!-- <svelte:fragment slot="toolbar">
<ToolFullscreen on:click={() => (fullscreen = !fullscreen)} />
Expand All @@ -189,7 +192,7 @@
</svelte:fragment>
</Chart>
</div>
<div style="height:400px;width:900px;" bind:this={wrapDiv}>
<!-- <div style="height:400px;width:900px;" bind:this={wrapDiv}>
<Chart
{traces}
title="Titulek"
Expand All @@ -210,13 +213,19 @@
<ToolExportToPng />
<ToolHideLegend />
<ToolExportToCsv />
</svelte:fragment> -->
</svelte:fragment>
<svelte:fragment slot="infobox">
<Fa icon={faArrowRight} />&ensp;1<br />
<Fa icon={faArrowLeft} />&ensp;1000<br />
<Fa icon={faChartLine} />&ensp;3/3
</svelte:fragment>
</Chart>
</div>
</div> -->
{/await}
</main>

<style>
:global(.bg) {
background-color: yellow;
}
</style>
11 changes: 9 additions & 2 deletions src/lib/components/Chart.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@
import type { InterpolationStrategy } from "../../../dist/wasm/libchartium.js";
import type { ChartStyleSheet } from "../state/core/style.js";
import { derived } from "@typek/signalhead";
import { filter } from "@typek/typek";
import RulerBubble from "./RulerBubble.svelte";
import { setContext } from "../utils/svelte-context.js";
import { filter } from "@typek/typek";
// SECTION Props
let klass: string = "";
Expand Down Expand Up @@ -118,6 +118,8 @@
export let hideXBubble: boolean = false;
/** Hides the coordinate bubble by the odge of the graph */
export let hideYBubble: boolean = false;
/** Shrinks Y bubble if it is too wide and would overflow */
export let scaleYBubble: boolean = false;
/** Hides the tooltips shown next to cursor */
export let hideTooltip: boolean = false;
Expand Down Expand Up @@ -164,7 +166,7 @@
);
/** Charts supplied with the same FlockRegistry will have y axis of the same width */
export let commonYAxisWidth$: FlockRegistry<number> | undefined = undefined;
export let commonYAxisWidth$: FlockRegistry<number> = FlockRegistry<number>();
$: yAxisWidth = mapOpt(commonYAxisWidth$, (f) =>
flockReduce(f, (a, b) => Math.max(a, b), 0),
);
Expand Down Expand Up @@ -409,6 +411,7 @@
<div class="y bubble-reference">
<RulerBubble
autoDecimalPlaces={$yTicksDecimalPlaces$ + 1}
{chartStylesheet}
axis="y"
position={{
x: 0,
Expand All @@ -417,8 +420,11 @@
.fromQuantity($commonYRuler$)
.toLogicalPixels(),
}}
maxX={chart$.valueOnAxis("x").fromFraction(1).toLogicalPixels()}
maxWidth$={yAxisWidth}
value={$commonYRuler$}
displayUnit={$yDisplayUnit$}
scaleIfTooLarge={scaleYBubble}
/>
</div>
{/if}
Expand All @@ -435,6 +441,7 @@
.fromQuantity($commonXRuler$)
.toLogicalPixels(),
}}
maxX={chart$.valueOnAxis("x").fromFraction(1).toLogicalPixels()}
value={$commonXRuler$}
displayUnit={$xDisplayUnit$}
/>
Expand Down
43 changes: 35 additions & 8 deletions src/lib/components/RulerBubble.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,61 @@
import type { ChartStyleSheet } from "../state/core/style.js";
import type { ChartValue, DisplayUnit, Point } from "../types.js";
import { formatChartValue } from "../units/mod.js";
import { clamp } from "./position.js";
import type { Signal } from "@typek/signalhead";
import { measureText } from "../utils/format.js";
/** position relative to body; i.e. absolute :d */
export let position: Point;
export let maxX: number;
export let maxWidth$: Signal<number> | undefined = undefined;
export let value: ChartValue | undefined;
export let axis: "x" | "y";
export let displayUnit: DisplayUnit;
export let autoDecimalPlaces = 2;
export let chartStylesheet: Partial<ChartStyleSheet> = {};
export let scaleIfTooLarge = false;
const decimalPlaces =
chartStylesheet?.[`bubbles.${axis}`]?.decimalPlaces ??
chartStylesheet?.bubbles?.decimalPlaces ??
autoDecimalPlaces;
const bubbleClass = `${chartStylesheet?.[`bubbles.${axis}`]?.className ?? ""} ${chartStylesheet?.bubbles?.className ?? ""}`;
const bubbleStyle = `${chartStylesheet?.[`bubbles.${axis}`]?.style ?? ""} ${chartStylesheet?.bubbles?.style ?? ""}`;
let bubbleStyle = `${chartStylesheet?.[`bubbles.${axis}`]?.style ?? ""} ${chartStylesheet?.bubbles?.style ?? ""}`;
let borderBoxSize: ResizeObserverSize[];
$: clientWidth = borderBoxSize?.[0].inlineSize ?? 0;
$: clampedX = clamp(position.x, 0 + clientWidth / 2, maxX - clientWidth / 2);
$: bubbleText = formatChartValue(value ?? 0, {
unit: displayUnit,
decimalPlaces,
});
let bubbleMeasure: HTMLDivElement;
$: scaling = chartStylesheet?.[`bubbles.y`]?.scaleToFitAxis
? scaleIfTooLarge || $maxWidth$ === undefined || bubbleMeasure === undefined
? undefined
: clamp(
$maxWidth$ / (measureText(bubbleText, bubbleMeasure).width + 20),
0.65,
1,
)
: 1;
$: positionedStyle =
axis === "x"
? `left: ${position.x.toFixed(1)}px; top: ${position.y.toFixed(1)}px; transform: translateX(-50%)`
: `right: ${position.x.toFixed(1)}px; top: ${position.y.toFixed(1)}px; transform: translateY(-50%)`;
? `left: ${clampedX.toFixed(1)}px; top: ${position.y.toFixed(1)}px; transform: translateX(-50%) scale(${scaling}); transform-origin: right center`
: `right: ${position.x.toFixed(1)}px; top: ${position.y.toFixed(1)}px; transform: translateY(-50%) scale(${scaling}); transform-origin: right center`;
</script>

<div class="positioned" style={positionedStyle}>
<div
bind:this={bubbleMeasure}
class="axis-bubble {bubbleClass}"
style={bubbleStyle}
style:visibility={"hidden"}
></div>
<div class="positioned" style={positionedStyle} bind:borderBoxSize>
<div class="axis-bubble {bubbleClass}" style={bubbleStyle}>
{formatChartValue(value ?? 0, {
unit: displayUnit,
decimalPlaces,
})}
{bubbleText}
</div>
</div>

Expand Down
7 changes: 6 additions & 1 deletion src/lib/state/core/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ export interface BubbleStyle {
className: string;
decimalPlaces: number;
}

export interface YBubbleStyle extends BubbleStyle {
scaleToFitAxis: boolean;
}

export interface TooltipStyle {
manyTraces: Partial<{
style: string;
Expand Down Expand Up @@ -71,7 +76,7 @@ export interface ChartStyleSheet {

bubbles: Partial<BubbleStyle>;
"bubbles.x": Partial<BubbleStyle>;
"bubbles.y": Partial<BubbleStyle>;
"bubbles.y": Partial<YBubbleStyle>;

tooltip: Partial<TooltipStyle>;

Expand Down

0 comments on commit 7cafa8a

Please sign in to comment.