There is a column from a table that contains numeric values unordered. Each td needs to be painted using solid colors in a way that the column forms a unordered gradient.
I created a numeric array which contains those values ordered and now I need to generate the gradient array based on that, so each value of the array will have a corresponding solid color.
Lower numbers must be red, medium numbers must be yellow and higher numbers must be green. All those colors smoothly transiting from itself to the next one.
So basically, the ordered array will have a ordered gradient, but when I paint the column the gradient will become unordered, because the columns values aren't ordered.
What I'm trying to reach is "crescent rank" gradient in that column.
How can I do that with javascript or jQuery?
Modified Answer After Update to Question
I still think I can help you with this. I forked and modified my original JSFiddle to show how this is applied. The CSS stays relatively the same.
It sounds like you want to have specific values for each level of gradient, but I still think the moving "bar" concept works best when applying multi-stop gradients. IE going from one color to a different to another different. This is because it is MUCH less work if you need to modify the gradient colors since you can just change out the background linear-gradient code in the CSS, as well as it gives you the smoothest and realest gradient no matter how many rows you have. The JSFiddle still has the input boxes so you can see each "step" of the gradient. As I said before you can go to a site like www.colorzilla.com/gradient-editor/ and modify the gradient to your needs and even add an in-between color stop if say you don't like the transition from yellow to green.
Here is the jQuery code you would need to input all your values from a table into a multidimensional array. After it is in the array, you can then order each column in the array (since each column is it's own array in the array) and move the background based on the "rank" or index in that array. Since my understanding is that you wanted to sort based on lowest value to highest value, and not say 0 to 100.
//jQuery for table
$("#someTable td").wrapInner("<span class='tdData'></span>");
$(".tdData").wrap("<div class='css3gradient'></div>");
var colVal = [];
var numCol = $("#someTable").find('tr')[0].cells.length;
var numRows = $("#someTable tr").length - 1; //subtract if header
var itemCount = 0;
var gradientWidth = $(".css3gradient").css("width").replace(/[^-\d\.]/g, '')-$(".tdData").css("width").replace(/[^-\d\.]/g, '');
//initialize array
for (var i = 0; i < numCol; i++) {
colVal[i] = new Array();
}
//fill multidimensional array
$("table tr td").each(function () {
curCol = itemCount % numCol;
colVal[curCol].push($(this).text());
itemCount++;
});
//sort values in array and assign value for gradient
for (i = 0; i < numCol; i++) {
//sort values as numbers
colVal[i] = colVal[i].sort(function (a, b) {
return a - b;
});
//match each value in the array in order with value in table
$.each(colVal[i], function (index, value) {
$("#someTable td:nth-child(" + (i + 1) + ")").each(function () {
if ($(this).text() == colVal[i][index]) {
//Multiply current index with
///Divide the total width of gradient box with
////Subtract total number of rows with one to make zero the first left position
////and the last number the final position
$(this).find(".css3gradient").css({ backgroundPosition: '-' + (index * (gradientWidth / (numRows - 1))) + 'px 0' });
}
});
});
}
Feel free to comment again if I've misunderstood something. This has been a really fun problem to solve, and I hope I helped or gave you at least a step in the right direction.
Original Answer
I made a JSFiddle for you that should get you started. Explanation below.
From what I understand, you want to have a background within a div/span/input change colors based on the value in that div/span/input. You would like lower numbers to represent red, and the a gradient to change the color from red > yellow > green, with green being the max color. You would also like this to be controlled by jQuery.
To do that we can stack a couple of divs, and utilize positioning and overflows to “hide” any excess of the div we are using for the background.
First, I’d recommend using a CSS Gradient Generator like the one at http://www.colorzilla.com/gradient-editor/ to generate your CSS code.
Next, lets look at the structure of your data. You’ll want to have 3 elements to get this to work. The inner element which holds the data. For my example I used an input element so you can change the values and test. The next element you want is a div which you can use as the “background”. This element will be positioned absolutely so we can move it left to right to get the gradient we want. Finally you’ll want the outer wrapped div so you can utilize the overflow css rule to hide the excess from the background div.
So for a reference, here is what the html looks like for this particular task:
<div class=“data”><div class=“css3gradient”><input /></div></div>
If you don’t have access to the HTML, a quick fix is to use the .wrap() jQuery function. For instance, if you just had an outer div and input, you could “wrap” the input with
$(“.data input”).wrap(“<div class=“css3gradient”></div>”);
For the gradient div, mathematically, it can get a bit wonky trying to make it “line up”. For my example I just went with a total width to display the data of 100px, and a total width for the gradient background of 1100px;. The reason for the extra 100px on the background is because when you move the element over by 10, you need the extra width to fill the remaining div. IE zero position takes up 0-100, second position takes up 200-300, and the final tenth position takes up 1000-1100. You can apply this method to any width you have by making the width of the gradient div be (x * 10) + x.
This also looks at the data from the standpoint that you go from 0 to 100 as if you are doing %s.
So for my CSS this is what it looks like:
.css3gradient{
width:1100px;
height:100px;
position:absolute;
background: #ff0000; /* Old browsers */
background: -moz-linear-gradient(left, #ff0000 0%, #ffff00 50%, #00ff00 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, right top, color-stop(0%,#ff0000), color-stop(50%,#ffff00), color-stop(100%,#00ff00)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(left, #ff0000 0%,#ffff00 50%,#00ff00 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(left, #ff0000 0%,#ffff00 50%,#00ff00 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(left, #ff0000 0%,#ffff00 50%,#00ff00 100%); /* IE10+ */
background: linear-gradient(to right, #ff0000 0%,#ffff00 50%,#00ff00 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff0000', endColorstr='#00ff00',GradientType=1 ); /* IE6-9 */
}
.data {
width: 100px;
height: 50px;
vertical-align: middle;
position: relative;
overflow: hidden;
border: 1px solid #000;
margin: 3px;
}
.data input {
width: 100px;
height: 50px;
background: transparent;
border: 0;
text-align: center;
}
Finally, the fun part. We have to actually move this background based on the value in the input. I’m not sure if you have some sort of input or dynamic way your changing the values within each element. At any rate, this jQuery will get you started.
$(".data input").each(function(){
var dataValue = $(this);
//call this initially set the background based on the value
changeColor(dataValue.val());
//this is what allows the background to change dynamically when you type into the input element
dataValue.bind("keyup change input",function(){
changeColor(dataValue.val());
});
function changeColor(e) {
var mulitplyColor = e * 10;
dataValue.parent(".css3gradient").css({backgroundPosition: '-' + mulitplyColor + 'px 0'});
}
});
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With