klinecharts / KLineChart

📈Lightweight k-line chart that can be highly customized. Zero dependencies. Support mobile.(可高度自定义的轻量级k线图,无第三方依赖,支持移动端)
https://klinecharts.com/
Apache License 2.0
2.32k stars 573 forks source link

Annotation at 'point' position jumping around when panning chart #129

Closed DeeeeLAN closed 3 years ago

DeeeeLAN commented 3 years ago

https://user-images.githubusercontent.com/12877032/120276680-dcfe3780-c267-11eb-8292-589866bf79f2.mov

Here is a short clip demonstrating it. I am using a couple custom annotations but I tested it and it worked the same with the default ones. I tried going through the source code to determine what is happening but I couldn't quite figure it out. As best as I could tell, computeAxis for the Y axis is not getting called after the annotation is drawn and it is using an old Y value, which changes when it starts moving and calls the function again. I saw that after the annotations were added it should invalidate and reload the image, so I am not sure why this is happening. Also as it moves around the Y value jumps around a bit causing the arrow to bounce up and down.

I checked the sample you provided and it did not behave this way, which tells me it might be something in my configuration. If you have any thoughts about where I can look, let me know.

liihuu commented 3 years ago

I want to see what your input is when you use createAnnotation, if possible, it is best to show your code.

DeeeeLAN commented 3 years ago

Sure, here is the input:

    if (props.koReg.length > 0) {
      kLineChart.createAnnotation(
        props.koReg.reduce((r, ko) => {
          let koReg = props.row[ko];
          let startDate = parseDate(koReg['startDate']).getTime()
          let endDate = parseDate(koReg['endDate']).getTime()
          let startPrice = cleanData.filter(d => d.timestamp === startDate)[0]?.high;
          let endPrice = cleanData.filter(d => d.timestamp === endDate)[0]?.low;
          r.push({
            point: { timestamp: startDate, price: startPrice, fillColor: koColors[ko] },
            styles: {
              symbol: {
                type: 'custom',
                position: 'point',
                offset: [0, -2],
              }
            },
            drawCustomSymbol: drawKOHigh,
          })
          r.push({
            point: { timestamp: endDate, price: endPrice, fillColor: koColors[ko] },
            styles: {
              symbol: {
                type: 'custom',
                position: 'point',
                offset: [0, 2],
              }
            },
            drawCustomSymbol: drawKOLow,
          })
          return r
        }, [])
      )
    }

Let me know if you need more.

liihuu commented 3 years ago

Show the code of drawKOHigh and drawKOLow.

DeeeeLAN commented 3 years ago
const koHalfWidth = 10;
const koBottomWidth = 3;
const koHeight = 20;

function drawKOHigh({ ctx, point, coordinate, viewport, isActive, styles }) {
  const x = coordinate.x;
  const y = coordinate.y;
  const fillColor = point.fillColor;

  console.log(point, coordinate)

  ctx.fillStyle = fillColor;
  ctx.beginPath();
  ctx.moveTo(x, y);
  ctx.lineTo(x + koHalfWidth, y - koHalfWidth);
  ctx.lineTo(x + koBottomWidth, y - koHalfWidth);
  ctx.lineTo(x + koBottomWidth, y - koHeight);
  ctx.lineTo(x - koBottomWidth, y - koHeight);
  ctx.lineTo(x - koBottomWidth, y - koHalfWidth);
  ctx.lineTo(x - koHalfWidth, y - koHalfWidth);
  ctx.closePath();
  ctx.fill()
}

function drawKOLow({ ctx, point, coordinate, viewport, isActive, styles }) {
  const x = coordinate.x;
  const y = coordinate.y;
  const fillColor = point.fillColor;

  ctx.fillStyle = fillColor;
  ctx.beginPath();
  ctx.moveTo(x, y);
  ctx.lineTo(x + koHalfWidth, y + koHalfWidth);
  ctx.lineTo(x + koBottomWidth, y + koHalfWidth);
  ctx.lineTo(x + koBottomWidth, y + koHeight);
  ctx.lineTo(x - koBottomWidth, y + koHeight);
  ctx.lineTo(x - koBottomWidth, y + koHalfWidth);
  ctx.lineTo(x - koHalfWidth, y + koHalfWidth);
  ctx.closePath();
  ctx.fill()
}

Although like I said, I saw the same behavior using the predefined annotation shapes too.

liihuu commented 3 years ago

The code you gave does not seem to be a problem. This is most likely a bug in the chart. I need to verify it.

liihuu commented 3 years ago

Fixed it, see commit.

DeeeeLAN commented 3 years ago

Wow, that was a quick turnaround! I will test it out, although I assume you already did.

DeeeeLAN commented 3 years ago

Works perfectly, thanks!

DeeeeLAN commented 3 years ago

Weird the issue wasn't showing up on the demo page you had. Do you know why that was?

liihuu commented 3 years ago

The sample page has the same problem.