569 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			569 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
// Although inspired by the https://github.com/bluef/gitgraph.js/blob/master/gitgraph.js
 | 
						|
// this has been completely rewritten with almost no remaining code
 | 
						|
 | 
						|
// GitGraphCanvas is a canvas for drawing gitgraphs on to
 | 
						|
class GitGraphCanvas {
 | 
						|
  constructor(canvas, widthUnits, heightUnits, config) {
 | 
						|
    this.ctx = canvas.getContext('2d');
 | 
						|
 | 
						|
    const width = widthUnits * config.unitSize;
 | 
						|
    this.height = heightUnits * config.unitSize;
 | 
						|
 | 
						|
    const ratio = window.devicePixelRatio || 1;
 | 
						|
 | 
						|
    canvas.width = width * ratio;
 | 
						|
    canvas.height = this.height * ratio;
 | 
						|
 | 
						|
    canvas.style.width = `${width}px`;
 | 
						|
    canvas.style.height = `${this.height}px`;
 | 
						|
 | 
						|
    this.ctx.lineWidth = config.lineWidth;
 | 
						|
    this.ctx.lineJoin = 'round';
 | 
						|
    this.ctx.lineCap = 'round';
 | 
						|
 | 
						|
    this.ctx.scale(ratio, ratio);
 | 
						|
    this.config = config;
 | 
						|
  }
 | 
						|
  drawLine(moveX, moveY, lineX, lineY, color) {
 | 
						|
    this.ctx.strokeStyle = color;
 | 
						|
    this.ctx.beginPath();
 | 
						|
    this.ctx.moveTo(moveX, moveY);
 | 
						|
    this.ctx.lineTo(lineX, lineY);
 | 
						|
    this.ctx.stroke();
 | 
						|
  }
 | 
						|
  drawLineRight(x, y, color) {
 | 
						|
    this.drawLine(
 | 
						|
      x - 0.5 * this.config.unitSize,
 | 
						|
      y + this.config.unitSize / 2,
 | 
						|
      x + 0.5 * this.config.unitSize,
 | 
						|
      y + this.config.unitSize / 2,
 | 
						|
      color
 | 
						|
    );
 | 
						|
  }
 | 
						|
  drawLineUp(x, y, color) {
 | 
						|
    this.drawLine(
 | 
						|
      x,
 | 
						|
      y + this.config.unitSize / 2,
 | 
						|
      x,
 | 
						|
      y - this.config.unitSize / 2,
 | 
						|
      color
 | 
						|
    );
 | 
						|
  }
 | 
						|
  drawNode(x, y, color) {
 | 
						|
    this.ctx.strokeStyle = color;
 | 
						|
 | 
						|
    this.drawLineUp(x, y, color);
 | 
						|
 | 
						|
    this.ctx.beginPath();
 | 
						|
    this.ctx.arc(x, y, this.config.nodeRadius, 0, Math.PI * 2, true);
 | 
						|
    this.ctx.fillStyle = color;
 | 
						|
    this.ctx.fill();
 | 
						|
  }
 | 
						|
  drawLineIn(x, y, color) {
 | 
						|
    this.drawLine(
 | 
						|
      x + 0.5 * this.config.unitSize,
 | 
						|
      y + this.config.unitSize / 2,
 | 
						|
      x - 0.5 * this.config.unitSize,
 | 
						|
      y - this.config.unitSize / 2,
 | 
						|
      color
 | 
						|
    );
 | 
						|
  }
 | 
						|
  drawLineOut(x, y, color) {
 | 
						|
    this.drawLine(
 | 
						|
      x - 0.5 * this.config.unitSize,
 | 
						|
      y + this.config.unitSize / 2,
 | 
						|
      x + 0.5 * this.config.unitSize,
 | 
						|
      y - this.config.unitSize / 2,
 | 
						|
      color
 | 
						|
    );
 | 
						|
  }
 | 
						|
  drawSymbol(symbol, columnNumber, rowNumber, color) {
 | 
						|
    const y = this.height - this.config.unitSize * (rowNumber + 0.5);
 | 
						|
    const x = this.config.unitSize * 0.5 * (columnNumber + 1);
 | 
						|
    switch (symbol) {
 | 
						|
      case '-':
 | 
						|
        if (columnNumber % 2 === 1) {
 | 
						|
          this.drawLineRight(x, y, color);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
      case '_':
 | 
						|
        this.drawLineRight(x, y, color);
 | 
						|
        break;
 | 
						|
      case '*':
 | 
						|
        this.drawNode(x, y, color);
 | 
						|
        break;
 | 
						|
      case '|':
 | 
						|
        this.drawLineUp(x, y, color);
 | 
						|
        break;
 | 
						|
      case '/':
 | 
						|
        this.drawLineOut(x, y, color);
 | 
						|
        break;
 | 
						|
      case '\\':
 | 
						|
        this.drawLineIn(x, y, color);
 | 
						|
        break;
 | 
						|
      case '.':
 | 
						|
      case ' ':
 | 
						|
        break;
 | 
						|
      default:
 | 
						|
        console.error('Unknown symbol', symbol, color);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
class GitGraph {
 | 
						|
  constructor(canvas, rawRows, config) {
 | 
						|
    this.rows = [];
 | 
						|
    let maxWidth = 0;
 | 
						|
 | 
						|
    for (let i = 0; i < rawRows.length; i++) {
 | 
						|
      const rowStr = rawRows[i];
 | 
						|
      maxWidth = Math.max(rowStr.replace(/([_\s.-])/g, '').length, maxWidth);
 | 
						|
 | 
						|
      const rowArray = rowStr.split('');
 | 
						|
 | 
						|
      this.rows.unshift(rowArray);
 | 
						|
    }
 | 
						|
 | 
						|
    this.currentFlows = [];
 | 
						|
    this.previousFlows = [];
 | 
						|
 | 
						|
    this.gitGraphCanvas = new GitGraphCanvas(
 | 
						|
      canvas,
 | 
						|
      maxWidth,
 | 
						|
      this.rows.length,
 | 
						|
      config
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  generateNewFlow(column) {
 | 
						|
    let newId;
 | 
						|
 | 
						|
    do {
 | 
						|
      newId = generateRandomColorString();
 | 
						|
    } while (this.hasFlow(newId, column));
 | 
						|
 | 
						|
    return {id: newId, color: `#${newId}`};
 | 
						|
  }
 | 
						|
 | 
						|
  hasFlow(id, column) {
 | 
						|
    // We want to find the flow with the current ID
 | 
						|
    // Possible flows are those in the currentFlows
 | 
						|
    // Or flows in previousFlows[column-2:...]
 | 
						|
    for (
 | 
						|
      let idx = column - 2 < 0 ? 0 : column - 2;
 | 
						|
      idx < this.previousFlows.length;
 | 
						|
      idx++
 | 
						|
    ) {
 | 
						|
      if (this.previousFlows[idx] && this.previousFlows[idx].id === id) {
 | 
						|
        return true;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    for (let idx = 0; idx < this.currentFlows.length; idx++) {
 | 
						|
      if (this.currentFlows[idx] && this.currentFlows[idx].id === id) {
 | 
						|
        return true;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
  takePreviousFlow(column) {
 | 
						|
    if (column < this.previousFlows.length && this.previousFlows[column]) {
 | 
						|
      const flow = this.previousFlows[column];
 | 
						|
      this.previousFlows[column] = null;
 | 
						|
      return flow;
 | 
						|
    }
 | 
						|
    return this.generateNewFlow(column);
 | 
						|
  }
 | 
						|
 | 
						|
  draw() {
 | 
						|
    if (this.rows.length === 0) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    this.currentFlows = new Array(this.rows[0].length);
 | 
						|
 | 
						|
    // Generate flows for the first row - I do not believe that this can contain '_', '-', '.'
 | 
						|
    for (let column = 0; column < this.rows[0].length; column++) {
 | 
						|
      if (this.rows[0][column] === ' ') {
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
      this.currentFlows[column] = this.generateNewFlow(column);
 | 
						|
    }
 | 
						|
 | 
						|
    // Draw the first row
 | 
						|
    for (let column = 0; column < this.rows[0].length; column++) {
 | 
						|
      const symbol = this.rows[0][column];
 | 
						|
      const color = this.currentFlows[column] ? this.currentFlows[column].color : '';
 | 
						|
      this.gitGraphCanvas.drawSymbol(symbol, column, 0, color);
 | 
						|
    }
 | 
						|
 | 
						|
    for (let row = 1; row < this.rows.length; row++) {
 | 
						|
      // Done previous row - step up the row
 | 
						|
      const currentRow = this.rows[row];
 | 
						|
      const previousRow = this.rows[row - 1];
 | 
						|
 | 
						|
      this.previousFlows = this.currentFlows;
 | 
						|
      this.currentFlows = new Array(currentRow.length);
 | 
						|
 | 
						|
      // Set flows for this row
 | 
						|
      for (let column = 0; column < currentRow.length; column++) {
 | 
						|
        column = this.setFlowFor(column, currentRow, previousRow);
 | 
						|
      }
 | 
						|
 | 
						|
      // Draw this row
 | 
						|
      for (let column = 0; column < currentRow.length; column++) {
 | 
						|
        const symbol = currentRow[column];
 | 
						|
        const color = this.currentFlows[column] ? this.currentFlows[column].color : '';
 | 
						|
        this.gitGraphCanvas.drawSymbol(symbol, column, row, color);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  setFlowFor(column, currentRow, previousRow) {
 | 
						|
    const symbol = currentRow[column];
 | 
						|
    switch (symbol) {
 | 
						|
      case '|':
 | 
						|
      case '*':
 | 
						|
        return this.setUpFlow(column, currentRow, previousRow);
 | 
						|
      case '/':
 | 
						|
        return this.setOutFlow(column, currentRow, previousRow);
 | 
						|
      case '\\':
 | 
						|
        return this.setInFlow(column, currentRow, previousRow);
 | 
						|
      case '_':
 | 
						|
        return this.setRightFlow(column, currentRow, previousRow);
 | 
						|
      case '-':
 | 
						|
        return this.setLeftFlow(column, currentRow, previousRow);
 | 
						|
      case ' ':
 | 
						|
        // In space no one can hear you flow ... (?)
 | 
						|
        return column;
 | 
						|
      default:
 | 
						|
        // Unexpected so let's generate a new flow and wait for bug-reports
 | 
						|
        this.currentFlows[column] = this.generateNewFlow(column);
 | 
						|
        return column;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  // setUpFlow handles '|' or '*' - returns the last column that was set
 | 
						|
  // generally we prefer to take the left most flow from the previous row
 | 
						|
  setUpFlow(column, currentRow, previousRow) {
 | 
						|
    // If ' |/' or ' |_'
 | 
						|
    //    '/|'     '/|'  -> Take the '|' flow directly beneath us
 | 
						|
    if (
 | 
						|
      column + 1 < currentRow.length &&
 | 
						|
      (currentRow[column + 1] === '/' || currentRow[column + 1] === '_') &&
 | 
						|
      column < previousRow.length &&
 | 
						|
      (previousRow[column] === '|' || previousRow[column] === '*') &&
 | 
						|
      previousRow[column - 1] === '/'
 | 
						|
    ) {
 | 
						|
      this.currentFlows[column] = this.takePreviousFlow(column);
 | 
						|
      return column;
 | 
						|
    }
 | 
						|
 | 
						|
    // If ' |/' or ' |_'
 | 
						|
    //    '/ '     '/ '  -> Take the '/' flow from the preceding column
 | 
						|
    if (
 | 
						|
      column + 1 < currentRow.length &&
 | 
						|
      (currentRow[column + 1] === '/' || currentRow[column + 1] === '_') &&
 | 
						|
      column - 1 < previousRow.length &&
 | 
						|
      previousRow[column - 1] === '/'
 | 
						|
    ) {
 | 
						|
      this.currentFlows[column] = this.takePreviousFlow(column - 1);
 | 
						|
      return column;
 | 
						|
    }
 | 
						|
 | 
						|
    // If ' |'
 | 
						|
    //    '/'   ->  Take the '/' flow - (we always prefer the left-most flow)
 | 
						|
    if (
 | 
						|
      column > 0 &&
 | 
						|
      column - 1 < previousRow.length &&
 | 
						|
      previousRow[column - 1] === '/'
 | 
						|
    ) {
 | 
						|
      this.currentFlows[column] = this.takePreviousFlow(column - 1);
 | 
						|
      return column;
 | 
						|
    }
 | 
						|
 | 
						|
    // If '|' OR '|' take the '|' flow
 | 
						|
    //    '|'    '*'
 | 
						|
    if (
 | 
						|
      column < previousRow.length &&
 | 
						|
      (previousRow[column] === '|' || previousRow[column] === '*')
 | 
						|
    ) {
 | 
						|
      this.currentFlows[column] = this.takePreviousFlow(column);
 | 
						|
      return column;
 | 
						|
    }
 | 
						|
 | 
						|
    // If '| ' keep the '\' flow
 | 
						|
    //    ' \'
 | 
						|
    if (column + 1 < previousRow.length && previousRow[column + 1] === '\\') {
 | 
						|
      this.currentFlows[column] = this.takePreviousFlow(column + 1);
 | 
						|
      return column;
 | 
						|
    }
 | 
						|
 | 
						|
    // Otherwise just create a new flow - probably this is an error...
 | 
						|
    this.currentFlows[column] = this.generateNewFlow(column);
 | 
						|
    return column;
 | 
						|
  }
 | 
						|
 | 
						|
  // setOutFlow handles '/' - returns the last column that was set
 | 
						|
  // generally we prefer to take the left most flow from the previous row
 | 
						|
  setOutFlow(column, currentRow, previousRow) {
 | 
						|
    // If  '_/' -> keep the '_' flow
 | 
						|
    if (column > 0 && currentRow[column - 1] === '_') {
 | 
						|
      this.currentFlows[column] = this.currentFlows[column - 1];
 | 
						|
      return column;
 | 
						|
    }
 | 
						|
 | 
						|
    // If '_|/' -> keep the '_' flow
 | 
						|
    if (
 | 
						|
      column > 1 &&
 | 
						|
      (currentRow[column - 1] === '|' || currentRow[column - 1] === '*') &&
 | 
						|
      currentRow[column - 2] === '_'
 | 
						|
    ) {
 | 
						|
      this.currentFlows[column] = this.currentFlows[column - 2];
 | 
						|
      return column;
 | 
						|
    }
 | 
						|
 | 
						|
    // If  '|/'
 | 
						|
    //    '/'   -> take the '/' flow (if it is still available)
 | 
						|
    if (
 | 
						|
      column > 1 &&
 | 
						|
      currentRow[column - 1] === '|' &&
 | 
						|
      column - 2 < previousRow.length &&
 | 
						|
      previousRow[column - 2] === '/'
 | 
						|
    ) {
 | 
						|
      this.currentFlows[column] = this.takePreviousFlow(column - 2);
 | 
						|
      return column;
 | 
						|
    }
 | 
						|
 | 
						|
    // If ' /'
 | 
						|
    //    '/'  -> take the '/' flow, but transform the symbol to '|' due to our spacing
 | 
						|
    // This should only happen if there are 3 '/' - in a row so we don't need to be cleverer here
 | 
						|
    if (
 | 
						|
      column > 0 &&
 | 
						|
      currentRow[column - 1] === ' ' &&
 | 
						|
      column - 1 < previousRow.length &&
 | 
						|
      previousRow[column - 1] === '/'
 | 
						|
    ) {
 | 
						|
      this.currentFlows[column] = this.takePreviousFlow(column - 1);
 | 
						|
      currentRow[column] = '|';
 | 
						|
      return column;
 | 
						|
    }
 | 
						|
 | 
						|
    // If ' /'
 | 
						|
    //    '|'  -> take the '|' flow
 | 
						|
    if (
 | 
						|
      column > 0 &&
 | 
						|
      currentRow[column - 1] === ' ' &&
 | 
						|
      column - 1 < previousRow.length &&
 | 
						|
      (previousRow[column - 1] === '|' || previousRow[column - 1] === '*')
 | 
						|
    ) {
 | 
						|
      this.currentFlows[column] = this.takePreviousFlow(column - 1);
 | 
						|
      return column;
 | 
						|
    }
 | 
						|
 | 
						|
    // If '/' <- Not sure this ever happens... but take the '\' flow
 | 
						|
    //    '\'
 | 
						|
    if (column < previousRow.length && previousRow[column] === '\\') {
 | 
						|
      this.currentFlows[column] = this.takePreviousFlow(column);
 | 
						|
      return column;
 | 
						|
    }
 | 
						|
 | 
						|
    // Otherwise just generate a new flow and wait for bug-reports...
 | 
						|
    this.currentFlows[column] = this.generateNewFlow(column);
 | 
						|
    return column;
 | 
						|
  }
 | 
						|
 | 
						|
  // setInFlow handles '\' - returns the last column that was set
 | 
						|
  // generally we prefer to take the left most flow from the previous row
 | 
						|
  setInFlow(column, currentRow, previousRow) {
 | 
						|
    // If '\?'
 | 
						|
    //    '/?' -> take the '/' flow
 | 
						|
    if (column < previousRow.length && previousRow[column] === '/') {
 | 
						|
      this.currentFlows[column] = this.takePreviousFlow(column);
 | 
						|
      return column;
 | 
						|
    }
 | 
						|
 | 
						|
    // If '\?'
 | 
						|
    //    ' \' -> take the '\' flow and reassign to '|'
 | 
						|
    // This should only happen if there are 3 '\' - in a row so we don't need to be cleverer here
 | 
						|
    if (column + 1 < previousRow.length && previousRow[column + 1] === '\\') {
 | 
						|
      this.currentFlows[column] = this.takePreviousFlow(column + 1);
 | 
						|
      currentRow[column] = '|';
 | 
						|
      return column;
 | 
						|
    }
 | 
						|
 | 
						|
    // If '\?'
 | 
						|
    //    ' |' -> take the '|' flow
 | 
						|
    if (
 | 
						|
      column + 1 < previousRow.length &&
 | 
						|
      (previousRow[column + 1] === '|' || previousRow[column + 1] === '*')
 | 
						|
    ) {
 | 
						|
      this.currentFlows[column] = this.takePreviousFlow(column + 1);
 | 
						|
      return column;
 | 
						|
    }
 | 
						|
 | 
						|
    // Otherwise just generate a new flow and wait for bug-reports if we're wrong...
 | 
						|
    this.currentFlows[column] = this.generateNewFlow(column);
 | 
						|
    return column;
 | 
						|
  }
 | 
						|
 | 
						|
  // setRightFlow handles '_' - returns the last column that was set
 | 
						|
  // generally we prefer to take the left most flow from the previous row
 | 
						|
  setRightFlow(column, currentRow, previousRow) {
 | 
						|
    // if '__' keep the '_' flow
 | 
						|
    if (column > 0 && currentRow[column - 1] === '_') {
 | 
						|
      this.currentFlows[column] = this.currentFlows[column - 1];
 | 
						|
      return column;
 | 
						|
    }
 | 
						|
 | 
						|
    // if '_|_' -> keep the '_' flow
 | 
						|
    if (
 | 
						|
      column > 1 &&
 | 
						|
      currentRow[column - 1] === '|' &&
 | 
						|
      currentRow[column - 2] === '_'
 | 
						|
    ) {
 | 
						|
      this.currentFlows[column] = this.currentFlows[column - 2];
 | 
						|
      return column;
 | 
						|
    }
 | 
						|
 | 
						|
    // if ' _' -> take the '/' flow
 | 
						|
    //    '/ '
 | 
						|
    if (
 | 
						|
      column > 0 &&
 | 
						|
      column - 1 < previousRow.length &&
 | 
						|
      previousRow[column - 1] === '/'
 | 
						|
    ) {
 | 
						|
      this.currentFlows[column] = this.takePreviousFlow(column - 1);
 | 
						|
      return column;
 | 
						|
    }
 | 
						|
 | 
						|
    // if ' |_'
 | 
						|
    //    '/? ' -> take the '/' flow (this may cause generation...)
 | 
						|
    //             we can do this because we know that git graph
 | 
						|
    //             doesn't create compact graphs like: ' |_'
 | 
						|
    //                                                 '//'
 | 
						|
    if (
 | 
						|
      column > 1 &&
 | 
						|
      column - 2 < previousRow.length &&
 | 
						|
      previousRow[column - 2] === '/'
 | 
						|
    ) {
 | 
						|
      this.currentFlows[column] = this.takePreviousFlow(column - 2);
 | 
						|
      return column;
 | 
						|
    }
 | 
						|
 | 
						|
    // There really shouldn't be another way of doing this - generate and wait for bug-reports...
 | 
						|
 | 
						|
    this.currentFlows[column] = this.generateNewFlow(column);
 | 
						|
    return column;
 | 
						|
  }
 | 
						|
 | 
						|
  // setLeftFlow handles '----.' - returns the last column that was set
 | 
						|
  // generally we prefer to take the left most flow from the previous row that terminates this left recursion
 | 
						|
  setLeftFlow(column, currentRow, previousRow) {
 | 
						|
    // This is: '----------.' or the like
 | 
						|
    //          '   \  \  /|\'
 | 
						|
 | 
						|
    // Find the end of the '-' or nearest '/|\' in the previousRow :
 | 
						|
    let originalColumn = column;
 | 
						|
    let flow;
 | 
						|
    for (; column < currentRow.length && currentRow[column] === '-'; column++) {
 | 
						|
      if (column > 0 && column - 1 < previousRow.length && previousRow[column - 1] === '/') {
 | 
						|
        flow = this.takePreviousFlow(column - 1);
 | 
						|
        break;
 | 
						|
      } else if (column < previousRow.length && previousRow[column] === '|') {
 | 
						|
        flow = this.takePreviousFlow(column);
 | 
						|
        break;
 | 
						|
      } else if (
 | 
						|
        column + 1 < previousRow.length &&
 | 
						|
        previousRow[column + 1] === '\\'
 | 
						|
      ) {
 | 
						|
        flow = this.takePreviousFlow(column + 1);
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    // if we have a flow then we found a '/|\' in the previousRow
 | 
						|
    if (flow) {
 | 
						|
      for (; originalColumn < column + 1; originalColumn++) {
 | 
						|
        this.currentFlows[originalColumn] = flow;
 | 
						|
      }
 | 
						|
      return column;
 | 
						|
    }
 | 
						|
 | 
						|
    // If the symbol in the column is not a '.' then there's likely an error
 | 
						|
    if (currentRow[column] !== '.') {
 | 
						|
      // It really should end in a '.' but this one doesn't...
 | 
						|
      // 1. Step back - we don't want to eat this column
 | 
						|
      column--;
 | 
						|
      // 2. Generate a new flow and await bug-reports...
 | 
						|
      this.currentFlows[column] = this.generateNewFlow(column);
 | 
						|
 | 
						|
      // 3. Assign all of the '-' to the same flow.
 | 
						|
      for (; originalColumn < column; originalColumn++) {
 | 
						|
        this.currentFlows[originalColumn] = this.currentFlows[column];
 | 
						|
      }
 | 
						|
      return column;
 | 
						|
    }
 | 
						|
 | 
						|
    // We have a terminal '.' eg. the current row looks like '----.'
 | 
						|
    // the previous row should look like one of '/|\' eg.    '     \'
 | 
						|
    if (column > 0 && column - 1 < previousRow.length && previousRow[column - 1] === '/') {
 | 
						|
      flow = this.takePreviousFlow(column - 1);
 | 
						|
    } else if (column < previousRow.length && previousRow[column] === '|') {
 | 
						|
      flow = this.takePreviousFlow(column);
 | 
						|
    } else if (
 | 
						|
      column + 1 < previousRow.length &&
 | 
						|
      previousRow[column + 1] === '\\'
 | 
						|
    ) {
 | 
						|
      flow = this.takePreviousFlow(column + 1);
 | 
						|
    } else {
 | 
						|
      // Again unexpected so let's generate and wait the bug-report
 | 
						|
      flow = this.generateNewFlow(column);
 | 
						|
    }
 | 
						|
 | 
						|
    // Assign all of the rest of the ----. to this flow.
 | 
						|
    for (; originalColumn < column + 1; originalColumn++) {
 | 
						|
      this.currentFlows[originalColumn] = flow;
 | 
						|
    }
 | 
						|
 | 
						|
    return column;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function generateRandomColorString() {
 | 
						|
  const chars = '0123456789ABCDEF';
 | 
						|
  const stringLength = 6;
 | 
						|
  let randomString = '',
 | 
						|
    rnum,
 | 
						|
    i;
 | 
						|
  for (i = 0; i < stringLength; i++) {
 | 
						|
    rnum = Math.floor(Math.random() * chars.length);
 | 
						|
    randomString += chars.substring(rnum, rnum + 1);
 | 
						|
  }
 | 
						|
 | 
						|
  return randomString;
 | 
						|
}
 | 
						|
 | 
						|
export default async function initGitGraph() {
 | 
						|
  const graphCanvas = document.getElementById('graph-canvas');
 | 
						|
  if (!graphCanvas || !graphCanvas.getContext) return;
 | 
						|
 | 
						|
  // Grab the raw graphList
 | 
						|
  const graphList = [];
 | 
						|
  $('#graph-raw-list li span.node-relation').each(function () {
 | 
						|
    graphList.push($(this).text());
 | 
						|
  });
 | 
						|
 | 
						|
  // Define some drawing parameters
 | 
						|
  const config = {
 | 
						|
    unitSize: 20,
 | 
						|
    lineWidth: 3,
 | 
						|
    nodeRadius: 4
 | 
						|
  };
 | 
						|
 | 
						|
 | 
						|
  const gitGraph = new GitGraph(graphCanvas, graphList, config);
 | 
						|
  gitGraph.draw();
 | 
						|
  graphCanvas.closest('#git-graph-container').classList.add('in');
 | 
						|
}
 |