html5画布在一个圆圈中画线

时间:2018-04-04 05:12:21

标签: javascript html5 canvas

使用html5画布在圆圈中绘制线条时遇到一些麻烦。 我试图使条形看起来像这样enter image description here

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
var bars = 50;
var radius = 100;
for(var i = 0; i < bars; i++){
  var x = radius*Math.cos(i);
  var y = radius*Math.sin(i);
  draw_rectangle(x+200,y+200,1,13,i, ctx );
}


function draw_rectangle(x,y,w,h,deg, ctx){
  ctx.save();
  ctx.translate(x, y);
  ctx.rotate(degrees_to_radians(deg));
  ctx.fillStyle = "yellow";
  ctx.fillRect(-1*(w/2), -1*(h/2), w, h);
  ctx.restore();
}
function degrees_to_radians(degrees){
  return degrees * Math.PI / 180;
}
function radians_to_degrees(radians){
  return radians * 180 / Math.PI;
};

由于某种原因,我的线条都是弯曲的和未对齐的。我真的需要帮助。 https://codepen.io/anon/pen/PRBdYV

3 个答案:

答案 0 :(得分:2)

处理此类可视化的最简单方法是使用上下文的转换矩阵。

你需要理解它,好像你手里拿着一张纸一样。 不要试图以正确的角度绘制线条,而是旋转纸张,并始终以相同的方向绘制线条。

这样,绘图方法所需要的只是角度和每个条形的高度。

&#13;
&#13;
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
// the position of the whole thing
var circleX = canvas.width / 2;
var circleY = canvas.height / 2;
//
var bars = 50;
var barWidth = 5;
// inner radius
var radius = 50;
ctx.fillStyle = "yellow";
// no need to use degrees, a full circle is just 2π
for(var i = 0; i < Math.PI*2; i+= (Math.PI*2 / bars)){
  draw_rectangle(i, (Math.random()*30) + 10);
}

function draw_rectangle(rad, barHeight){
  // reset and move to the center of our circle
  ctx.setTransform(1,0,0,1, circleX, circleY);
  // rotate the context so we face the correct angle
  ctx.rotate(rad);
  // move along y axis to reach the inner radius
  ctx.translate(0, radius);
  // draw the bar
  ctx.fillRect(
    -barWidth/2, // centered on x
    0, // from the inner radius
    barWidth,
    barHeight // until its own height
  );
}
&#13;
canvas#canvas{
  background:black;
}
&#13;
<html>
  <body>
    <canvas id="canvas" width="400" height="400"></canvas>
  </body>
</html>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

检查您的codepen并找出问题出在##options namely stop , remove or pass error_handle <- "remove" cores <- round(detectCores()*percent) cl<-makeCluster(cores) registerDoParallel(cl) predict_load_all <- foreach(i=1:length(id),.export=func,.packages (.packages()),.errorhandling = error_handle) %dopar% { possibleError <- tryCatch({ weather_cast <- data.frame(udata$date,j,coeff_i,predict(hour_fits[[j]], newdata=udata)) },error=function(e)return(paste0("The hour '",j, "'", " caused the error: '", e, "'"))) if(!exists("weather_cast")){ #possibleError <- data.frame('coeff_item' = coeff_i,'Error' = possibleError) possibleError <- data.frame('Error' = possibleError) write_csv(possibleError,file.path(path_predict, 'Error_weather_cast.csv'),append = T) stop('error') } colnames(weather_cast)<- c("Date","Hour","coeff_item","Predicted_Load") ifelse(j==1,predict_load <-weather_cast,predict_load <- rbind(predict_load,weather_cast)) predict_load <- spread(predict_load, Hour, Predicted_Load) predict_load }

以下是您的代码的更新链接。Link

PS我只看了圆圈的形状而不是条形的对齐方式:D

答案 2 :(得分:0)

https://codepen.io/anon/pen/YajONR

  1. 问题已修复:Math.cos需要弧度,而非度数
  2. 我们需要从0到360,所以我调整了条形数量使其更容易,并将i乘以6(因此最大值为60 * 6 == 360)
  3. 如果我们在绘制条形图时不添加+90,我们只需要一个圆圈