@bubblesjs/vue-annotation

一个用于 NLP 任务的 Vue 3 文本标注组件,支持实体标注和关系标注,提供直观的可视化界面。

特性

  • 🏷️ 实体标注:使用可自定义的实体类型标记文本片段
  • 🔗 关系标注:创建实体之间的关系
  • 🌍 RTL 支持:支持从右到左的文本方向
  • 🎨 可定制标签:定义你自己的实体和关系标签类型
  • 📱 触摸支持:同时支持桌面和移动设备
  • 🌙 暗色模式:内置暗色主题支持

安装

pnpm
npm
yarn
pnpm add @bubblesjs/vue-annotation

快速开始

基础用法

<template>
  <Annotator
    :text="text"
    :entities="entities"
    :entity-labels="entityLabels"
    @add-entity="handleAddEntity"
    @click-entity="handleClickEntity"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { Annotator } from '@bubblesjs/vue-annotation'
import type { Entity, Label } from '@bubblesjs/vue-annotation'
import '@bubblesjs/vue-annotation/style.css'

const text = ref('苹果公司是一家总部位于美国加利福尼亚州库比蒂诺的跨国科技公司。')

const entityLabels = ref<Label[]>([
  { id: 1, text: '组织', color: '#4CAF50' },
  { id: 2, text: '地点', color: '#2196F3' }
])

const entities = ref<Entity[]>([
  { id: 1, startOffset: 0, endOffset: 4, label: 1 },   // 苹果公司
  { id: 2, startOffset: 14, endOffset: 19, label: 2 }, // 加利福尼亚州
  { id: 3, startOffset: 19, endOffset: 23, label: 2 }  // 库比蒂诺
])

const handleAddEntity = (event, startOffset, endOffset) => {
  console.log('选中文本:', text.value.slice(startOffset, endOffset))
  // 在这里添加你的实体创建逻辑
}

const handleClickEntity = (event, entityId) => {
  console.log('点击实体:', entityId)
}
</script>

带关系标注

<template>
  <Annotator
    :text="text"
    :entities="entities"
    :entity-labels="entityLabels"
    :relations="relations"
    :relation-labels="relationLabels"
    @click-relation="handleClickRelation"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { Annotator } from '@bubblesjs/vue-annotation'
import type { Entity, Label, Relation } from '@bubblesjs/vue-annotation'

const text = ref('张三在谷歌公司工作,位于山景城。')

const entityLabels = ref<Label[]>([
  { id: 1, text: '人物', color: '#E91E63' },
  { id: 2, text: '组织', color: '#4CAF50' },
  { id: 3, text: '地点', color: '#2196F3' }
])

const entities = ref<Entity[]>([
  { id: 1, startOffset: 0, endOffset: 2, label: 1 },   // 张三
  { id: 2, startOffset: 3, endOffset: 7, label: 2 },  // 谷歌公司
  { id: 3, startOffset: 13, endOffset: 16, label: 3 } // 山景城
])

const relationLabels = ref<Label[]>([
  { id: 1, text: '工作于', color: '#FF9800' },
  { id: 2, text: '位于', color: '#9C27B0' }
])

const relations = ref<Relation[]>([
  { id: 1, fromId: 1, toId: 2, type: 1 }, // 张三 工作于 谷歌公司
  { id: 2, fromId: 2, toId: 3, type: 2 }  // 谷歌公司 位于 山景城
])

const handleClickRelation = (event, relation) => {
  console.log('点击关系:', relation)
}
</script>

Props

属性 类型 默认值 说明
text string 必填 要标注的文本内容
entities Entity[] [] 实体标注列表
entityLabels Label[] [] 可用的实体标签类型
relations Relation[] [] 关系标注列表
relationLabels Label[] [] 可用的关系标签类型
maxLabelLength number 12 显示的最大标签文本长度
allowOverlapping boolean false 允许重叠的实体标注
rtl boolean false 从右到左的文本方向
graphemeMode boolean true 正确处理 Unicode 字素
dark boolean false 启用暗色模式
selectedEntities Entity[] [] 当前选中的实体

事件

事件 参数 说明
add-entity (event, startOffset, endOffset) 用户选择文本创建实体时触发
click-entity (event, entityId) 用户点击实体时触发
click-relation (event, relation) 用户点击关系时触发
contextmenu-entity (entity) 实体右键点击时触发
contextmenu-relation (relation) 关系右键点击时触发

类型定义

// 实体标注
interface Entity {
  id: number
  startOffset: number
  endOffset: number
  label: number // 引用 Label.id
}

// 标签定义
interface Label {
  id: number
  text: string
  color?: string
}

// 关系标注
interface Relation {
  id: number
  fromId: number // 引用 Entity.id
  toId: number   // 引用 Entity.id
  type: number   // 引用 Label.id
}

高级用法

暗色模式

<template>
  <div :class="{ 'dark-theme': isDark }">
    <Annotator
      :text="text"
      :entities="entities"
      :entity-labels="entityLabels"
      :dark="isDark"
    />
  </div>
</template>

RTL 支持(阿拉伯语、希伯来语等)

<template>
  <Annotator
    :text="arabicText"
    :entities="entities"
    :entity-labels="entityLabels"
    :rtl="true"
  />
</template>

正确处理 Unicode

graphemeMode 属性确保正确处理复杂的 Unicode 字符,如 emoji:

<template>
  <Annotator
    :text="'你好 👨‍👩‍👧‍👦 世界'"
    :entities="entities"
    :entity-labels="entityLabels"
    :grapheme-mode="true"
  />
</template>

使用场景

  • 命名实体识别(NER)标注
  • 文本分类标注
  • 关系抽取标注
  • 情感分析标注
  • 机器学习文档标注