feat: set control highlight rule #332
parent
285aeec2f6
commit
b6fe21230b
@ -0,0 +1,145 @@
|
|||||||
|
import { ElementType } from '../../../../dataset/enum/Element'
|
||||||
|
import { DeepRequired } from '../../../../interface/Common'
|
||||||
|
import {
|
||||||
|
IControlHighlight,
|
||||||
|
IControlHighlightRule
|
||||||
|
} from '../../../../interface/Control'
|
||||||
|
import { IEditorOption } from '../../../../interface/Editor'
|
||||||
|
import { IElement, IElementPosition } from '../../../../interface/Element'
|
||||||
|
import {
|
||||||
|
ISearchResult,
|
||||||
|
ISearchResultRestArgs
|
||||||
|
} from '../../../../interface/Search'
|
||||||
|
import { Draw } from '../../Draw'
|
||||||
|
import { Control } from '../Control'
|
||||||
|
|
||||||
|
type IHighlightMatchResult = (ISearchResult & IControlHighlightRule)[]
|
||||||
|
|
||||||
|
export class ControlSearch {
|
||||||
|
private draw: Draw
|
||||||
|
private options: DeepRequired<IEditorOption>
|
||||||
|
private highlightList: IControlHighlight[]
|
||||||
|
private highlightMatchResult: IHighlightMatchResult
|
||||||
|
|
||||||
|
constructor(control: Control) {
|
||||||
|
this.draw = control.getDraw()
|
||||||
|
this.options = this.draw.getOptions()
|
||||||
|
|
||||||
|
this.highlightList = []
|
||||||
|
this.highlightMatchResult = []
|
||||||
|
}
|
||||||
|
|
||||||
|
public getHighlightMatchResult(): IHighlightMatchResult {
|
||||||
|
return this.highlightMatchResult
|
||||||
|
}
|
||||||
|
|
||||||
|
public getHighlightList(): IControlHighlight[] {
|
||||||
|
return this.highlightList
|
||||||
|
}
|
||||||
|
|
||||||
|
public setHighlightList(payload: IControlHighlight[]) {
|
||||||
|
this.highlightList = payload
|
||||||
|
}
|
||||||
|
|
||||||
|
public computeHighlightList() {
|
||||||
|
const search = this.draw.getSearch()
|
||||||
|
const computeHighlight = (
|
||||||
|
elementList: IElement[],
|
||||||
|
restArgs?: ISearchResultRestArgs
|
||||||
|
) => {
|
||||||
|
let i = 0
|
||||||
|
while (i < elementList.length) {
|
||||||
|
const element = elementList[i]
|
||||||
|
i++
|
||||||
|
// 表格下钻处理
|
||||||
|
if (element.type === ElementType.TABLE) {
|
||||||
|
const trList = element.trList!
|
||||||
|
for (let r = 0; r < trList.length; r++) {
|
||||||
|
const tr = trList[r]
|
||||||
|
for (let d = 0; d < tr.tdList.length; d++) {
|
||||||
|
const td = tr.tdList[d]
|
||||||
|
const restArgs: ISearchResultRestArgs = {
|
||||||
|
tableId: element.id,
|
||||||
|
tableIndex: i - 1,
|
||||||
|
trIndex: r,
|
||||||
|
tdIndex: d,
|
||||||
|
tdId: td.id
|
||||||
|
}
|
||||||
|
computeHighlight(td.value, restArgs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const controlConceptId = element?.control?.conceptId
|
||||||
|
if (!controlConceptId) continue
|
||||||
|
const highlightIndex = this.highlightList.findIndex(
|
||||||
|
highlight => highlight.conceptId === controlConceptId
|
||||||
|
)
|
||||||
|
if (!~highlightIndex) continue
|
||||||
|
// 搜索后控件结束索引
|
||||||
|
const startIndex = i
|
||||||
|
let newEndIndex = i
|
||||||
|
while (newEndIndex < elementList.length) {
|
||||||
|
const nextElement = elementList[newEndIndex]
|
||||||
|
if (nextElement.controlId !== element.controlId) break
|
||||||
|
newEndIndex++
|
||||||
|
}
|
||||||
|
i = newEndIndex
|
||||||
|
// 高亮信息
|
||||||
|
const controlElementList = elementList.slice(startIndex, newEndIndex)
|
||||||
|
const highlight = this.highlightList[highlightIndex]
|
||||||
|
const { ruleList } = highlight
|
||||||
|
for (let r = 0; r < ruleList.length; r++) {
|
||||||
|
const rule = ruleList[r]
|
||||||
|
const searchResult = search.getMatchList(
|
||||||
|
rule.keyword,
|
||||||
|
controlElementList
|
||||||
|
)
|
||||||
|
this.highlightMatchResult.push(
|
||||||
|
...searchResult.map(result => ({
|
||||||
|
...result,
|
||||||
|
...rule,
|
||||||
|
...restArgs,
|
||||||
|
index: result.index + startIndex // 实际索引
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.highlightMatchResult = []
|
||||||
|
computeHighlight(this.draw.getOriginalMainElementList())
|
||||||
|
}
|
||||||
|
|
||||||
|
public renderHighlightList(ctx: CanvasRenderingContext2D, pageIndex: number) {
|
||||||
|
if (!this.highlightMatchResult?.length) return
|
||||||
|
const { searchMatchAlpha, searchMatchColor } = this.options
|
||||||
|
const positionList = this.draw.getPosition().getOriginalPositionList()
|
||||||
|
const elementList = this.draw.getOriginalElementList()
|
||||||
|
ctx.save()
|
||||||
|
for (let s = 0; s < this.highlightMatchResult.length; s++) {
|
||||||
|
const searchMatch = this.highlightMatchResult[s]
|
||||||
|
let position: IElementPosition | null = null
|
||||||
|
if (searchMatch.tableId) {
|
||||||
|
const { tableIndex, trIndex, tdIndex, index } = searchMatch
|
||||||
|
position =
|
||||||
|
elementList[tableIndex!]?.trList![trIndex!].tdList[tdIndex!]
|
||||||
|
?.positionList![index]
|
||||||
|
} else {
|
||||||
|
position = positionList[searchMatch.index]
|
||||||
|
}
|
||||||
|
if (!position) continue
|
||||||
|
const {
|
||||||
|
coordinate: { leftTop, leftBottom, rightTop },
|
||||||
|
pageNo
|
||||||
|
} = position
|
||||||
|
if (pageNo !== pageIndex) continue
|
||||||
|
ctx.fillStyle = searchMatch.backgroundColor || searchMatchColor
|
||||||
|
ctx.globalAlpha = searchMatch.alpha || searchMatchAlpha
|
||||||
|
const x = leftTop[0]
|
||||||
|
const y = leftTop[1]
|
||||||
|
const width = rightTop[0] - leftTop[0]
|
||||||
|
const height = leftBottom[1] - leftTop[1]
|
||||||
|
ctx.fillRect(x, y, width, height)
|
||||||
|
}
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in new issue