Q: Построить линию по полученным данным из базы получаю данные json = {[x,y],[x,y]}
как мне построить линию по этим данным?
    let canvas = document.getElementById('crash-canvas');
    let ctx = canvas.getContext('2d');
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.strokeStyle = '#e4c358';
    ctx.lineWidth = "1";
    ctx.beginPath();
    ctx.moveTo(20,canvas.height - 20);
    ctx.lineTo(20, 20 );
    ctx.moveTo(20,canvas.height - 20);
    ctx.lineTo(canvas.width - 20, canvas.height - 20 );
    ctx.stroke();
    ctx.save();


    /*
        *  Canvas
        */

    let h = canvas.height;
    let w = canvas.width;
    ctx.strokeStyle = '#000';
    ctx.fillStyle = '#0002';
    let pad = 20;
    let axes = [[pad, pad], [pad, h-pad], [w-pad, h-pad]];
    let x = 0;
    let points = [];

    //Таймер обратного отсчета
    let waitTimeShow = $('#waitTimeShow');
    let mutShow = $('#mutShow');

    let timerTime = 500;
    waitTimeShow.html((timerTime / 1000).toFixed(2) + "s");
    function timer(){
      timerTime--;
      waitTimeShow.html((timerTime / 1000).toFixed(2)+ "s");
      if (timerTime === 0){
        waitTimeShow.addClass('hide');
        mutShow.removeClass('hide');
        setTimeout(function(){},1);
        // fake server data
        let interval = setInterval(() => {
          points.push([pad+x, h-pad-Math.sin(x/50)*25*Math.cos(x/14)-x/5])
          x += 5;
          redraw();
          x > (w-pad*2) && clearInterval(interval)
        }, 30)

        } else {
          setTimeout(timer,1);
        }
    }
    setTimeout(timer,1);

function mapPoint(pt){
  return [pt[0]*55+pad, h - pad - pt[1]]
}

    function polyline(width, pts) {
      ctx.lineWidth = width;
      ctx.beginPath();  
      ctx.moveTo(...pts[0]);
      for (var i = 1; i < pts.length; i++)
        ctx.lineTo(...pts[i]);
      ctx.stroke();
    }

    function redraw(){
  ctx.clearRect(0, 0, w, h);
   // рисуем оси
  polyline(1, axes)

  //рисуем линию
  let pts = points.filter(p => p[0] > 0).map(mapPoint);
  if (pts.length < 2)
    return;
  let lastPt = pts[pts.length-1];
  let prevPt = pts[pts.length-2];
  polyline(8, pts);

  // рисуем область под линией
  ctx.lineTo(lastPt[0], h - 20);  
  ctx.fill();

  // рисуем стрелку
  ctx.save();
  ctx.fillStyle = '#000';
  ctx.translate(...lastPt);
  ctx.rotate(Math.atan2(lastPt[1] - prevPt[1], lastPt[0] - prevPt[0]));
  ctx.beginPath();
  ctx.moveTo(0 , 8);
  ctx.lineTo(16, 0);
  ctx.lineTo(0, -8);
  ctx.fill();
  ctx.restore();
}


A: Нужно каждый раз когда приходит точка все перерисовывать:


let ctx = canvas.getContext('2d');
let h = canvas.height;
let w = canvas.width;
ctx.font = '40px Arial'
ctx.strokeStyle = '#000';
ctx.fillStyle = '#0002';
let pad = 20;
let arrow = [[0 , 8], [16, 0], [0, -8]];
let axes = [[pad, pad], [pad, h-pad], [w-pad, h-pad]];
let points = [];

// fake server data
let time = - Math.random()*4 - 1;
let interval = setInterval(() => {
  points.push([time, Math.sin(time*2)*15*Math.cos(time*5)+time*10])
  time += 0.02;
  redraw();
  time > 7 && clearInterval(interval)
}, 20)

function mapPoint(pt){
  return [pt[0]*55+pad, h - pad - pt[1]]
}

function polyline(width, pts) {
  ctx.lineWidth = width;
  ctx.beginPath();  
  ctx.moveTo(...pts[0]);
  for (var i = 1; i < pts.length; i++)
    ctx.lineTo(...pts[i]);
  ctx.stroke();
}

function redraw(){
  ctx.clearRect(0, 0, w, h);
  let t = Math.min(0, points[points.length-1][0]).toFixed(1)
  ctx.fillText(t, 30, 30)
  
  // рисуем оси
  polyline(1, axes)
  
  //рисуем линию
  let pts = points.filter(p => p[0] > 0).map(mapPoint);
  if (pts.length < 2)
    return;
  let lastPt = pts[pts.length-1];
  let prevPt = pts[pts.length-2];
  polyline(8, pts);
  
  // рисуем область под линией
  ctx.lineTo(lastPt[0], h - 20);  
  ctx.fill();

  // рисуем стрелку
  ctx.save();
  ctx.fillStyle = '#000';
  ctx.translate(...lastPt);
  ctx.rotate(Math.atan2(lastPt[1] - prevPt[1], lastPt[0] - prevPt[0]));
  polyline(0.1, arrow)
  ctx.fill();
  ctx.restore();
}
<canvas id=canvas width=500></canvas>



A: 

let canvas = document.getElementById('crash-canvas');
let ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.strokeStyle = '#e4c358';
ctx.lineWidth = "1";
ctx.beginPath();
ctx.moveTo(20,canvas.height - 20);
ctx.lineTo(20, 20 );
ctx.moveTo(20,canvas.height - 20);
ctx.lineTo(canvas.width - 20, canvas.height - 20 );
ctx.stroke();
ctx.save();


/*
 *  Canvas
 */

let h = canvas.height;
let w = canvas.width;
ctx.strokeStyle = '#000';
ctx.fillStyle = '#0002';
let pad = 20;
let axes = [[pad, pad], [pad, h-pad], [w-pad, h-pad]];
let x = 0;
let points = [];

//Таймер обратного отсчета
let waitTimeShow = $('#waitTimeShow');
let mutShow = $('#mutShow');

let timerTime = 500;
waitTimeShow.html((timerTime / 1000).toFixed(2) + "s");
function timer(){
  timerTime--;
  waitTimeShow.html((timerTime / 1000).toFixed(2)+ "s");
  if (timerTime === 0){
    waitTimeShow.addClass('hide');
    mutShow.removeClass('hide');
    setTimeout(function(){},1);
    // fake server data
    let interval = setInterval(() => {
      points.push([pad+x, h-pad-Math.sin(x/50)*25*Math.cos(x/14)-x/5])
      x += 5;
      redraw();
      x > (w-pad*2) && clearInterval(interval)
    }, 30)

    } else {
      setTimeout(timer,1);
    }
}
setTimeout(timer,1);

function mapPoint(pt){
  return [pt[0]*55+pad, h - pad - pt[1]]
}

function polyline(width, pts) {
  ctx.lineWidth = width;
  ctx.beginPath();  
  ctx.moveTo(...pts[0]);
  for (var i = 1; i < pts.length; i++)
    ctx.lineTo(...pts[i]);
  ctx.stroke();
}

function redraw(){
  ctx.clearRect(0, 0, w, h);
   // рисуем оси
  polyline(1, axes)
  
  //рисуем линию
  let pts = points.filter(p => p[0] > 0);
  if (pts.length < 2)
    return;
  let lastPt = pts[pts.length-1];
  let prevPt = pts[pts.length-2];
  polyline(8, pts);
  
  // рисуем область под линией
  ctx.lineTo(lastPt[0], h - 20);  
  ctx.fill();
  
  // рисуем стрелку
  ctx.save();
  ctx.fillStyle = '#000';
  ctx.translate(...lastPt);
  ctx.rotate(Math.atan2(lastPt[1] - prevPt[1], lastPt[0] - prevPt[0]));
  ctx.beginPath();
  ctx.moveTo(0 , 8);
  ctx.lineTo(16, 0);
  ctx.lineTo(0, -8);
  ctx.fill();
  ctx.restore();
}
.hide{
  display: none !important;
}
.graphic__frame{
      background-color: #ccc;
   height: 400px;
   width: 100%;
   background-repeat: no-repeat;
   background-size: cover;
   background-position: 50%;
   position: relative;
   #crash-game-notice {
       position: absolute;
       top: 0;
       width: 100%;
       height: 100%;
       text-align: center;
       left: 0;
       #mutShow{
        span {
         margin: 45px auto 0;
         display: flex;
         align-items: center;
         justify-content: center;
         width: 170px;
         background: rgba(19, 34, 52, 0.8);
         border: 1px solid #F1CD5B;
         padding: 0 20px;
         height: 40px;
         font-size: 18px;
         font-weight: 900;
         color: #ffffff;
     }
      }
        #waitTimeShow {
          margin: 45px auto 0;
          display: flex;
          align-items: center;
          justify-content: center;
          width: 170px;
          background: rgba(19, 34, 52, 0.8);
          border: 1px solid #F1CD5B;
          padding: 0 20px;
          height: 40px;
          font-size: 18px;
          font-weight: 900;
          color: #fff;
        }
  }
}
<body>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<div class="col-md-8">
  <div id="crash-view" class="graphic__frame">
    <canvas width="999" height="400" id="crash-canvas" style="width: 100%; height: 400px;"></canvas>
    <div id="crash-game-notice" title="">
      <span id="mutShow" class="hide">
        <span style="">1.11x</span>
      </span>
      <span id="waitTimeShow" class="">0.00s</span>
    </div>
  </div>
  <p id="one"></p>
</div>
</body>


