feat: 支持用手机标注ner

This commit is contained in:
maxmon 2022-04-07 20:26:04 +08:00
parent ac1d2d41e4
commit a9e7a08805
6 changed files with 64 additions and 7 deletions

View File

@ -1,4 +1,4 @@
# dw-tool-ner
# whale-anno
> Datawhale's ner tool.

View File

@ -17,7 +17,7 @@ module.exports = {
},
// Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST
host: '0.0.0.0', // can be overwritten by process.env.HOST
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: false,
errorOverlay: true,

2
fe/dist/index.html vendored
View File

@ -1,4 +1,4 @@
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>dw-tool-ner</title><link href=/static/css/app.cb359e49664391241f41c3263ba7c710.css rel=stylesheet></head><body><div id=app></div><style>html, body {
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>whale-anno</title><link href=/static/css/app.cb359e49664391241f41c3263ba7c710.css rel=stylesheet></head><body><div id=app></div><style>html, body {
display: inline-block;
margin: 0;
width: 100%;

View File

@ -2,8 +2,8 @@
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>dw-tool-ner</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
<title>whale-anno</title>
</head>
<body>
<div id="app"></div>

View File

@ -43,7 +43,24 @@
</span>
</div>
</div>
<div id="ner-box" class="ner-box" @mouseup="setMode('')" @mouseleave="setMode('');setFocus('')" @keydown="setTypeByFastKey" @mouseover="setFocus('ner-box')">
<div id="ner-box" class="ner-box" @mouseup="setMode('')" @touchend="setMode('')" @mouseleave="setMode('');setFocus('')" @keydown="setTypeByFastKey" @mouseover="setFocus('ner-box')">
<!-- <svg style=" position: absolute; z-index: 99999999; overflow: unset; pointer-events: none">
<template class="rect" v-for="(word, idx) in nowNers" >
<template v-for="(w, i) in word.name">
<line
v-if="i === 0 || ((word.start%columnWordCount)+i) % columnWordCount === 0"
:key="`${word}${w}${i}`"
:x1="`${((word.start+i)%columnWordCount)*20 + (word.isSmall && i === 0 ? 2 : 0)}px`"
:y1="`${((word.start+i)/columnWordCount|0)*35 + (word.isSmall ? 0 : -2)}px`"
:x2="`${((Math.min(word.end-(word.start+i), columnWordCount, columnWordCount - (word.start+i)%columnWordCount))*20 - (word.isSmall && i === 0 ? 4 : 0)) + ((word.start+i)%columnWordCount)*20 + (word.isSmall && i === 0 ? 2 : 0)}px`"
:y2="`${word.isSmall?18:22+((word.start+i)/columnWordCount|0)*35 + (word.isSmall ? 0 : -2)}px`"
style="stroke:rgb(255,0,0);stroke-width:2"
></line>
</template>
</template>
</span>
<text x="201" y="10" fill="red">关系一</text>
</svg> -->
<div class="word-rect-area">
<span class="rect" v-for="(word, idx) in nowNers" :key="idx">
<span v-for="(w, i) in word.name" :key="`${word}${w}${i}`">
@ -77,7 +94,7 @@
</span>
</div>
<div v-if="projectType === '命名实体识别'">
<span class="word" v-for="(word, idx) in nowText" :key="idx" @contextmenu="stopPrev" @mousedown="startSelect(idx, $event)" @mousemove="pointWord(idx)"
<span class="word" v-for="(word, idx) in nowText" :key="idx" :id="idx" @contextmenu="stopPrev" @mousedown="startSelect(idx, $event)" @touchstart="startSelect(idx, $event)" @mousemove="pointWord(idx)" @touchmove="pointWordByTouch($event)"
>
{{ word }}
</span>
@ -328,6 +345,7 @@ export default {
* @param idx 点击文字的定位
*/
pointWord: function (idx, config = {}) {
console.log(this.mode, idx, config)
if (this.mode === 'select') {
if (!this.nowType) {
alert('请先选择标签')
@ -342,6 +360,13 @@ export default {
return idx
}
},
pointWordByTouch: function (event) {
let {pageX, pageY} = event.touches[0]
let dom = document.elementFromPoint(pageX, pageY)
if (dom && dom.id) {
this.pointWord(dom.id)
}
},
/**
* 配置标注类型
* @param 类型
@ -457,7 +482,19 @@ export default {
},
startSelect: function (idx, event) {
if (this.projectType !== '命名实体识别') return
let isNeedDel = false
if (event.touches) {
//
if (this.startSelectTouchTs && Date.now() - this.startSelectTouchTs < 300) {
isNeedDel = true
}
this.startSelectTouchTs = Date.now()
}
if (event.which === 3) {
//
isNeedDel = true
}
if (isNeedDel) {
event.preventDefault()
//
const ners = this.ners
@ -494,6 +531,7 @@ export default {
}
const isRepeat = this.checkIsRepeat(this.nowNer)
if (!isRepeat && this.nowNer.isMove) {
console.log(this.nowNer)
delete this.nowNer.isMove
this.ners.push(this.nowNer)
this.$set(this, 'ners', this.ners.sort((a, b) => {
@ -963,4 +1001,22 @@ export default {
top: -9px;
right: -9px;
}
@media only screen and (max-width: 800px) {
.out-title {
text-align: right !important;
}
}
@media only screen and (max-width: 600px) {
.out-title {
font-size: 0;
}
}
@media only screen and (max-width: 800px) {
.result-box {
display: none;
}
.left {
display: none;
}
}
</style>

View File

@ -290,6 +290,7 @@ export default {
display: flex;
flex: 1 1;
flex-direction: row;
margin: 0 10px;
/* height: calc(100% - 92px); */
}
.button {