用 Layer Cake 制作的 Svelte 图表上有工具提示吗?

问题描述 投票:0回答:2

我正在尝试向我使用 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框架。

tooltip svelte
2个回答
0
投票

我想通了。最重要的是在 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 中一样)。


0
投票

我想做类似的事情并遇到完全相同的问题 - 您更新的 REPL/代码不会在我的鼠标悬停时显示工具提示 -

谢谢

© www.soinside.com 2019 - 2024. All rights reserved.