Open katyo opened 3 years ago
Here's a workaround for the time being. Please understand that I extracted this from a larger codebase and didn't test it by itself. Some assembly required.
<Chart
data={[{x: 1, y: 1}, {x: 2, y: 10}, {x: 3, y: 100}]}
logarithmic=true
/>
<script>
import * as Pancake from '@sveltejs/pancake';
export let data;
export let logarithmic = false;
export let x = p => p.x;
export let y = p => p.y;
const identity = a => a;
export let fmtX = identity;
export let fmtY = identity
function safeLog10(x) {
if (x > 0) {
return Math.log10(x);
}
return 0;
}
function exp10(x) {
return Math.pow(10, x);
}
$: scaleY = logarithmic ? safeLog10 : identity;
$: yScaled = p => scaleY(y(p));
$: unScaleY = logarithmic ? exp10 : identity;
let closest;
let x1;
let y1;
let x2;
let y2;
$: {
x1 = Infinity;
y1 = Infinity;
x2 = -Infinity;
y2 = -Infinity;
if (Array.isArray(data)) {
data.forEach(point => {
x1 = Math.min(x1, x(point));
y1 = Math.min(y1, yScaled(point));
x2 = Math.max(x2, x(point));
y2 = Math.max(y2, yScaled(point));
})
}
}
</script>
<div class=chart>
<Pancake.Chart {x1} {y1} {x2} {y2}>
<Pancake.Grid horizontal count={3} let:value>
<div class="grid-line horizontal"><span>{fmtY(unScaleY(value))}</span></div>
</Pancake.Grid>
<Pancake.Grid vertical count={5} let:value>
<div class="grid-line vertical"><span>{fmtX(value)}</span></div>
</Pancake.Grid>
<Pancake.Svg>
<Pancake.SvgLine {data} {x} y={yScaled} let:d>
<path class=line {d}/>
</Pancake.SvgLine>
<Pancake.SvgScatterplot {data} {x} y={yScaled} let:d>
<path class=scatter {d}/>
</Pancake.SvgScatterplot>
{#if closest}
<Pancake.SvgPoint x={x(closest)} y={yScaled(closest)} let:d>
<path class=highlight {d}/>
</Pancake.SvgPoint>
{/if}
</Pancake.Svg>
{#if closest}
<Pancake.Point x={x(closest)} y={yScaled(closest)}>
<span class="annotation-point"></span>
<div class="annotation" style="transform: translate(-{100 * ((x(closest) - x1) / (x2 - x1))}%, 0)">
<span>{fmtX(x(closest))}, {fmtY(y(closest))}</span>
</div>
</Pancake.Point>
{/if}
<Pancake.Quadtree {data} {x} y={yScaled} bind:closest/>
</Pancake.Chart>
</div>
<style>
.chart {
box-sizing: border-box;
height: 300px;
padding: 3em 2em 2em 3em;
}
.axes {
width: 100%;
height: 100%;
border-left: 1px solid black;
border-bottom: 1px solid black;
}
.grid-line {
position: relative;
display: block;
}
.grid-line.horizontal {
width: calc(100% + 2em);
left: -2em;
border-bottom: 1px dashed #ccc;
}
.grid-line.vertical {
border-left: 1px dashed #ccc;
height: 100%;
}
.grid-line.horizontal span {
position: absolute;
left: 0;
bottom: 2px;
font-family: sans-serif;
font-size: 14px;
color: #999;
}
.grid-line.vertical span {
position: absolute;
width: 4em;
left: -2em;
bottom: -30px;
font-family: sans-serif;
font-size: 14px;
color: #999;
text-align: center;
}
.x-label {
position: absolute;
width: 4em;
left: -2em;
bottom: -22px;
font-family: sans-serif;
font-size: 14px;
color: #999;
text-align: center;
}
path {
stroke-linejoin: round;
stroke-linecap: round;
fill: none;
}
path.highlight {
stroke: red;
stroke-width: 10px;
}
path.line {
stroke: black;
stroke-width: 2px;
}
path.scatter {
stroke: black;
stroke-width: 7px;
}
div.annotation {
position: absolute;
white-space: nowrap;
width: 8em;
bottom: 1em;
background-color: white;
line-height: 1;
text-shadow: 0 0 10px white, 0 0 10px white, 0 0 10px white, 0 0 10px white, 0 0 10px white, 0 0 10px white, 0 0 10px white;
}
</style>
Have you plans to support logarithmic scale grids?