Home » Php » php – positioning by percentage in a foreach

php – positioning by percentage in a foreach

Posted by: admin July 12, 2020 Leave a comment

Questions:

I have a page that looks like this right now:

How the page looks

and the code for this is:

<?php
   $count_axle = $database->count_axles($_GET['train_id']);     
   foreach($count_axle as $counting){ 
}?>
    <div id="axle_bogie_border">
        <img id="count_train_image" src="Images/add_train1.png" alt="Train look" style="width:<?php echo $counting['totaldistance']; ?>%">
        <?php
                $show_axle = $database->axles($_GET['train_id']);
        ?>


        <div id="axle_position_count">
            <?php      
                foreach($show_axle as $axlefigure){ ?>
                    <div id="count_axle_figure" style="margin-left:<?php echo $counting['totaldistance']; ?>%"> 
                        <?php echo $axlefigure['axle'] ?>
                    </div>
            <?php
                } 
            ?><br /><br /><br />    
        </div>
    </div>

And the css:

#axle_bogie_border {
    border: 2px solid black;
    width: 100%;
    height: auto;
    overflow-x: scroll;
    white-space: nowrap;
}

#count_train_image{
    margin-left: 10%;
    margin-right: 10%;
    height: 100px;
    display: inline-block;
    position: relative;
    float: left;
}


#show_length{
    border-bottom: 2px solid black;
    width: 100%;
}

#show_length2{
    border-bottom: 2px solid black;
    width: 10%;
}



#axle_position_count {
    margin-top: 10%;
    margin-left: 10%;
}

#count_axle_figure {
    background: black;
    width: 40px;
    height: 40px;
    border-radius: 50px;
    float: left;
}

Right. So i make the width of the image depending on the sum of the database. So for example. Each circle you see (4 in this case) has a distance. Soo:

  • axle 1 = 2000
  • axle 2= 8000
  • axle 3= 2000
  • axle 4= 8000

In total this is 20.000mm 20.000mm=20 meter. So this train is 20 meter. Now i scale this down to percantages:(See image width )

function count_axles($id) {
        $sql = "SELECT (sum(distance))/(25000)*(100) as totaldistance from axle WHERE train_id = :train_id";
        $sth = $this->pdo->prepare($sql);
        $sth->bindParam(":train_id", $id, PDO::PARAM_STR);
        $sth->execute();
        return $sth->fetchAll();
    }

Here i tell that 100% is 25.000mm (25meter).
Now i also need this for the axle position.
So axle 1= for example 10% of the total. So i need it to be 10% on the left (Margin)
axle 2= 5%. So i need axle 1+ 5% = 15% on the left.
etc.

Each axle has his own ID (Here the DB image)

Database axles

So eventually i want the end result needs to look like a little train. (So the first 2 axles left and the last 2 axles right) under the train image.
Like this:
enter image description here

How to&Answers:

I don’t know why so many people upvoted this question.

For me it seems very unclear. I can’t get what is the question?

I guess the only question is how to generate dynamic margin for axles.

But even this question wasn’t clearly asked and expected result is not described well.

So here are my guess:

shift = -25; //my circle is 50px width 
             //so for the 1st axel if distance=0 
             //circle must be shifted to the left by -25px
viewWidth = 800;

axles = [{distance: 2000}, 
         {distance: 8000}, 
         {distance: 2000}, 
         {distance: 8000}];
trainWidth = 0;
axles.forEach(function (axle) {
  trainWidth += axle.distance;
});

width = Math.round(800*trainWidth/25000);

$('#train h2').text(""+(Math.round(trainWidth/10)/100)+"m");

unusedLeft = Math.round((viewWidth - width)/2);
unusedRight = unusedLeft;
$('#info .leftBox').width(""+unusedLeft+"px" );

unusedMeters = Math.round((25000-trainWidth)/10/2)/100;
$('#info .leftBox h3').text(""+unusedMeters+"m");
$('#info .rightBox h3').text(""+unusedMeters+"m");

$('#info .rightBox').width(""+unusedRight+"px" );

$('#train').width(""+width+"px" );

$('#axels').width(""+width+"px" );



idx = 0;
d = 0;
div = '';

axles.forEach(function (axle) {
  idx++;
  d += axle.distance;
  axle.idx = idx;
  margin = shift + Math.round(d*width/trainWidth);
  axle.margin = margin;
  div += '<div id="axel'+idx+'" style="margin-left: '+margin+'px ;" class="axel circle"></div>';
  
});

$('#axles').append(div);//.marginLeft(""+margin+"px");
h2, h3 {
  text-align:center;
  margin:2px auto;
}

.container {
  width:800px; 
  height:400px;
  border: solid 1px red;
}

#info {
  width:800px; 
  height:20px;
  border: none;
  position:relative;
}

#info .leftBox {
  left:0;
  top:0; 
  height:20px;
  width:75px;
  border-bottom: 1px solid blue;
  position:absolute;
}
#info .rightBox {
  right:0;
  top:0;
  height:20px;
  width:75px;
  border-bottom: 1px solid blue;
  position:absolute;
}
#train {
  margin:3px auto;
  width:650px;
  height:200px;
  background:black;
  vertical-align:middle;
  color:#FFFFFF;
}
#train h2{
  margin:auto auto;
  line-height:200px;
  color:#FFFFFF;
}

#axles {
  width:650px; 
  height:50px;
  margin: 1px auto;
  border: none;
  position:relative;
}

.axel {
	position: absolute;
  float:left;
}
.circle {
	width: 50px; height: 50px;
	border-radius: 50%;
	background: lightblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<div class="container">
  <h2>25m</h2>
  <hr />
  <div id="info">
    <div class="leftBox"><h3>2.5m</h3></div>
    <div class="rightBox"><h3>2.5m</h3></div>
  </div>
  <div id="train">
    <h2>20m</h2>
  </div>
  <div id="axles">
    

  </div>

It is done only with JS for now, just to clarify how to set dynamic margins and widths of elements.

So you can play with this snippet just by chnaging value of axles like:

axles = [{distance: 2000}, 
         {distance: 2000}, 
         {distance: 2000}, 
         {distance: 2000}, 
         {distance: 2000}, 
         {distance: 2000}, 
         {distance: 2000}, 
         {distance: 2000}];

http://codepen.io/anon/pen/QbwRMJ

Answer:

OOP is imho created for this type of functionality.
I will give you a small example how I would build this. The example gives you only a hint how to do it, but this basics is already a very flexible way to build it up. I did not test it, but I know that the principle works and that is where this example is made for.

/*
    A wheel pattern is an ordering of a group of wheels and the required CSSclasses for each or all wheels.
*/
interface iWheelGroup{
    public function getPattern();
}


class BasePattern implements iWheelGroup{
    protected $pattern;

    public function __construct($pPattern){
        $this->pattern = $pPattern;
    }


    public function getPattern(){
        return $this->pattern;
    }

    public function __toString(){
        $tmp = "";
        if(is_null($this->getPattern()) === true){
            return $tmp;
        }
        $arClasses = explode('_&_', $this->getPattern());
        $max = count($arClasses);
        for($i=0;$i<$max;$i++){
            $tmp .= "<img class=\"".$arClasses[$i]."\" > ";
        }
        $tmp .= "\n";
        return $tmp;
    }
}


class WheelAndPattern extends BasePattern{
    protected $wheels;

    public function __construct($pWheels, $pPattern){
        $this->$wheels = $pWheels;
        parent::__construct($pPattern);
    }


    public function getWheels(){
        return $this->wheels;
    }

    public function __toString(){
        $tmp = "";
        if(is_null($this->getPattern()) === true || is_null($this->getWheels() === true)){
            return $tmp;
        }
        $arClasses = explode('_&_', $this->getPattern());
        $max = count($arClasses);

        $arWheeltypes = explode('_&_', $this->getWheels());
        $maxWheels = count($arWheeltypes);
        if($max === $maxWheels){
            for($i=0;$i<$max;$i++){
                $tmp .= "<img class=\"".$arClasses[$i]."\" src=\"".$arWheeltypes[$i]."\> ";
            }
        }else{
            for($i=0;$i<$max;$i++){
                $tmp .= "<img class=\"".$arClasses[$i]."\" src=\"".$arWheeltypes[0]."\> ";
            }
        }
        $tmp .= "\n";
        return $tmp;
    }
}

$wg = new BasePattern('wheelsleft_&_wheelsleft_&_wheelsright_&_wheelsright');
$wg2= new WheelAndPattern('openWheel','wheelseven_&_wheelseven_&_wheelseven');
$wg3= new WheelAndPattern('blackWheel_&_greyWheel_&_whiteWheel','wheelsleft_&_wheelscenter_&_wheelsright');
print $wg.$wg2.$wg3;