CSS& JS饼图

时间:2016-02-07 19:17:58

标签: javascript css

由于主要的CSS属性pieChartrotate:xdegborder-radius:100%,我创建了overflow:hidden函数。这帮我制作了任何尺寸的旋转四分之一馅饼。

以下是代码:

function getRandomColor() {
  var letters = '0123456789ABCDEF'.split('');
  var color = '#';
  for (var i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
} //http://stackoverflow.com/questions/1484506/random-color-generator-in-javascript

function drawQuarter(percent, angle, color) {
  var widthPercent = 90 - percent;
  var widthAngle = angle - 90 + percent;
  var output = '<div class="frame_0" style="transform: rotate(' + widthAngle + 'deg);">';
  output += '<div class="frame_1">';
  output += '<div class="frame_2" style="transform: rotate(' + widthPercent + 'deg);">';
  output += '<div class="square" style="background-color:' + color + '">';
  output += '</div>';
  output += '</div>';
  output += '</div>';
  output += '</div>';

  return output;
}

function pieChart(valuesArray) {
  var percent = [];
  var quarterQuantityArray = [];
  var HTMLoutput, dtop, dleft;
  var startAngle = 90;
  var rotation = startAngle;
  var output = '';
  var piechartSize = 40; // Half width of the piechart defined in css
  var pi = Math.PI;

  var sum = valuesArray.reduce(function(pv, cv) {
    return parseInt(pv) + parseInt(cv);
  }, 0); //http://stackoverflow.com/questions/3762589/fastest-javascript-summation

  if (sum == 0) //Case no data
  {
    HTMLoutput = '<div class="frame_square nodata"></div>';
    dtop = 30;
    dleft = 16;
    HTMLoutput += '<div class="label" style="top:' + dtop + 'px; left:' + dleft + 'px; line-height:normal;width:50px;">No data</div>';
    return HTMLoutput;
  } else { //Case with data

    for (var i = 0; i < valuesArray.length; i++) {
      percent[i] = valuesArray[i] / sum;
      quarterQuantityArray[i] = Math.ceil(percent[i] * 4);
    }

    for (var m = 0; m < valuesArray.length; m++) {
      var colorArray = ['#ef5350', '#66BB6A', '#26A69A'];
      var color = m > 2 ? getRandomColor() : colorArray[m];
      for (var j = 1; j <= quarterQuantityArray[m]; j++) {
        if (j != quarterQuantityArray[m]) {
          output += drawQuarter(90, rotation, color);
          rotation += 90;
        }
        if (j == quarterQuantityArray[m]) {
          var angle = percent[m] * 360 % 90;
          angle = angle == 0 ? 90 : angle; //In case of 25%, 50%, 75% and 100%
          output += drawQuarter(angle, rotation, color);
          rotation += angle;
        }
      }
    }

    var HTMLoutput = output;

    //Add labels
    //Case 100% for one value
    if (percent.indexOf(1) != -1) {
      dtop = piechartSize - 5;
      dleft = piechartSize - 10;
      HTMLoutput += '<div class="label" style="top:' + dtop + 'px; left:' + dleft + 'px; line-height:normal;">100%</div>';
    } else {
      var labelFrameSize = 10; //Half .piechart .label css size
      var label_int = piechartSize * 1 / 3; //retrait vers l'interieur du disque
      var rotation = (startAngle + 180) / 180;
      for (var n = 0; n < valuesArray.length; n++) {
      var deg = (rotation + percent[n]) * pi ;
        var labelY = piechartSize * (1 + Math.sin(deg)) - labelFrameSize - label_int * Math.sin(deg);
        var labelX = piechartSize * (1 + Math.cos(deg)) - labelFrameSize - label_int * Math.cos(deg);
        HTMLoutput += '<div class="label" style="top:' + labelY + 'px; left:' + labelX + 'px;">' + Math.round(percent[n] * 100, 0) + '%</div>';
        rotation += 2 * percent[n];
      }
    }
    return HTMLoutput;
  }
}

var test = pieChart(['6', '5', '4','8']);
document.getElementById('test').innerHTML = test;;
div.piechart,
.piechart .frame_0,
.piechart .frame_2 {
  width: 80px;
  height: 80px;
}

.piechart .frame_1,
.piechart .square {
  width: 40px;
  height: 40px;
}

div.piechart {
  position: relative;
  float: left;
  margin-right: 10px;
  text-align: center;
}

.piechart .frame_0 {
  position: absolute;
}

.piechart .frame_1 {
  overflow: hidden;
}

.piechart .square {
  border-radius: 100% 0 0 0;
}

.piechart .nodata {
  border-radius: 100%;
  background-color: #FFD419;
}

.piechart .label {
  position: absolute;
  text-align: center;
  width: 20PX;
  height: 20PX;
  line-height: 20PX;
  font-size: 7pt;
  color: white;
  font-weight: bold;
}
<div id="test" class="piechart">

</div>

问题是宿舍和内部宿舍之间有白线大于25%,我想要删除,但我不知道怎么样,有没有人有想法?

JSfiddle

1 个答案:

答案 0 :(得分:0)

我找到了一个解决问题的技巧:我在.square div上添加了一个0.01em的border-bottom。此处更新了代码(自第一个版本以来已经过优化):

&#13;
&#13;
function getRandomColor() {
  var letters = '0123456789ABCDEF'.split('');
  var color = '#';
  for (var i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
} //http://stackoverflow.com/questions/1484506/random-color-generator-in-javascript

function drawQuarter(percent, angle, color) {
  var widthPercent = 90 - percent;
  var widthAngle = angle - 90 + percent;
  var output = '<div class="frame_0" style="transform: rotate(' + widthAngle + 'deg);"><div class="frame_1"><div class="frame_2" style="transform: rotate(' + widthPercent + 'deg);"><div class="square" style="background-color:' + color + '; border-bottom:' + color + ' 0.01em solid;"></div></div></div></div>';

  return output;
}

function pieChart(valuesArray) {
  var percent = [];
  var quarterQuantityArray = [];
  var HTMLoutput, dtop, dleft;
  var startAngle = 90;
  var rotation = startAngle;
  var output = '';
  var piechartSize = 100; // Half width of the piechart defined in css
  var pi = Math.PI;

  var sum = valuesArray.reduce(function(pv, cv) {
    return parseInt(pv) + parseInt(cv);
  }, 0); //http://stackoverflow.com/questions/3762589/fastest-javascript-summation

  if (sum == 0) //Case no data
  {
    HTMLoutput = '<div class="frame_square nodata"></div>';
      dtop = piechartSize - 5;
      dwidth = 2*piechartSize;
    HTMLoutput += '<div class="label" style="top:' + dtop + 'px; width:' + dwidth + 'px; line-height:normal;">No data</div>';
    return HTMLoutput;
  } else { //Case with data

    for (var i = 0; i < valuesArray.length; i++) {
      percent[i] = valuesArray[i] / sum;
      quarterQuantityArray[i] = Math.ceil(percent[i] * 4);
    }

    for (var m = 0; m < valuesArray.length; m++) {
      var colorArray = ['#ef5350', '#66BB6A', '#26A69A'];
      var color = m > 2 ? getRandomColor() : colorArray[m];
      for (var j = 1; j <= quarterQuantityArray[m]; j++) {
        if (j != quarterQuantityArray[m]) {
          output += drawQuarter(90, rotation, color);
          rotation += 90;
        } else {
          var angle = percent[m] * 360 % 90;
          angle = angle == 0 ? 90 : angle; //In case of 25%, 50%, 75% and 100%
          output += drawQuarter(angle, rotation, color);
          rotation += angle;
        }
      }
    }

    var HTMLoutput = output;

    //Add labels
    //Case 100% for one value
    if (percent.indexOf(1) != -1) {
      dtop = piechartSize - 5;
      dleft = piechartSize - 10;
      HTMLoutput += '<div class="label" style="top:' + dtop + 'px; left:' + dleft + 'px; line-height:normal;">100%</div>';
    } else {
      var labelFrameSize = 10; //Half .piechart .label css size
      var label_int = piechartSize * 1 / 3; //retrait vers l'interieur du disque
      var rotation = (startAngle + 180) / 180;
      for (var n = 0; n < valuesArray.length; n++) {
      var deg = (rotation + percent[n]) * pi ;
        var labelY = piechartSize * (1 + Math.sin(deg)) - labelFrameSize - label_int * Math.sin(deg);
        var labelX = piechartSize * (1 + Math.cos(deg)) - labelFrameSize - label_int * Math.cos(deg);
        HTMLoutput += '<div class="label" style="top:' + labelY + 'px; left:' + labelX + 'px;">' + Math.round(percent[n] * 100, 0) + '%</div>';
        rotation += 2 * percent[n];
      }
    }
    return HTMLoutput;
  }
}

document.getElementById('test0').innerHTML = pieChart(['6', '5', '5','1']);
document.getElementById('test1').innerHTML = pieChart(['0', '0', '0']);
&#13;
div.piechart,
.piechart .frame_0,
.piechart .frame_2,
.piechart .nodata {
  width: 200px;
  height: 200px;
}

.piechart .frame_1,
.piechart .square {
  width: 100px;
  height: 100px;
}

div.piechart {
  position: relative;
  float: left;
  margin-right: 10px;
  text-align: center;
}

.piechart .frame_0 {
  position: absolute;
}

.piechart .frame_1 {
  overflow: hidden;
}

.piechart .square {
  border-radius: 100% 0 0 0;
}

.piechart .nodata {
  border-radius: 100%;
  background-color: #FFD419;
}

.piechart .label {
  position: absolute;
  text-align: center;
  width: 20PX;
  height: 20PX;
  line-height: 20PX;
  font-size: 7pt;
  color: white;
  font-weight: bold;
}
&#13;
<div id="test0" class="piechart"></div>
<div id="test1" class="piechart"></div>
&#13;
&#13;
&#13;

我希望有人会发现这个免费的简单的饼图很有用。但要确保它至少对我自己有用......