+109
-60
@@ -39,3 +39,3 @@ import { h } from "./h"; | ||
| //x轴线高度 | ||
| private xAxisLineHeight: number = 21; | ||
| private xAxisLineHeight: number = 30; | ||
@@ -52,3 +52,3 @@ //y轴线 | ||
| //时间轴上边距 | ||
| private lineTop: number = 20; | ||
| private lineTop: number = 5; | ||
| //时间轴左边距 | ||
@@ -69,17 +69,18 @@ private lineLeft: number = 20; | ||
| ) { | ||
| if (lineOptions) { | ||
| mergeObjs(this.lineOptions, lineOptions); | ||
| } | ||
| requestAnimationFrame(() => { | ||
| if (lineOptions) { | ||
| mergeObjs(this.lineOptions, lineOptions); | ||
| } | ||
| this.container = document.getElementById(containerId)!; | ||
| this.container.style.position = "relative"; | ||
| this.startDate = startDate; | ||
| this.endDate = endDate; | ||
| this.zoomLevel = 1; | ||
| this.offset = this.lineOptions.textWidth!; | ||
| this.container = document.getElementById(containerId)!; | ||
| this.container.style.position = "relative"; | ||
| this.startDate = startDate; | ||
| this.endDate = endDate; | ||
| this.zoomLevel = 1; | ||
| this.offset = this.lineOptions.textWidth!; | ||
| const timelineContainer = this.createTimelineElement(); | ||
| this.container.appendChild(timelineContainer); | ||
| const timelineContainer = this.createTimelineElement(); | ||
| this.container.appendChild(timelineContainer); | ||
| this.init(); | ||
| this.init(); | ||
| }); | ||
| } | ||
@@ -95,4 +96,4 @@ private createTimelineElement(): HTMLElement { | ||
| { | ||
| style: `width:calc(100% - ${this.lineTop * 2}px);height:calc(100% - ${ | ||
| this.lineLeft * 2 | ||
| style: `width:calc(100% - ${this.lineLeft * 2}px);height:calc(100% - ${ | ||
| this.lineTop * 2 | ||
| }px);position:absolute;top:${this.lineTop}px;left:${ | ||
@@ -132,2 +133,8 @@ this.lineLeft | ||
| private drawTimeline() { | ||
| if (!this.timeline || this.timeline.clientWidth == 0) { | ||
| setTimeout(() => { | ||
| this.drawTimeline(); | ||
| }, 10); | ||
| return; | ||
| } | ||
| this.timeline.innerHTML = ""; | ||
@@ -138,3 +145,2 @@ this.timeline.style.transform = ` translateX(${this.offset}px)`; | ||
| let pixelsPerMs = timelineWidth / range; | ||
| let lastDate; | ||
@@ -153,7 +159,10 @@ const length = 180; | ||
| style: | ||
| "background:#fff;width:1px;height:10px;position:relative;top:-10px;", | ||
| "background:#fff;width:1px;height:10px;position:relative;bottom:10px;", | ||
| }), | ||
| h( | ||
| "div", | ||
| { style: "color:#fff;position:relative;top:0px;left:-50%" }, | ||
| { | ||
| style: | ||
| "color:#fff;position:relative;top:0px;left:-50%;text-align:center;height:20px", | ||
| }, | ||
| dayjs(date).format("YYYY-MM-DD HH:mm:ss") | ||
@@ -173,7 +182,10 @@ ) | ||
| style: | ||
| "background:#fff;width:1px;height:10px;position:relative;top:-10px;", | ||
| "background:#fff;width:1px;height:10px;position:relative;bottom:10px;", | ||
| }), | ||
| h( | ||
| "div", | ||
| { style: "color:#fff;position:relative;top:0px;left:-50%" }, | ||
| { | ||
| style: | ||
| "color:#fff;position:relative;top:0px;left:-50%;text-align:center;height:20px", | ||
| }, | ||
| dayjs(date).format("HH:mm:ss") | ||
@@ -187,16 +199,27 @@ ) | ||
| if (this.data) { | ||
| this.yAxisLineDiv = h("div", { | ||
| className: "timeline-y-line", | ||
| style: `position:absolute;width:1px;height:calc(100% - 30px);background-color:#fff;bottom:30px;left:${ | ||
| this.offset > 0 | ||
| ? 0 + this.lineOptions.textWidth! | ||
| : -this.offset + this.lineOptions.textWidth! | ||
| }px;z-index:1`, | ||
| }); | ||
| this.timeline.appendChild(this.yAxisLineDiv); | ||
| } else { | ||
| this.yAxisLineDiv = h("div", { | ||
| className: "timeline-y-line", | ||
| style: `position:absolute;width:1px;height:calc(100% - 30px);background-color:#fff;bottom:30px;left:${ | ||
| 0 + this.lineOptions.textWidth! | ||
| }px;z-index:1`, | ||
| }); | ||
| this.timeline.appendChild(this.yAxisLineDiv); | ||
| } | ||
| this.xAxisLineDiv = h("div", { | ||
| style: `position:absolute;width:${timelineWidth}px;height:1px;background-color:#fff;bottom:30px;left:${this.lineOptions.textWidth}px;`, | ||
| }); | ||
| this.yAxisLineDiv = h("div", { | ||
| className: "timeline-y-line", | ||
| style: `position:absolute;width:1px;height:calc(100% - 30px);background-color:#fff;bottom:30px;left:${ | ||
| this.offset > 0 | ||
| ? 0 + this.lineOptions.textWidth! | ||
| : -this.offset + this.lineOptions.textWidth! | ||
| }px;z-index:1`, | ||
| }); | ||
| this.timeline.appendChild(this.yAxisLineDiv); | ||
| this.timeline.appendChild(this.xAxisLineDiv); | ||
@@ -208,4 +231,7 @@ | ||
| private getHeightPerGroup() { | ||
| const height = this.timeline.clientHeight - this.xAxisLineHeight - 9; | ||
| const heightPerGroup = height / this.data.length; | ||
| const height = this.timeline.clientHeight - this.xAxisLineHeight; | ||
| let heightPerGroup = 0; | ||
| if (this.data) { | ||
| heightPerGroup = height / this.data.length; | ||
| } | ||
| return { height, heightPerGroup }; | ||
@@ -215,4 +241,3 @@ } | ||
| private getGroupIndex(heightPerGroup) { | ||
| const rect = this.timeline.getBoundingClientRect(); | ||
| const y = this.y - rect.top; | ||
| const y = this.y; | ||
| const index = Math.ceil(y / heightPerGroup); | ||
@@ -299,3 +324,3 @@ return index; | ||
| { | ||
| style: `color:${group.groupOptions.textColor};font-size:${group.groupOptions.textSize}px`, | ||
| style: `color:${group.groupOptions.textColor};font-size:${group.groupOptions.textSize}px;`, | ||
| }, | ||
@@ -316,4 +341,7 @@ item.itemName | ||
| //由于offset小于0会发生位置偏移,因此需要对绘制的数据进行同等偏移 | ||
| let left = start - this.offset - this.lineLeft; | ||
| const crect = this.container.getBoundingClientRect(); | ||
| let left = start - this.offset - this.lineLeft - crect.left; | ||
| let menus = [] as HTMLElement[]; | ||
@@ -343,3 +371,10 @@ if (this.lineOptions.menus) { | ||
| const endTime = this.getTimeByPx(endPx); | ||
| menu.clickEvent(e, startTime.curDate, endTime.curDate); | ||
| const { heightPerGroup } = this.getHeightPerGroup(); | ||
| const index = this.getGroupIndex(heightPerGroup); | ||
| menu.clickEvent( | ||
| e, | ||
| startTime, | ||
| endTime, | ||
| this.data[index - 1] | ||
| ); | ||
| }, | ||
@@ -390,3 +425,3 @@ }, | ||
| this.lineOptions.tipTextSize | ||
| }px;top:${this.y - 30}px;left:${this.x + 10}px;z-index:1`, | ||
| }px;top:${this.y}px;left:${this.x + 10}px;z-index:1`, | ||
| }, | ||
@@ -418,2 +453,4 @@ h("div", {}, dayjs(this.curTime).format("YYYY-MM-DD HH:mm:ss")), | ||
| let top = 0; | ||
| const crect = this.container.getBoundingClientRect(); | ||
| const rect = this.timeline.getBoundingClientRect(); | ||
| const { heightPerGroup } = this.getHeightPerGroup(); | ||
@@ -437,5 +474,13 @@ const index = this.getGroupIndex(heightPerGroup); | ||
| x <= left + item.width && | ||
| y >= item.top + heightPerGroup * (index - 1) + this.lineTop && | ||
| y >= | ||
| item.top + //自身顶点 | ||
| heightPerGroup * (index - 1) + //上一组的高度 | ||
| this.lineTop - //时间轴边距 | ||
| (rect.top - crect.top) && //timeline对象与父容器的距离 | ||
| y <= | ||
| item.top + heightPerGroup * (index - 1) + this.lineTop + item.height | ||
| item.top + | ||
| heightPerGroup * (index - 1) + | ||
| this.lineTop - | ||
| (rect.top - crect.top) + | ||
| item.height | ||
| ) { | ||
@@ -450,3 +495,3 @@ top = item.top + heightPerGroup * (index - 1); | ||
| } | ||
| return { flag, top, height, item: curItem }; | ||
| return { flag, top, height, item: curItem, group: this.data[index - 1] }; | ||
| } | ||
@@ -457,5 +502,10 @@ | ||
| if (this.lineOptions.dblClickEvent) { | ||
| const { curDate } = this.getTimeByPx(this.x); | ||
| const { flag, top, height, item } = this.isInItems(); | ||
| this.lineOptions.dblClickEvent(event, curDate, Object.assign({}, item)); | ||
| const curDate = this.getTimeByPx(this.x); | ||
| const { item, group } = this.isInItems(); | ||
| this.lineOptions.dblClickEvent( | ||
| event, | ||
| curDate, | ||
| Object.assign({}, item), | ||
| Object.assign({}, group) | ||
| ); | ||
| } | ||
@@ -488,6 +538,8 @@ } | ||
| this.endX = event.clientX; | ||
| const { flag, top, height } = this.isInItems(); | ||
| this.isSelecting = flag; | ||
| this.selectTop = top; | ||
| this.selectHeight = height; | ||
| if (this.data) { | ||
| const { flag, top, height } = this.isInItems(); | ||
| this.isSelecting = flag; | ||
| this.selectTop = top; | ||
| this.selectHeight = height; | ||
| } | ||
| } | ||
@@ -507,6 +559,7 @@ | ||
| } | ||
| this.y = event.clientY; | ||
| const rect = this.timeline.getBoundingClientRect(); | ||
| this.y = event.clientY - rect.top; | ||
| this.x = event.clientX - rect.left; | ||
| const { curDate, x } = this.getTimeByPx(event.clientX); | ||
| this.x = x; | ||
| const curDate = this.getTimeByPx(this.x); | ||
| this.curTime = curDate; | ||
@@ -520,10 +573,6 @@ this.drawTimeline(); | ||
| } | ||
| private getTimeByPx(curX) { | ||
| private getTimeByPx(x) { | ||
| let timelineWidth = this.timeline.clientWidth * this.zoomLevel; | ||
| let range = this.endDate.getTime() - this.startDate.getTime(); | ||
| let pixelsPerMs = timelineWidth / range; | ||
| const rect = this.timeline.getBoundingClientRect(); | ||
| let x = curX - rect.left; | ||
| if (x < this.lineOptions.textWidth!) x = this.lineOptions.textWidth!; | ||
@@ -533,3 +582,3 @@ const curDate = new Date( | ||
| ); | ||
| return { curDate, x }; | ||
| return curDate; | ||
| } | ||
@@ -536,0 +585,0 @@ } |
@@ -0,1 +1,2 @@ | ||
| import Group from "./group"; | ||
| import Item from "./item"; | ||
@@ -15,3 +16,4 @@ import Menu from "./menu"; | ||
| curTime: Date, | ||
| item: Item | undefined | ||
| item: Item | undefined, | ||
| group: Group | undefined | ||
| ) => void; | ||
@@ -29,3 +31,4 @@ constructor( | ||
| curTime: Date, | ||
| item: Item | undefined | ||
| item: Item | undefined, | ||
| group: Group | undefined | ||
| ) => void | ||
@@ -32,0 +35,0 @@ ) { |
+14
-2
@@ -0,1 +1,3 @@ | ||
| import Group from "./group"; | ||
| class Menu { | ||
@@ -6,3 +8,8 @@ public text: string = ""; | ||
| public textSize: number = 14; | ||
| public clickEvent: (e: MouseEvent, startTime: Date, endTime: Date) => void; | ||
| public clickEvent: ( | ||
| e: MouseEvent, | ||
| startTime: Date, | ||
| endTime: Date, | ||
| group: Group | ||
| ) => void; | ||
@@ -14,3 +21,8 @@ constructor({ | ||
| textSize = 14, | ||
| clickEvent = (e: MouseEvent, startTime: Date, endTime: Date) => {}, | ||
| clickEvent = ( | ||
| e: MouseEvent, | ||
| startTime: Date, | ||
| endTime: Date, | ||
| group: Group | ||
| ) => {}, | ||
| }: Partial<Menu>) { | ||
@@ -17,0 +29,0 @@ this.text = text; |
+1
-1
| { | ||
| "name": "glibline", | ||
| "version": "0.0.2", | ||
| "version": "0.0.3", | ||
| "description": "时间轴(timeline),用于实现根据时间对数据事件操作。", | ||
@@ -5,0 +5,0 @@ "main": "index.ts", |
29035
6.49%732
9.58%