Analisis Kalkulator

ANALISIS DESIGN KALKULATOR

    Kali ini penulis akan membuat analisis mengenai design kalkulator. berikut adalah design kalkulator yang akan penulis analisis.


CODE HTML

<div class="calculator">
  <div class="input" id="input"></div>
  <div class="buttons">
    <div class="operators">
      <div>+</div>
      <div>-</div>
      <div>&times;</div>
      <div>&divide;</div>
    </div>
    <div class="leftPanel">
      <div class="numbers">
        <div>7</div>
        <div>8</div>
        <div>9</div>
      </div>
      <div class="numbers">
        <div>4</div>
        <div>5</div>
        <div>6</div>
      </div>
      <div class="numbers">
        <div>1</div>
        <div>2</div>
        <div>3</div>
      </div>
      <div class="numbers">
        <div>0</div>
        <div>.</div>
        <div id="clear">C</div>
      </div>
    </div>
    <div class="equal" id="result">=</div>
  </div>
</div>
    

CODE CSS

<style>
body {
  width: 500px;
  margin: 4% auto;
  font-family: 'Source Sans Pro', sans-serif;
  letter-spacing: 5px;
  font-size: 1.8rem;
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
}

.calculator {
  padding: 20px;
  -webkit-box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.2);
  box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.2);
  border-radius: 1px;
}

.input {
  border: 1px solid #ddd;
  border-radius: 1px;
  height: 60px;
  padding-right: 15px;
  padding-top: 10px;
  text-align: right;
  margin-right: 6px;
  font-size: 2.5rem;
  overflow-x: auto;
  transition: all .2s ease-in-out;
}

.input:hover {
  border: 1px solid #bbb;
  -webkit-box-shadow: inset 0px 1px 4px 0px rgba(0, 0, 0, 0.2);
  box-shadow: inset 0px 1px 4px 0px rgba(0, 0, 0, 0.2);
}

.buttons {}

.operators {}

.operators div {
  display: inline-block;
  border: 1px solid #bbb;
  border-radius: 1px;
  width: 80px;
  text-align: center;
  padding: 10px;
  margin: 20px 4px 10px 0;
  cursor: pointer;
  background-color: #ddd;
  transition: border-color .2s ease-in-out, background-color .2s, box-shadow .2s;
}

.operators div:hover {
  background-color: #ddd;
  -webkit-box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.2);
  box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.2);
  border-color: #aaa;
}

.operators div:active {
  font-weight: bold;
}

.leftPanel {
  display: inline-block;
}

.numbers div {
  display: inline-block;
  border: 1px solid #ddd;
  border-radius: 1px;
  width: 80px;
  text-align: center;
  padding: 10px;
  margin: 10px 4px 10px 0;
  cursor: pointer;
  background-color: #f9f9f9;
  transition: border-color .2s ease-in-out, background-color .2s, box-shadow .2s;
}

.numbers div:hover {
  background-color: #f1f1f1;
  -webkit-box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.2);
  box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.2);
  border-color: #bbb;
}

.numbers div:active {
  font-weight: bold;
}

div.equal {
  display: inline-block;
  border: 1px solid #3079ED;
  border-radius: 1px;
  width: 17%;
  text-align: center;
  padding: 127px 10px;
  margin: 10px 6px 10px 0;
  vertical-align: top;
  cursor: pointer;
  color: #FFF;
  background-color: #4d90fe;
  transition: all .2s ease-in-out;
}

div.equal:hover {
  background-color: #307CF9;
  -webkit-box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.2);
  box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.2);
  border-color: #1857BB;
}

div.equal:active {
  font-weight: bold;
}
</style>

CODE JS

"use strict";

var input = document.getElementById('input'), // input/output button
  number = document.querySelectorAll('.numbers div'), // number buttons
  operator = document.querySelectorAll('.operators div'), // operator buttons
  result = document.getElementById('result'), // equal button
  clear = document.getElementById('clear'), // clear button
  resultDisplayed = false; // flag to keep an eye on what output is displayed

// adding click handlers to number buttons
for (var i = 0; i < number.length; i++) {
  number[i].addEventListener("click", function(e) {

    // storing current input string and its last character in variables - used later
    var currentString = input.innerHTML;
    var lastChar = currentString[currentString.length - 1];

    // if result is not diplayed, just keep adding
    if (resultDisplayed === false) {
      input.innerHTML += e.target.innerHTML;
    } else if (resultDisplayed === true && lastChar === "+" || lastChar === "-" || lastChar === "×" || lastChar === "÷") {
      // if result is currently displayed and user pressed an operator
      // we need to keep on adding to the string for next operation
      resultDisplayed = false;
      input.innerHTML += e.target.innerHTML;
    } else {
      // if result is currently displayed and user pressed a number
      // we need clear the input string and add the new input to start the new opration
      resultDisplayed = false;
      input.innerHTML = "";
      input.innerHTML += e.target.innerHTML;
    }

  });
}

// adding click handlers to number buttons
for (var i = 0; i < operator.length; i++) {
  operator[i].addEventListener("click", function(e) {

    // storing current input string and its last character in variables - used later
    var currentString = input.innerHTML;
    var lastChar = currentString[currentString.length - 1];

    // if last character entered is an operator, replace it with the currently pressed one
    if (lastChar === "+" || lastChar === "-" || lastChar === "×" || lastChar === "÷") {
      var newString = currentString.substring(0, currentString.length - 1) + e.target.innerHTML;
      input.innerHTML = newString;
    } else if (currentString.length == 0) {
      // if first key pressed is an opearator, don't do anything
      console.log("enter a number first");
    } else {
      // else just add the operator pressed to the input
      input.innerHTML += e.target.innerHTML;
    }

  });
}

// on click of 'equal' button
result.addEventListener("click", function() {

  // this is the string that we will be processing eg. -10+26+33-56*34/23
  var inputString = input.innerHTML;

  // forming an array of numbers. eg for above string it will be: numbers = ["10", "26", "33", "56", "34", "23"]
  var numbers = inputString.split(/\+|\-|\×|\÷/g);

  // forming an array of operators. for above string it will be: operators = ["+", "+", "-", "*", "/"]
  // first we replace all the numbers and dot with empty string and then split
  var operators = inputString.replace(/[0-9]|\./g, "").split("");

  console.log(inputString);
  console.log(operators);
  console.log(numbers);
  console.log("----------------------------");

  // now we are looping through the array and doing one operation at a time.
  // first divide, then multiply, then subtraction and then addition
  // as we move we are alterning the original numbers and operators array
  // the final element remaining in the array will be the output

  var divide = operators.indexOf("÷");
  while (divide != -1) {
    numbers.splice(divide, 2, numbers[divide] / numbers[divide + 1]);
    operators.splice(divide, 1);
    divide = operators.indexOf("÷");
  }

  var multiply = operators.indexOf("×");
  while (multiply != -1) {
    numbers.splice(multiply, 2, numbers[multiply] * numbers[multiply + 1]);
    operators.splice(multiply, 1);
    multiply = operators.indexOf("×");
  }

  var subtract = operators.indexOf("-");
  while (subtract != -1) {
    numbers.splice(subtract, 2, numbers[subtract] - numbers[subtract + 1]);
    operators.splice(subtract, 1);
    subtract = operators.indexOf("-");
  }

  var add = operators.indexOf("+");
  while (add != -1) {
    // using parseFloat is necessary, otherwise it will result in string concatenation :)
    numbers.splice(add, 2, parseFloat(numbers[add]) + parseFloat(numbers[add + 1]));
    operators.splice(add, 1);
    add = operators.indexOf("+");
  }

  input.innerHTML = numbers[0]; // displaying the output

  resultDisplayed = true; // turning flag if result is displayed
});

// clearing the input on press of clear
clear.addEventListener("click", function() {
  input.innerHTML = "";
})

Analisis Usability
  • Konsistensi - tombol 0-9 mirip dengan kalkulator pada umumnya
  • Efesiensi - Hasilnya langsung keluar dilayar
  • Error Handling - Ketika kita melakukan operasi yang abnormal maka akan memperlihatkan hasil infinity
  • Estetika - Tampilannya cukup nyaman dan gampang untuk dipahami
  • Efektifitas - Setelah beberapa kali percobaan hasil yang keluar selalu benar

Kekurangan
  • Tidak ada tanda untuk plus minus
  • Tombol operator tidak konsisten
  • Tidak ada tombol untuk backspace
  • Tidak ada perbedaan mencolok antara tombol operator dan angka

Setelah melalui analisis usability, saya menyimpulkan beberapa hal yang sudah bagus dan yang masih perlu perbaikan. Letak tombol angka sudah tepat dan konsisten dengan kalkulator-kalkulator pada umumnya, namun konsistensi letak tombol operatornya tidak sesuai dengan kalkulator pada umumnya. Efisiensi dan efektifitasnya cukup bagus, hasil akan langsung terlihat dilayar dan akurasinya tinggi. Namun penulis melihat bahwa pada bagian tombol masih ada kekurangan seperti, tidak ada tombol untuk menghapus satu karakter. Ketika kita salah memasukkan angka maka kita harus menghapus semua angka dan operator yang telah dimasukkan. Efisiensi dan efektifitasnya akan sangat berkurang hanya karena hal ini. Tampilannya bagus namun tidak ada perbedaan mencolok pada tombol angka dan operator yang mana itu cukup membuat bingung.

     Setelah tahap analisis, penulis selanjutnya membuat redesign kalkulator yang digunakan. Berikut adalah redesign dari penulis.


Selanjutnya penulis mengimplementasikan design pada codepen untuk selanjutnya diuji apakah perubahan meningkatkan kenyamanan pengguna.
CODE HTML

<div class="calculator">
  <div class="input" id="input"></div>
  <div class="buttons">
    <div class="operators">
      <div id="backspace" class="operator">⌫</div> <!-- backspace -->
      <div id="plusminus" class="operator">±</div> <!-- plus minus -->
      <div id="clear" class="operator">C</div> <!-- clear -->
      <div class="operator">&divide;</div>
    </div>

    <div class="leftPanel">
      <div class="numbers">
        <div>7</div>
        <div>8</div>
        <div>9</div>
        <div class="operator">&times;</div>
      </div>

      <div class="numbers">
        <div>4</div>
        <div>5</div>
        <div>6</div>
        <div class="operator">+</div>
      </div>

      <div class="numbers">
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div class="operator">-</div>
      </div>

      <div class="numbers">
        <div>0</div>
        <div>00</div> <!-- double zero -->
        <div>.</div>
        <div id="result" class="operator">=</div> <!-- sama dengan -->
      </div>
    </div>
  </div>
</div>
        

CODE CSS

<style>
.calculator {
  width: 260px;
  margin: 20px auto;
  padding: 20px;
  border-radius: 10px;
  background: #f2f2f2;
  box-shadow: 0px 0px 10px #aaa;
}

.input {
  background: #fff;
  height: 50px;
  margin-bottom: 10px;
  padding: 10px;
  text-align: right;
  font-size: 20px;
  border: 1px solid #ccc;
  border-radius: 5px;
  overflow-x: auto;
}

.buttons {
  display: flex;
  flex-direction: column;
}

.numbers,
.operators {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 5px;
  margin-bottom: 5px;
}

.numbers div,
.operators div {
  background: #e0e0e0;
  padding: 15px;
  text-align: center;
  border-radius: 5px;
  font-size: 18px;
  cursor: pointer;
  user-select: none;
}

/* angka hitam */
.numbers div {
  color: black;
}

/* semua operator & tombol fungsi jadi biru terang */
.operator,
.operators div,
.numbers div.operator {
  color: #007bff; /* biru terang */
  font-weight: bold;
}

</style>
        

CODE JS

"use strict";

var input = document.getElementById("input"),
  number = document.querySelectorAll(".numbers div"),
  operator = document.querySelectorAll(".operators div"),
  result = document.getElementById("result"),
  clear = document.getElementById("clear"),
  backspace = document.getElementById("backspace"),
  plusminus = document.getElementById("plusminus"),
  resultDisplayed = false;

// === angka ===
for (var i = 0; i < number.length; i++) {
  number[i].addEventListener("click", function (e) {
    var currentString = input.innerHTML;
    var lastChar = currentString[currentString.length - 1];

    // tombol "00"
    if (e.target.innerHTML === "00") {
      input.innerHTML += "00";
      return;
    }

    if (!resultDisplayed) {
      input.innerHTML += e.target.innerHTML;
    } else if (["+", "-", "×", "÷"].includes(lastChar)) {
      resultDisplayed = false;
      input.innerHTML += e.target.innerHTML;
    } else {
      resultDisplayed = false;
      input.innerHTML = e.target.innerHTML;
    }
  });
}

// === operator (hanya + - × ÷) ===
for (var i = 0; i < operator.length; i++) {
  operator[i].addEventListener("click", function (e) {
    var op = e.target.innerHTML;
    if (!["+", "-", "×", "÷"].includes(op)) return; // cegah fungsi ikut masuk

    var currentString = input.innerHTML;
    var lastChar = currentString[currentString.length - 1];

    if (["+", "-", "×", "÷"].includes(lastChar)) {
      input.innerHTML = currentString.slice(0, -1) + op;
    } else if (currentString.length != 0) {
      input.innerHTML += op;
    }
  });
}

// === tombol sama dengan ===
result.addEventListener("click", function () {
  var inputString = input.innerHTML;
  if (!inputString) return;

  // ambil angka (bisa negatif & desimal)
  var numbers = inputString.match(/-?\d+(\.\d+)?/g) || [];
  // ambil operator (hapus angka dulu, sisanya operator)
  var operators = inputString
    .replace(/-?\d+(\.\d+)?/g, "")
    .split("")
    .filter((op) => op);

  // urutan operasi: ÷ × - +
  var divide = operators.indexOf("÷");
  while (divide != -1) {
    numbers.splice(
      divide,
      2,
      parseFloat(numbers[divide]) / parseFloat(numbers[divide + 1])
    );
    operators.splice(divide, 1);
    divide = operators.indexOf("÷");
  }

  var multiply = operators.indexOf("×");
  while (multiply != -1) {
    numbers.splice(
      multiply,
      2,
      parseFloat(numbers[multiply]) * parseFloat(numbers[multiply + 1])
    );
    operators.splice(multiply, 1);
    multiply = operators.indexOf("×");
  }

  var subtract = operators.indexOf("-");
  while (subtract != -1) {
    numbers.splice(
      subtract,
      2,
      parseFloat(numbers[subtract]) - parseFloat(numbers[subtract + 1])
    );
    operators.splice(subtract, 1);
    subtract = operators.indexOf("-");
  }

  var add = operators.indexOf("+");
  while (add != -1) {
    numbers.splice(
      add,
      2,
      parseFloat(numbers[add]) + parseFloat(numbers[add + 1])
    );
    operators.splice(add, 1);
    add = operators.indexOf("+");
  }

  input.innerHTML = numbers[0] ?? "";
  resultDisplayed = true;
});

// === tombol clear ===
clear.addEventListener("click", function () {
  input.innerHTML = "";
});

// === tombol backspace (⌫) ===
backspace.addEventListener("click", function () {
  input.innerHTML = input.innerHTML.slice(0, -1);
});

// === tombol plus/minus (±) ===
plusminus.addEventListener("click", function () {
  if (input.innerHTML) {
    // cari angka terakhir
    var current = input.innerHTML;
    var match = current.match(/(\d+(\.\d+)?)$/);
    if (match) {
      var lastNum = match[0];
      var toggled = -parseFloat(lastNum);
      input.innerHTML = current.slice(0, -lastNum.length) + toggled;
    }
  }
});

        

Setelah berapa kali pengujian oleh penulis. Terjadi beberapa peningkatan kenyamanan saat digunakan. Penulis tidak perlu lagi menghapus keseluruhan input bila terjadi kesalahan dalam memasukkan input terakhir. Bila ingin memasukkan angka jutaan dengan angka terakhir nol yang lebih dari dua, tidak perlu memasukkan angka nol satu persatu. Melakukan operasi dengan bilangan negatif sekarang bisa dilakukan. Penempatan tombol operator sekarang sudah sesuai dengan kalkulator pada umumnya. Hal ini sangat meningkatkan kenyamanan saat memasukkan tombol operator. Penulis menarik kesimpulan bahwa perubahan meningkatkan kenyamanan saat kalkulator digunakan.

    Selanjutnya penulis mencoba memasukkan input abnormal. Penulis kemudian memasukkan input 10 dibagi 0 hasil yang didapatkan adalah infinity. Hal ini disebabkan oleh operasi yang tidak memungkinkan. Kalau outputnya adalah infinity maka akan menyebabkan kesalahpahaman pada hasil. Penulis menyarankan agar output yang dihasilkan adalah ‘tidak valid’ untuk menghindari kesalahpahaman. Saat penulis memasukkan lebih dari satu operator secara bersamaan, kalkulator masih menerima input tersebut. Output yang dihasilkan ketika penggunaan dua operator secara bersamaan adalah NaN. Sebaiknya output yang diberikan adalah keterangan bahwa ada dua input operator yang dimasukkan secara bersamaan. Lebih baik lagi jika program otomatis mengganti operator sebelumnya ke yang terakhir dimasukkan.

Komentar

Postingan Populer