npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@melt-js/comps-vue3-datav

v2026.11.8

Published

数据可视化(datav)远程组件包:从 fengtianxi001/MF-2.5DMap 抽出的 2.5D 行政区地图 DvMap25D(three.js + geojson,挤出 / 边框 / 光圈 / 标签 / 交互)与行政区选择器 DvRegionSelect,通过 hel-micro 以远程组件方式加载;后续图表、边框、装饰等大屏组件继续放进本包

Readme

@melt-js/comps-vue3-datav

数据可视化(datav)方向的 Vue 3 远程组件包:第一个组件是从 fengtianxi001/MF-2.5DMap 抽出的 2.5D 行政区地图 DvMap25D(geojson + three.js:挤出、边框、光圈、点阵、行政区标签、悬停 / 点击交互), 外加一个不依赖 UI 框架的行政区选择器 DvRegionSelect。 通过 hel-micro 以远程组件方式加载,本地端口 20093。

DvMap25D

这个包是「datav 组件集合」的容器,后续图表、边框、装饰、地图类组件继续按 新增组件约定 放进本包,不需要再新建工程。

组件一览

| 组件 | 说明 | | --- | --- | | DvMap25D | 2.5D 行政区地图。按 adcode 请求 geojson.cn,或用 geojson / loader 传自己的数据;自动取景、拖拽旋转、滚轮缩放、点击 / 悬停事件、加载与错误重试 | | DvRegionSelect | 全国 + 省级行政区选择器(原生 <select>,深色大屏皮肤,v-model 绑 adcode) | | 工具函数 | loadGeojson / resolveGeojsonUrl / getGeojsonBbox / getFeatureCenter / clearGeojsonCache 等;行政区数据 CN_REGIONS / CN_PROVINCES / findRegion |

开发 / 构建

pnpm comps-datav:dev            # http://localhost:20093 独立调试页(playground)
pnpm comps-datav:build          # 发布产物:资源地址指向 unpkg
pnpm comps-datav:build:local    # 本地联调产物:资源地址指向 http://localhost:20093
pnpm comps-datav:preview        # 预览已构建的 hel_dist
pnpm comps-datav:publish:stage  # 构建 + npm stage 暂存

产物结构与仓库内其它 comps-* 一致:

  • hel_dist/:UMD 单文件 + 单个 css + 贴图 + hel-meta.json;
  • hel_proxy/、hel_proxy_es/:给 npm i @melt-js/comps-vue3-datav 的消费方 import 的空壳代理, 真正实现由 preFetchLib 注入。

宿主接入

import { bindVueRuntime, preFetchLib } from 'hel-micro'
import * as Vue from 'vue'
import { createApp } from 'vue'
import lib from '@melt-js/comps-vue3-datav' // npm 包只是一层空壳代理

bindVueRuntime({ Vue }) // 远程包把 vue external 成 window.Vue,两边必须共用一份

await preFetchLib('comps-vue3-datav', {
  custom: {
    // 本地:pnpm comps-datav:dev 的地址;生产:unpkg 上的 hel-meta.json
    host: 'http://localhost:20093',
    skipFetchHelMeta: true,
    enable: true,
    trust: true
  }
})

const app = createApp(App)
lib.installDatavComponents(app) // 全局注册 DvMap25D / DvRegionSelect
app.mount('#app')

也可以按需注册:app.component('DvMap25D', lib.DvMap25D),或遍历 lib.components。

最小示例

<template>
  <!-- 尺寸由父容器决定:组件自身是 100% × 100%,父级必须有高度 -->
  <div style="height: 520px">
    <DvMap25D
      :adcode="340000"
      :depth="0.04"
      :pitch="45"
      @load="onLoad"
      @region-click="onRegionClick"
      @region-hover="onRegionHover"
      @error="onError"
    >
      <!-- 默认插槽:图例 / 标题 / 指标卡等覆盖层,默认不拦截地图交互 -->
      <div class="legend">安徽省 16 个地市</div>
    </DvMap25D>
  </div>
</template>

插槽里的按钮、下拉框等可交互元素需要自己加 pointer-events: auto—— 覆盖层本身是 pointer-events: none,否则整块透明层会把地图的拖拽 / 拾取吃掉。

DvMap25D

Props

| 属性 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | adcode | string \| number | 100000 | 行政区代码。未传 geojson 时请求 https://geojson.cn/api/data/{adcode}.json | | geojson | object \| string | — | 直接给 FeatureCollection 或 geojson 地址,优先级高于 adcode | | depth | number | 0.04 | 挤出厚度,相对地图包围盒最大边长的比例(源项目省级地图 0.2 / 约 5° 跨度 ≈ 0.04,所以全国地图也不会糊成一张纸) | | pitch | number | 45 | 相机俯仰参数,范围 5 ~ 85,越大越接近俯视;内部换算为仰角 atan(1.5 · tan(pitch)),与上游一致 | | labels | boolean | true | 是否显示行政区标签 | | background | boolean | true | 是否显示光圈 / 点阵背景 | | interactive | boolean | true | 是否允许拖拽 / 缩放 | | hoverHighlight | boolean | true | 悬停是否高亮行政区(高亮不影响 region-hover 事件的派发) | | loader | (url) => Promise<FeatureCollection> | — | 自定义 geojson 加载器(走自己的代理 / 内网接口时用) | | loadingText | string | 地图加载中… | 加载中文案 |

Events

| 事件 | 载荷 | 说明 | | --- | --- | --- | | ready | { scene, camera, renderer, controls } | three 场景就绪(组件挂载后立即触发,此时还没有数据) | | load | { geojson, adcode, regionCount } | geojson 加载、贴图就绪、场景构建完成 | | error | Error | 加载失败(组件会同时显示错误态 + 「重新加载」按钮) | | region-click | MapRegion | 点击行政区;拖拽视角不会误触发 | | region-hover | MapRegion \| null | 悬停行政区,移出时 null |

MapRegion 结构:

interface MapRegion {
  name: string // 行政区名,如「合肥」
  code: string // 行政区代码,如「340100」
  properties: Record<string, any> // geojson.properties(name / fullname / center / pinyin ...)
  feature: GeoJsonFeature
}

Expose

| 方法 | 说明 | | --- | --- | | reload() | 重新请求 / 重新渲染当前行政区(错误重试也用它) | | fitView(animate?) | 让相机重新适配当前地图范围,默认带 1.1s 缓动 | | getGeojson() | 当前 FeatureCollection | | getScene() / getCamera() / getRenderer() / getControls() | three 对象,方便宿主叠加自定义图层 |

取景与交互

  • 相机始终站在地图南侧朝北俯视,center 为包围盒中心;
  • 取景距离按「实际轮廓点投影到视口」二分求出(不是简单按包围盒高度), 任何 pitch、全国 / 窄长省份都不会把地图裁掉或缩成一小块;
  • 首次进入有一次从远处推进的入场动画,切换行政区时从当前机位平滑过渡;
  • 鼠标移到行政区上会高亮并派发 region-hover;按下到抬起位移 > 6px 视为拖拽,不派发点击。

DvRegionSelect

<DvRegionSelect v-model="adcode" label="行政区" />

| 属性 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | modelValue | string \| number | 100000 | 当前 adcode | | options | RegionOption[] | CN_REGIONS | 选项,默认「全国 + 34 个省级行政区」,可传自己的 | | label | string | '' | 左侧标题 | | placeholder | string | '' | 占位项(会多一个 disabled 空选项) | | disabled | boolean | false | 禁用 | | block | boolean | false | 占满父容器宽度 |

事件:update:modelValue(value: number)、change(value, option)。

数据源

  • 默认走 geojson.cn:https://geojson.cn/api/data/{adcode}.json;
  • 免费接口只开放**国家(100000)与省级(如 340000)**数据,市级 / 区县需要授权 (https://geojson.cn/api/data/340000/340100.json 会返回 403);
  • 需要市级 / 区县 / 自定义边界时,把 geojson 传成 FeatureCollection 或 URL, 或者用 loader 接自己的接口;
  • 默认加载器按 URL 做内存缓存(切回同一行政区不重复请求), 可用 lib.clearGeojsonCache() 清空。

与上游的差异

上游是一个 300 行左右的演示页(BaseMap + useMap + useThree),抽包时按「可复用组件」重写了一遍:

| 项目 | 上游 | 本包 | | --- | --- | --- | | 生命周期 | rAF / 监听器 / 渲染器基本不回收,多页面切换会泄漏 | onBeforeUnmount 统一 dispose:rAF、ResizeObserver、指针事件、几何体、材质、贴图、WebGL 上下文 | | 尺寸 | 容器写死 100vw / 100vh,只读一次 clientWidth | 组件 100% × 100%,ResizeObserver 跟随容器;Line2 线宽同步 resolution | | 贴图地址 | ./texture/xxx,相对路径在远端加载时 404 | ?url 静态导入,随 base 走 unpkg / localhost 绝对地址 | | 标签中心 | 用了 properties.centroid(geojson.cn 实际叫 center),取不到时又用整幅地图的 centroid,标签会全叠在中心 | properties.center → properties.centroid → 逐要素坐标平均值 | | 厚度 | extrudeSettings.depth 写死 0.2,depth 参数只影响标签高度 | depth 按地图尺寸取比例,全国 / 省级都成立 | | 取景 | 依赖 maxDistance 夹紧相机,低角度 / 宽地图会裁切 | 按照实际轮廓点投影二分求距离;对「远离主体的零碎多边形」(如 geojson.cn 天津多出的 113.7, 36.6 碎块)只渲染、不参与取景,避免地图被推到画布角落 | | 相机入场 | 从世界原点 (0,0,0) 穿过地图 | 从当前机位 / 稍远处平滑推进 | | 依赖 | @turf/turf、@tweenjs/tween.js、axios、lodash | 只留 three;bbox / 中心点 / 补间 / 请求都收敛成几十行内部实现 | | 点击 / 悬停 | 只有每帧 raycast 变红,没有对外事件 | region-click / region-hover 事件 + 可关闭的高亮;拖拽不误触 | | 加载态 | 无 | loading 遮罩、错误文案 + 重试、load / error 事件 | | 资源 | 5.4 MB 原图(2048 卫星图 3.7 MB、若干 PNG) | 压成 webp 共约 0.9 MB,纹理细节在 2048 下保持 | | 选择器 | Arco a-select,把 UI 框架带进组件包 | 原生 <select>,零 UI 依赖 |

另外修掉了上游两个小问题:control.maxDistance 连续赋值两次(minDistance 笔误)、 adjustCamera 里 camera 初始位置为 (0,0,0) 导致首帧穿过几何体。

数据层面还有两个兼容处理:

  • 主区域聚类取景:有些 geojson 会给要素挂一个远离主体的零碎多边形(geojson.cn 的天津 多出一块 113.7, 36.6 附近的 6 点碎块;海南要素里还带南海诸岛)。从面积最大的多边形开始, 把「离当前聚类包围盒不超过 0.35 倍聚类尺寸」的多边形逐步并进来,剩下的碎块只渲染、不参与 取景 —— 天津因此能正常居中;全国视图的聚类会长到大陆尺度,南海诸岛照旧进入取景;
  • 只给面状要素加标签:MultiLineString 类型的「十段线」不再按坐标平均值挂一个孤立标签。

新增组件约定

后续组件直接放进本包,按下面几步走:

  1. 实现:新建 src/components/<Name>/index.vue,类名 / 全局组件名统一 Dv 前缀 (如 DvScatterMap、DvPanel),样式写在组件内,动态 DOM 的样式用 .dv-xxx 前缀命名;
  2. 登记:在 src/components/index.ts 里 import / export / 加进默认导出, installDatavComponents(app) 会自动遍历注册,不用改 install.ts;
  3. 导出:需要给宿主用的工具函数放 src/utils/,再按需加进 src/entrance/libProperties.ts;
  4. 调试页:在 src/playground/App.vue 里加一个演示区块(这是 pnpm comps-datav:dev 的页面);
  5. 文档:更新本 README 的「组件一览」与对应 API 小节;
  6. 构建:pnpm comps-datav:build 会跑 check_name(组名一致性)、check:tdz(TDZ 产物守卫)、 build_meta(hel-meta.json)、build_proxy(空壳代理),新增组件不需要改脚本。

约定:

  • 组件里不要 import 宿主的 store / router / 请求实例;需要宿主能力时走 props / 事件 / 运行时注入;
  • 第三方运行时依赖(three、echarts 等)可以随包打进 hel_dist,vue 必须 external 成 window.Vue;
  • 新增较大的静态资源优先压成 webp / 压缩后再入库,避免包体膨胀。

目录结构

comps-vue3-datav/
├─ src/
│  ├─ components/
│  │  ├─ Map25D/
│  │  │  ├─ index.vue                 # DvMap25D
│  │  │  └─ hooks/
│  │  │     ├─ useThreeScene.ts       # three 场景外壳:相机 / 渲染器 / CSS2D / 控制器 / resize / dispose
│  │  │     └─ useMap25D.ts           # geojson → 图层 / 取景 / 拾取 / 生命周期
│  │  ├─ RegionSelect/index.vue       # DvRegionSelect
│  │  └─ index.ts                     # 组件清单
│  ├─ data/regions.ts                 # CN_REGIONS / CN_PROVINCES / findRegion
│  ├─ utils/geojson.ts                # 数据请求 + 缓存 + bbox / 中心点
│  ├─ utils/tween.ts                  # 极简 rAF 补间
│  ├─ assets/textures/*.webp          # 地图 / 光圈 / 点阵贴图
│  ├─ entrance/libProperties.ts       # 对外导出(宿主拿到的 lib 对象)
│  ├─ entrance/libTypes.js            # exposeLib,rollup 入口
│  ├─ configs/subApp.js               # LIB_NAME
│  ├─ install.ts                      # installDatavComponents(app)
│  ├─ playground/App.vue              # 独立调试页
│  ├─ main.js                         # UMD 入口:libReady + 独立页挂载
│  ├─ loadApp.js                      # 独立页 createApp(App)
│  └─ styles/index.css                # 调试页样式(只在 hel-standalone 生效)
├─ scripts/                           # check / meta / prepublishOnly / check-tdz
├─ appInfo.mjs                        # 端口与 homePage 推导
├─ vite.config.ts                     # UMD 单文件产物(vue external)
└─ rollup.config.js                   # hel_proxy / hel_proxy_es

已知限制

  • geojson.cn 免费接口只有国家级 / 省级数据,市级下钻需要自备 geojson;
  • 全国视图下省级标签会比较密(数据本身如此),可以在宿主侧传 :labels="false" 自己画;
  • 依赖 WebGL,SSR 环境只能渲染空容器,需要 <ClientOnly> 或在 onMounted 后再挂载;
  • 地图坐标直接用 WGS84 经纬度当世界坐标(与上游一致),不涉及投影换算。

来源与许可

  • 组件逻辑抽自 fengtianxi001/MF-2.5DMap(MIT 未声明、 仓库无 LICENSE 文件),贴图资源同样来自该仓库;
  • 上游仓库未声明开源协议,本包 license 暂标 UNLICENSED,公开发布前请先确认上游授权;
  • 仓库内其它包(comps-mini3d 等)的实现风格、构建链与本包保持一致。