shape onModel improvements; vline fixes; time entry; couple bugs remain with dca dragging

This commit is contained in:
Tim
2024-04-19 19:51:06 -04:00
parent 1579060024
commit 59342e2e26
9 changed files with 457 additions and 144 deletions

View File

@@ -216,7 +216,13 @@ function handleCrosshairMovement(point) {
draggingShapeIds = chart.selection().allSources();
// console.log('dragging selected', draggingShapeIds)
for (const shapeId of draggingShapeIds) {
const shape = chart.getShapeById(shapeId);
let shape
try {
shape = chart.getShapeById(shapeId);
}
catch (e) {
continue
}
const points = shape.getPoints();
// console.log(`dragging ${shapeId}`, shape, points1, points2, points3)
// invokeCallbacks(shapeCallbacks[shapeId], 'onDrag', shapeId, shape, points)

View File

@@ -146,9 +146,10 @@ export class Shape {
this.setProps(newProps)
}
onModel(model, changedKeys) {} // model was changed by a TradingView user action
onModel(model, oldModel, changedKeys) {} // model was changed by a TradingView user action
updateModel(changes) {
const oldModel = {...this.model}
if (this.debug) console.log('updateModel', this.id, changes)
const changedKeys = []
for (const k of Object.keys(changes)) {
@@ -158,7 +159,7 @@ export class Shape {
}
}
if (changedKeys.length)
this.onModel(this.model, changedKeys)
this.onModel(this.model, oldModel, changedKeys)
}
colorProps() {
@@ -195,31 +196,37 @@ export class Shape {
if (this.id !== null) return
// programatically create the shape using the current this.points
if( this.ourPoints && this.ourPoints.length ) {
this.doCreate()
this.doCreate(this.ourPoints, this.ourProps, this.creationOptions)
}
}
doCreate() {
doCreate(points, props, options={}) {
// createShape(this.type, this.points, {overrides:this.props}, new ShapeTVCallbacks(this))
const options = {...this.creationOptions}
options['overrides'] = this.ourProps
this.tvPoints = [...this.ourPoints]
options = {...options}
options['overrides'] = props
this.tvPoints = [...points]
this.tvCallbacks = new ShapeTVCallbacks(this);
createShape(this.type, this.ourPoints, options, this.tvCallbacks)
if (this.debug) console.log('created', this.type.name, this.ourPoints, this.id)
createShape(this.type, points, options, this.tvCallbacks)
if (this.debug) console.log('created', this.type.name, points, this.id)
}
createOrDraw() {
if(this.id) return
if(this.ourPoints && this.ourPoints.length)
this.doCreate(this.ourPoints)
this.create()
else
this.draw()
}
tvShape() {
return this.id === null ? null : chart.getShapeById(this.id);
try {
return this.id === null ? null : chart.getShapeById(this.id);
}
catch (e) {
console.error(`Could not get chart shape ${this.id}`)
return null
}
}
@@ -233,19 +240,25 @@ export class Shape {
this.delete()
else {
if (this.id === null)
this.doCreate()
this.create()
else if (dirtyPoints(this.tvPoints, points)) {
const s = this.tvShape();
let sbm = false
if( draggingShapeIds.length ) {
const dragShape = chart.getShapeById(draggingShapeIds[0])
const sbms = [...dragShape._model._sourcesBeingMoved]
// console.log('shape setPoints', this.id, dragShape, sbm)
sbm = !sbms.length
// if (!sbms.length) {
// console.log('shape setPoints SBM return')
// return
// }
let dragShape
try {
dragShape = chart.getShapeById(draggingShapeIds[0])
const sbms = [...dragShape._model._sourcesBeingMoved]
// console.log('shape setPoints', this.id, dragShape, sbm)
sbm = !sbms.length
// if (!sbms.length) {
// console.log('shape setPoints SBM return')
// return
// }
}
catch (e) {
console.error(`could not get drag shape ${draggingShapeIds[0]}`)
}
}
if (this.debug) console.log('adjusting tv points', this.tvPoints, points, dragging, this.beingDragged())
// if ( dragging && !this.beingDragged())
@@ -328,7 +341,10 @@ export class Shape {
onRedraw() {} // the mouse moved while in drawing mode
onUndraw() {} // drawing was canceled by clicking on a different tool
onAddPoint() {} // the user clicked a point while drawing (that point is added to the points list)
onCreate(points, props) {} // the user has finished creating all the control points. drawing mode is exited and the initial shape is created.
onCreate(points, props) {
this.tvPoints = points
this.tvProps = props
} // the user has finished creating all the control points. drawing mode is exited and the initial shape is created.
onMove(points) {} // the shape was moved by dragging a drawing element not the control point
onDrag(points) {}
onHide(props) {}
@@ -512,15 +528,6 @@ export class HLine extends Line {
}
function timeAdjustmentTooSmall(orig, newValue) {
// TradingView adjusts our lines to be at the start of the intervals, so
// we ignore deltas smaller than one interval prior
return newValue === undefined ||
orig !== null && orig !== undefined && newValue !== null &&
newValue < orig && orig - newValue < useChartOrderStore().intervalSecs
}
function nearestOhlcStart(time) {
const period = useChartOrderStore().intervalSecs
return Math.round(time/period) * period
@@ -534,11 +541,22 @@ export class VLine extends Line {
// Model
this.model.time = null
// since VLines must be on the start of an OHLC boundry, we track that value separately
this.shapeTime = null
this.setModel(model) // call setModel at the end
}
doCreate(points, props, options = {}) {
this.shapeTime = nearestOhlcStart(points[0].time);
points = [{time: this.shapeTime, price:0}]
super.doCreate(points, props, options);
}
delete() {
this.model.time = null
this.shapeTime = null
super.delete()
}
@@ -546,28 +564,37 @@ export class VLine extends Line {
setModel(model) {
// console.log('VLine setModel', this.id, {...this.model}, model)
super.setModel(model)
if (model.time === null) {
this.model.time = null
if (model.time === null)
this.delete()
}
else if (model.time !== this.model.time) {
this.model.time = model.time
const time = nearestOhlcStart(model.time);
this.setPoints([{time, price:0}])
this.setPoints([{time: model.time, price: 0}])
}
}
setPoints(points) {
// console.error('VLine setPoints', points)
super.setPoints(points);
if (this.debug) console.error('VLine setPoints...', points)
if (points !== null && points.length) {
// adjust shape to ohlc boundry
const time = nearestOhlcStart(points[0].time);
if (time !== this.shapeTime) {
this.shapeTime = time
super.setPoints([{time, price:0}]);
}
}
else {
this.shapeTime = null
super.setPoints(points);
}
if (this.debug) console.error('VLine setPoints', points)
}
onPoints(points) {
const orig = this.ourPoints && this.ourPoints.length ? this.ourPoints[0].time : null
super.onPoints(points);
const time = points[0].time;
if (!timeAdjustmentTooSmall(orig, time))
if ( time !== this.shapeTime ) {
super.onPoints(points);
this.updateModel({time: time})
}
}
}