Kendo Avoid Text Overlapping

Script to avoid text overlapping

by Edson Henrique

HTML

<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.2.621/styles/kendo.common-material.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.2.621/styles/kendo.material.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.2.621/styles/kendo.material.mobile.min.css">
<script src="https://kendo.cdn.telerik.com/2017.2.621/js/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2017.2.621/js/kendo.all.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
<div id="chart"></div>
<img id='img' />

JavaScript

$(document).ready(function() {
  console.clear();
  var positions = [];

  const collisitonTest = (position, list, detectHorizontalCollision = false) => {
    let rangeX = 5;
    let rangeY = 15;
    let collided = _.filter(list, i =>
      (detectHorizontalCollision ? (Math.abs(i[0] - position[0]) <= rangeX) : (i[0] == position[0])) &&
      Math.abs(i[1] - position[1]) <= rangeY);

    if (collided.length) {
      let haveAbove = _.some(collided, i => i[0] - position[0] <= 0);
      let haveBelow = _.some(collided, i => i[0] - position[0] > 0);
      return collisitonTest(moveObject(position, haveAbove, haveBelow), list);
    }

    return position;
  }

  const collisionAvoid = (position, list) => {
    return collisitonTest(position, list);
  }

  const moveObject = (obj, haveAbove, haveBelow) => {
    let position = _.clone(obj);
    let distance = 40;

    if (haveAbove) {
      position[1] += distance;
    } else if (haveBelow) {
      position[1] -= distance;
    }

    return position;
  }

  var data = _.map(_.range(0, 12), (i) => ({
    value: _.random(600, 600),
    value2: _.random(600, 600),
    value3: _.random(600, 600),
    value4: _.random(600, 600)
  }));

  var labelPosition = (label) => {
    let draw = kendo.drawing;
    let geom = kendo.geometry;

    let position = collisionAvoid([label.rect.origin.x, label.rect.origin.y], positions);
    positions.push(position);

    let rectPosition = [position[0] - 1, position[1] - 0];

    let rectGeometry = new geom.Rect(rectPosition, [label.rect.size.width - 3, label.rect.size.height - 6]);
    let rectDraw = new draw.Rect(rectGeometry).fill(label.options.background).stroke(label.options.border.color, 1);

    let textPosition = [position[0] + 2, position[1] + 2];
    let text = new kendo.drawing.Text(label.text, textPosition);

    //TESTING
    let g = new draw.Group();
    g.append(rectDraw, text);
    return g;
  }

  $("#chart").kendoChart({
    series: [{
      type: "line",
      labels: {
  ...