Overlap two Pie SVG charts in inoERP - php

I have two sets of data
1. Purchased orders received before the need by date.
2. Purchase orders received after the need by date.
Currently we are using inoERP pie chart to show two graphs side by side to compare.
Now, I want to combine the two a single over-lapping SVG chart.i.e Left side showing all data from x <=-3 and right side x >=3 .Any data between -3 & +3 will be in the overlapping period.
I dropped a mail to the their team but got the reply that they wont do any free customization of features not available in Oracle / SAP. So, I would like to know if there is any way to achieve this.
I looked into the code of the product and it's using below code
private function _draw_pie() {
if ((empty($this->_data)) || (!is_array($this->_data))) {
return;
}
$x_cordinate = $this->_left_margin;
$y_cordinate = $this->_top_margin;
$this->_prepare_pie();
$title_yaxis = 10;
if ($this->_chart_width > $this->_chart_height) {
$radius = ($this->_chart_height / 2);
} else {
$radius = ($this->_chart_width / 2);
}
$title_xaxis = $this->_left_margin + $radius;
$cx = $x_cordinate + $radius;
$cy = $y_cordinate + $radius;
$sum_of_elements = array_sum($this->_data);
if ($sum_of_elements <= 0) {
echo "<br> Wrong data selection. No value in value field";
return;
}
$legend_yaxis = $this->_top_margin;
$legend_xaxis = $cx + $radius * 1.2;
$chart = "<div class='chart_name'>" . $this->_chart_name . '</div>';
if ($this->_chart_type != 'donut') {
$pie_chart_height = 2.5 * $radius;
$chart .= "<svg class='chart pie' width=\"$this->_chart_width_orginal\" height=\"{$pie_chart_height}\">";
} else {
$chart .= "<svg class='chart pie' width=\"$this->_chart_width_orginal\" height=\"$this->_chart_height_orginal\">";
}
$chart .= '<text x="' . $title_xaxis . '" y="' . $title_yaxis . '" class="chart_xaxis_title" >' . $this->_x_axis_text . ' </text>';
$last_x = $radius;
$last_y = 0;
$cum_val = $cum_segment = 0;
$count = 0;
$large_arc = 0;
$chart .= "<g transform=\"translate(0,0)\">";
foreach ($this->_data as $key => $value) {
$cum_val += $value;
$div_class = 'pie_element value cluster_class_' . $count;
if ((($value / $sum_of_elements) * 360) > 180) {
$large_arc = 1;
} else {
$large_arc = 0;
}
$cum_segment += ($value / $sum_of_elements) * 360;
$last_y_m = -($last_y);
$next_x = $radius * cos(deg2rad($cum_segment));
$next_y = $radius * sin(deg2rad($cum_segment));
$end_point_x = ($next_x - $last_x);
$end_point_y = -($next_y - $last_y);
$chart .= "<path id=\"pie_path_$count\" d=\"M$cx,$cy
l$last_x, $last_y_m
a$radius,$radius 0 $large_arc,0 $end_point_x,$end_point_y z \"
style=\"stroke:#660000; \" class=\"$div_class\"/>";
$last_x = $next_x;
$last_y = $next_y;
$count++;
}
$chart .= '</g>';
$key_count = 0;
foreach ($this->_data as $key => $value) {
$cluster_class = 'pie_element cluster_class_' . $key_count;
$legend_y_axis_rect = $legend_yaxis - 10;
$chart .= "<rect x=\"$legend_xaxis\" y=\"$legend_y_axis_rect\" width=\"10\" height=\"10\" class=\" $key $cluster_class legend \"/>";
$legend_xaxis += 15;
$chart .= '<text x="' . $legend_xaxis . '" y="' . $legend_yaxis . '" class="chart_pie_value " >' . round($value / $sum_of_elements * 100, 1) . '% </text>';
$legend_xaxis += 45;
if (strlen($key) > 15) {
$legend_yaxis_os = 0;
$legend_xaxis_os = 0;
$key_a = explode(' ', $key);
foreach ($key_a as $nl_k => $new_line) {
$chart .= '<text x="' . $legend_xaxis . '" y="' . $legend_yaxis . '" class="chart_legend_title" >' . $new_line . ' </text>';
$legend_yaxis += 20;
$legend_xaxis -= 60;
}
$legend_xaxis += 60;
} else {
$chart .= '<text x="' . $legend_xaxis . '" y="' . $legend_yaxis . '" class="chart_legend_title" >' . $key . ' </text>';
$legend_yaxis += 40;
$legend_xaxis -= 60;
}
$key_count++;
}
$chart .= '<text x="' . $legend_xaxis . '" y="' . $legend_yaxis . '" class="chart_pie_value" > (Total : ' . $sum_of_elements . ') </text>';
if ($this->_chart_type != 'donut') {
$chart .= '</svg>';
}
return $chart;
}

I think it might help you.
the keyword is VENN DIAGRAMS.
install.packages('VennDiagram')
library(VennDiagram)
grid.newpage()
draw.pairwise.venn(22, 20, 11, category = c("Dog", "Cat"), lty = rep("blank",
2), fill = c("light blue", "pink"), alpha = rep(0.5, 2), cat.pos = c(0,
0), cat.dist = rep(0.025, 2), scaled = FALSE)
Venn diagram here

I have an idea how you can do it.
First find out the value of overlapping as a percentage of radius. Ex. if you are using radius of two circles as x then the value of the overlapping distance should be m*x (you have to calculate m dynamically by dividing total value to the overlapping value)
next draw the second circle by changing the center of the circle by that amoun

Related

PHP : how to get original value of number after being scaled (for zoom logic)

currently i am making some "zoom in / zoom out" logic in php,
and now i have some problem with scaling value and reverting it back to original value in php (if applicable to js it would be awesome).
here is the codes
$scale = 1;
$currentScale = 1;
$position = 50;
$step = 5; // or 10
for($index = 1; $index <= $step; $index++){
echo('-----------------------------------------------------<br>');
$currentScale = $scale / $index;
$position = $position * $currentScale;
$originalPosition = (($scale / $currentScale) * $position) * (($scale / $currentScale) / $scale);
echo('current scale : ' . $currentScale . '<br>');
echo('current position : ' . $position . '<br>');
echo('original position : ' . $originalPosition . '<br>');
}
the goal is to make the $originalPosition value same as the first $position value (on every scale), i have tried many formula but no luck, hope you guys can help.
thanks in advance.
rule $originalPosition not stored before loop
ok, i think i found out the solution, i'll leave this code here in case somebody facing same problem
$scale = 1;
$currentScale = 1;
$position = 80; // change it to any value
$step = 5;
echo('original position : ' . $position . '<br>');
for($i = $step; $i >= 1; $i--){
echo('-----------------------------------------------------<br>');
$currentScale = ($scale / $step) * $i;
$position = $position * $currentScale;
$originalPosition = $position;
$maxLoop = $step - $i;
if($maxLoop){
for($j = $maxLoop; $j >= 0 ; $j--){
$tempScale = $scale - (($scale / $step) * $j);
$originalPosition = $originalPosition / $tempScale;
}
}
echo('max rescale loop : ' . $maxLoop . '<br>');
echo('current scale : ' . $currentScale . ' ( ' . $currentScale * 100 . '% )<br>');
echo('current position : ' . $position . '<br>');
echo('original position : ' . $originalPosition . '<br>');
}
exit;
here is the result, the original position stays the same as initial value

Change Excel Circular Dependency into PHP

I deleted a question I posted earlier because I oversimplified the example, and got more flak for problems there, so have decided to post the whole problem here instead.
The Task
Much like this question here...Copying Excel's Circular Reference formula in PHP I am trying to change an Excel Circular reference into PHP.
Most of my frustration is not knowing the correct terms to google this for myself.
The Situation
I have converted all logic in the following spreadsheet into PHP below...
<?php
$vat = '1.2';
$mileage = 10;
$price = 6250.00;
$contract_term = 24;
$deposit_months = 6;
$otr_price = 9409.00;
$discount = 0;
$lom_a = 36.08;
$lom_b = 5.14;
$vehicletype = "Car";
$first_reg_fee = 55.00;
$emission_price = 30.00;
$fees = 21.03;
$margin = 50.00;
if (!empty($discount)) {
$discounted_otr_percent = (int)$discount/100;
$discounted_otr_amount = $discounted_otr_percent * $otr_price;
$discounted_otr = $otr_price-$discounted_otr_amount;
} else {
$discounted_otr = $otr_price;
}
$totaltobefunded = ($discounted_otr - $first_reg_fee - 0 /* Emissions */) / $vat;
print '<hr><p>Total to be Funded: <strong>' . $totaltobefunded . '</strong></p>';
$vatbal = $discounted_otr - $first_reg_fee - 0 /* Emissions */ - $totaltobefunded;
print '<p>VAT: <strong>' . $vatbal . '</strong></p>';
if($vehicletype == "Car") {
$balloon = $price / $vat * 0.9;
} else {
$balloon = $price * 0.9;
}
print '<p>CAP 90% price: <strong>' . $balloon . '</strong></p>';
$totalamountborrowed = $totaltobefunded - $balloon;
print '<p>Total Amount Borrowed: <strong>' . $totalamountborrowed . '</strong></p>';
$fundingrental = $totalamountborrowed * $lom_a / 1000;
print '<p>Funding Rental: <strong>' . $fundingrental . '</strong></p>';
$balloonrental = $balloon * $lom_b / 1000;
print '<p>Funding Rental: <strong>' . $balloonrental . '</strong></p>';
$monthlyfinancerental = $fundingrental + $balloonrental;
print '<p>Monthly Finance Rental: <strong>' . $monthlyfinancerental . '</strong></p>';
$monthlyrentalwithfees = $monthlyfinancerental + $fees;
print '<p>Monthly Finance Rental With Fees: <strong>' . $monthlyrentalwithfees . '</strong></p>';
$totalmargin = $margin * $contract_term;
print '<p>Total Margin: <strong>' . $totalmargin . '</strong></p>';
$totalrentalandfees = $monthlyrentalwithfees * ($contract_term + $deposit_months -1);
print '<p>Total Rental and Fees: <strong>' . $totalrentalandfees . '</strong></p>';
$totalcontractcost = $totalmargin + $totalrentalandfees;
print '<p>Total Contract Cost: <strong>' . $totalcontractcost . '</strong></p>';
$actualmonthlyrental = $totalcontractcost / ($contract_term + $deposit_months -1);
print '<p>Actual Monthly Rental: <strong>' . $actualmonthlyrental . '</strong></p>';
$deposit = $actualmonthlyrental * $deposit_months;
print '<p>Deposit: <strong>' . $deposit . '</strong></p>';
In the PHP code above, I have hard coded all of the variables for the time being just to get this working. In the real life example, these will change for each vehicle.
A Circular Reference exists between N19 (Total to be funded) , N34 (Actual Monthly Rental) and N36 (Deposit).
So at some point before, during, or after the FOR statement, there needs to be...
$totaltobefunded = $totaltobefunded - $deposit;
What I have tried
I have tried using the PHP for from the linked question on my example, but it just keeps taking away the deposit from the Total to be funded, and I am left with minus numbers.
In the example in the link, it has the following results...
1410
1211.19
1239.22221
1235.26966839
1235.826976757
1235.7483962773
1235.7594761249
1235.7579138664
1235.7581341448
1235.7581030856
1235.7581074649
1235.7581068474
This refines the number to the best possible outcome, and this is what I am trying to achieve. Just like my Excel document.
At the moment, my PHP prints out....
Total to be Funded: 7795
VAT: 1559
CAP 90% price: 4687.5
Total Amount Borrowed: 3107.5
Funding Rental: 112.1186
Funding Rental: 24.09375
Monthly Finance Rental: 136.21235
Monthly Finance Rental With Fees: 157.24235
Total Margin: 1200
Total Rental and Fees: 4560.02815
Total Contract Cost: 5760.02815
Actual Monthly Rental: 198.62166034483
Deposit: 1191.729962069
What I need help with
Using the PHP code above (which I have over simplified for this question btw), where should I put my "for" statement in order to correctly loop through the 3 numbers in the circular reference to get the result Im after?
As you can see in the Excel Screenshot, the target numbers are...
Total to be Funded: 6815.32
VAT: 2538.68
CAP 90% price: 4687.5
Total Amount Borrowed: 2127.82
Funding Rental: 76.7717456
Funding Rental: 24.09375
Monthly Finance Rental: 100.8654956
Monthly Finance Rental With Fees: 121.8954956
Total Margin: 1200
Total Rental and Fees: 3534.9693724
Total Contract Cost: 4734.9693724
Actual Monthly Rental: 163.27480594483
Deposit: 979.64883566897
I hope this makes sense to someone and they can assist. I'll answer any questions as best as I can.
The solution in PHP is as follows....
<?php
$vat = '1.2';
$mileage = 10;
$price = 6250.00;
$contract_term = 24;
$deposit_months = 6;
$otr_price = 9409.00;
$discount = 0;
$lom_a = 36.08;
$lom_b = 5.14;
$vehicletype = "Car";
$first_reg_fee = 55.00;
$emission_price = 30.00;
$fees = 21.03;
$margin = 50.00;
$deposit = 0;
if (!empty($discount)) {
$discounted_otr_percent = (int)$discount/100;
$discounted_otr_amount = $discounted_otr_percent * $otr_price;
$discounted_otr = $otr_price-$discounted_otr_amount;
} else {
$discounted_otr = $otr_price;
}
$max_iter = 100;
$max_change = 0.001;
$prev_target_val = PHP_INT_MAX;
$totaltobefunded = 0;
$crt_iter = 0;
while(($crt_iter < $max_iter) && (abs($prev_target_val - $totaltobefunded) > $max_change)) {
$crt_iter++;
$prev_target_val = $totaltobefunded;
$totaltobefunded = ($discounted_otr - $first_reg_fee - 0 /* Emissions */) / $vat - $deposit;
$vatbal = $discounted_otr - $first_reg_fee - 0 /* Emissions */ - $totaltobefunded;
if($vehicletype == "Car") {
$balloon = $price / $vat * 0.9;
} else {
$balloon = $price * 0.9;
}
$totalamountborrowed = $totaltobefunded - $balloon;
$fundingrental = $totalamountborrowed * $lom_a / 1000;
$balloonrental = $balloon * $lom_b / 1000;
$monthlyfinancerental = $fundingrental + $balloonrental;
$monthlyrentalwithfees = $monthlyfinancerental + $fees;
$totalmargin = $margin * $contract_term;
$totalrentalandfees = $monthlyrentalwithfees * ($contract_term + $deposit_months -1);
$totalcontractcost = $totalmargin + $totalrentalandfees;
$actualmonthlyrental = $totalcontractcost / ($contract_term + $deposit_months -1);
$deposit = $actualmonthlyrental * $deposit_months;
}
print '<p>Final Number: <strong>' . $actualmonthlyrental . '</strong></p>';
?>

PHP Table Data Show Results Vertically not Horizontally

I'm really frustrated.. I really need to show this table right. How can I set this code to show table vertically like this:
1 - 4 - 7
2 - 5 - 8
3 - 6 - 9
And not like this:
1 - 2 - 3 - 4
5 - 6 - 7 - 8
9 - ... ect
<?php
$PNG_WEB_DIR = plugin_dir_path( __FILE__ ).'temp/';
wp_mkdir_p($PNG_WEB_DIR);
$cols = $this->settings['cols'];
$rows = $this->settings['rows'];
$label_number = 0;
// die($_GET['order_ids']);
$order_ids = explode(',',$_GET['ids']);
$order_count = count($order_ids);
$labels_per_page = $cols*$rows;
$page_count = ceil(($order_count)/$labels_per_page);
for ($page=0; $page < $page_count; $page++) {
echo '<table class="address-labels" width="100%" height="100%" border="0" cellpadding="0">';
$last_height = 0;
$current_height = $current_width = 0;
$current_row = 0;
for ($label=0; $label < $labels_per_page; $label++) {
$label_number++;
$current_col = (($label_number-1) % $cols)+1;
if ($current_col == 1) {
$last_height = $current_height;
$last_width = 0;
$current_row++;
echo '<tr class="label-row">';
}
if ( $label_number > $this->offset && isset($order_ids[$label_number - $this->offset - 1]) ) {
$order_id = $order_ids[$label_number - $this->offset - 1];
} else {
$order_id = '';
}
$current_width = round( $current_col * (100/$cols) );
$width = $current_width - $last_width;
$last_width = $current_width;
$current_height = round( $current_row * (100/$rows) );
$height = $current_height - $last_height;
printf('<td width="%s%%" height="%s%%" class="label"><div class="label-wrapper">', $width, $height);
// because we are also looping through the empty labels,
// we need to check if there's an order for this label
if (!empty($order_id)) {
// get label data from order
$order = new WC_Order( $order_id );
// replace placeholders
$label_data = isset($this->settings['address_data'])? nl2br( $this->settings['address_data'] ): '[shipping_address]';
$label_data = $this->make_replacements( $label_data, $order );
echo '<div class="address-block">';
echo '<div class="addrress_show">';
// process label template to display content
echo $label_data;
echo '</div>';
echo '<div class="clearb"></div>';
echo '</div>';
} else {
echo ' ';
}
echo '</div></td>';
if ($current_col == $cols) {
echo '</tr>';
}
}
echo '</table>';
}
// shpt_after_page hook
do_action( 'shpt_after_page' );
?>
Since I can't know your raw data structure which you use to loop through it and produce the table, I presumed it as one-dimensional array and you want to print the table as 3 columns as you said, to see in action here's a PHP Fiddle - hit run to execute it - this will work for any array length as long as columns is 3, the rows is dynamic
PHP: Updated for naming purpose
<?php
$table = '<table class="address-labels" width="30%" border="0" cellpadding="0">';
$dataArr = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, 17);
$colNum = 3;
$rowNum = ceil(count($dataArr)/$colNum);
for($i=0; $i < $rowNum; $i++){
$x1 = isset( $dataArr[$i] ) ? $dataArr[$i] : '-';
$x2 = isset( $dataArr[$i + $rowNum] ) ? $dataArr[$i + $rowNum] : '-';
$x3 = isset( $dataArr[$i + 2 * $rowNum] ) ? $dataArr[$i + 2 * $rowNum] : '-';
$table .= '<tr><td>' . $x1 . '</td><td>' . $x2 . '</td><td>' . $x3 . '</td></tr>';
}
$table .= '</table>';
echo $table;
?>
EDIT:
Now if you want to change the column number, like set it to 5 for example, you need to do the following:
1st - set $colNum = 5;
2nd - add more variables to hold the values like, *considering it is 5 columns:
$x4 = isset( $dataArr[$i + 3 * $rowNum] ) ? $dataArr[$i + 3 * $rowNum] : '-';
$x5 = isset( $dataArr[$i + 4 * $rowNum] ) ? $dataArr[$i + 4 * $rowNum] : '-';
and don't forget to increase the multiplier * $rowNum
then for each extra column you add you need to add <td></td> like:
'<td>' . $x4 . '</td><td>' . '</td><td>' . $x5 . '</td><td>' . '</td>'
Here's another PHP Fiddle showing the above for 5 columns.
Try this. It's in pure php
<?php
$cols = 3;
$data = range(1,29);
// classic
$index = 1;
foreach($data as $el)
{
echo $el.' '; if ($index % $cols ==0) echo '<br/>';
$index++;
}
echo '<br/><br/>';
// special
$rows = $cols ;
$cols = floor(count($data)/$cols);
for($row = 0 ; $row < $rows; $row++){
for ($index = $row; $index < count($data); $index += $rows)
echo $data[$index].' ';
echo '<br/>';
}

how can I sort and display dynamic data under dymanic table headers?

The project is a web calendar/scheduler using php. The idea is that a user can schedule a job that is assigned to specific machine at a specific time and others can see the job schedule and which 'asset' the job is assigned to. The scheduling works, however, I cannot tie the data to header/columns they belong to. It looks like this:
<?php
include_once("HTML/TABLE.PHP");
$data = array( 0=>array(1,'asset1','2013-07-24 10:00:00', '2013-07-24 12:00:00','red',2),
1=>array(2,'asset1','2013-07-24 12:00:00', '2013-07-24 13:00:00','green',3),
2=>array(3,'asset2','2013-07-24 11:00:00', '2013-07-24 12:00:00','blue', 4),
3=>array(4,'asset2','2013-07-24 12:00:00', '2013-07-24 14:00:00','red', 2),
4=>array(5,'asset3','2013-07-24 11:30:00', '2013-07-24 12:00:00','green', 4),
5=>array(6,'asset4','2013-07-24 12:00:00', '2013-07-24 14:00:00','blue', 3),
6=>array(7,'asset1','2013-07-24 11:45:00', '2013-07-24 13:00:00','red', 1),
7=>array(8,'asset4','2013-07-24 13:00:00', '2013-07-24 15:00:00','yellow', 5)
);
$attrs = array( 'class' => 'main',
'id' => 'main_id',
'width' => '100%',
'border' => '1',
'cellspacing' => '0',
'cellpadding' => '0');
$table = new HTML_Table($attrs);
$table->setAutoGrow(true);
$table->setAutoFill('n/a');
$heads = array( array('asset1','asset2','asset3','asset4'));
$i = 1;
foreach($heads as $val)
{
$table->setHeaderContents(0, $i++, $val);
unset($val);
}
$now = date('U');
$offset = ($now % 900);
$now = $now-$offset;
for ($i = 0;$i < 33; $i++)
{
$table->setHeaderContents($i,0, date('g:i',$now));
$now += 900;
}
$cellPosition = 1;
$rowCounter = 1;
for ($i=0;$i < count($data);$i++)
{
$table->setCellAttributes ($rowCounter,$cellPosition,' bgcolor = '. $data[$i][4]. ' rowspan=' . $data[$i][5]);
$table->setCellContents($rowCounter,$cellPosition,"Job# ".$data[$i][0] . " belongs to: " . $data[$i][1]);
$cellPosition++;
$rowCounter =1;
}
echo $table->display();
?>
How can I tie the information to only the column it belongs to?
I have gotten this far, but I get odd results if the first column is true:
$cellPosition = 0;
$rowCounter = 1;
for ($x=0;$x <= count($heads);$x++)
{
for ($i=0;$i < count($data);$i++)
{
if ($data[$i][1] == $table->getCellContents(0,$x))
{
$table->setCellAttributes ($rowCounter,$cellPosition,' bgcolor = '. $data[$i][4]. ' rowspan=' . $data[$i][5]);
$table->setCellContents($rowCounter,$cellPosition,"Job# ".$data[$i][0] . " belongs to: " . $data[$i][1]);
//$cellPosition++;
//echo ;
echo "<br> The current count of x = : ". $x;
echo "<br>" . $table->getCellContents(0,$x) . " Matches " . $table->getCellContents(0,$x) . " at index " . $i;
$rowCounter += $data[$i][5];
}
else
{
$rowCounter = 1;
}
}
$cellPosition++;
Ok this is working, but only if the array results are in order by asset. If not the row is reset to row 1 and the second entry overlays the previous.
$cellPosition = 0;
$rowCounter = 1;
for ($x=0;$x <= count($heads);$x++)
{
for ($i=0;$i < count($data);$i++)
{
if ($data[$i][1] == $table->getCellContents(0,$x))
{
$table->setCellAttributes ($rowCounter,$cellPosition,' bgcolor = '. $data[$i][4]. ' rowspan=' . $data[$i][5]);
$table->setCellContents($rowCounter,$cellPosition,"Job# ".$data[$i][0] . " belongs to: " . $data[$i][1]);
echo "<br> The current count of x = : ". $x;
echo "<br>" . $table->getCellContents(0,$x) . " Matches " . $data[$i][1] . " at index " . $i;
$rowCounter += $data[$i][5];
}
else
{
$rowCounter = 1;
}
}
$cellPosition++;
}
My solution is to presort the records using sql order by. I don't know how elegant that is but for the moment it is working and I can move further into this project. Any suggestions would be welcome. Thanks!

generate smooth hex gradient table

generate list of hex colours?
Hi there,
Currently I am trying to generate a list of 50 hex colours that create a roughly smooth gradient from white to black, with all the colours in between.
How would I go about doing this in php?
Well,
Although The colours could prob be in a better order,
Here was my working.
<?php
function Gradient($HexFrom, $HexTo, $ColorSteps) {
$FromRGB['r'] = hexdec(substr($HexFrom, 0, 2));
$FromRGB['g'] = hexdec(substr($HexFrom, 2, 2));
$FromRGB['b'] = hexdec(substr($HexFrom, 4, 2));
$ToRGB['r'] = hexdec(substr($HexTo, 0, 2));
$ToRGB['g'] = hexdec(substr($HexTo, 2, 2));
$ToRGB['b'] = hexdec(substr($HexTo, 4, 2));
$StepRGB['r'] = ($FromRGB['r'] - $ToRGB['r']) / ($ColorSteps - 1);
$StepRGB['g'] = ($FromRGB['g'] - $ToRGB['g']) / ($ColorSteps - 1);
$StepRGB['b'] = ($FromRGB['b'] - $ToRGB['b']) / ($ColorSteps - 1);
$GradientColors = array();
for($i = 0; $i <= $ColorSteps; $i++) {
$RGB['r'] = floor($FromRGB['r'] - ($StepRGB['r'] * $i));
$RGB['g'] = floor($FromRGB['g'] - ($StepRGB['g'] * $i));
$RGB['b'] = floor($FromRGB['b'] - ($StepRGB['b'] * $i));
$HexRGB['r'] = sprintf('%02x', ($RGB['r']));
$HexRGB['g'] = sprintf('%02x', ($RGB['g']));
$HexRGB['b'] = sprintf('%02x', ($RGB['b']));
$GradientColors[] = implode(NULL, $HexRGB);
}
$GradientColors = array_filter($GradientColors, "len");
return $GradientColors;
}
function len($val){
return (strlen($val) == 6 ? true : false );
}
$count = 0;
$steps = 9;
$Gradients = Gradient("FFFFFF", "FF0000", $steps);
foreach($Gradients as $Gradient)
echo '<div style="background-color: #' . strtoupper($Gradient) . '">' . htmlentities('<option value="' . strtoupper($Gradient) . '">' . strtoupper($Gradient) . '</option>') . '</div>';
$count += count($Gradients);
$Gradients = Gradient("df1f00", "00FF00", $steps);
foreach($Gradients as $Gradient)
echo '<div style="background-color: #' . strtoupper($Gradient) . '">' . htmlentities('<option value="' . strtoupper($Gradient) . '">' . strtoupper($Gradient) . '</option>') . '</div>';
$count += count($Gradients);
$Gradients = Gradient("00df1f", "0000FF", $steps);
foreach($Gradients as $Gradient)
echo '<div style="background-color: #' . strtoupper($Gradient) . '">' . htmlentities('<option value="' . strtoupper($Gradient) . '">' . strtoupper($Gradient) . '</option>') . '</div>';
$count += count($Gradients);
$Gradients = Gradient("0000df", "000000", $steps);
foreach($Gradients as $Gradient)
echo '<div style="background-color: #' . $Gradient . '">' . htmlentities('<option value="' . $Gradient . '">' . $Gradient . '</option>') . '</div>';
$count += count($Gradients);
echo 'count: ' . $count;
with all the colours in between
You can find a path from white to black but you will have a difficult time including all colours - colour space is 3-dimensional, not linear.
You could look at this for some ideas:
http://www.exorithm.com/algorithm/view/create_gradient
Here is some customisation of the function, it's also handle case only 1 or 2 graduation needed, and also remove # on hexa before calculs and send back an array of color starting with #. so that can be directly applied to a content.
public function gradient($from_color, $to_color, $graduations = 10) {
$graduations--;
$startcol = str_replace("#", "", $from_color);
$endcol = str_replace("#", "", $to_color);
$RedOrigin = hexdec(substr($startcol, 0, 2));
$GrnOrigin = hexdec(substr($startcol, 2, 2));
$BluOrigin = hexdec(substr($startcol, 4, 2));
if ($graduations >= 2) { // for at least 3 colors
$GradientSizeRed = (hexdec(substr($endcol, 0, 2)) - $RedOrigin) / $graduations; //Graduation Size Red
$GradientSizeGrn = (hexdec(substr($endcol, 2, 2)) - $GrnOrigin) / $graduations;
$GradientSizeBlu = (hexdec(substr($endcol, 4, 2)) - $BluOrigin) / $graduations;
for ($i = 0; $i <= $graduations; $i++) {
$RetVal[$i] = strtoupper("#" . str_pad(dechex($RedOrigin + ($GradientSizeRed * $i)), 2, '0', STR_PAD_LEFT) .
str_pad(dechex($GrnOrigin + ($GradientSizeGrn * $i)), 2, '0', STR_PAD_LEFT) .
str_pad(dechex($BluOrigin + ($GradientSizeBlu * $i)), 2, '0', STR_PAD_LEFT));
}
} elseif ($graduations == 1) { // exactlly 2 colors
$RetVal[] = $from_color;
$RetVal[] = $to_color;
} else { // one color
$RetVal[] = $from_color;
}
return $RetVal;
}
Also could be helpful to take a look at my answer here.
It has the code to convert any number from any given range (let's say [0,20]) to particular color where 0 is red, 10 is yellow, 20 is green. You can use any colors and even use combination of 4 colors, so it's red - yellow - green - blue.
function rgb2hex($rgb) {
$hex = "#";
$hex .= str_pad(dechex($rgb[0]), 2, "0", STR_PAD_LEFT);
$hex .= str_pad(dechex($rgb[1]), 2, "0", STR_PAD_LEFT);
$hex .= str_pad(dechex($rgb[2]), 2, "0", STR_PAD_LEFT);
return $hex; // returns the hex value including the number sign (#)
}
function dif($c1, $c2, $percent) {
$array=array();
for($x=0;$x<3;$x++) {
$d=($c2[$x]-$c1[$x])*$percent+$c1[$x];
$array[]=(int)$d;
}
return $array;
}
for($x=0;$x<=255;$x++) {
echo rgb2hex( dif(array(255,255,255), array(0,0,0), $x/255 /*percent*/) );
echo "<br>";
}

Categories