数组到 SVG,使用 PHP 的灵活算法

2023-12-06

问题: 我有几个不同的数组 - 例如:

  • [0.21、0.001、0.0245、0.31、0.05、...]

  • [1234、1342、1232、1625、2200、2205、1804、...]

  • [5, 12, 42, 2, 32, 42, ...]

my problem now is: I'm looking for an algorithm to calculate a SVG Path for a simple chart like: enter image description here

我当前的问题是通用算法和每个 SVG 的视图框的计算。

目前我已经存储了一个示例,例如:

{
  "path": ".....",
  "min_value": 2, // min. value of array
  "max_value": 31, // max. value of array
  "raw_data": [2, 3, 3, 5, 25, 31],
}

编辑: 现在我添加了动态步骤计算,例如:$step = (($width/$height) * (max($points)-min($points)))/count($points);

所以当前的代码如下所示:

$width=200;
$height=50;
$paths = '';
$i= 0;
$j = 0;
$step = (($width/$height) * (max($points)-
min($points)))/count($points);
foreach($points as $point) {
    if($j == 0) {
        $paths = 'M 0 '.$point;
    }
     else if($j == 1) {
        $paths .= ' L '.$i.' '.$point;
     }
     else {
        $paths .= ' '.$i.' '.$point;
     }
     $i+=$step;
     $j++;
 }
 $viewbox = '0 0 '.(count($points)+1).' '.(max($points)+1);

now it looks much better - but still have the following problem: small values (all < 1.0) and stroke-width=1px: enter image description here

<svg width="200" height="50" viewBox="0 0 31 1.99" style="background-color: white;">
        <path fill="none" stroke="blue" stroke-width="1px" d="M 0 0.91 L 0.12333333333333 0.16 0.24666666666667 0.285 0.37 0.845 0.49333333333333 0.87 0.61666666666667 0.14 0.74 0.935 0.86333333333333 0.955 0.98666666666667 0.51 1.11 0.855 1.2333333333333 0.41 1.3566666666667 0.97 1.48 0.115 1.6033333333333 0.095 1.7266666666667 0.885 1.85 0.49 1.9733333333333 0.83 2.0966666666667 0.115 2.22 0.555 2.3433333333333 0.99 2.4666666666667 0.23 2.59 0.21 2.7133333333333 0.14 2.8366666666667 0.265 2.96 0.435 3.0833333333333 0.11 3.2066666666667 0.485 3.33 0.725 3.4533333333333 0.48 3.5766666666667 0.065"/>
    </svg>

big values (all >1000.0) and stroke-width=100px: enter image description here

<svg width="200" height="50" viewBox="0 0 31 4797.885" style="background-color: white;">
        <path fill="none" stroke="blue" stroke-width="1px" d="M 0 3401.91 L 185.99666666667 3515.16 371.99333333333 4007.285 557.99 4149.845 743.98666666667 4141.87 929.98333333333 4176.14 1115.98 4227.935 1301.9766666667 4416.955 1487.9733333333 4594.51 1673.97 4486.855 1859.9666666667 4302.41 2045.9633333333 4413.97 2231.96 4584.115 2417.9566666667 4740.095 2603.9533333333 4796.885 2789.95 4629.49 2975.9466666667 4567.83 3161.9433333333 4484.115 3347.94 4383.555 3533.9366666667 4363.99 3719.9333333333 4362.23 3905.93 4352.21 4091.9266666667 4236.14 4277.9233333333 4120.265 4463.92 4049.435 4649.9166666667 4046.11 4835.9133333333 4138.485 5021.91 4165.725 5207.9066666667 4242.48 5393.9033333333 4358.065"/>
    </svg>

所有图表应使用 100% 的宽度和高度空间,并具有相同的笔划宽度。


生成有什么难的SVG小路 ?这里的例子SVG:

<svg width="512" height="512" viewBox="-3.775377 -42.30107 144.356959 147.801089" >
 <path fill="none" stroke="blue" stroke-width="1px" transform="matrix(1,0,0,1,0,0)" d="M 70 30 q 0.466506 0.468696 1.055021 -0.160683 q 0.529113 -0.764957 -0.278312 -1.82735 q -0.968481 -1.043055 -2.776709 -0.511966 q -1.848076 0.710151 -2.220084 3.142734 q -0.198986 2.550856 2.278312 4.32735 q 2.680178 1.650105 5.941772 0.029915 q 3.229646 -1.888998 3.385148 -6.124785 q -0.13114 -4.336754 -4.278312 -6.82735 q -4.391875 -2.257156 -9.106836 0.452135 q -4.611215 3.067846 -4.550211 9.106836 q 0.461267 6.122652 6.278312 9.32735 q 6.103572 2.864207 12.2719 -0.934186 q 5.992785 -4.246694 5.715275 -12.088886 q -0.791394 -7.908551 -8.278312 -11.82735 q -7.815269 -3.471258 -15.436963 1.416237 q -7.374355 5.425541 -6.880338 15.070937 q 1.121521 9.694449 10.278312 14.32735 q 9.526965 4.078309 18.602026 -1.898287 q 8.755925 -6.604389 8.045402 -18.052988 q -1.451648 -11.480347 -12.278312 -16.82735 q -11.238662 -4.685359 -21.76709 2.380338 q -10.137495 7.783236 -9.210465 21.035039 q 1.781775 13.266246 14.278312 19.32735 q 12.950359 5.29241 24.932153 -2.862389 q 11.519065 -8.962084 10.375529 -24.01709 q -2.111902 -15.052144 -16.278312 -21.82735 q -14.662056 -5.899461 -28.097217 3.34444 q -12.900635 10.140931 -11.540592 26.99914 q 2.442029 16.838043 18.278312 24.32735 q 16.373753 6.506512 31.26228 -3.826491 q 14.282204 -11.319779 12.705656 -29.981191 q -2.772156 -18.623941 -20.278312 -26.82735 q -18.08545 -7.113563 -34.427344 4.308541 q -15.663774 12.498627 -13.870719 32.963242 q 3.102283 20.409839 22.278312 29.32735 q 19.797147 7.720613 37.592407 -4.790592 q 17.045344 -13.677474 15.035783 -35.945293 q -3.43241 -22.195738 -24.278312 -31.82735 q -21.508844 -8.327664 -40.757471 5.272643 q -18.426914 14.856322 -16.200846 38.927344 q 3.762537 23.981636 26.278312 34.32735 q 23.22054 8.934715 42.922534 -5.754694 q 19.808484 -16.035169 17.36591 -41.909394 q -4.092664 -25.767535 -28.278312 -36.82735 q -24.932237 -9.541766 -47.087598 6.236745 q -21.190054 17.214017 -18.530973 44.891445 q 4.422791 27.553433 30.278312 39.32735 q 26.643934 10.148817 50.252661 -6.718795 q 22.571624 -18.392864 19.696037 -47.873496 q -4.752918 -29.339331 -32.278312 -41.82735 q -28.355631 -10.755867 -53.417725 7.200846 q -23.953193 19.571712 -20.8611 50.855547 q 5.083045 31.12523 34.278312 44.32735 q 30.067328 11.362918 56.582788 -7.682897 q 25.334763 -20.75056 22.026164 -53.837598 q -5.413172 -32.911128 -36.278312 -46.82735 q -31.779025 -11.969969 -59.747852 8.164948 q -26.716333 21.929407 -23.191227 56.819648 q 5.7433 34.697026 38.278312 49.32735 q 33.490722 12.57702 62.912915 -8.647 "/>
</svg>

因此,对标题和标签进行硬编码...然后创建d=""包括您的路径点的部分...从命令开始M移动然后剩下的就用L(行至,您不需要重复 L 命令,直到使用不同的命令)。大写字母表示绝对坐标,小写字母表示相对坐标。这里预览:

preview

有关路径命令用法,请参阅 SVG 规范...如果您的数据包含 x,y 点,那么它将是这样的:

d="M x0,y0 L x1 y1 x2 y2 x3 y3 ... xn yn"

因此,只需创建 php 脚本,从数组中生成此类内容。

重要的部分是定义浏览器视图的 viewBox 和 view。如果设置不正确或根本没有设置,某些浏览器将不会呈现您的SVG适当地。

使用您的示例数组和 x-step = 1 我得到:

x = { 0,1,2,3, 4, 5 }
y = { 2,3,3,5,25,31 }

所以让我们使用x=<-1,+6> and y=<1,32>作为视图框(最小最大+一些边框):

<svg width="512" height="512" viewBox="-1 1 6 32" >
     <path fill="none" stroke="blue" stroke-width="1px" transform="matrix(1,0,0,1,0,0)" d="M 0 2 L 1 3 2 3 3 5 4 25 5 31"/>
    </svg>

preview

正如您所看到的,Y 轴向下,您可以调整 y 位置或使用矩阵......

[Edit2] 我为此创建了 C++/VCL 脚本(按承诺)

    {
    int xs=512,ys=256;  // view resolution
    float x0,x1,y0,y1;  // data bbox
    float x,dx,px;
    AnsiString svg;
    float data[]={ 3401.91, 3515.16, 4007.285, 4149.845, 4141.87, 4176.14, 4227.935, 4416.955, 4594.51, 4486.855, 4302.41, 4413.97, 4584.115, 4740.095, 4796.885, 4629.49, 4567.83, 4484.115, 4383.555, 4363.99, 4362.23, 4352.21, 4236.14, 4120.265, 4049.435, 4046.11, 4138.485, 4165.725, 4242.48, 4358.065 };
//  float data[]={ 0.21, 0.001, 0.0245, 0.31, 0.05 };
//  float data[]={ 1234, 1342, 1232, 1625, 2200, 2205, 1804 };
//  float data[]={ 5, 12, 42, 2, 32, 42 };
    int i,n=sizeof(data)/(sizeof(data[0]));

    y0=data[0]; y1=y0;
    for (i=0;i<n;i++)
        {
        if (y0>data[i]) y0=data[i];
        if (y1<data[i]) y1=data[i];
        }
    x0=0.0; x1=x0+((y1-y0)*float(xs)/float(ys));
    dx=(x1-x0)/float(n);
    px=(x1-x0)/float(xs);

    svg="<svg width=\""+AnsiString(xs)+"\" height=\""+AnsiString(ys)+"\""
       +" viewBox=\""+AnsiString(x0)+" "+AnsiString(y0)+" "+AnsiString(x1-x0)+" "+AnsiString(y1-y0)+"\">\r\n"
       +" <path fill=\"none\" stroke=\"black\" stroke-width=\""+AnsiString(px)+"px\" transform=\"matrix(1,0,0,1,0,0\" d=\"M "+AnsiString(x0)+" "+AnsiString(y0)+" L";
    for (x=x0+dx,i=0;i<n;i++,x+=dx)
        {
        svg+=" "+AnsiString(x)+" "+AnsiString(data[i]);
        if ((i&3)==3) svg+="\r\n ";
        }
    svg+="\"/>\r\n";
    svg+="</svg>\r\n";

    Memo1->Text=svg;
    i=FileCreate("test.svg");
    FileWrite(i,svg.c_str(),svg.Length());
    FileClose(i);
    }

这里输出:

<svg width="512" height="256" viewBox="0 3401.90991210938 2789.94970703125 1394.97485351563">
 <path fill="none" stroke="black" stroke-width="5.44912052154541px" transform="matrix(1,0,0,1,0,0" d="M 0 3401.90991210938 L 92.9983215332031 3401.90991210938 185.996643066406 3515.15991210938 278.994964599609 4007.28491210938 371.993286132813 4149.84521484375
  464.991607666016 4141.8701171875 557.989929199219 4176.14013671875 650.98828125 4227.93505859375 743.986572265625 4416.955078125
  836.98486328125 4594.509765625 929.983154296875 4486.85498046875 1022.9814453125 4302.41015625 1115.97973632813 4413.97021484375
  1208.97802734375 4584.115234375 1301.97631835938 4740.09521484375 1394.974609375 4796.884765625 1487.97290039063 4629.490234375
  1580.97119140625 4567.830078125 1673.96948242188 4484.115234375 1766.9677734375 4383.55517578125 1859.96606445313 4363.990234375
  1952.96435546875 4362.22998046875 2045.96264648438 4352.2099609375 2138.9609375 4236.14013671875 2231.95922851563 4120.26513671875
  2324.95751953125 4049.43505859375 2417.95581054688 4046.11010742188 2510.9541015625 4138.48486328125 2603.95239257813 4165.72509765625
  2696.95068359375 4242.47998046875 2789.94897460938 4358.06494140625"/>
</svg>

preview

你忘记了transform并且你还需要设置描边宽度px适当地。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数组到 SVG,使用 PHP 的灵活算法 的相关文章

  • 枚举 PHP DOMDocument 对象的已注册命名空间

    对于我的一个项目 我正在使用DOMDocument类来加载和操作 XML 文档 我需要检索文档中使用的每个名称空间 但是 我找不到如何做到这一点 这DOMDocument类具有获取 URI 的命名空间前缀或命名空间前缀的 URI 的方法 但
  • 尝试使用 swift mailer、gmail smtp、php 发送邮件

    这是我的代码
  • C:将 unsigned char 数组转换为signed int(反之亦然)

    我正在尝试将无符号字符数组缓冲区转换为有符号整数 反之亦然 下面是演示代码 int main int argv char argc int original 1054 unsigned int i 1054 unsigned char c
  • {{ Auth::user()->name }} 如何在 Blade 文件中打印用户名?

    我一直在 laravel 中使用默认身份验证功能 我在一个刀片文件中发现 Auth user gt name 能够显示存储在用户表中的名称 但我想知道的是它是如何显示的用雄辩的口号在刀锋中呼唤名字 你可以像这样使用它 auth gt use
  • 如何从 PHP 输出 XML 字符串

    我正在获取一个 XML 字符串并在 PHP 中对其进行编辑 以便在访问 PHP 文件时最终输出编辑后的 XML 字符串 我一直在尝试使用 echo 和 print 来输出 XML 文档 但它只打印最里面标签内的数据 我希望它的功能就像直接加
  • PHP:将字符串分成 8 个块,我该怎么做?

    我基本上有二进制 假设它的长度是300 我如何将它分割 就像使用爆炸一样 成 8 位块 我查看了 chunk split 但它似乎只有一个 end 参数 而不是将其放入数组的选项 或者它可以插入数组吗 末尾 8 位数字可以低于 8 如果有人
  • PHP 选择后立即删除

    我有一个 PHP 服务器脚本 它从 MySQL 数据库中选择一些数据 一旦我将 mysql query 和 mysql fetch assoc 的结果存储在我自己的局部变量中 我就想删除我刚刚选择的行 这种方法的问题在于 PHP 似乎对我的
  • php simpleXMLElement 到数组:空值

    我有以下 XML
  • 如何使用 PHP SDK 在 AWS SES 发送的电子邮件中实现 List-Unsubscribe 标头

    我尝试使用 AWS PHP SDK 添加自定义标头 以便可以实现 List unsubscribe 标头 问题是我找不到任何地方如何实现它 我已阅读文档但什么也没有 http docs aws amazon com aws sdk php
  • 为什么我的函数将布尔值更改为“on”?

    所以我是 php 编程世界的新手 我正在在线学习和其他形式等 但我找不到任何东西来帮助回答我的问题 这就是我在这里的原因 任何帮助当然不胜感激 谢谢 我想将下面的代码变成我可以调用的函数 它的工作原理如下所示 如果我选中表单中的复选框 它会
  • Codeigniter:重置表单值

    在我看来 我想要做的是在用户成功注册后清除表单字段 这里一切正常 即用户正在注册 成功消息正在向用户显示 除了我想要做的是清除表单字段的值 我正在使用这个 Clear the form validation field data so th
  • 比较表中的行以了解字段之间的差异

    我有一个包含 20 多列的表 客户端 其中大部分是历史数据 就像是 id clientID field1 field2 etc updateDate 如果我的数据如下所示 10 12 A A 2009 03 01 11 12 A B 200
  • Symfony2 Twig 扩展

    我在实现树枝扩展时遇到一些问题 我需要创建自己的过滤器 子过滤器 所以我想到了使用twig扩展 我在 MyApp Bundle WebsiteBundle 和文件上创建了一个名为 Extension 的文件夹 网站扩展 php namesp
  • “包含字符串”的快速索引

    在我的应用程序中 我有多达数百万个短字符串 大部分短于 32 个字符 我想实现一个带有附加列表的搜索框 该列表仅包含包含在搜索框中输入的整个字符串的元素 如何预先建立索引来快速找到此类字符串 所有排序的 STL 容器都会检查整个字符串 对于
  • 如何使用CSS将背景图像放入选择选项标签中

    我有一个从 json 响应接收的国家 地区下拉列表 并且想要在国家 地区名称旁边添加相应的国家 地区国旗图标 也从 json 响应获取图像 我已经尝试了不同的 jQuery 和 bootstrap 插件 但他们所做的是破坏我以前的选择框样式
  • 是否有一种算法可以在线性时间内计算数组反转?

    我知道有多少倒转 en wikipedia org wiki Inversion 28discrete mathematics 29 in an n 元素数组可以在 O n log n 操作使用增强型归并排序 http www geeksf
  • PHP - Filter_var 替代方案?

    我构建了一个 php 脚本来输出以表单形式发布的数据 但遇到了问题 网站将运行的服务器运行 PHP 5 1 6 此版本的 PHP 不支持 filter var 我需要知道短期内的替代方案 最好是昨天 但在 Google 或 Stack Ov
  • 如何在 C# 中以编程方式创建柔和的颜色?

    根据所需的颜色数量均匀分布地生成它们 如果指定的计数为 8 则看起来像这样 List
  • 使用 php 获取当前月份的最后 3 个月

    我想获取当前月份最近 3 个月的名称 例如当前月份是八月 所以 我想要六月 七月 八月这样的数据 我已经尝试过这段代码echo date F strtotime 3 months 它只返回六月 如何使用 php 获取当前月份的最后 3 个月
  • 通过 __get() 通过引用返回 null

    快速规格 PHP 5 3 error reporting 1 the highest 我正在使用 get 通过引用技巧神奇地访问对象中任意深度的数组元素 快速示例 public function get key return isset t

随机推荐

  • 无法读取未定义 vue 的属性“post”

    感谢您阅读我的问题 我已阅读有关我的问题的信息 VUE JS 2 WEBPACK 无法读取未定义 VUE 资源的属性 get 但我的系统没有读取 Vue var 我有一个 vue 组件调用 app vue 我需要使用 vue resourc
  • 如何获取大 LinkedIn 图片共享格式

    我正在使用 linkedin api 在 linkedin 上分享帖子 如下所示 How to get make post like this through api 我正在尝试帖子正文的所有组合 但无法发布如上所述的内容 comment
  • 在 Ionic 4 应用程序中进行的 API 调用无法在 Android 设备上运行

    我可以使用以下命令在笔记本电脑上运行我的离子应用程序ionic lab命令 该应用程序调用 IMDB api 并显示从中检索到的数据 现在 我正在尝试在 Android 设备上运行该应用程序 使用以下命令 ionic cordova run
  • macOS Mojave 版本 10.14.1 bash-3.2 expr:语法错误

    我遇到这样的错误 expr syntax error 我的脚本是 bin bash echo expr index sarasara a 如何修复它 man expr最后给出这个 根据 POSIX 标准 使用字符串参数length subs
  • 我可以使用 allocate 来复制对象的对象吗?

    我有一个从 TPersistent 三级继承的对象 我想使用Assign程序 MyFirstObj GrandSonOfPersistent Create I modify the objects inside MyFirstObj MyS
  • 如何使用GridBagConstraints创建布局?

    我想像这样布局我的 JPane 这样 顶部部分比底部部分更大 更高 顶部部分由另一个 JPanel 组成 并使用 Graphics 对象来显示图像 而底部部分也由另一个 JPanel 组成 但使用 Graphics 对象来绘制一些线条和文字
  • sqlite是否缓存查询结果以进行优化?

    我在 sqlite 中注意到了这种行为 当我重新使用游标对象时 任务管理器中的工作集内存不断增加 直到我的程序抛出内存不足异常 我重构了代码 以便每次查询时我都会打开一个到 sqlite 文件的连接 查询我想要的内容 然后关闭连接 后者似乎
  • 如何从 Wix 安装程序将自签名 SSL 证书安装到商店中?

    我找不到任何有关如何针对当前版本的 Wix Toolset 3 11 1 2318 执行此操作的文档 鉴于我有一个cert cer文件在我的SourceDir and INSTALLDIR如何在安装时将其放入 Windows 受信任的根证书
  • 无法读取 dotnet core 中链接的 appsettings.json 文件中的值

    在一个 aspnetcore 2 0 项目中 我尝试在我的 Web 应用程序和几个 xunit 测试项目中设置一个共享的 appsettings json 文件 首先 当我 定期 将 appsettings json 单独添加到我的项目中时
  • 定期 JobScheduler 不尊重约束

    使用JobScheduler 我设置了一个简单的JobService如下 TargetApi 21 public class SimpleJobService extends JobService private static final
  • wxpython菜单栏不显示

    我正在尝试使用 wxpython for gui 编写一个时间表程序 并使用 wxpython wiki 上的入门教程来加快 wxpython 的速度 但是当我尝试向 wxFrame 添加菜单栏时 菜单栏不显示 有什么想法为什么会发生这种情
  • 如何在 Intel 环形和网状架构上选择引导处理器 (BSP)

    第2 13 2节提到仲裁 ID 用于确定哪个处理器首先发出无操作周期 我在多个来源和英特尔手册上看到了这一点 引用 MP 初始化序列的英特尔手册仅在存在 系统总线 时以及在此之前最初存在 APIC 总线 时解决 Pentium 4 我的印象
  • 在 iOS (Flutter) 中使用 Firebase 和 Geolocator(或任何 Swift 插件)构建错误

    我正在尝试创建一个使用 Firebase 和 Geolocator 插件的 flutter 应用程序 我将使用的 Firebase 插件认证 使用RTDB and FCM The 地理定位器显然是一个非常可靠的位置感知插件 在 Androi
  • 如何在 Windows 上通过内置命令使用 subprocess.Popen

    在我的旧 python 脚本中 我使用以下代码来显示 Windows cmd 命令的结果 print os popen dir c read 正如 python 2 7 文档所说os popen已经过时并且subprocess被推荐 我按照
  • 实例成员“view”不能在类型“GameScene”上使用

    我最近更新到 Xcode 7 Beta 现在收到一条错误消息 实例成员 视图 无法在第 5 行的 GameScene 类型上使用 有人知道如何解决此问题吗 另外 如果您想提供额外帮助 请参阅我的另一个问题 ConvertPointToVie
  • 在智能卡上上传 .cap 文件?

    我有一张新卡 其 ATR 代码如下 3B 68 00 00 00 73 C8 40 12 00 90 00 我在谷歌上搜索了这张ATR 最后我知道这是一张 巴西电子公积金卡 问题是我该如何使用这张卡 我的意思是它支持哪些 APDU 有它的数
  • PHP - 使用表单输入中的 id 制作 switch 语句

    我正在用 PHP 做一个简短的测验 根据 4 个是 否问题告诉你你想到的生物是什么 我这样做是为了根据您对每个问题的回答 您会遇到不同的问题 我主要使用 switch 语句来完成此操作 我的问题是有什么方法可以使用条件作为表单提交按钮的 i
  • Flutter 蓝牙热敏打印机集成

    我有一个 flutter 食品配送应用程序 除此之外 我还有一个单独的餐厅应用程序 我可以在其中接受和拒绝订单 我很长一段时间以来一直在尝试做一些事情 以便当餐厅接受订单时 蓝牙热敏打印机会自动打印出一张收据 我找到了很多代码 但我不明白如
  • Powershell:将 pracl 命令的输出通过管道传输到数组

    pracl 是一个 sysinternal 命令 可用于列出目录的 ACL 我有一个共享列表 我想创建一个 csv 文件 这样对于每个 ACL 条目 我希望共享路径位于一列中 共享权限位于下一列中 我试图通过使用以下代码来做到这一点 inp
  • 数组到 SVG,使用 PHP 的灵活算法

    问题 我有几个不同的数组 例如 0 21 0 001 0 0245 0 31 0 05 1234 1342 1232 1625 2200 2205 1804 5 12 42 2 32 42 my problem now is I m loo