I have this code for chart working as fine. I can make the color background for the legend depends on the $scope.colours but for this example is I have a static of 3 datas only. But my problem here is that the data I get is from the database.
It is possible that generated color for the graph should be the background color for the legends?.
Source Link for chart
var app = angular.module('App', ['chart.js']);
app.controller('Ctrl', function ($scope) {
$scope.labels = ["A","B","C"];
$scope.data = ["1","2","3"];
$scope.colours = ['#bff0dd', '#ffa67b','#b1c2ff'];
});
<html ng-app="App" ng-controller="Ctrl">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-chart.js/0.10.2/angular-chart.js"></script>
</head>
<body>
<canvas id="doughnut" class="chart chart-doughnut doughnut-year"
chart-colours="colours"
chart-data="data" chart-labels="labels">
</canvas>
<h3>Legends</h3>
<div class="legend-item" ng-repeat="a in colours">
<label>
A
</label>
</div>
</body>
</html>
you can generate color codes as follows:
angular.forEach($scope.data , function (dataItem, index) {
var colorCode = getColorHex(index);
$scope.colours.push(colorCode);
});
var getColorHex = function (i) {
//skip black & white
i+=2;
var colorDecimal = getRGB(i);
var colorHex = decimalColorToHTMLcolor(colorDecimal);
return colorHex;
}
function decimalColorToHTMLcolor(colorDecimal) {
var intnumber = colorDecimal - 0;
var red, green, blue;
var template = "#000000";
red = (intnumber & 0x0000ff) << 16;
green = intnumber & 0x00ff00;
blue = (intnumber & 0xff0000) >>> 16;
intnumber = red | green | blue;
var HTMLcolor = intnumber.toString(16);
HTMLcolor = template.substring(0, 7 - HTMLcolor.length) + HTMLcolor;
return HTMLcolor;
}
function getRGB(index) {
var p = getPattern(index);
return getElement(p[0]) << 16 | getElement(p[1]) << 8 | getElement(p[2]);
}
function getElement(index) {
var value = index - 1;
var v = 0;
for (var i = 0; i < 8; i++) {
v = v | (value & 1);
v <<= 1;
value >>= 1;
}
v >>= 1;
return v & 0xff;
}
function getPattern(index) {
var n = parseInt(Math.cbrt(index));
index -= (n*n*n);
var p = [n, n, n];
if (index == 0) {
return p;
}
index--;
var v = index % 3;
index = parseInt(index / 3);
if (index < n) {
p[v] = index % n;
return p;
}
index -= n;
p[v] = parseInt(index / n);
p[++v % 3] = index % n;
return p;
}
Related
The order of the numbers in my box is as follows:
function boxNumbers(){
let boxes = document.querySelectorAll('.box')
boxes.forEach((box,i)=>{
if(String(i).length==1 || (String(i).length==2 && Number(String(i)[0]))%2==0){
//box.innerHTML = `${100-i}, i=${i}`
box.innerHTML = 100-i
}
else{
box.innerHTML = String(Number(`${9-Number(String(i)[0])}${String(i)[1]}`)+ 1)
}
})
}
how can I change it to look like this:
You can use this:
function boxNumbers() {
let boxes = document.querySelectorAll('.box');
let n = Math.sqrt(boxes.length);
[...boxes].reverse().forEach((box, i) => {
box.textContent = i % (n * 2) < n ? i + 1 : i + n - 2*(i % n);
})
}
With the assignment to n you make it a bit more generic -- still assuming your table is square. By reversing the iteration, you eliminate the need for the 100- subtraction. What remains is a formula that detects whether we're on a row with a reverse sequence or not, and adapts the number accordingly. The number "1" will always be in the bottom-right corner:
function boxNumbers() {
let boxes = document.querySelectorAll('.box');
let n = Math.sqrt(boxes.length);
[...boxes].reverse().forEach((box, i) => {
box.textContent = i % (n * 2) < n ? i + 1 : i + n - 2*(i % n);
})
}
// Utility to create the table
function fillTable(table, n) {
for (let i = 0; i < n; i++) {
let row = table.insertRow();
for (let j = 0; j < n; j++) {
let cell = row.insertCell();
cell.className = "box";
}
}
}
// Example run with n=5. Adapt as needed
let n = 5
fillTable(document.querySelector('table'), n);
boxNumbers();
table { border-collapse: collapse }
td { border: 1px solid ; width: 20px; height: 20px; text-align: center }
<table></table>
Here is a function which builds a bi-dimensional array and appends it as a table (row/col) to a dom element. You can adapt it to your template as you wish.
Works with any base number, yours is 5
function buildMatrix(baseNumber){
var flip = false;
var countDownNumber = baseNumber * baseNumber;
var currNumber = countDownNumber;
var matrix = "";
for(i = 0; i < baseNumber; i++) {
if(i !== 0){
currNumber = (flip)? countDownNumber + 1 - baseNumber : countDownNumber;
}
matrix += "<tr>";
for(j = 0; j < baseNumber; j++){
matrix += "<td>" + currNumber + "</td>";
// depending on the direction (flip) we increment or decrement
(flip)? currNumber++ : currNumber--;
countDownNumber--;
}
// change direction at the end of a row
flip = !flip;
matrix += "</tr>";
}
return matrix;
}
var baseSquareNumber = 11; // here you put 5
var matrixHtml = buildMatrix(baseSquareNumber);
document.getElementById("matrix").innerHTML = matrixHtml;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<table id="matrix">
</table>
</body>
</html>
I have a function which generates six random numbers (areacanvas.length is 6)
And then paints it on canvas as a array of dots. What I need to do is to write those canvas values in my HTML file using .innerHTML
I don't know how to do it,because the window.generatedNumber is different after single iteration,how I am supposed to save all six values and then write them on HTML?
function generateDotMap() {
for (let index = 0; index < areacanvas.length; index++) {
var canvas = document.getElementById(areacanvas[index]);
var ctx = canvas.getContext('2d');
// generate random number
window.generatedNumber = (Math.floor(Math.random() * 89) + 10).toString();
This is my table:
<table style="width:100%">
<tr>
<th>Answers from input :</th>
<td id ="one"></td>
</tr>
<tr>
<th>Answers from method :</th>
<td id="two"></td>
</tr>
</tr>
</table>
I use the method below to write in HTML values from my textboxes in order to compare the generated values and guessed by user ( daltonism test)
function checkHumanInput() {
clearTimeout(humanInputCheckTimeout);
if (parseInt(document.getElementById('HUMAN_INPUTT').value) == 1) {
let liczba1 = document.getElementById('HUMAN_INPUT_1').value;
let liczba2 = document.getElementById('HUMAN_INPUT_2').value;
let liczba3 = document.getElementById('HUMAN_INPUT_3').value;
let liczba4 = document.getElementById('HUMAN_INPUT_4').value;
let liczba5 = document.getElementById('HUMAN_INPUT_5').value;
let liczba6 = document.getElementById('HUMAN_INPUT_6').value;
document.getElementById('one').innerHTML="Values given by user " + liczba1 +"," + liczba2 +","+ liczba3 +","+ liczba4 +","+ liczba5 +","+ liczba6 +"." ;
document.getElementById('two').innerHTML="And random numbers? " + +"." ;
document.getElementById('HUMAN_INPUT_BOX').style.borderColor = '#00A000';
} else {
document.getElementById('HUMAN_INPUT_BOX').style.borderColor = '#A00000';
}
The whole genereateDOtMap method looks like that:
function generateDotMap() {
for (let index = 0; index < areacanvas.length; index++) {
var canvas = document.getElementById(areacanvas[index]);
var ctx = canvas.getContext('2d');
// white background
ctx.globalAlpha = 1;
ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 0, parseInt(canvas.width), parseInt(canvas.height));
var canvasCenter = {
x: Math.floor(canvas.width / 2) - 20,
y: Math.floor(canvas.height / 2) - 20
};
// dots array
var dots = [];
// generate random number
window.generatedNumber = (Math.floor(Math.random() * 89) + 10).toString();
// number as black text
ctx.font = 'italic bold ' + (canvasCenter.y + Math.floor(canvas.height / 5)) + 'px "Comic Sans MS"';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillStyle = '#000000';
ctx.fillText(window.generatedNumber, canvasCenter.x - Math.floor(canvasCenter.x / 7), canvasCenter.y - Math.floor(canvasCenter.y / 16));
for (var i = 0; i < DOTS_TO_RENDER; i++) {
var x, y, radius, j;
// loop
do {
// get point inside of a cricle
var point = getRandomPointInCircle();
// radius
var radius = getGaussianRandom(DOT_SIZE_mean, DOT_SIZE_var);
j = 0;
for (; j < i; j++) {
if (distanceCheck([point.x, point.y, radius], dots[j])) {
break;
}
}
} while (j != i);
// get canvas coordinates
var hX = point.x * canvasCenter.x + canvasCenter.x;
var hY = canvasCenter.x - point.y * canvasCenter.y;
var overNumber = ctx.isPointInPath(hX, hY);
// ctx.getImageData(point.x,point.y,ctx.width,ctx.height);
// [redColor, greenColor, blueColor, alpha]
var overNumber = (ctx.getImageData(hX, hY, 1, 1).data[0] == 0);
if (overNumber) {
color = hsvToRgb(HUE_NUMBER + Math.random() * HUE_VARIANCE, SATURATION, VALUE + 10);
} else {
color = hsvToRgb(HUE_BACKGROUND + Math.random() * HUE_VARIANCE, SATURATION, VALUE);
}
dots.push([point.x, point.y, radius, overNumber, color]);
}
// powiększanie kropek (wypełnienie)
// sortowanie od najmniejszej do największej, małe powiększane najpierw
dots.sort(function (a, b) { return a[2] - b[2] });
for (var pass = 0; pass < 2; pass++) {
for (var j = 0; j < dots.length; j++) {
var small_d = 99999;
for (var k = 0; k < dots.length; k++) {
if (j == k) {
continue;
}
var d = distanceCalc(dots[j], dots[k]) - (dots[j][2] + dots[k][2] + MIN_DISTANCE);
if (d < small_d) {
small_d = d;
}
}
if (small_d > 0) {
dots[j][2] += small_d;
}
}
dots.sort(function (a, b) { return a[2] - b[2] });
}
window.saved_dots.push(dots)
}
Based on what I understand, I have commented out the parts that we do not have information for (i.e. HTML) and I have added the insertion of random numbers to a specified div with id of randomNumDiv
This should be good enough to help you
function generateDotMap() {
var randomNumDiv = document.getElementById("randomNumbers");
for (let index = 0; index < 6 /*areacanvas.length*/ ; index++) {
//var canvas = document.getElementById(areacanvas[index]);
//var ctx = canvas.getContext('2d'); // generate random number
var generatedNumber = (Math.floor(Math.random() * 89) + 10).toString();
randomNumDiv.innerHTML = randomNumDiv.innerHTML + " " + generatedNumber;
}
}
generateDotMap();
<div id="randomNumbers"></div>
I've got a small web app in development to simulate the Ising model of magnetism. I've found that the animation slows down considerably after a few seconds of running, and it also doesn't loop after 5 seconds like I want it to with the command:
setInteval(main, 500)
I've added start and stop buttons. When I stop the animation, and then restart it, it begins fresh at the usual speed, but again slows down.
My question is: what steps can I take to troubleshoot and optimize the performance of my canvas animation? I hope to reduce or mitigate this slowing effect.
JS code:
window.onload = function() {
var canvas = document.getElementById("theCanvas");
var context = canvas.getContext("2d");
var clength = 100;
var temperature = 2.1;
var playAnim = true;
canvas.width = clength;
canvas.height = clength;
var imageData = context.createImageData(clength, clength);
document.getElementById("stop").addEventListener("click",function(){playAnim=false;});
document.getElementById("start").addEventListener("click",function(){playAnim=true;});
function init2DArray(xlen, ylen, factoryFn) {
//generates a 2D array of xlen X ylen, filling each element with values defined by factoryFn, if called.
var ret = []
for (var x = 0; x < xlen; x++) {
ret[x] = []
for (var y = 0; y < ylen; y++) {
ret[x][y] = factoryFn(x, y)
}
}
return ret;
}
function createImage(array, ilen, jlen) {
for (var i = 0; i < ilen; i++) {
for (var j = 0; j < jlen; j++) {
var pixelIndex = (j * ilen + i) * 4;
if (array[i][j] == 1) {
imageData.data[pixelIndex] = 0; //r
imageData.data[pixelIndex+1] = 0; //g
imageData.data[pixelIndex+2] = 0; //b
imageData.data[pixelIndex+3] = 255; //alpha (255 is fully visible)
//black
} else if (array[i][j] == -1) {
imageData.data[pixelIndex] = 255; //r
imageData.data[pixelIndex+1] = 255; //g
imageData.data[pixelIndex+2] = 255; //b
imageData.data[pixelIndex+3] = 255; //alpha (255 is fully visible)
//white
}
}
}
}
function dU(i, j, array, length) {
var m = length-1;
//periodic boundary conditions
if (i == 0) { //top row
var top = array[m][j];
} else {
var top = array[i-1][j];
}
if (i == m) { //bottom row
var bottom = array[0][j];
} else {
var bottom = array[i+1][j];
}
if (j == 0) { //first in row (left)
var left = array[i][m];
} else {
var left = array[i][j-1];
}
if (j == m) { //last in row (right)
var right = array[i][0];
} else {
var right = array[i][j+1]
}
return 2.0*array[i][j]*(top+bottom+left+right); //local magnetization
}
function randInt(max) {
return Math.floor(Math.random() * Math.floor(max));
}
var myArray = init2DArray(clength, clength, function() {var c=[-1,1]; return c[Math.floor(Math.random()*2)]}); //creates a 2D square array populated with -1 and 1
function main(frame) {
if (!playAnim){return;} // stops
window.requestAnimationFrame(main);
createImage(myArray, clength, clength);
context.clearRect(0,0,clength,clength);
context.beginPath();
context.putImageData(imageData,0,0);
for (var z = 0; z < 10*Math.pow(clength,2); z++) {
i = randInt(clength-1);
j = randInt(clength-1);
var deltaU = dU(i, j, myArray, clength);
if (deltaU <= 0) {
myArray[i][j] = -myArray[i][j];
} else {
if (Math.random() < Math.exp(-deltaU/temperature)) {
myArray[i][j] = -myArray[i][j];
}
}
}
}
var timer = setInterval(main, 500);
}
I want to generate a color palette of every 5th, 15th,17th or 51th RGB-value.
Something like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Color Palette</title>
<style type="text/css">
div{margin:0;width:20px;height:20px;float:left}
.clear{clear:both}
</style>
</head>
<body>
<script>
var r = 0,
g = 0,
b = 0;
function createBr() {
var b = document.createElement('br');
b.style.clear = 'both';
document.body.appendChild(b);
}
function createDiv(r,g,b) {
var a = document.createElement('div');
a.style.background = 'rgb(' + r + ',' + g + ',' + b + ')';
document.body.appendChild(a);
}
function createColorPalette(value) {
var v = 255/value;
for(i = 0; i < v; i++) {
r = r + value;
g = g + value;
b = b + value;
createDiv(r,g,b);
}
createBr();
}
// put in 5,15,17 or 51 as value below
window.onload = createColorPalette(17);
</script>
</body>
</html>
I'm not smart enough to figure out how to generate all the 3375 colors with a small script. Any ideas how to do that?
Cycle through the fractions for each color like so:
function createColorPalette(value) {
var v = 255/value;
for( var rStep = 0, r = 0; rStep < v; rStep++) {
for( var gStep = 0, g = 0; gStep < v; gStep++ ) {
for( var bStep = 0, b = 0; bStep < v; bStep++ ) {
createDiv(r,g,b);
b += value;
}
g += value;
}
r += value;
}
createBr();
}
I have a 4x3 matrix where the class is set to blank (white background). I'm using
var rand = Math.floor(Math.random()*2 + 1);
and if its 1, the class is set to one (red background) and if its 2, the class is set to two (blue background). My code is suppose to make 6 links red and 6 links blue with the newgame function, however, sometimes a few of them are still white or there are not exactly 6 red or blue. You might need to refresh (not click new game button) to see what I mean
here it is live: https://dl.dropbox.com/u/750932/iPhone/risk.html
<!DOCTYPE html>
<html>
<head>
<title>RISK</title>
<style type="text/css" media="screen">
a:link, a:visited {color: #eee;border:3px solid #ccc;display:inline-block;margin:3px;text-decoration:none;padding:26px;}
.blank {background:#fff;}
.one {background: #7B3B3B;}
.two {background: #547980;}
#status {color: #eee;padding:1px;text-align:center}
.current {border:3px solid #000;}
p {margin:0 0 15px;padding:0;}
</style>
<script type="text/javascript" charset="utf-8">
var oneTurn = true;
var gameOver = false;
var numMoves = 0;
function newgame()
{
var status = document.getElementById('status');
var one = 0;
var two = 0;
numMoves = 0;
gameOver = false;
oneTurn = true;
status.innerHTML = 'Player One\'s turn';
for(var x = 0; x < 4; x++)
{
for(var y = 0; y < 3; y++)
{
var rand = Math.floor(Math.random()*2 + 1);
if(rand == 1 && one < 7)
{
document.getElementById('a' + x + '_' + y).setAttribute("class", "one");
one++;
console.log("one");
}
else if(rand == 2 && two < 7)
{
document.getElementById('a' + x + '_' + y).setAttribute("class", "two");
two++;
console.log("two");
}
document.getElementById('a' + x + '_' + y).innerHTML = Math.floor(Math.random()*5 + 1);
}
}
console.log(one);
console.log(two);
}
function current(selected)
{
var status = document.getElementById('status');
var value = selected.value;
}
</script>
<meta name="viewport" content="user-scalable=no, width=device-width" />
</head>
<body onload='newgame();'>
<p id="status" class="one">Player One's turn</p>
<br />
<br />
<br />
<br /><br />
<p><input type="button" id="newgame" value="New Game" onclick="newgame();" /></p>
</body>
</html>
Let me offer you a slightly different approach. Represent the board as an array of 12 integers.
Fill the first half of this array with one's and the second half with two's.
Shuffle the array
Loop through the array and update the DOM elements by converting the array index to the corresponding row and column in the matrix
// initialize the array
var board = [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2];
// shuffle the array
for(var j, x, i = board.length; i; j = parseInt(Math.random() * i),
x = board[--i], board[i] = board[j], board[j] = x);
// At this stage one's and two's will be randomly distributed
var row = -1;
for (var i = 0; i < board.length; i++) {
var class = board[i] == 1 ? 'one' : 'two';
var col = i % 4;
if (col == 0) row++;
var box = document.getElementById('a' + col + '_' + row);
if (box != null) {
box.setAttribute('class', class);
box.innerHTML = 1 + Math.floor(Math.random() * 5);
}
}
Read your code again:
if(rand == 1 && one < 7)
...
else if(rand == 2 && two < 7)
Once you roll a red more than six times, or a blue more than six times, your code just does nothing for that square, this is why you end up with white squares.
Try something like this:
if((rand == 1 && one <= 6) || two > 6)
...
else