记录一次曲折的需求完成

2023-10-31 18:20

本文主要是介绍记录一次曲折的需求完成,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

需求:

将WPF程序中一段调用Cgal编译的dll的treemap算法 改成 调用d3.js中的packing Circle算法

重要程度

⭐⭐⭐⭐

人物性格:

非常懒

时限

10小时

思路

一.将d3.js打包成dll,然后WPF调用(因为C#中有现成的调用dll代码,因此修改的非常少)

a) 尝试JScript.NET

在VS开发人员命令行中输入

 jsc /t:library d3.js

报错

D://1.js(2,323) : error JS1160: 特性列表不适用于当前上下文
D://1.js(2,334) : error JS1193: 应为“,”或“)”
D://1.js(2,449) : error JS1018: “return”语句在函数范围外
D://1.js(2,479) : error JS1195: 应为表达式
D://1.js(2,513) : error JS1195: 应为表达式
D://1.js(2,527) : error JS1004: 应为“;”
D://1.js(2,543) : error JS1004: 应为“;”
D://1.js(2,552) : error JS1010: 应为标识符
D://1.js(2,661) : error JS1195: 应为表达式
D://1.js(2,676) : error JS1010: 应为标识符
D://1.js(2,677) : warning JS1111: 已经定义了“t”
D://1.js(2,780) : error JS1002: 语法错误
D://1.js(2,825) : error JS1111: 已经定义了“i”
D://1.js(2,881) : error JS1160: 特性列表不适用于当前上下文
D://1.js(2,911) : error JS1004: 应为“;”
D://1.js(2,913) : error JS1004: 应为“;”
D://1.js(2,916) : error JS1006: 应为“)”
D://1.js(2,917) : error JS1004: 应为“;”
D://1.js(2,947) : error JS1160: 特性列表不适用于当前上下文
D://1.js(2,964) : error JS1004: 应为“;”
D://1.js(2,966) : error JS1004: 应为“;”
D://1.js(2,969) : error JS1006: 应为“)”
D://1.js(2,970) : error JS1004: 应为“;”
D://1.js(2,978) : error JS1197: 错误太多。该文件可能不是 JScript 文件

放弃

二.WPF直接调用js代码

a) 尝试MSScriptControl.ScriptControl

//string _MD5_js = "MD5.js";private object ExecuteScript(string funcName, string argument, string jsPath){string js = System.IO.File.ReadAllText(jsPath);object o = ExecuteScript(string.Format("{0}('{1}')", funcName, argument), js);return o;}/// <summary>/// 执行JS/// </summary>/// <param name="sExpression">参数体</param>/// <param name="sCode">JavaScript代码的字符串</param>/// <returns></returns>private object ExecuteScript(string sExpression, string sCode){MSScriptControl.ScriptControl scriptControl = new MSScriptControl.ScriptControl();scriptControl.UseSafeSubset = true;scriptControl.Language = "JScript";scriptControl.AddCode(sCode);try{return scriptControl.Eval(sExpression);}catch (Exception ex){}return null;}

报错
在这里插入图片描述
放弃

三.Asp.net后台调用js代码,然后WPF通过post获取数据(因为Asp.net有现成的post函数)

a) 尝试ValuesController.cs中在Post函数中调用JS代码

在这里插入图片描述
对MVC不是特别熟,没有余力去思考ValuesController对应的view在哪儿了
放弃

四.直接写一个post服务器,然后WPF通过post获取数据

服务器

// postserver.js
// 获取客户端post来的title、text参数,然后返回给客户端var http = require('http');
var querystring = require('querystring');var server = http.createServer(function(req, res) {var post = '';req.on('data', function(chunk) {post += chunk;});req.on('end', function() {post = querystring.parse(post);res.write(post.title);res.write(post.text);res.end();});
}).listen(3000);

在控制台中执行node server.js,开启http服务,监听3000端口。

客户端

var http = require('http');
var querystring = require('querystring');var contents = querystring.stringify({title: 'Hello ',text: 'Arthur',
});var options = {host: '127.0.0.1',port: '3000',  //非80端口需要指定,如果是80端口则可以省略。path: '/',headers: {'Content-Type': 'application/x-www-form-urlencoded','Content-Length': contents.length}
};var req = http.request(options, function(res) {res.setEncoding('utf8');res.on('data', function(data) {console.log('request begin:');console.log(data);console.log('request end.');console.log('--------------------');});
});req.write(contents);
req.end();

在另一个控制台中执行node client.js

a) 安装Nodejs

b) 写一个简单的post服务器和客户端测试

在这里插入图片描述
成功

c) 在post服务器中调用d3.js

var d3 = require("./d3.js");

报错

ReferenceError: XMLHttpRequest is not definedat nu (C:\Users\lunhui\Desktop\d3.js:2:63462)at Object.json (C:\Users\lunhui\Desktop\d3.js:2:65084)at d33 (C:\Users\lunhui\Desktop\test.js:41:8)at IncomingMessage.<anonymous> (C:\Users\lunhui\Desktop\test.js:21:18)
[90m    at IncomingMessage.emit (node:events:406:35)[39m
[90m    at endReadableNT (node:internal/streams/readable:1329:12)[39m
[90m    at processTicksAndRejections (node:internal/process/task_queues:83:21)[39m
α)尝试1:

原因:xmlhttprequest 不是Node 内置的,需要单独安装:
安装命令:npm install xmlhttprequest

失败

β)尝试2:

搜索nodejs调用d3.js
报错
在这里插入图片描述
安装express

npm install express

然后不报错了,但是脚本也没用
失败

γ)尝试3:

找到一份代码node.js中用d3.js

npm install d3

报错
在这里插入图片描述
尝试解决方案1
Check for 2 things:

Node version >= 14. It only works with latest version of node.
Make sure your package.json includes a line for “type”: “module”, Without this line node assumes you want to use Common JS modules rather than ESM.

报错
在这里插入图片描述
尝试解决方案2
在你要require的代码前引入如下代码即可:

import { createRequire } from 'module';
const require = createRequire(import.meta.url);

报错
在这里插入图片描述
尝试解决方案3
在 Node.js 中使用 import
Node 版本需在 9.0 及以上
不加 loader 时候,使用 import/export 的文件后缀名必须为 .mjs

import d3 from 'd3'

在这里插入图片描述
修改为

import * as d3 from 'd3';

其他的require也都要改成这个亚子
成功!

d) 尝试连接
报错

ReferenceError: fetch is not defined

在node_module/d3_fectch/src/json.js开头添加以下两句

import { fetch as fetchPolyfill } from 'whatwg-fetch'
global.fetch = fetchPolyfill

报错
在这里插入图片描述
把var转换成字符串

报错
在这里插入图片描述
node_modules\whatwg-fetch\dist\fetch.umd.js
添加

 import * as XMLHttpRequest from 'xmlhttprequest';

报错
在这里插入图片描述
这是个终极大错!
退无可退!
放弃不了了!
现在已经22点.明天记续

给明天留个希望: d3.json()和d3.csv()出了问题,也就是读取文件出了问题

五.中期总结

我好像没有时间详细记录问题和解决方案了,只能草草描述.

果然是读取文件出了问题
换成了fs.readFileSync就再也没有报错了
然而接下来的第二天时间却浪费在了d3.js的返回数据格式上

这件事给我的教训是 一定要先去看说明文档,不要自己想当然的测试
https://observablehq.com/@d3/d3-hierarchy1

第三天的时间浪费在了fs.readFileSync之后没有转化成Json格式.

var root = JSON.parse(fs.readFileSync('./flare-2.json', 'utf8'));

成功输出正确格式的root;
终于,马上要成功了.

然而好像并没有那个简单,除了根节点的x,y被计算出来,其他的所有属性都没有记录.

六.神奇的转折-C#

结果在github找到一个C#的circle packing程序
Circle Packing Algorithm for C# (in a Windows Universal project)
兜兜转转又回到最初的起点

正在下载相关组件,测试是否work
发现Visual Studio 2017 和Visual Studio 2019 都打不开UWP项目
期间测试了一波下载Visual Studio 2015
失败

Visual Studio 2019 加载UWP项目
失败

于是直接从源代码里摘出来放到WPF项目中,然而,发现并不是自己需要的效果
失败
在这里插入图片描述

七.重回Html

又回到Github,找到了Html
Github:balakrishna-k/CirclePack
这个能运行
在这里插入图片描述
并且可以获取到数据的返回值,很是成功.

var circle = g.selectAll("circle").data(nodes).enter().append("circle").attr("class", function(d) { return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root"; });alert(circle._groups[0][0].__data__.x);

八.Html的Socket通信

html的websocket与我已有的C#的TCP socket连接失败
Websocket错误:ERR_INVALID_HTTP_RESPONSE
原因是:
在这里插入图片描述
因此实现了一个C#的WebSocket的服务器,连接成功.

最终我的伞兵架构为下图:
在这里插入图片描述
1.把服务端放在服务器而不是本地上是因为快速解决跨域问题(后来放弃了,因为外网IP的问题,最后放在了本地IIS服务器上)
2.写两个socket是因为WPF和服务端的Tcp socket是现成的,最简单的修改是直接websocket与tcp socket之间互传字符串

九.最终调试

在这里插入图片描述
经过了几个小bug,最终三个程序联调成功.(C#服务器调用UI组件一定要用Dispatcher.BeginInvoke,否则会出各种奇怪的bug)

剩下的就是规范数据传输格式,封装函数等工作了.

十.总结

看似初衷是为了省事,实则花费了更多时间和精力.
究竟是变通了,不撞南墙了?还是浮躁了,静不下来了呢?

十一.番外

如同之前很多次一样,在一切都结束的时候,我才突然意识到,d3.js中的packing Circle算法不能计算非矩形内的packing circle.
因此,这些工作好像都没有用上.
之前是想得太多,做的太少.现在是想的太少,直接去莽.
都是教训

这篇关于记录一次曲折的需求完成的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/317241

相关文章

Node.js学习记录(二)

目录 一、express 1、初识express 2、安装express 3、创建并启动web服务器 4、监听 GET&POST 请求、响应内容给客户端 5、获取URL中携带的查询参数 6、获取URL中动态参数 7、静态资源托管 二、工具nodemon 三、express路由 1、express中路由 2、路由的匹配 3、路由模块化 4、路由模块添加前缀 四、中间件

Java 后端接口入参 - 联合前端VUE 使用AES完成入参出参加密解密

加密效果: 解密后的数据就是正常数据: 后端:使用的是spring-cloud框架,在gateway模块进行操作 <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>30.0-jre</version></dependency> 编写一个AES加密

记录每次更新到仓库 —— Git 学习笔记 10

记录每次更新到仓库 文章目录 文件的状态三个区域检查当前文件状态跟踪新文件取消跟踪(un-tracking)文件重新跟踪(re-tracking)文件暂存已修改文件忽略某些文件查看已暂存和未暂存的修改提交更新跳过暂存区删除文件移动文件参考资料 咱们接着很多天以前的 取得Git仓库 这篇文章继续说。 文件的状态 不管是通过哪种方法,现在我们已经有了一个仓库,并从这个仓

学习记录:js算法(二十八):删除排序链表中的重复元素、删除排序链表中的重复元素II

文章目录 删除排序链表中的重复元素我的思路解法一:循环解法二:递归 网上思路 删除排序链表中的重复元素 II我的思路网上思路 总结 删除排序链表中的重复元素 给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。 图一 图二 示例 1:(图一)输入:head = [1,1,2]输出:[1,2]示例 2:(图

perl的学习记录——仿真regression

1 记录的背景 之前只知道有这个强大语言的存在,但一直侥幸自己应该不会用到它,所以一直没有开始学习。然而人生这么长,怎就确定自己不会用到呢? 这次要搭建一个可以自动跑完所有case并且打印每个case的pass信息到指定的文件中。从而减轻手动跑仿真,手动查看log信息的重复无效低质量的操作。下面简单记录下自己的思路并贴出自己的代码,方便自己以后使用和修正。 2 思路整理 作为一个IC d

(function() {})();只执行一次

测试例子: var xx = (function() {     (function() { alert(9) })(); alert(10)     return "yyyy";  })(); 调用: alert(xx); 在调用的时候,你会发现只弹出"yyyy"信息,并不见弹出"10"的信息!这也就是说,这个匿名函数只在立即调用的时候执行一次,这时它已经赋予了给xx变量,也就是只是

SSM项目使用AOP技术进行日志记录

本步骤只记录完成切面所需的必要代码 本人开发中遇到的问题: 切面一直切不进去,最后发现需要在springMVC的核心配置文件中中开启注解驱动才可以,只在spring的核心配置文件中开启是不会在web项目中生效的。 之后按照下面的代码进行配置,然后前端在访问controller层中的路径时即可观察到日志已经被正常记录到数据库,代码中有部分注释,看不懂的可以参照注释。接下来进入正题 1、导入m

flume系列之:记录一次flume agent进程被异常oom kill -9的原因定位

flume系列之:记录一次flume agent进程被异常oom kill -9的原因定位 一、背景二、定位问题三、解决方法 一、背景 flume系列之:定位flume没有关闭某个时间点生成的tmp文件的原因,并制定解决方案在博主上面这篇文章的基础上,在机器内存、cpu资源、flume agent资源都足够的情况下,flume agent又出现了tmp文件无法关闭的情况 二、

Linux常用工具与命令日常记录(长期更新)

Linux常用工具与命令日常记录(长期更新) 目录 1.本地复制到远程2.Linux压缩拆包与解压3.生成随机密码4.ubuntu默认Python版本设置5.计算当前文件夹中文件数量6.windows中编写shell脚本,在Linux运行出错7.history 历史命令显示时间用户8.Ubuntu18.04设置源、网卡9.Ubuntu18.04设置网卡10.Ubuntu:自定义开

Excel和Word日常使用记录:

Excel使用总结 表格颜色填充: 合并单元格: 选中你要合并的单元格区域。按下快捷键 Alt + H,然后松开这些键。再按下 M,接着按 C。这个组合键执行的操作是:Alt + H:打开“主页”选项卡。M:选择“合并单元格”选项。C:执行“合并并居中”操作。 插入行: 在Excel中,插入一行的快捷键是:Windows:选择整行(可以点击行号)。按下 Ctrl + Sh