I'm struggling with a simple SVG Image, where I try to update the color of two rectangles.
In Chrome they get updated, In IE(10) the reactangles are just black!
In my controller I'm setting the color via $scope.cvrColor=[random generated color code]
I've made this simple sample to illustrate my problem:
http://jsfiddle.net/mvg123/td7py264/
My Controller:
function testController($scope, $timeout) {
var test = updateSvg();
function updateSvg() {
$scope.startColor = getRandomColor();
$scope.cvrColor = getRandomColor();
$timeout(updateSvg, 1000);
};
function getRandomColor() {
var number = Math.floor(Math.random() * 11);
var color = "";
switch (true) {
case (number < 3):
color = "#808000";
break;
case (number > 3 && number < 8):
color = "#666666";
break;
case (number > 8 && number < 12):
color = "#ff0000";
break;
default: color = "#ffff00";
}
return color;
}
}
Any hints out there?
/Best regards
While your example should work, I have discovered that having expressions inside class or style is somewhat unreliable. It's better to use ng-class and ng-style. So in your case you can write:
<rect ng-style="{fill:startColor, fillOpacity:1}" ... />
http://jsfiddle.net/c5ozbv52/
You must use the angularjs directive "ng-style" :
ng-style="{fill:startColor,fillOpacity:1}"
https://docs.angularjs.org/api/ng/directive/ngStyle
Related
In my website user can enter two input . Input1 and Input2 .
So i have to calculate difference with these two number .
difference =input1-input2
so if the difference is greater than 700 i have to apply color red Please see the follow.
dIFFERENCE > 700 = red
dIFFERENCE > 800 = blue
dIFFERENCE > 900 = green
dIFFERENCE > 1000 = white
dIFFERENCE > 1100 = yellow
dIFFERENCE > 1200 = orange
dIFFERENCE > 1300 = purple
etc.. UP TO dIFFERENCE > 5000 = other color
So here i am writing the following jquery ,
var difference= $(".input1")-$(".input2");
if(difference>700){
$(".result").css("color","red");
}
if(difference>800){
$(".result").css("color","blue");
}
etc
is there any easy way to reduce this query ? Like i can store the color in an array and based on the difference i can fetch the result etc .
Please help
EDIT
What i tried is
var difference= $(".input1")-$(".input2");
if(difference >700 && difference<=800){
difference=700;
}else if(difference>=800 && difference<=900 ){
difference=800;
}else if(difference>=900 && difference<=1000 ){
difference=900;
}else if(difference>=1000 && difference<=1100 ){
difference=1000;
}
...
else if(difference>=4900 && difference<=5000 ){
difference=4900;
}
var differnce_array =[];
difference_array[700]="red";
difference_array[800]="blue";
difference_array[900]="green";
difference_array[1000]="white";
etc...
Still it is too much query . So please help to optimize this code
In this case i would create a dictionary, where the keys represent the thresholds and round the difference down to hundreds and look that key up in the dictionary:
var diff = 789; // your value
var diffs = {700: 'red', 800: 'blue', 900: 'green'}; //etc
var diffcol = Math.floor(diff/100)*100; //Floor down to hundreds
if(diffcol in diffs) console.log(diffs[diffcol]); //Validation
1ST APPROACH
You use a hashtable, it's a little bit like a hashset in c# or java, you just pair the keys to the values:
var hash = {
700:"red",
800:"blue",
900:"green",
//etc...
};
And this is how you can get your color:
var difference= $(".input1")-$(".input2");
roundedDifference = Math.floor(difference/100)*100
var color = hash[roundedDifference];
//This will be your color
2ND APPROACH:
You can round the number so you only get the hundereds i.e. 100,200,300,400,etc.
then you can use a switch statement:
var difference= $(".input1")-$(".input2");
roundedDifference = Math.floor(difference/100)*100
switch(roundedDifference) {
case 700:
$(".result").css("color","red");
break;
case 800:
$(".result").css("color","blue");
break;
case 900:
$(".result").css("color","green");
break;
case 1000:
$(".result").css("color","white");
break;
case 1100:
$(".result").css("color","yellow");
break;
case 1200:
$(".result").css("color","orange");
break;
case 1300:
$(".result").css("color","purple");
break;
case ... until 5000
break;
default:
console.log("difference not within range of 700-5000"
}
You can do this up to 5000.
Here is a working code for you:
function submit() {
var difference = $(".input1").val() - $(".input2").val();
console.log(difference)
function getColor() {
var color;
switch (difference) {
case 700:
color = "red";
break;
case 800:
color = "blue";
break;
case 900:
color = "green";
break;
case 1000:
color = "white";
break;
case 1100:
color = "yellow";
break;
case 1200:
color = "orange";
break;
case 1300:
color = "purple";
break;
default:
color = "magenta"
}
return color
}
$(".result").css("color", getColor(difference));
$(".result").html("The color is: "+ getColor(difference));
}
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<input type="text" class="input1" placeholder="input1">
<input type="text" class="input2" placeholder="input2">
<button onclick="submit()">Difference</button>
<div class="result"> This changes color</div>
</body>
</html>
Please run the above snippet
Here is a working DEMO
function updateGrid() {
//this for loop moves the matrix and sets a position
for (var row = row_start; row < row_end; row+=5) {
for (var i = 0; i < 5; i++) {
//these for loops call each individual rect on the grid by a unique id.
d3.select("#x-"+row+"y-"+(i*20))
.transition()
.style("fill", function(d) {
var alt = 0;
switch (i) {
//ignore this switch statement. It's just reversing the i because the tag is backwards.
case 0: alt = 4; break;
case 1: alt = 3; break;
case 3: alt = 1; break;
case 4: alt = 0; break;
default: alt = 2; break;
}
//color_matrix is an object. row is the key, and alt is the position of the array that is the key value.
if (color_matrix[row][alt] == 0) return colors[0];
if (color_matrix[row][alt] == 1) return colors[1];
if (color_matrix[row][alt] == 2) return colors[2];
if (color_matrix[row][alt] == 3) return colors[3];
if (color_matrix[row][alt] >= 4) return colors[4];
})
.duration(750);
}
}
//this moves the matrix by one column. console.log() shows that it works.
row_start += 5;
row_end += 5;
}
var run = window.setInterval(function() { updateGrid() }, 5000);
So I cannot seem to figure this one out. A few things to note first:
1. The colors work perfectly in the rect initialization.
2. The transition works correctly the first time as well.
3. The function is being called correctly, because I console.log() tested it.
4. The matrix/object is also cycling correctly.
5. the position of duration doesn't seem to matter.
The only thing that doesn't work correctly is the color change. This update function will be called every five seconds to change the color of the rects. However, it doesn't seem to work. Is there something wrong with the way the transition is being called?
Turns out the matrix wasn't cycling correctly after all. The for loop was trying to cycle rect where there wasn't any, and to fix it I added a separate increment.
I have the following implementation, it works and functional. I am checking if fname properties are same in the following javascript object, then I assign the same color for these paired objects.
Here is one javascript object sample:
{"value": 10,"series": 1,"category": "LG","fname": "","valueColor": ""},
However, I would like to use more distinguished colors, rather than very similar color, for example in the given fiddle, colors are almost all in green spectrum. Also I do not want to give any color value where value property equals to 0
Here is the core implementation
function colorSpectrum(N) {
var colorMap = [], inc = 50, start = 1000;
for (i = start; i < start+N*inc; i+=inc) {
var num = ((4095 * i) >>> 0).toString(16);
while (num.length < 3) {
num = "0" + num;
}
colorMap.push("#" + num);
}
return colorMap;
}
function process(data){
var map = {}, colorMap = colorSpectrum(data.length);
data.forEach(function(item, index){
if(!map.hasOwnProperty(item.fname)){
map[item.fname] = colorMap[index];
}
data[index].valueColor = map[item.fname];
});
return data;
}
FIDDLE
Try picking random colors
function colorSpectrum(N) {
var colorMap = [];
for (i = 0; i < N; i+=1) {
var color = getRndColor()
colorMap.push("#"+color);
}
return colorMap;
}
function getRndColor() {
var n = Math.floor(Math.random()*255*255*255);
var hex = Number(n).toString(16);
while(hex.length < 6) {
hex = "0"+hex;
}
return hex;
}
If you want a full range of colors from black to white, you need to change this part:
var colorMap = [], inc = 50, start = 1000;
for (i = start; i < start+N*inc; i+=inc) {
You see, the loop starts from 1000, which is the color #3e8, already green. The scale should go from 0 to 4095 (for 3-character values like #007, #abc, etc...), with having the increment based on the amount of data.
However, I'd suggest getting at least a little bit of the control by having all RGB components generated separately instead of the full HEX value right away.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Javascript dynamic variable name
I have variables being passed from an onClick event to a JavaScript function. There are four variables in total: two that tell the direction and two that tell the speed change. I want the function to evaluate which direction was chosen (either h_ or v_, for horizontal and vertical) and then apply the necessary speed (either faster or slower).
Right now, I do this successfully by first evaluating the direction and calling a different changeSpeed function depending on the direction which was chosen.
What I would like to do is combine these functions. In the example, $(direction + "speed") is meant to become either h_speed or v_speed.
Is JavaScript equipped to do this? (sincerely, miguel)
var h_speed = 10;
var v_speed = 10;
function changeSpeed(speed, direction){
var direction = direction;
switch (speed)
{
case 'slower':
$($direction + "speed") = $($direction + "speed")*2;
break;
case 'faster':
$($direction + "speed") = $($direction + "speed")/2;
break;
}
}
Here are two versions of my working code:
VERSION 1
var h_speed = 10;
var v_speed = 10;
function identifyDirection(speed, direction){
switch (direction)
{
case 'vertical':
v_changeSpeed(speed);
break;
case 'horizontal':
h_changeSpeed(speed);
break;
}
}
function h_changeSpeed(speed){
switch (speed)
{
case 'slower':
h_speed = h_speed*2;
break;
case 'faster':
h_speed = h_speed/2;
break;
}
}
function v_changeSpeed(speed){
switch (speed)
{
case 'slower':
v_speed = v_speed*2;
break;
case 'faster':
v_speed = v_speed/2;
break;
}
}
VERSION 2
/**
* the changeSpeed functions' arguments
* are placed directly in the function that
* determines whether horizontal or vertical
* speed is changing.
*
*/
function changeSpeed(speed, direction){
switch (direction)
{
case 'vertical':
switch (speed)
{
case 'slower':
v_speed = v_speed*2;
break;
case 'faster':
v_speed = v_speed/2;
break;
}
break;
case 'horizontal':
switch (speed)
{
case 'slower':
h_speed = h_speed*2;
break;
case 'faster':
h_speed = h_speed/2;
break;
}
break;
}
}
Variables are made properties of a variable object. The only variable object you can access by name is the global variable object (this in a global context or window in a browser). So for global variables you could do:
function hSpeed() {...}
function vSpeed(){...}
// Set direction
var direction = 'h';
// Call related function
window[direction + 'Speed']();
However, you can't do that in a function execution context (because ECMA-262 explicitly denies access to function execution and variable objects), you need to make the "variable" a property of an object that you access the same way (i.e. using square bracket notation):
var lib = {};
var lib.hSpeed = function(){...};
var lib.vSpeed = function(){...};
// Set direction
var direction = 'h';
// Call related function
lib[direction + 'Speed']();
Put the 2 variables in a single object like:
var directions = {
horizontal: 1,
vertical: 1
}
Then you'd be able to take the direction out of the arguments and match the child of the object:
function changeSpeed(speed, direction) {
//operate on diections[direction]
}
As far as changing the speed you could do a similar thing with functions in an object, but in your case I'd just suggest using another data structure since the logic doesn't change, only the parameter:
var speedFactor = {
faster: 2,
slower: .5
}
then you'd be able to do everything with:
function changeSpeed(speed, direction) {
directions[direction] = directions[direction] * speedFactor[speed]
}
There are certainly better ways to do what you wanna achieve, but if you wanna have the same thing (note that you shouldn't use global variables, you can use function scoping to make them private, but that's another topic).
var speed = {
h: 10,
v: 10
};
function changeSpeed(speedChange, direction) {
switch (speedChange) {
case 'slower':
speed[direction] *= 2;
break;
case 'faster':
speed[direction] /= 2;
break;
}
}
Now you can change the speed by calling, for example:
changeSpeed("slower", "h");
and access that speed by speed.h or speed.v
Okay...
Tricky but:
//Global namespace
var speeds = {};
speeds['h_speed'] = 10;
speeds['v_speed'] = 10;
function changeSpeed(speed, direction){
var dir = direction.substring(0,1);
var sp = (speed === 'slower') ? 0.5 : 2;
//Still accessible from inside your function
speeds[dir + '_speed'] = speeds[dir + '_speed'] * sp;
}
Will do the work.
I have an Array like this:
var colors = {
1: '#FFFF00',
2: '#FF0000',
3: '#80FF00',
4: '#00FFFF',
5: '#FF00FF'
};
And Javascript like this:
var color = Math.floor(Math.random()*5)+1;
if(color == document.getElementById('awards').style.borderColor) {
var color = Math.floor(Math.random()*5)+1;
}
else {
document.getElementById('awards').style.borderColor = color;
}
But my Javascript isn't working.
You are generating an index, but not subscripting the array.
jsFiddle.
Also, to nitpick, {} creates an object with properties, technically not an Array (though an Array is an object). [] is the literal notation for an Array in JavaScript.
Update
Here is maybe how I'd have written it, if that helps...
var getRandomColor = function() {
var colors = [
'#FFFF00',
'#FF0000',
'#80FF00',
'#00FFFF',
'#FF00FF'
];
return colors[Math.floor(Math.random() * colors.length) + 1];
}
var color = getRandomColor(),
element = document.getElementById('awards'),
borderColor = element.style.borderColor;
if (color == borderColor) {
color = getRandomColor();
}
else {
element.style.borderColor = color;
}
jsFiddle.
You are not really getting the random color, just getting the random number in a range, you'll need to change your code to this:
var color = colors[(Math.floor(Math.random() * 5) + 1).toString()];
if(color == document.getElementById('awards').style.borderColor) {
var color = colors[(Math.floor(Math.random() * 5) + 1).toString()];
}
else {
document.getElementById('awards').style.borderColor = color;
}
If you want to write dynamic CSS and write some code and logic inside, I recommend to take a look at http://www.dotlesscss.org/
I know it will take time to learn, but I proffered to mention about it, may be it help someone.