PHP 生成图表。 CSS 错误。刻度错误。 SVG-多边形
PHP Generated Chart. CSS error. Scale wrong. SVG-Polygons
我写了一个使用 SVG-Poligons 来显示图表的脚本。
情况。我有一个具有最高价格和最低价格的产品。我每周一(称为周期)收集该信息。
我的系统计算产品的基本价格和获胜百分比并设置自己的价格。
示例
cycle | max | min | own
1 | 10.99 | 9.00 | 12.90
2 | 10.50 | 9.50 | 11.90
3 | 9.00 | 8.00 | 9.50
现在我用值画多边形。 为了做到这一点,我必须将 max-min-own Price 缩放到 100%,因为 poligons。看起来像这样
/B
/ |
/ |
/ |
A |
| |
| /D
| /
C/
- A = Cycle1 最大值
- B = Cycle2 最大值
- C = Cycle1 最小值
- D = Cycle2 最小值
图形不一样。来自传奇...只是一个视觉效果。
这是我目前的输出
但它必须像这样缩放
<?php
$sql_table_low = "SELECT t1.run_cycle,t1.ean,t1.shop,t1.price_total,t1.timestamp_update,t2.newprice FROM Horn_UPM_Product_Price_History as t1 inner join Horn_UPM_Product_Price_Change_History as t2 on t1.ean = t2.ean WHERE t1.ean = '".$artikel."' order by run_cycle,price_total";
// $content .= $sql_table_low;
$q = $readConnection->fetchAll($sql_table_low);
foreach($q as $row)
{
$graph_raw[$row['run_cycle']][] = $row;
}
$g['maxheight-row'] = 0;
foreach($graph_raw as $row2)
{
// $content .= "<br />".$row2[0]['shop'].'--'.$row2[(count($row2)-1)]['shop']."<br />";
$graph[$row2[0]['run_cycle']] = array("low" => $row2[0]['price_total'],"low_shop" => $row2[0]['shop'],"high" => $row2[(count($row2)-1)]['price_total'],"high_shop" => $row2[(count($row2)-1)]['shop'],"timestamp" => $row2[0]['timestamp_update'],"price_set" => $row2[0]['newprice']);
if($row2[(count($row2)-1)]['price_total']>$g['row-max'])
{
$g['row-max'] = $row2[(count($row2)-1)]['price_total'];
}
if($row2[0]['price_total']<$g['row-min'])
{
$g['row-min'] = $row2[(count($row2)-1)]['price_total'];
}
}
$content .= '<br><br>';
// ------------- Settings
$g['maxwidth'] = 800;
$g['maxheight'] = 600; // = 100%
$g['scale_hight'] = 600;
$g['dotsize'] = 6;
$g['dotcolor_height'] = 'green';
$g['dotcolor_low'] = 'red';
$g['dotcolor_fix'] = 'orange';
$g['linecolor'] = 'red';
$g['scale_multi'] = 50;
// DONT CHANGE AFTER THIS LINE
$g['colwidth'] = $g['maxwidth'] / count($graph);
$g['row_pixel_ratio'] = $g['maxheight'] / ($g['row-max']-$g['row-min']+100);
$content .= '<div style="background:white;position:relative;width:'.$g['maxwidth'].'px;height:'.$g['maxheight'].'px;display:block;">';
$row_count = 1;
$height_old=0;
$low_old=0;
$fixo_price_old_scale=floor(($standartfixprice * 100) / $g['row-max']);
$fixo_price_old=$standartfixprice;
foreach(array_keys($graph) as $key)
{
// print_r($graph);
$height_new = $graph[$key]['high'];
$low_new = $graph[$key]['low'];
if($height_old==0){$height_old=$height_new;}
if($low_old==0){$low_old=$low_new;}
// print_r($q2);
// $height_new = rand(0,100);
/*
$dot[1] = array(0,0); // Oben Links // x,y
$dot[2] = array(100,0); // Oben Rechts // x,y
$dot[3] = array(100,100); // Unten Rechts // x,y
$dot[4] = array(0,100); // Unten Links // x,y
$dot1[1] = array(0, high_old)
$dot1[2] = array(colwidth, high_new)
$dot1[3] = array(colwidth, low_new)
$dot1[4] = array(0, low_old)
(($high_old * 100) / $g['row-max']);
(($high_new * 100) / $g['row-max']);
(($low_new * 100) / $g['row-max']);
(($low_old * 100) / $g['row-max']);
*/
$dot[1] = array('x' => 0, 'y' => 100 - floor(($height_old * 100) / $g['row-max']));
$dot[2] = array('x' => floor($g['colwidth']), 'y' => 100 - floor(($height_new * 100) / $g['row-max']));
$dot[3] = array('x' => floor($g['colwidth']), 'y' => 100 - floor(($low_new * 100) / $g['row-max'])+$g['scale_multi']);
$dot[4] = array('x' => 0, 'y' => 100 - floor(($low_old * 100) / $g['row-max'])+$g['scale_multi']);
$sql_table_low_2 = "SELECT newprice*1.19 as fixprice FROM Horn_UPM_Product_Price_Change_History WHERE timestamp_unix < '".$graph[$key]['timestamp']."' AND ean = '".$artikel."' order by id DESC LIMIT 1";
// $content .= $sql_table_low_2;
$q2 = $readConnection->fetchRow($sql_table_low_2);
if(!isset($q2['fixprice']))
{
$fixo_price_new = 0;
$fixo_price_new_scale = 0;
}
else
{
$fixo_price_new = $q2['fixprice'];
$fixo_price_new_scale = 100-floor(($q2['fixprice'] * 100) / $g['row-max']);
}
// $content .= 100 - floor(($height_old * 100) / $g['row-max']).'-';
// $content .= 100 - floor(($height_new * 100) / $g['row-max']).'-';
// $content .= 100 - floor(($low_new * 100) / $g['row-max']).'-';
// $content .= 100 - floor(($low_old * 100) / $g['row-max']).'|||';
// $content .= $dot[1]['y'].'-';
// $content .= $dot[2]['y'].'-';
// $content .= $dot[3]['y'].'-';
// $content .= $dot[4]['y'].'|||';
$height_old=$height_new;
$low_old=$low_new;
$fixo_price_old=$fixo_price_new;
$fixo_price_old_scale=$fixo_price_new_scale;
// print_r($dot);
$content .= '
<div style="position:absolute;left:'.floor($g['colwidth']*($key-1)).'px;width:'.floor($g['colwidth']).'px">
<svg id="svg-'.$row_count.'" class="clip-svg" style="height:200px;">
<rect class="svg-bg-'.$row_count.'" width="'.floor($g['colwidth']).'" height="200" fill="#e6e6ff" />
</svg>
<svg id="svg-defs" style="height:0;">
<defs>
<clipPath id="clip-'.$row_count.'">
<polygon points="'.$dot[1]['x'].' '.$dot[1]['y'].', '.$dot[2]['x'].' '.$dot[2]['y'].', '.$dot[3]['x'].' '.$dot[3]['y'].', '.$dot[4]['x'].' '.$dot[4]['y'].'" />
<!-- <polygon points="0 0, '.$dot[2]['x'].' 0, '.$dot[3]['x'].' '.$dot[3]['y'].', '.$dot[4]['x'].' '.$dot[4]['y'].'" /> -->
</clipPath>
</defs>
</svg>
<style>
.svg-bg-'.$row_count.' { clip-path: url(#clip-'.$row_count.'); }
</style>
<div class="dot_high" style="z-index:1000;position:absolute;top:'.$dot[2]['y'].'px;left:'.($g['colwidth']-$g['dotsize']/1.5).'px;height:'.$g['dotsize'].'px;width:'.$g['dotsize'].'px;background:'.$g['dotcolor_height'].';display:block;"></div>
<div class="dot_low" style="z-index:1000;position:absolute;top:'.($dot[3]['y']-$g['dotsize']/1.5).'px;left:'.($g['colwidth']-$g['dotsize']/1.5).'px;height:'.$g['dotsize'].'px;width:'.$g['dotsize'].'px;background:'.$g['dotcolor_low'].';display:block;"></div>
<div class="dot_fix" style="z-index:1000;position:absolute;top:'.($fixo_price_new_scale-$g['dotsize']/1.5).'px;left:'.($g['colwidth']-$g['dotsize']/1.5).'px;height:'.$g['dotsize'].'px;width:'.$g['dotsize'].'px;background:'.$g['dotcolor_fix'].';display:block;"></div>
</div>';
$row_count++;
}
正如解释的那样,代码有效。但它缩放错误 (100%)..
SVG
这需要大量工作和大量混乱的代码,因此我将草拟出一个建议,告诉您如何解决此问题:
Svg 图
我不会通读你所有的代码,因为我一半都看不懂。
我会告诉你我们如何解决这个问题:
找出单行中的点数
我们将在这个例子中使用 5 个高点和 5 个低点。
$highArray = array(115, 117, 116, 117, 118);
$lowArray = array(113, 114, 114, 115);
现在我假设它必须扩展,因为你有:
$g['maxheight'] = 600
$g['maxwidth'] = 800
为了便于使用,我们称它们为
$maxheight = 600
$maxwidth = 800
我看到有; Linecolor、dotsize 等。这些不言而喻,所以我会像 $linecolor
和 $dotsize
这样使用它们
因此我们的 svg 文档将是 600 个单位高和 800 个单位宽。
然后我们可以这样创建文档:
echo '<svg viewBox="0 ,0 '.$maxwidth.','.$maxheight.'" >';
希望您能关注。这是 svg,所以我们不使用像素大小,所以将它们排除在外。
接下来是添加图形:
现在我们需要看看这些点需要去哪里:
1. 我们希望它们均匀分布在整个 svg 上,所以我们将单个数组中的点数与 svg 的大小分开:
$ColumnSize = $maxwidth / $highArray + 1 ;
Example:
800 / 5 = 160
in our example we will use 160 as each column size.
现在让我们用路径和圆元素创建图形:
Circles:
for($i=0; $i<$heightArray.count(); $i++) {
echo '<circle class="circle-high" cx="'.($ColumnSize*i).'" cy="'.($maxheight - $highArray[i]).'" r="'.$dotSize.'" >';
}
//Same for $lowArray
echo '<circle class="circle-low" cx="'.($ColumnSize*n).'" cy="'.($maxheight - $lowArray[n]).'" r="'.$dotSize.'" >';
Path:
$xPath = "M";
for($i=0; $i<$hightArray.count(); $i++) {
$xPath += " ".$ColumnSize*$i.",".($maxheight - $highArray[$i]);
}
for ($j=$lowArray.count(); $j>0; $j--) {
$xPath += " ".$ColumnSize*$j.",".($maxheight - $lowArray[$j-1]);
}
echo '<path class="dotbackground" d="'.$xPath.'z"/>';
并将颜色添加到 css:
.circle-low {
fill: red;
}
.circle-high {
fill: green;
}
.dotbackground {
fill: #ccc;
}
如果你做了所有这些,输出应该是这样的:
/*FOR DISPLAY ONLY*/
svg {
height: 300px;
border: 5px solid black;
}
/*END DISPLAY ONLY */
.circle-high {
fill: red;
}
.circle-low {
fill: green;
}
.dotbackground {
fill: #aaa;
}
<svg viewBox="-5 0 800 600">
<path class="dotbackground" d="M0,375 160,364, 320,374 480,363, 640,352 640,442 480,453 320,464 160,503 0,465z" />
<circle class="circle-high" cx="0" cy="375" r="6" />
<circle class="circle-high" cx="160" cy="363" r="6" />
<circle class="circle-high" cx="320" cy="374" r="6" />
<circle class="circle-high" cx="480" cy="363" r="6" />
<circle class="circle-high" cx="640" cy="352" r="6" />
<circle class="circle-low" cx="0" cy="465" r="6" />
<circle class="circle-low" cx="160" cy="503" r="6" />
<circle class="circle-low" cx="320" cy="464" r="6" />
<circle class="circle-low" cx="480" cy="453" r="6" />
<circle class="circle-low" cx="640" cy="442" r="6" />
</svg>
您可以考虑的附加功能:
- 找到两个数组中的最低值和最高值,然后缩放它们在高度上的响应显示方式。
- 通过 class 向 svg 文档添加 max-height: 和 max-width 并在 ccs
中设置样式
我写了一个使用 SVG-Poligons 来显示图表的脚本。
情况。我有一个具有最高价格和最低价格的产品。我每周一(称为周期)收集该信息。
我的系统计算产品的基本价格和获胜百分比并设置自己的价格。
示例
cycle | max | min | own
1 | 10.99 | 9.00 | 12.90
2 | 10.50 | 9.50 | 11.90
3 | 9.00 | 8.00 | 9.50
现在我用值画多边形。 为了做到这一点,我必须将 max-min-own Price 缩放到 100%,因为 poligons。看起来像这样
/B
/ |
/ |
/ |
A |
| |
| /D
| /
C/
- A = Cycle1 最大值
- B = Cycle2 最大值
- C = Cycle1 最小值
- D = Cycle2 最小值
图形不一样。来自传奇...只是一个视觉效果。
这是我目前的输出
但它必须像这样缩放
<?php
$sql_table_low = "SELECT t1.run_cycle,t1.ean,t1.shop,t1.price_total,t1.timestamp_update,t2.newprice FROM Horn_UPM_Product_Price_History as t1 inner join Horn_UPM_Product_Price_Change_History as t2 on t1.ean = t2.ean WHERE t1.ean = '".$artikel."' order by run_cycle,price_total";
// $content .= $sql_table_low;
$q = $readConnection->fetchAll($sql_table_low);
foreach($q as $row)
{
$graph_raw[$row['run_cycle']][] = $row;
}
$g['maxheight-row'] = 0;
foreach($graph_raw as $row2)
{
// $content .= "<br />".$row2[0]['shop'].'--'.$row2[(count($row2)-1)]['shop']."<br />";
$graph[$row2[0]['run_cycle']] = array("low" => $row2[0]['price_total'],"low_shop" => $row2[0]['shop'],"high" => $row2[(count($row2)-1)]['price_total'],"high_shop" => $row2[(count($row2)-1)]['shop'],"timestamp" => $row2[0]['timestamp_update'],"price_set" => $row2[0]['newprice']);
if($row2[(count($row2)-1)]['price_total']>$g['row-max'])
{
$g['row-max'] = $row2[(count($row2)-1)]['price_total'];
}
if($row2[0]['price_total']<$g['row-min'])
{
$g['row-min'] = $row2[(count($row2)-1)]['price_total'];
}
}
$content .= '<br><br>';
// ------------- Settings
$g['maxwidth'] = 800;
$g['maxheight'] = 600; // = 100%
$g['scale_hight'] = 600;
$g['dotsize'] = 6;
$g['dotcolor_height'] = 'green';
$g['dotcolor_low'] = 'red';
$g['dotcolor_fix'] = 'orange';
$g['linecolor'] = 'red';
$g['scale_multi'] = 50;
// DONT CHANGE AFTER THIS LINE
$g['colwidth'] = $g['maxwidth'] / count($graph);
$g['row_pixel_ratio'] = $g['maxheight'] / ($g['row-max']-$g['row-min']+100);
$content .= '<div style="background:white;position:relative;width:'.$g['maxwidth'].'px;height:'.$g['maxheight'].'px;display:block;">';
$row_count = 1;
$height_old=0;
$low_old=0;
$fixo_price_old_scale=floor(($standartfixprice * 100) / $g['row-max']);
$fixo_price_old=$standartfixprice;
foreach(array_keys($graph) as $key)
{
// print_r($graph);
$height_new = $graph[$key]['high'];
$low_new = $graph[$key]['low'];
if($height_old==0){$height_old=$height_new;}
if($low_old==0){$low_old=$low_new;}
// print_r($q2);
// $height_new = rand(0,100);
/*
$dot[1] = array(0,0); // Oben Links // x,y
$dot[2] = array(100,0); // Oben Rechts // x,y
$dot[3] = array(100,100); // Unten Rechts // x,y
$dot[4] = array(0,100); // Unten Links // x,y
$dot1[1] = array(0, high_old)
$dot1[2] = array(colwidth, high_new)
$dot1[3] = array(colwidth, low_new)
$dot1[4] = array(0, low_old)
(($high_old * 100) / $g['row-max']);
(($high_new * 100) / $g['row-max']);
(($low_new * 100) / $g['row-max']);
(($low_old * 100) / $g['row-max']);
*/
$dot[1] = array('x' => 0, 'y' => 100 - floor(($height_old * 100) / $g['row-max']));
$dot[2] = array('x' => floor($g['colwidth']), 'y' => 100 - floor(($height_new * 100) / $g['row-max']));
$dot[3] = array('x' => floor($g['colwidth']), 'y' => 100 - floor(($low_new * 100) / $g['row-max'])+$g['scale_multi']);
$dot[4] = array('x' => 0, 'y' => 100 - floor(($low_old * 100) / $g['row-max'])+$g['scale_multi']);
$sql_table_low_2 = "SELECT newprice*1.19 as fixprice FROM Horn_UPM_Product_Price_Change_History WHERE timestamp_unix < '".$graph[$key]['timestamp']."' AND ean = '".$artikel."' order by id DESC LIMIT 1";
// $content .= $sql_table_low_2;
$q2 = $readConnection->fetchRow($sql_table_low_2);
if(!isset($q2['fixprice']))
{
$fixo_price_new = 0;
$fixo_price_new_scale = 0;
}
else
{
$fixo_price_new = $q2['fixprice'];
$fixo_price_new_scale = 100-floor(($q2['fixprice'] * 100) / $g['row-max']);
}
// $content .= 100 - floor(($height_old * 100) / $g['row-max']).'-';
// $content .= 100 - floor(($height_new * 100) / $g['row-max']).'-';
// $content .= 100 - floor(($low_new * 100) / $g['row-max']).'-';
// $content .= 100 - floor(($low_old * 100) / $g['row-max']).'|||';
// $content .= $dot[1]['y'].'-';
// $content .= $dot[2]['y'].'-';
// $content .= $dot[3]['y'].'-';
// $content .= $dot[4]['y'].'|||';
$height_old=$height_new;
$low_old=$low_new;
$fixo_price_old=$fixo_price_new;
$fixo_price_old_scale=$fixo_price_new_scale;
// print_r($dot);
$content .= '
<div style="position:absolute;left:'.floor($g['colwidth']*($key-1)).'px;width:'.floor($g['colwidth']).'px">
<svg id="svg-'.$row_count.'" class="clip-svg" style="height:200px;">
<rect class="svg-bg-'.$row_count.'" width="'.floor($g['colwidth']).'" height="200" fill="#e6e6ff" />
</svg>
<svg id="svg-defs" style="height:0;">
<defs>
<clipPath id="clip-'.$row_count.'">
<polygon points="'.$dot[1]['x'].' '.$dot[1]['y'].', '.$dot[2]['x'].' '.$dot[2]['y'].', '.$dot[3]['x'].' '.$dot[3]['y'].', '.$dot[4]['x'].' '.$dot[4]['y'].'" />
<!-- <polygon points="0 0, '.$dot[2]['x'].' 0, '.$dot[3]['x'].' '.$dot[3]['y'].', '.$dot[4]['x'].' '.$dot[4]['y'].'" /> -->
</clipPath>
</defs>
</svg>
<style>
.svg-bg-'.$row_count.' { clip-path: url(#clip-'.$row_count.'); }
</style>
<div class="dot_high" style="z-index:1000;position:absolute;top:'.$dot[2]['y'].'px;left:'.($g['colwidth']-$g['dotsize']/1.5).'px;height:'.$g['dotsize'].'px;width:'.$g['dotsize'].'px;background:'.$g['dotcolor_height'].';display:block;"></div>
<div class="dot_low" style="z-index:1000;position:absolute;top:'.($dot[3]['y']-$g['dotsize']/1.5).'px;left:'.($g['colwidth']-$g['dotsize']/1.5).'px;height:'.$g['dotsize'].'px;width:'.$g['dotsize'].'px;background:'.$g['dotcolor_low'].';display:block;"></div>
<div class="dot_fix" style="z-index:1000;position:absolute;top:'.($fixo_price_new_scale-$g['dotsize']/1.5).'px;left:'.($g['colwidth']-$g['dotsize']/1.5).'px;height:'.$g['dotsize'].'px;width:'.$g['dotsize'].'px;background:'.$g['dotcolor_fix'].';display:block;"></div>
</div>';
$row_count++;
}
正如解释的那样,代码有效。但它缩放错误 (100%)..
SVG
这需要大量工作和大量混乱的代码,因此我将草拟出一个建议,告诉您如何解决此问题:
Svg 图
我不会通读你所有的代码,因为我一半都看不懂。
我会告诉你我们如何解决这个问题:
找出单行中的点数
我们将在这个例子中使用 5 个高点和 5 个低点。
$highArray = array(115, 117, 116, 117, 118);
$lowArray = array(113, 114, 114, 115);
现在我假设它必须扩展,因为你有:
$g['maxheight'] = 600
$g['maxwidth'] = 800
为了便于使用,我们称它们为
$maxheight = 600
$maxwidth = 800
我看到有; Linecolor、dotsize 等。这些不言而喻,所以我会像 $linecolor
和 $dotsize
因此我们的 svg 文档将是 600 个单位高和 800 个单位宽。 然后我们可以这样创建文档:
echo '<svg viewBox="0 ,0 '.$maxwidth.','.$maxheight.'" >';
希望您能关注。这是 svg,所以我们不使用像素大小,所以将它们排除在外。 接下来是添加图形:
现在我们需要看看这些点需要去哪里: 1. 我们希望它们均匀分布在整个 svg 上,所以我们将单个数组中的点数与 svg 的大小分开:
$ColumnSize = $maxwidth / $highArray + 1 ;
Example:
800 / 5 = 160
in our example we will use 160 as each column size.
现在让我们用路径和圆元素创建图形:
Circles:
for($i=0; $i<$heightArray.count(); $i++) {
echo '<circle class="circle-high" cx="'.($ColumnSize*i).'" cy="'.($maxheight - $highArray[i]).'" r="'.$dotSize.'" >';
}
//Same for $lowArray
echo '<circle class="circle-low" cx="'.($ColumnSize*n).'" cy="'.($maxheight - $lowArray[n]).'" r="'.$dotSize.'" >';
Path:
$xPath = "M";
for($i=0; $i<$hightArray.count(); $i++) {
$xPath += " ".$ColumnSize*$i.",".($maxheight - $highArray[$i]);
}
for ($j=$lowArray.count(); $j>0; $j--) {
$xPath += " ".$ColumnSize*$j.",".($maxheight - $lowArray[$j-1]);
}
echo '<path class="dotbackground" d="'.$xPath.'z"/>';
并将颜色添加到 css:
.circle-low {
fill: red;
}
.circle-high {
fill: green;
}
.dotbackground {
fill: #ccc;
}
如果你做了所有这些,输出应该是这样的:
/*FOR DISPLAY ONLY*/
svg {
height: 300px;
border: 5px solid black;
}
/*END DISPLAY ONLY */
.circle-high {
fill: red;
}
.circle-low {
fill: green;
}
.dotbackground {
fill: #aaa;
}
<svg viewBox="-5 0 800 600">
<path class="dotbackground" d="M0,375 160,364, 320,374 480,363, 640,352 640,442 480,453 320,464 160,503 0,465z" />
<circle class="circle-high" cx="0" cy="375" r="6" />
<circle class="circle-high" cx="160" cy="363" r="6" />
<circle class="circle-high" cx="320" cy="374" r="6" />
<circle class="circle-high" cx="480" cy="363" r="6" />
<circle class="circle-high" cx="640" cy="352" r="6" />
<circle class="circle-low" cx="0" cy="465" r="6" />
<circle class="circle-low" cx="160" cy="503" r="6" />
<circle class="circle-low" cx="320" cy="464" r="6" />
<circle class="circle-low" cx="480" cy="453" r="6" />
<circle class="circle-low" cx="640" cy="442" r="6" />
</svg>
您可以考虑的附加功能:
- 找到两个数组中的最低值和最高值,然后缩放它们在高度上的响应显示方式。
- 通过 class 向 svg 文档添加 max-height: 和 max-width 并在 ccs 中设置样式