kd-lane-chart
v0.1.10
Published
kd 泳道图 + 实时曲线组件
Downloads
974
Readme
kd-lane-chart(Vue 2)使用文档
面向第一次接入的开发者:从安装、跑通演示,到配置模板、灌数据、监听事件、调用 ref 方法,以及常见问题。
| 项 | 说明 |
| ------ | ---------------------------- |
| npm 包名 | kd-lane-chart(当前约 0.1.5) |
| 框架 | Vue ^2.6 / 2.7 |
| UI | Element UI |
| 演示工程 | 本目录 kd-curve-v2(vue-cli) |
| 发布产物 | kd-curve-v2/publish/ |
| 仓库总览 | 仓库根目录 使用文档.md(v2/v3 对照) |
旧包名
kd-curve-v2、kd-lane-container已废弃,请统一使用kd-lane-chart。
专题手册(按需阅读,不要整份拷贝 App.vue):
| 专题 | 路径 |
| ----- | ------------------------------------------------ |
| 趋势线 | src/components/kdCurveV2/trend-line/趋势线使用手册.md |
| 对数轴 | src/components/kdCurveV2/log-axis/对数轴使用手册.md |
| 加载/内存 | src/components/kdCurveV2/perf/加载优化文档.md |
目录
- 它是什么 / 能做什么
- 环境与安装
- 本地跑演示
- 最小接入(5 分钟)
- 页面必须满足的条件
- 布局面板说明
- Props 一览
- depthConfig / timeConfig 详解
- 曲线数据 curveDatas
- 工具栏 toolBarConfig
- 插槽(自定义表头 / 地层)
- 事件
- ref 方法(重点)
- 强制更新配置 forceUpdateCurveConfig
- 预警 / Tooltip / 主题
- 交互模式与轴标签
- 单独使用 KdLaneContainer
- 多语言
- 接入检查清单
- 常见问题
1. 它是什么 / 能做什么
kd-lane-chart 提供两套可注册组件:
| 组件 | 用途 |
| --------------------------------- | --------------------------------------------- |
| FrameLayout / frameLayout | 业务主入口:左侧参数栏 + 井深时间小图 + 中间泳道曲线 + 右侧工具栏 |
| KdLaneContainer | 仅泳道图(模板配置、拖拽、编辑模板),一般嵌在 FrameLayout 内部;也可单独使用 |
典型场景:钻井实时/历史曲线、井深或时间轴切换、比例尺缩放、预警线、趋势线编辑、自定义岩性道插槽等。
数据流(简化):
你的业务页
├─ depthConfig / timeConfig → 模板(泳道、曲线样式、量程)→ 可落 IndexedDB
├─ curveDatas → 实际测点(replace / append)
├─ toolBarConfig.form → 当前轴类型、历史/实时、比例尺…
└─ ref 方法 / 事件 → 读配置、强制写库、切轴补数、趋势线…2. 环境与安装
2.1 依赖要求(peer)
请在你的业务工程中自行安装(版本按 peer 建议):
| 依赖 | 建议版本 |
| ----------------- | ---------------- |
| vue | ^2.6.0(推荐 2.7) |
| element-ui | ^2.15.14 |
| echarts | *(演示用 5/6 均可) |
| vuedraggable | ^2.24.3 |
| v-click-outside | ^2.1.3 |
| resize-detector | ^0.3.0 |
| lodash-es | ^4.18.1 |
业务工程还需自行 Vue.use(ElementUI)(或按需引入),并引入 Element UI 样式。
2.2 从 npm 安装
npm install kd-lane-chart
# 或
pnpm add kd-lane-chart
yarn add kd-lane-chart2.3 本仓库 monorepo 开发
仓库根目录已配置 workspace,发布包在 kd-curve-v2/publish,包名仍是 kd-lane-chart。
# 仓库根
pnpm install
pnpm build:v2 # 构建 publish 产物
# 业务工程可用 workspace 或 link
# 例:test-v2 中 "kd-lane-chart": "workspace:*"本地 link:
cd kd-curve-v2/publish
pnpm run link # build + pnpm link --global
# 再到业务工程:pnpm link --global kd-lane-chart2.4 注册组件
全局注册(推荐):
import Vue from "vue";
import ElementUI from "element-ui";
import "element-ui/lib/theme-chalk/index.css";
import { KdLaneContainer, FrameLayout, setCurrentLocale } from "kd-lane-chart";
Vue.use(ElementUI);
Vue.use(KdLaneContainer);
Vue.use(FrameLayout); // 同时注册 FrameLayout 与 frameLayout(兼容旧名)
setCurrentLocale("zh-CN"); // 可选,默认中文局部注册:
import { FrameLayout, KdLaneContainer } from "kd-lane-chart";
export default {
components: { FrameLayout, KdLaneContainer },
};模板里可用:
<frame-layout>/<FrameLayout>/<frameLayout><kd-lane-container>(组件name以源码为准)
2.5 源码调试(不经过 npm)
import frameLayout from "@/components/kdCurveV2/frame-layout/index.js";
Vue.use(frameLayout);路径按你工程别名调整,并保证 echarts / element-ui 等依赖可用。
3. 本地跑演示
cd kd-curve-v2
pnpm install # 若根目录已 install,可跳过
pnpm serve- 默认:
http://127.0.0.1:8888/(见vue.config.js) - 若端口被占用,vue-cli 可能自动升到
8889等,以终端输出为准
演示页是 src/App.vue,含大量 mock 与调试按钮,不要整页拷进生产业务,只复用配置形态与事件对接方式。
构建发布包:
# 仓库根
pnpm build:v24. 最小接入(5 分钟)
<template>
<div class="page" data-theme="dark">
<frame-layout
ref="frameLayout"
theme-name="dark"
:depth-config="depthConfig"
:time-config="timeConfig"
:curve-datas="curveDatas"
:tool-bar-config="toolBarConfig"
@template-change="onTemplateChange"
@update-settings="onUpdateSettings"
@config-change="onConfigChange"
/>
</div>
</template>
<script>
export default {
data() {
return {
depthConfig: {
type: "local",
caseId: "my-well-depth",
versionCode: 1,
dataSource: {
templates: [
{
templateName: "默认",
isPublic: "1",
createUser: "SYSTEM_USER",
lanes: [
{
laneName: "井深",
laneKey: "wellDepth",
canScroll: false,
canDrag: false,
width: 60,
sort: 0,
lines: [],
},
{
laneName: "大钩负荷",
sort: 1,
width: 120,
lines: [
{
paramId: "8010",
lineSort: 1,
min: 0,
max: 8000,
lineSize: "2",
lineType: "solid",
isUsed: "1",
lineColor: "#3DE375",
},
],
},
],
},
],
params: [
{ paramId: "wellDepth", paramName: "井深", paramUnit: "m" },
{ paramId: "8010", paramName: "大钩负荷", paramUnit: "kN" },
],
},
},
timeConfig: {
type: "local",
caseId: "my-well-time",
versionCode: 1,
dataSource: {
templates: [/* 结构同 depth,轴列 laneKey 用 timestamp */],
params: [/* ... */],
},
},
toolBarConfig: {
show: true,
axisTypeList: { depth: "wellDepth", time: "timestamp" },
form: {
axisType: "depth",
dataType: "history",
displayType: "float",
scale: 5,
},
},
curveDatas: {
type: "replace",
data: [
{ wellDepth: 1000, timestamp: Date.now(), "8010": 1200 },
{ wellDepth: 1001, timestamp: Date.now() + 1000, "8010": 1250 },
],
},
};
},
mounted() {
document.body.setAttribute("data-theme", "dark");
},
methods: {
onTemplateChange() {},
onUpdateSettings({ key, value }) {
// 切轴 / 切实时历史时建议 replace 对应数据
console.log("settings", key, value);
},
onConfigChange({ axisType, config, reason }) {
// 编辑模板保存 / 强制更新后,把 config 写回你的 depthConfig 或 timeConfig
if (axisType === "time") this.timeConfig = { ...this.timeConfig, ...config, dataSource: config.dataSource };
else this.depthConfig = { ...this.depthConfig, ...config, dataSource: config.dataSource };
console.log("config-change", reason, axisType);
},
},
};
</script>
<style>
.page {
height: 100vh;
width: 100%;
}
</style>5. 页面必须满足的条件
- 外层有明确高度(如
100vh/ 父级 flex 撑满)。组件内部多为overflow: hidden,高度为 0 时什么也看不见。 - 主题一致:
:theme-name="'dark'"且document.body.setAttribute("data-theme", "dark")。可选:white/dark/gray。 - 先
replace一批数据,实时场景再append。 axisTypeList字段名 = 数据行键名 = 轴列laneKey(例如都用wellDepth/timestamp)。paramId= 数据行字段名;缺测请用null,不要用0冒充空值。- 改了模板结构务必
versionCode + 1,否则浏览器 IndexedDB 仍用旧缓存。
6. 布局面板说明
从左到右最多四栏,中间可拖宽:
| 面板 | 内容 | 如何开关 |
| --- | ---------- | ------------------------------------------------------------- |
| 左 1 | 参数列表 | parameterPanelConfig.show !== false |
| 左 2 | 井深-钻头-时间小图 | WellBitDepthTimePlotConfig.show !== false |
| 中 3 | 主曲线泳道 | 配置非空即显示 |
| 右 4 | 工具栏 | toolBarConfig === false 或 toolBarConfig.show === false 隐藏 |
弹窗内只嵌曲线、不要工具栏时::tool-bar-config="false"。隐藏工具栏时内部仍保留默认 form,避免轴类型丢失。
注意:
formCache不是 FrameLayout 的 prop,而是内部状态,由toolBarConfig.form初始化。
7. Props 一览
| 参数 | 类型 | 默认 | 说明 |
| ---------------------------- | ---------------- | ---------------- | ------------------------------------ |
| depthConfig | Object | {} | 井深轴模板配置 |
| timeConfig | Object | {} | 时间轴模板配置 |
| curveDatas | Object | {} | { type: 'replace'|'append', data } |
| themeName | String | "" | white / dark / gray |
| toolBarConfig | Object / false | {} | 右侧工具栏;false 隐藏 |
| parameterPanelConfig | Object | {} | { show, width, columns, data } |
| WellBitDepthTimePlotConfig | Object | {} | 左侧小图 |
| headerStyle | Object | 见下 | 表头样式 |
| headerSlotName | Array | [] | 自定义表头槽登记 |
| contentSlotName | Array | [] | 自定义内容槽登记 |
| customMenuList | Array | [] | 右键扩展菜单 |
| showContextMenuStatus | Boolean | true | 是否启用右键 |
| warningData | Array | [] | 预警横线 |
| warningLabelConfig | Object | { show: true } | 预警文字 |
| warningAreaData | Array | [] | 预警色带 |
| tooltipFormatter | Function | null | 必须返回 HTML 字符串 |
| lineListData | Array | [] | 趋势线回显 |
| isGeomechanical | Boolean | false | 地应力模式 |
| missingPointMenuConfig | Object | 内置 | 缺数点菜单 |
| markAreaMenuConfig | Array | 内置 | 区块菜单 |
headerStyle 示例:
headerStyle: {
headerPadding: 4,
headerItemHeight: 48,
itemGap: 4,
}8. depthConfig / timeConfig 详解
组件根据当前 form.axisType(depth / time)选用对应配置。
8.1 外层结构
{
type: "local", // local:IndexedDB + 内置策略;其它走 CustomStrategy
caseId: "depth", // 存储隔离键,必填;井/场景不同请用不同 caseId
versionCode: 1, // 模板结构变更必须递增,否则继续用旧缓存
dataSource: {
templates: [ /* 树形:template → lanes → lines */ ],
params: [ /* 参数字典 */ ],
},
}dataSource 也可为扁平 { templates, lanes, lines, params },内部会规范化。
8.2 params
params: [
{ paramId: "wellDepth", paramName: "井深", paramUnit: "m", paramNameEn: "Depth" },
{ paramId: "8010", paramName: "大钩负荷", paramUnit: "kN" },
]8.3 泳道 lanes
| 字段 | 说明 |
| -------------------- | ---------------------------------------------------- |
| laneName | 显示名 |
| laneKey | 特殊道:等于 axisTypeList.depth / .time 则为轴列;也可作自定义表头键 |
| contentKey | 有则该道绘图区走插槽(如岩性) |
| width / minWidth | 列宽 |
| sort | 排序 |
| canScroll | false:不跟滚轮窗口(轴列、地层列常用) |
| canDrag | false:禁止拖列 |
| isLogScale | '1' / true 打开对数轴 |
| lines | 曲线数组;轴列、纯插槽列可为空 |
| createUser | 如 "SYSTEM_USER" |
8.4 曲线 lines
{
paramId: "8010",
lineSort: 1,
min: 0,
max: 8000,
lineSize: "2",
lineType: "solid",
isUsed: "1",
lineColor: "#3DE375",
// 或 themeConfig: { white: { lineColor }, dark: {...}, gray: {...} }
}- 用户在「编辑模板」里改过的 min/max 会带
templateRangeSaved,之后setCurveMinMaxByParamId默认不会覆盖。 - 原先未设量程时,刷新后以用户编辑保存的值为准(见近期量程锁定逻辑)。
改完静态种子模板后务必提高 versionCode,或使用下文的 forceUpdateCurveConfig 强制写库。
9. 曲线数据 curveDatas
// 整表替换(初始化、切轴、切历史/实时)
this.curveDatas = { type: "replace", data: rows };
// 实时追加
this.curveDatas = { type: "append", data: row };
this.curveDatas = { type: "append", data: [row1, row2] };每一行:
- 必须有当前轴字段(如
wellDepth和/或timestamp) - 曲线点:键 =
paramId,值为数字 - 缺测用
null,不要用0
{ wellDepth: 5128.31, timestamp: 1709019984000, "8010": 1200, "8018": null }实时场景:
dataType === "real":业务侧定时 / WebSocketappend@chart-scroll:触顶/触底补历史@updateSettings:切轴/切实时历史时replace对应数据集
10. 工具栏 toolBarConfig
toolBarConfig: {
show: true,
width: 120,
axisTypeList: {
time: "timestamp",
depth: "wellDepth",
},
scaleList: [
{ label: "1:100", value: 1 },
{ label: "1:500", value: 5 },
{ label: "1:2000", value: 20 },
],
form: {
axisType: "depth", // time | depth
dataType: "history", // real | history
displayType: "float", // header | float
scale: 5,
showLogAxis: true,
},
// 另有各类 *BtnShow / *SelectShow 开关,未传走组件默认
}scale 与 scaleList.value 对应:值越大,可见井深窗口通常越「深」(同一屏显示更多米)。
11. 插槽(自定义表头 / 地层)
在 @template-change 里根据 laneKey / contentKey 维护 headerSlotName / contentSlotName,再在模板用动态 slot:
<template v-for="lane in headerSlotName" :slot="lane.laneId">
<div :key="lane.laneId">{{ lane.laneName }}</div>
</template>
<template v-for="lane in contentSlotName" :slot="lane.laneId">
<div :key="lane.laneId"><!-- 自定义 ECharts / 岩性 --></div>
</template>登记示例:
onTemplateChange(data) {
const { lanes } = data;
(lanes || []).forEach((item) => {
if (Object.prototype.hasOwnProperty.call(item, "laneKey")) {
const rec = {
laneId: `lane${item.laneId}`,
laneKey: item.laneKey,
laneName: item.laneName,
};
// push 或更新 headerSlotName
}
if (Object.prototype.hasOwnProperty.call(item, "contentKey")) {
const rec = {
laneId: `content${item.laneId}`,
contentKey: item.contentKey,
laneName: item.laneName,
};
// push 或更新 contentSlotName
}
});
}@visibleDataChange 给出当前窗口 { firstValue, lastValue },用于重算自定义道内容。
12. 事件
| 事件 | 载荷 | 何时 |
| --------------------- | -------------------------------- | -------------------- |
| template-change | 当前模板 | 模板/泳道增删改、拖拽落定 |
| line-change | { ...line, actionType } | 曲线配置变更 |
| config-change | { reason, config, axisType } | 保存/重置/拖拽/强制更新后回传最新配置 |
| params-change | params 数组 | 参数表变更 |
| chart-scroll | { direction, currentData } | 窗口触顶/触底 |
| updateSettings | { key, value, settings } | 切轴、切实时/历史等 |
| visibleDataChange | { firstValue, lastValue, ... } | 可见轴范围变化 |
| dialogFunction | { type, start, end } | 井深段/时间段/导出 |
| refresh | — | 刷新按钮 |
| showContextMenu | 右键目标 | 打开菜单 |
| onCustomMenuClicked | 菜单事件 | 自定义菜单 |
| trend-change | 趋势线结构 | 趋势线编辑后 |
| lane-width-change | 列宽 map | 拖列宽 |
config-change.reason 常见值:save | confirm | restore | drag | force-update。
建议在业务里把 config 按 axisType 写回 depthConfig / timeConfig(可原地改 dataSource,避免无谓整表重建)。
13. ref 方法(重点)
const fl = this.$refs.frameLayout;| 方法 | 说明 |
| -------------------------------------------------------------------------- | ----------------------------------------------------- |
| getCurrentConfig() | 返回 { axisType, config },config 含最新 templates/params |
| forceUpdateCurveConfig(nextConfig?, options?) | 强制覆盖当前轴配置(内存 + IndexedDB),并触发 config-change |
| setCurveMinMaxByParamId(paramsId, min, max) | 改量程;模板已锁定则返回 false |
| getTrendLineData() / setTrendLineData(paramId, segments) | 趋势线读写 |
| breakTrendSegment() / resetTrendLine(paramId) / resetAllTrendLines() | 趋势线编辑 |
| clearActiveLane() | 清泳道选中红框 |
| clearChartData() | 清空图上数据 |
| refresh() | 内部重置到初始 form/数据 |
| startLoading() / stopLoading() | 加载态 |
| jumpToNextMarkLine(percent?) | 跳下一条预警线(0 顶、100 底,默认 50) |
| updateForm({ key, value }) | 改内部 form |
14. 强制更新配置 forceUpdateCurveConfig
当你需要不管 IndexedDB 旧缓存,直接用新配置(或把当前内存配置强制落库)时使用。
14.1 只强制落库「当前内存配置」
await this.$refs.frameLayout.forceUpdateCurveConfig();
// 会:清空该 caseId 的 IndexedDB → 写入当前快照 → 重载图 → emit config-change14.2 用外部新配置强制覆盖
const next = {
type: "local",
caseId: "my-well-depth",
versionCode: 2,
dataSource: {
templates: [/* 新模板树 */],
params: [/* ... */],
},
};
const { axisType, config, reason } = await this.$refs.frameLayout.forceUpdateCurveConfig(next);
// reason === 'force-update'
if (axisType === "time") {
this.$set(this.timeConfig, "dataSource", config.dataSource);
} else {
this.$set(this.depthConfig, "dataSource", config.dataSource);
}14.3 选项
await this.$refs.frameLayout.forceUpdateCurveConfig(next, {
updateDefaultSnapshot: true, // 默认 true:同步作为「恢复默认」基准
});14.4 与 versionCode 的关系
- 日常改种子模板:优先
versionCode++,让初始化逻辑升级存储。 - 需要立刻覆盖且不想改版本号:用
forceUpdateCurveConfig(内部forceInit清库重写)。
14.5 恢复默认
右键「恢复默认」会尽量用策略内默认 / 初始化时冻结的传入 depthConfig|timeConfig.dataSource。若找不到匹配泳道,会回退到该快照再匹配。
15. 预警 / Tooltip / 主题
预警横线:
warningData: [
{ data: { depth: 8177.68, timestamp: 1735925795000 }, color: "#FF4D4F80" },
]Tooltip:
tooltipFormatter({ series, mousePositionData }) {
let html = `<div>井深 ${mousePositionData && mousePositionData.depth}</div>`;
(series || []).forEach((s) => {
html += `<div>${s.seriesName}: ${s.value}</div>`;
});
return html; // 必须是字符串
}主题:themeName + body[data-theme] 同步。
16. 交互模式与轴标签
| isGeomechanical | 行为 |
| ----------------- | ---------------------- |
| false | 滚轮改可见窗口,多泳道同步 |
| true | 地应力:窗口缩放/平移;趋势线与曲线共用视图 |
井深刻度由 HTML 叠层绘制。缩放时会按可视密度疏化刻度,避免挤压重叠;松手后再精确刷新。
对数轴:泳道 isLogScale = '1',详见对数轴手册。
17. 单独使用 KdLaneContainer
<kd-lane-container :config="depthConfig" theme-name="dark" />config 必须含 caseId、type、versionCode、dataSource。
事件:template-change、line-change、params-change、config-change、lane-width-change 等。
同样支持 getCurrentConfig / forceUpdateCurveConfig(在泳道容器 ref 上)。
18. 多语言
import { setCurrentLocale, getCurrentLocale } from "kd-lane-chart";
setCurrentLocale("en"); // 或 "zh-CN"
console.log(getCurrentLocale());曲线显示名优先 paramNameEn / laneNameEn,否则走内置映射表。
19. 接入检查清单
- [ ] 容器有高度;
data-theme与themeName一致 - [ ] 已安装 peer:vue / element-ui / echarts / vuedraggable 等
- [ ]
Vue.use(FrameLayout)与 ElementUI - [ ]
axisTypeList= 数据行键 = 轴列laneKey - [ ]
paramId= 数据行键;缺测null - [ ] 改模板后
versionCode + 1,或调用forceUpdateCurveConfig - [ ] 监听
config-change写回业务侧 depth/time 配置 - [ ] tooltip 返回字符串
- [ ] 切轴/切实时历史时
replace数据 - [ ] 不要
chart.getOption()做业务逻辑;不要connectNulls: true糊缺口
20. 常见问题
切井深/时间后图是空的replace 的数据缺少当前轴字段,或模板 laneKey 对不上 axisTypeList。
改了模板没变化
IndexedDB 仍是旧 versionCode。加一版本,或 forceUpdateCurveConfig(新配置)。
曲线扎到 0 / 量程被拉开
空值被写成了 0。保持 null。
量程接口返回 false
模板已保存过该曲线 min/max(templateRangeSaved),或 paramsId 无效。
缩放卡顿、井深轴挤在一起
请使用当前版本:缩放中会疏化刻度并节流刷新。若仍卡,检查是否一次灌入过大全量且窗口未限制。
恢复默认没反应
确认初始化时曾传入完整 depthConfig/timeConfig;组件会冻结首份 dataSource 作回退。
附录:导出一览
import {
KdLaneContainer,
FrameLayout,
frameLayout, // 同 FrameLayout,兼容旧名
setCurrentLocale,
getCurrentLocale,
} from "kd-lane-chart";