<?php 
/*
Plugin Name: Dashboard Builder
Plugin URI: https://dashboardbuilder.net/
Description: Dashboard Builder is a data visualization plugin for WordPress that offers all major charts and graphs templates, which enables you to retrives your own data from WordPress or MySQL database  to display charts and graphs on your WordPress website. For more information visit https://dashboardbuilder.net
Version: 1.5.3
Author: Dashboard Builder
Author URI: https://dashboardbuilder.net
License: GPL
*/

class dashboardbuilder
{
	var $type = array();
	var $data;
	var $title;
	var $xaxis;
	var $yaxis;
	var $xlabel;
	var $ylabel;
	var $width;
	var $height;	
	var $xaxistitle;
	var $yaxistitle;
	var $barmode;
	var $name;
	var $tracename;
	var $color;
	var $orientation;
	var $size;
	var $text;
	var $showgrid;
	var $showline;
	var $hole;
	var $csv;
	var $csvdata;
	var $servername;
	var $username;
	var $password;
	var $dbname;
	var $source;
	var $rdbms;
	var $mapdata=array();
	var $mapcode=array();
	var $mapcountry=array();
	var $sizeSQL=array();
	var $sizeCol=array();
	var $textSQL=array();
	var $textCol=array();
	var $maptype=array();
	var $yntitle=array();
	var $col;
	
	public function __construct()
    {
        // Constructor's functionality here, if you have any.
    }

	public function dashboardbuilder()
		{
			$this->type = array();
			$this->width = "";
			$this->height = "";
			$this->xaxis = array();
			$this->yaxis = array();
			$this->tracename = array();
			$this->yntitle = array();
			$this->color = array ();
			$this->sql = array();
			$this->xlabel = "";
			$this->ylabel = "";
			$this->title = "";	
			$this->xaxistitle = "";	
			$this->yaxistitle = "";	
			$this->barmode = "";
			$this->name = "";
			$this->orientation = "";
			$this->size = array();
			$this->text = array();
			$this->showgrid="";
			$this->showline="";
			$this->hole="";
			$this->csv="";
			$this->csvdata="";
			$this->servername = "";
			$this->username = "";
			$this->password = "";
			$this->dbname = "";
			$this->source="";
			$this->rdbms="";
			$this->xaxisSQL =array();
			$this->xaxisCol =array();
			$this->yaxisSQL=array();
			$this->yaxisCol=array();
			$this->sizeSQL=array();
			$this->sizeCol=array();
			$this->textSQL=array();
			$this->textCol=array();
			$this->maptype=array();
			$this->col="";
			
			self::__construct();
		}
		
	function result()
		{
		// setting default values
		
		ob_start();

			// DB module
			if (($this->source=='Database')) {
			if ((!$this->dbname=='') && (isset ($this->xaxisCol))) {
			//$conn = new mysqli($this->servername,$this->username,$this->password,$this->dbname);
			$DB_TYPE = $this->rdbms; //Type of database<br>
			$DB_HOST = $this->servername; //Host name<br>
			$DB_USER = $this->username; //Host Username<br>
			$DB_PASS = $this->password; //Host Password<br>
			$DB_NAME = $this->dbname; //Database name<br><br>
			$SERVER='host=';
			$DATABASE='dbname=';
			
			if ($DB_TYPE=='sqlsrv') {
				$SERVER='Server=';
				$DATABASE='Database=';
			}

			try{
					if ($DB_TYPE=='sqlite'){
						$conn = new PDO("$DB_TYPE:$DB_NAME");
					}
					else {
						$conn = new PDO("$DB_TYPE:host=$DB_HOST; dbname=$DB_NAME;", $DB_USER, $DB_PASS);
					}
				} catch(Exception $e){
					//echo $e;
					$result= '<div class="alert alert-danger alert-dismissable">
										<a href="#" class="close" data-dismiss="alert" aria-label="close">&times;</a>
										<strong>Error! Invalid Database Connection </strong> '.$DB_TYPE.
									  '</div>';
					return $result;
					}

				$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
				
				//if ($this->source=='ADatabase') {
				// do this 
						$i=0;
				 		foreach($this->xaxisSQL  as $value){
								$j=0;
								try {
									foreach ($conn->query($value) as $row) {
										$this->xaxis[$i][$j]= $row[$this->xaxisCol[$i]];
										$j++;
									}
								} catch (Exception $e) { //echo $e; 
								$result= '<div class="alert alert-danger alert-dismissable">
										<a href="#" class="close" data-dismiss="alert" aria-label="close">&times;</a>
										<strong>Error! Invalid Database Connection </strong> '.$this->xaxisSQL[0].
									  '</div>';
								return $result; }
						$i++;
						}
	
						$i=0;
						if(!($this->type[0]=='kpi')){
							foreach($this->yaxisSQL as $value){
									$j=0;
									foreach ($conn->query($value) as $row) {
										$this->yaxis[$i][$j]= $row[$this->yaxisCol[$i]];
										$j++;
									}
							$i++;
							}
						}
						
						if (($this->type[0]=='bubble') || ($this->type[0]=='sankey')){
							$i=0;
							foreach($this->sizeSQL as $value){
									$j=0;
									foreach ($conn->query($value) as $row) {
										$this->size[$i][$j]= $row[$this->sizeCol[$i]];
										$j++;
									}
							$i++;
							}
							
						}//end if bubble
						
						if (($this->type[0]=='bubble') || ($this->type[0]=='map') || ($this->type[0]=='heatmap') || ($this->type[0]=='sankey')) {
							$i=0;
							foreach($this->textSQL as $value){
									$j=0;
									foreach ($conn->query($value) as $row) {
										$this->text[$i][$j]= $row[$this->textCol[$i]];
										$j++;
									}
							$i++;
							}
						} //end if bubble and map
						
						
			
			} // if end
			} // end if Database
			/////		
			
		$defaultcharttitle = ucwords($this->type[0]) . " Chart";
		if ($this->title==''){ $this->title = $defaultcharttitle ;}
		if ($this->xaxistitle==''){ $this->xaxistitle ='X-axis';}
		if ($this->yaxistitle==''){ $this->yaxistitle ='Y-axis';}
		//if ($this->width==''){ $this->width ='default';}
		//if ($this->height==''){ $this->height ='default';}
		if ($this->barmode==''){ $this->barmode = 'group';}
		if ($this->name==''){ $this->name= $this->type;}
		if ($this->hole==''){ $this->hole =0;}
		if ($this->showgrid==''){ $this->showgrid= 'true';}
		if ($this->showline==''){ $this->showline= 'true';}
		
		
		//////////

		if ($this->type[0] =='donut'){$this->type[0] ='pie'; $this->hole=.4;} // set value for donut
		////////
		
		//Replacing ~ with , wihin text
		if ($this->source!='Database') {
	
			if(!empty($this->xaxis)) {
				foreach ($this->xaxis as $i => $value){
					$this->xaxis[$i] = str_replace(array("~", ), ',', $this->xaxis[$i]);
				}
			}

			if(!empty($this->yaxis)) {
				foreach ($this->yaxis as $i => $value){
					$this->yaxis[$i] = str_replace(array("~", ), ',', $this->yaxis[$i]);
				}
			}

			if(!empty($this->text)) {
				foreach ($this->text as $i => $value){
					$this->text[$i] = str_replace(array("~", ), ',', $this->text[$i]);
				}
			}

			if(!empty($this->size)) {
				foreach ($this->size as $i => $value){
					$this->size[$i] = str_replace(array("~", ), ',', $this->size[$i]);
				}
			}
		}
		
		?>
		
  		<div id="col<?php echo $this->col;?>" ><!-- chart will be drawn inside this DIV --></div><div style="text-align:center;"><a href="https://dashboardbuilder.net" target="_blank">Powered by Dashboard Builder</a></div><script>(function(){
		 window.PLOTLYENV={};

                var gd = document.getElementById("col<?php echo $this->col;?>")
                var resizeDebounce = null;

                function resizePlot() {
                    var bb = gd.getBoundingClientRect();
                    Plotly.relayout(gd, {
                        width: bb.width,
                        height: bb.height
                    });
                }

                
                window.addEventListener("resize", function() {
                    if (resizeDebounce) {
                        window.clearTimeout(resizeDebounce);
                    }
                    resizeDebounce = window.setTimeout(resizePlot, 100);
                });

			
		<?php 
		
		
		
		// Chart type KPI` Start //
		    if ($this->type[0]=='kpi' ) 
				{
					echo '</script>';
					$str = ob_get_clean();
					$str = "<div id='kpi'>".$this->xaxis[0][0]."</div>";
					$str .= "<div id='kpi_legand'>".$this->tracename[0]."</div>";
					
					
					//$str = 'document.getElementById("col'.$this->col.'").innerHTML="'.$this->xaxis[0][0].'";';
					
					
					return $str;
					return(true);

				}
			// Chart type KPI End //
		
		// Chart type Line, area, Histogram  and Bar End //
		
		// Chart type Line and Bar Start //
		    if ($this->type[0]=='line' || $this->type[0]=='bar' || $this->type[0]=='area' || $this->type[0]=='histogram' || $this->type[0]=='stack') 
				{
				if (!(count($this->xaxis)==count($this->yaxis))){
				   echo '</script>';		
					trigger_error("X-axis and Y-axis data must be same", E_USER_NOTICE );
					$str = ob_get_clean();
					return $str;
					return(true);
				   }
					?>
					
					<?php
					$j=0;
					foreach ($this->xaxis as $i) {
						$j++;
						if ($this->type[$j-1] =='stack'){$this->type[$j-1] ='bar';$this->barmode = "stack";} // set value for stack
						?>
						var trace<?php echo $j;?> = {
						  
						  <?php if (($this->orientation=='h') && (($this->type[$j-1]=='line') || ($this->type[$j-1]=='area') )) {?>
						     y: <?php echo json_encode($i);?>, 
						  	 x: <?php echo json_encode($this->yaxis[$j-1]);?>, 
							<?php } else { ?>
							 x: <?php echo json_encode($i);?>, 
						  	 y: <?php echo json_encode($this->yaxis[$j-1]);?>, 
							<?php } ?>
						  
						  <?php 
						  if (!empty($this->tracename[$j-1])){echo 'name:"'.$this->tracename[$j-1].'",';}
						  if($this->type[$j-1]=="area") {echo 'fill: "tozeroy", ';}
						  ?>
								
						  line: {
						  <?php if (!($this->type[$j-1]=='line')) {?> shape: "spline", <?php }
						  if (!empty($this->color[$j-1])) { ?>
						  color: "<?php echo $this->color[$j-1];?>"	
						  <?php } ?>
						  },  
						  
						  <?php if (!empty($this->color[$j-1])) { ?>
									  marker: {
										<?php
										if (!empty($this->color[$j-1])) { ?>
											color: "<?php echo $this->color[$j-1];?>"
										<?php } ?>
									  },
						  <?php }?>
							  
						  <?php if (!empty($this->yntitle[$j-1])) { ?>
							  yaxis: 'y<?php echo $j;?>',
						   <?php }?>
							  
						  <?php if ($this->orientation=='h'){echo "orientation: 'h',";}?>
						  	type: '<?php echo $this->type[$j-1];?>'
						};
						<?php 
						}// foreach xaxis end
					?>
					var data = [<?php for ($i=1;$i<$j+1;$i++){ echo 'trace'.$i.',';}?>];
					
					var layout = {
					title: false,
					 <?php if(!($this->height=='')){?>
					   height: <?php echo $this->height;?>,
					   <?php }
					   if (!($this->width=='')){?>
					    width: <?php echo $this->width;?>,
					   <?php }?>
					  xaxis: {
						title: '<?php echo $this->xaxistitle;?>', 
						showticklabels:true,
						<?php $c = 0; // adjusting width for yntitle
						$c = count(array_filter($this->yntitle));
						if ($c >0) {
							$c = $c-($c/2.5);
							?>
							domain: [0, 0.85],
						<?php
						}
						?>
						
						showgrid: <?php echo $this->showgrid;?>, 
						showline: <?php echo $this->showline;?>
					  }, 
					  yaxis: {
						title: '<?php echo $this->yaxistitle;?>', 
						showticklabels:true,
						showgrid: <?php echo $this->showgrid;?>, 
						showline: <?php echo $this->showline;?>
					  },
					  
				// for multiple yaxis 
					<?php 
					$j=0;
					foreach ($this->xaxis as $i) {
						$j++;
							 if (!empty($this->yntitle[$j-1])) {  ?>
								yaxis<?php echo $j;?>: {
								title: '<?php echo $this->yntitle[$j-1];?>',
								titlefont: {color: '<?php echo $this->color[$j-1];?>'},
								tickfont: {color: '<?php echo $this->color[$j-1];?>'},
								overlaying: 'y',
								showticklabels:true,
								showgrid: <?php echo $this->showgrid;?>, 
								showline: <?php echo $this->showline;?>,
								<?php if ($j >2) {?>
								position: <?php echo ($j/($j+0.4));?>,
								<?php } ?>
								side: 'right'
							  },
						 <?php 
						 }
						 
					} // forach yntitle end
					?>
			    // for multiple yaxis end 
					  
					   margin: {
						l: 50,
						r: 20,
						b: 20,
						t: 30,
						pad: 0
					  },
					 <?php if (empty($this->tracename[0])) 
					 	echo 'showlegend:false,';
					?>
					  barmode: '<?php echo $this->barmode;?>'
					};
					
				<?php
				}
				
				//////// maps ///////
				if ($this->type[0]=='map' ) 
				{
					if ($this->maptype[0]=='usa') {
						$locaitonmode = 'USA-states';
						}
						else if ($this->maptype[0]=='world') {
							$locaitonmode = 'ISO-3';
							}
					else {
						$locaitonmode = 'country name';
					}
				?>
				
			Plotly.d3.csv('', function(){
			 var data = [{
						 type: 'choropleth',
						 locationmode: '<?php echo $locaitonmode;?>',
						 locations: <?php echo json_encode($this->xaxis[0]);?>,
						 z: <?php echo json_encode($this->yaxis[0]);?>,
						 zauto: true, 
						 text: <?php echo json_encode($this->text[0]);?>,
						 colorscale: [
								[0,'rgb(5, 10, 172)'],[0.35,'rgb(40, 60, 190)'],
								[0.5,'rgb(70, 100, 245)'], [0.6,'rgb(90, 120, 245)'],
								[0.7,'rgb(106, 137, 247)'],[1,'rgb(220, 220, 220)']],

								reversescale: true,
								marker: {
									line: {
										color: 'rgb(0,0,0)',
										width: 0.6
									}
								},

						  colorbar: {
							autotic: true,
							title: '<?php echo $this->tracename[0];?>',
							thickness: 5,
						  }
					  }];

			console.log(data.locations);
			  var layout = {
					  //title: '<?php echo $this->title;?>',
					  title:false,
					 margin: {
						l: 10,
						r: 10,
						b: 5,
						t: 30,
						pad: 0
					  },
					  <?php if(!($this->height=='')){?>
					  height: <?php echo $this->height.',';}	 
					   if (!($this->width=='')){?>
					    width:<?php echo $this->width;?>,
					   <?php }?>
					geo:{
						scope: '<?php echo $this->maptype[0];?>',
						showlakes: true,
						lakecolor: 'rgb(255,255,255)',
						showframe: false,
						showcoastlines: false,
						/*projection:{
						type: 'mercator' //'robinson' 
						} */
					  },
				  };
				  	var modeBarManage = {
					modeBarButtonsToRemove: ['sendDataToCloud'],
					displaylogo: false};
				    Plotly.plot(gd, data, layout, modeBarManage);
				  
			  });
			  })();</script>
			<?php
			$str = ob_get_clean();
		    return $str;
				}
				?>
					var modeBarManage = {
					modeBarButtonsToRemove: ["sendDataToCloud"],
					displaylogo: false};

					Plotly.plot(gd, data, layout, modeBarManage);
					}());
</script>
		<?php
		$str = ob_get_clean();
		return $str;
		}
}

?>