我有html画布。每个内部都是一个计数盒,每个候选人的投票数量产生了计数盒的数量。当投票低于50时,计数框完全显示在画布内,但当投票超过100时,其他计数框就丢失了。它们都是水平显示的。我现在想要的是显示画布内的所有标签框。我添加了一个最大宽度的css:“100%”,我认为这样可以解决问题,但不能。我应该怎么做呢?任何建议将不胜感激。提前致谢
这是我的代码如下。特别感谢Shomz。
var tb = angular.module("tb", []);
tb.controller("tallyboxController", function($scope) {
'use strict';
$scope.label = {
table: {
cName: "Candidate's Name",
cVote: 'Vote',
cTB: 'Tally Boxes',
cNV: 'No of votes',
period: '.'
},
};
$scope.presidents = [{
no: '1',
name: 'Jeoanna Lingh',
votes: 1223,
},{
no: '2',
name: 'Jewel Miller',
votes: 1234,
},{
no: '3',
name: 'Shin Lee',
votes: 1001,
}];
$scope.candidates = [
$scope.presidents,
$scope.vicepresidents
];
});
var tb = angular.module('tb');
tb.directive('drawing', function() {
return {
restrict: 'A',
scope: {
candidate: '='
},
link: function(scope, element, attrs) {
var colors = ['Red', 'Green', 'Blue', 'Yellow','black'];
scope.$watch("candidate.votes", function(newValue, oldValue) {
console.log('rendering', newValue);
render();
});
function render() {
var votes = scope.candidate.votes;
var ctx = element[0].getContext('2d');
var remainder = 0;
var oneBox = 0;
// clear canvas (needed for subtracting votes)
// and is a good practice anyway
element[0].width = element[0].width;
if (votes > 4) {
if (remainder = votes % 5) {
oneBox = (votes - remainder) / 5;
}
else {
oneBox = votes / 5;
}
} else {
remainder = votes;
}
drawOneBox();
function drawOneBox() {
;
for (var i = 0; i < oneBox; i++) {
var color = colors[Math.floor(i/5)];
ctx.beginPath();
ctx.moveTo(5 + i * 25, 5);
ctx.lineTo(25 + i * 25, 5);
ctx.moveTo(5 + i * 25, 5);
ctx.lineTo(5 + i * 25, 25);
ctx.moveTo(25 + i * 25, 5);
ctx.lineTo(25 + i * 25, 25);
ctx.moveTo(5 + i * 25, 5);
ctx.lineTo(25 + i * 25, 25);
ctx.moveTo(25 + i * 25, 25);
ctx.lineTo(5 + i * 25, 25);
ctx.strokeStyle = color;
ctx.stroke();
}
// recheck the color
color = colors[Math.floor(oneBox/5)];
if (remainder == 1) {
ctx.beginPath();
ctx.moveTo(5 + i * 25, 5);
ctx.lineTo(5 + i * 25, 25);
ctx.strokeStyle = color;
ctx.stroke();
}
if (remainder == 2) {
ctx.beginPath();
ctx.moveTo(5 + i * 25, 5);
ctx.lineTo(25 + i * 25, 5);
ctx.moveTo(5 + i * 25, 5);
ctx.lineTo(5 + i * 25, 25);
ctx.strokeStyle = color;
ctx.stroke();
}
if (remainder == 3) {
ctx.beginPath();
ctx.moveTo(5 + i * 25, 5);
ctx.lineTo(25 + i * 25, 5);
ctx.moveTo(5 + i * 25, 5);
ctx.lineTo(5 + i * 25, 25);
ctx.moveTo(25 + i * 25, 5);
ctx.lineTo(25 + i * 25, 25);
ctx.strokeStyle = color;
ctx.stroke();
}
if (remainder == 4) {
ctx.beginPath();
ctx.moveTo(5 + i * 25, 5);
ctx.lineTo(25 + i * 25, 5);
ctx.moveTo(5 + i * 25, 5);
ctx.lineTo(5 + i * 25, 25);
ctx.moveTo(25 + i * 25, 5);
ctx.lineTo(25 + i * 25, 25);
ctx.moveTo(25 + i * 25, 25);
ctx.lineTo(5 + i * 25, 25);
ctx.strokeStyle = color;
ctx.stroke();
}
};
}
render();
} // end
};
});
canvas {
max-width: 100%;
height: auto;
border: 2px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html data-ng-app="tb">
<head lang="en">
<meta charset="utf-8">
<title>Tally Boxes</title>
</head>
<body data-ng-controller="tallyboxController" data-ng-init="init()">
<div id="container">
</div>
<div class="container-table">
<table border="1" width="100%">
<thead>
<tr>
<td>{{label.table.cName}}</td>
<td>{{label.table.cTB}}</td>
<td>{{label.table.cNV}}</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="(key,value) in candidates[0]">
<td>{{value.no}} {{label.table.period}} {{value.name}}</td>
<td>
<canvas width="1000" height="30" id="{{value.no}}" candidate="value" drawing></canvas>
</td>
<td>{{value.votes}}</td>
</tr>
</tbody
</table>
</div>
</body>
</html>
答案 0 :(得分:1)
在响应性方面,Canvas可能会遇到很多问题。当然,您可以使用CSS来缩放它(请记住,CSS尺寸与画布尺寸不同,如果不同,画布会拉伸)。
因此,您需要自己实施智能响应技术 - 考虑获取可用的画布大小,并相应地重新绘制框。这可以进入窗口调整大小回调,因此它也适用于窗口大小调整。
如果你不想搞砸所有这些,你仍然可以切换回使用常规图像(每种颜色5个),并使用标准的HTML / CSS响应实践。如果没有,则必须在每次调整大小时重新计算画布大小(加上首次加载时)并相应地定位标记框。
谢谢你的提及,顺便说一句。 :)
更新
我看到你同时设法实现了CSS缩放,但请记住,当票数增加时,盒子可能会变得非常小;你可能想要使用多行。
更新2
这就是我的意思 - 看看画布上的这个响应版本是否适合您。它仍然需要一些调整,但你明白了:
var tb = angular.module("tb", []);
tb.controller("tallyboxController", function($scope) {
'use strict';
$scope.label = {
table: {
cName: "Candidate's Name",
cVote: 'Vote',
cTB: 'Tally Boxes',
cNV: 'No of votes',
period: '.'
},
};
$scope.presidents = [{
no: '1',
name: 'Jeoanna Lingh',
votes: 1223,
}, {
no: '2',
name: 'Jewel Miller',
votes: 1234,
}, {
no: '3',
name: 'Shin Lee',
votes: 1001,
}];
$scope.candidates = [
$scope.presidents,
$scope.vicepresidents
];
});
var tb = angular.module('tb');
tb.directive('drawing', function() {
return {
restrict: 'A',
scope: {
candidate: '='
},
link: function(scope, element, attrs) {
var colors = ['Red', 'Green', 'Blue', 'Yellow', 'black'];
scope.$watch("candidate.votes", function(newValue, oldValue) {
console.log('rendering', newValue);
render();
});
function render() {
var votes = scope.candidate.votes;
var ctx = element[0].getContext('2d');
var remainder = 0;
var oneBox = 0;
// clear canvas (needed for subtracting votes)
// and is a good practice anyway
element[0].width = element[0].width;
if (votes > 4) {
if (remainder = votes % 5) {
oneBox = (votes - remainder) / 5;
} else {
oneBox = votes / 5;
}
} else {
remainder = votes;
}
window.addEventListener('resize', handleResize);
setTimeout(handleResize, 100);
function handleResize() {
var c = element[0];
var width = c.parentNode.offsetWidth;
var perRow = Math.floor((width - 10) / 25);
c.width = width;
c.height = Math.ceil(oneBox / perRow) * 25 + 5;
console.log(perRow, width, oneBox);
drawOneBox(perRow);
}
function drawOneBox(perRow) {
for (var r = 0; r < oneBox / perRow; r++) {
var remainingInRow = (oneBox - r * perRow);
if (remainingInRow > perRow) remainingInRow = perRow;
for (var i = 0; i < remainingInRow; i++) {
var rowOffset = r * 25;
var color = colors[Math.floor(i / 5)];
ctx.beginPath();
ctx.moveTo(5 + i * 25, 5 + rowOffset);
ctx.lineTo(25 + i * 25, 5 + rowOffset);
ctx.moveTo(5 + i * 25, 5 + rowOffset);
ctx.lineTo(5 + i * 25, 25 + rowOffset);
ctx.moveTo(25 + i * 25, 5 + rowOffset);
ctx.lineTo(25 + i * 25, 25 + rowOffset);
ctx.moveTo(5 + i * 25, 5 + rowOffset);
ctx.lineTo(25 + i * 25, 25 + rowOffset);
ctx.moveTo(25 + i * 25, 25 + rowOffset);
ctx.lineTo(5 + i * 25, 25 + rowOffset);
ctx.strokeStyle = color;
ctx.stroke();
}
}
// recheck the color
color = colors[Math.floor(oneBox / 5)];
if (remainder == 1) {
ctx.beginPath();
ctx.moveTo(5 + i * 25, 5 + rowOffset);
ctx.lineTo(5 + i * 25, 25 + rowOffset);
ctx.strokeStyle = color;
ctx.stroke();
}
if (remainder == 2) {
ctx.beginPath();
ctx.moveTo(5 + i * 25, 5 + rowOffset);
ctx.lineTo(25 + i * 25, 5 + rowOffset);
ctx.moveTo(5 + i * 25, 5 + rowOffset);
ctx.lineTo(5 + i * 25, 25 + rowOffset);
ctx.strokeStyle = color;
ctx.stroke();
}
if (remainder == 3) {
ctx.beginPath();
ctx.moveTo(5 + i * 25, 5 + rowOffset);
ctx.lineTo(25 + i * 25, 5 + rowOffset);
ctx.moveTo(5 + i * 25, 5 + rowOffset);
ctx.lineTo(5 + i * 25, 25 + rowOffset);
ctx.moveTo(25 + i * 25, 5 + rowOffset);
ctx.lineTo(25 + i * 25, 25 + rowOffset);
ctx.strokeStyle = color;
ctx.stroke();
}
if (remainder == 4) {
ctx.beginPath();
ctx.moveTo(5 + i * 25, 5 + rowOffset);
ctx.lineTo(25 + i * 25, 5 + rowOffset);
ctx.moveTo(5 + i * 25, 5 + rowOffset);
ctx.lineTo(5 + i * 25, 25 + rowOffset);
ctx.moveTo(25 + i * 25, 5 + rowOffset);
ctx.lineTo(25 + i * 25, 25 + rowOffset);
ctx.moveTo(25 + i * 25, 25 + rowOffset);
ctx.lineTo(5 + i * 25, 25 + rowOffset);
ctx.strokeStyle = color;
ctx.stroke();
}
};
}
render();
} // end
};
});
canvas {
max-width: 100%;
height: auto;
border: 2px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html data-ng-app="tb">
<head lang="en">
<meta charset="utf-8">
<title>Tally Boxes</title>
</head>
<body data-ng-controller="tallyboxController" data-ng-init="init()">
<div id="container">
</div>
<div class="container-table">
<table border="1" width="100%">
<thead>
<tr>
<td>{{label.table.cName}}</td>
<td>{{label.table.cTB}}</td>
<td>{{label.table.cNV}}</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="(key,value) in candidates[0]">
<td>{{value.no}} {{label.table.period}} {{value.name}}</td>
<td>
<canvas width="1000" height="30" id="{{value.no}}" candidate="value" drawing></canvas>
</td>
<td>{{value.votes}}</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>