我正在尝试向我使用 Svelte 图形框架 Layer Cake 制作的图表添加工具提示。我查看了 Layer Cake 网站上的地图示例,因为该示例有工具提示,但我不知道如何适应我的条形图。
我什至无法显示字符串,更不用说任何数据了。任何帮助将不胜感激。我想我一定错过了一些非常明显的东西。
下面是一个带有虚拟数据的最小示例。
您可以看到在此 REPL 中运行的代码: https://svelte.dev/repl/e8bb579754e6405ea19363b5d13d7f54?version=3.55.1
谢谢!
应用程序.svelte:
<script>
import { LayerCake, Svg, Html } from "layercake";
import Bar from "./Bar.svelte";
import AxisX from "./AxisX.svelte";
import AxisY from "./AxisY.svelte";
import Tooltip from "./Tooltip.html.svelte";
import { scaleBand } from "d3-scale";
let data = [
{
fruit: "Apple",
number: 364,
},
{
fruit: "Banana",
number: 263,
},
{
fruit: "Mango",
number: 872,
},
{
fruit: "Pear",
number: 156,
},
]
data.forEach((d) => {
d[xKey] = +d[xKey];
});
const xKey = "number";
const yKey = "fruit";
let evt;
let hideTooltip = false;
</script>
<div class="chart-container">
<LayerCake
padding={{ top: 20, bottom: 80, left: 60, right:40 }}
x={xKey}
y={yKey}
yScale={scaleBand().paddingInner([0.15])}
xDomain={[0, null]}
data={data}
>
<Svg>
<AxisX gridlines={true} baseline={true} snapTicks={true} ticks="4" />
<AxisY gridlines={false} />
<Bar
/>
</Svg>
<Html
pointerEvents={false}
>
{#if hideTooltip !== true}
<Tooltip
{evt}
>
{@const tooltipData = {data}}
{#each Object.entries(tooltipData) as [key, value]}
{console.log('tooltipData',tooltipData)}
<div class="row">hi is this showing up?</div>
{/each}
</Tooltip>
{/if}
</Html>
</LayerCake>
</div>
<style>
.chart-container {
width: 600px;
height: 300px;
}
</style>
其他组件直接取自LayerCake框架。
我想通了。最重要的是在 Bar 组件中添加一个调度事件,并为那里的矩形创建 mouseover、movemove、focus 事件。
更新 REPL:https://svelte.dev/repl/09725c92e4104d0cad53d0387a762269?version=3.55.1
应用程序.svelte:
<script>
import { LayerCake, Svg, Html } from "layercake";
import Bar from "./Bar.svelte";
import AxisX from "./AxisX.svelte";
import AxisY from "./AxisY.svelte";
import Tooltip from "./Tooltip.html.svelte";
import { scaleBand } from "d3-scale";
let data = [
{
fruit: "Apple",
number: 364,
},
{
fruit: "Banana",
number: 263,
},
{
fruit: "Mango",
number: 872,
},
{
fruit: "Pear",
number: 156,
},
]
data.forEach((d) => {
d[xKey] = +d[xKey];
});
const xKey = "number";
const yKey = "fruit";
let evt;
let hideTooltip = false;
</script>
<div id="chart-container">
<LayerCake
padding={{ top: 20, bottom: 80, left: 60, right:40 }}
x={xKey}
y={yKey}
yScale={scaleBand().paddingInner([0.15])}
xDomain={[0, null]}
data={data}
>
<Svg>
<AxisX gridlines={true} baseline={true} snapTicks={true} ticks="4" />
<AxisY gridlines={false} />
<Bar
on:mousemove={event => evt = hideTooltip = event}
on:mouseout={() => (hideTooltip = true)}
/>
</Svg>
<Html
pointerEvents={false}
>
{#if hideTooltip !== true}
<Tooltip
{evt}
let:detail
>
{@const tooltipData = { ...detail.props }}
<div class="row">{tooltipData.fruit}: {tooltipData.number}</div>
</Tooltip>
{/if}
</Html>
</LayerCake>
</div>
<style>
#chart-container {
width: 600px;
height: 300px;
}
</style>
Bar.svelte:
<script>
import { getContext, createEventDispatcher } from "svelte";
const { data, xGet, yGet, xScale, yScale } = getContext('LayerCake');
export let fill = '#ef4136';
let hideTooltip = false;
const dispatch = createEventDispatcher();
function handleMousemove(feature) {
return function handleMousemoveFn(e) {
raise(this);
// When the element gets raised, it flashes 0,0 for a second so skip that
if (e.layerX !== 0 && e.layerY !== 0) {
dispatch("mousemove", { e });
}
};
}
</script>
<g
class="bar-group"
on:mouseout={(e) => dispatch("mouseout")}
on:blur={(e) => dispatch("mouseout")}
>
{#each $data as d, i}
<rect
class='group-rect'
data-id="{i}"
x="{$xScale.range()[0]}"
y="{$yGet(d)}"
height={$yScale.bandwidth()}
width="{$xGet(d)}"
{fill}
on:mouseover={(e) => dispatch("mousemove", { e, props: d })}
on:focus={(e) => dispatch("mousemove", { e, props: d })}
on:mousemove={(e) => handleMousemove(e, d)}
></rect>
{/each}
</g>
Tooltip.html.svelte、AxisY.svelte 和 AxisX.svelte 保持原样(就像在 Layer Cake 中一样)。
我想做类似的事情并遇到完全相同的问题 - 您更新的 REPL/代码不会在我的鼠标悬停时显示工具提示 -
谢谢