Edit in JSFiddle

(function() {
  /* get elements */
  let root = document.getElementById("demo");
  let inputNode = root.getElementsByTagName("input")[0];
  let processNode = root.getElementsByTagName("button")[0];
  let imageCanvasNode = root.getElementsByTagName("canvas")[0];
  let imageContext = imageCanvasNode.getContext("2d");
  let histogramCanvasNode = root.getElementsByTagName("canvas")[1];
  let histogramContext = histogramCanvasNode.getContext("2d");

  let imgData = null;

  let histogram = Array.from({
    length: 3
  }, () => {
    return Array.from({
      length: 256
    }, () => 0);
  });

  let minHistogram = Array.from({
    length: 3
  }, () => 0);
  let maxHistogram = Array.from({
    length: 3
  }, () => 0);

  let cdf = Array.from({
    length: 3
  }, () => {
    return Array.from({
      length: 256
    }, () => 0);
  });

  // upload image
  inputNode.onchange = function() {
    let file = inputNode.files[0];
    if (file) {
      createImage(URL.createObjectURL(file));
    }
  };

  // create image to canvas
  let createImage = function(url) {
    let img = new Image();
    img.onload = function() {
      imageCanvasNode.width = img.width;
      imageCanvasNode.height = img.height;
      imageContext.drawImage(img, 0, 0);
      imgData = imageContext.getImageData(0, 0, img.width, img.height);
      calcHistogram();
      drawHistogram();
    };
    img.src = url;
  };

  // calculate histogram
  let calcHistogram = function() {
    // clear
    for (let c = 0; c < 3; c += 1) {
      for (let i = 0; i < 256; i += 1) {
        histogram[c][i] = 0;
      }
    }

    // calc.
    for (let i = 0, l = imgData.data.length; i < l; i += 4) {
      for (let c = 0; c < 3; c += 1) {
        histogram[c][imgData.data[i + c]] += 1;
      }
    }

    // get range
    for (let c = 0; c < 3; c += 1) {
      minHistogram[c] = histogram[c].reduce((m, v) => Math.min(m, v), 0);
      maxHistogram[c] = histogram[c].reduce((m, v) => Math.max(m, v), 0);
    }
  };

  // draw histogram
  let drawHistogram = function() {

    // set histogram size
    histogramCanvasNode.width = 256 * 3;
    histogramCanvasNode.height = 120;

    // draw histogram
    for (let c = 0; c < 3; c += 1) {
      // select color
      switch (c) {
        case 0:
          histogramContext.strokeStyle = "rgb(255, 0, 0)";
          break;
        case 1:
          histogramContext.strokeStyle = "rgb(0, 255, 0)";
          break;
        case 2:
          histogramContext.strokeStyle = "rgb(0, 0, 255)";
          break;
      }

      // draw line
      histogramContext.beginPath();
      let min = minHistogram[c];
      let max = maxHistogram[c];
      for (let x = 0; x < 256; x += 1) {
        let v = Math.round(100 * (histogram[c][x] - min) / max);
        histogramContext.moveTo(x * 3 + c, 120 - v);
        histogramContext.lineTo(x * 3 + c, 120);
      }
      histogramContext.stroke();
    }
  };

  // histogram equalization
  let histogramEqualization = function() {

    // calculate CDF
    calcHistogram();
    for (let c = 0; c < 3; c += 1) {
      cdf[c][0] = histogram[c][0];
      for (let i = 1; i < 256; i += 1) {
        cdf[c][i] = cdf[c][i - 1] + histogram[c][i];
      }
    }

    // create new image
    let newData = imageContext.createImageData(imgData.width, imgData.height);
    let max = imgData.width * imgData.height;
    for (let c = 0; c < 3; c += 1) {
      let min = cdf[c][0];
      for (let i = 0, l = imgData.data.length; i < l; i += 4) {
        let v = cdf[c][imgData.data[i + c]];
        newData.data[i + c] = Math.round(255 * (v - min) / (max - min));
        newData.data[i + 3] = 255;
      }
    }
    imageContext.putImageData(newData, 0, 0);
    imgData = newData;

    // draw new histogram
    calcHistogram();
    drawHistogram();
  };

  createImage("https://i.imgur.com/pgZKCEL.png");
  processNode.onclick = histogramEqualization;
})();
 <div id="demo">
   <div>
     <label>
       <input type="file" accept="image/*" />
       <canvas width="10px" height="10px"></canvas>
     </label>
   </div>
   <canvas width="768px" height="120px"></canvas>
   <br />
   <button>histogram equalization</button>
 </div>
body {
  color: #ffffff;
  background: #20262e;
  font-family: monospace, sans-serif;
}

#demo {
  padding: 5px;
}

#demo canvas {
  border: solid 1px #ffffff;
}

#demo>div {
  margin-top: 5px;
}

#demo label input {
  color: #ffffff;
  background: #20262e;
  outline: none;
  display: none;
}

#demo label:hover {
  cursor: pointer;
}

#demo label div {
  float: left;
  font-weight: bold;
  font-size: 13.3333px;
  text-align: center;
  padding: 1px 6px;
  margin-right: 10px;
  color: #ffffff;
  background: #20262e;
  border: 1px solid #ffffff;
  outline: none;
}

#demo label div:hover {
  color: #20262e;
  background: #ffffff;
  border: 1px solid #ffffff;
}

#demo button {
  font-weight: bold;
  float: left;
  color: #ffffff;
  background: #20262e;
  border: 1px solid #ffffff;
  outline: none;
  margin-right: 10px;
  margin-top: 3px;
  cursor: pointer;
}

#demo button:hover {
  color: #20262e;
  background: #ffffff;
  border: 1px solid #ffffff;
}