记录一次曲折的需求完成

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

相关文章

Java使用SLF4J记录不同级别日志的示例详解

《Java使用SLF4J记录不同级别日志的示例详解》SLF4J是一个简单的日志门面,它允许在运行时选择不同的日志实现,这篇文章主要为大家详细介绍了如何使用SLF4J记录不同级别日志,感兴趣的可以了解下... 目录一、SLF4J简介二、添加依赖三、配置Logback四、记录不同级别的日志五、总结一、SLF4J

在Spring Boot中浅尝内存泄漏的实战记录

《在SpringBoot中浅尝内存泄漏的实战记录》本文给大家分享在SpringBoot中浅尝内存泄漏的实战记录,结合实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录使用静态集合持有对象引用,阻止GC回收关键点:可执行代码:验证:1,运行程序(启动时添加JVM参数限制堆大小):2,访问 htt

MySQL 中查询 VARCHAR 类型 JSON 数据的问题记录

《MySQL中查询VARCHAR类型JSON数据的问题记录》在数据库设计中,有时我们会将JSON数据存储在VARCHAR或TEXT类型字段中,本文将详细介绍如何在MySQL中有效查询存储为V... 目录一、问题背景二、mysql jsON 函数2.1 常用 JSON 函数三、查询示例3.1 基本查询3.2

Python获取中国节假日数据记录入JSON文件

《Python获取中国节假日数据记录入JSON文件》项目系统内置的日历应用为了提升用户体验,特别设置了在调休日期显示“休”的UI图标功能,那么问题是这些调休数据从哪里来呢?我尝试一种更为智能的方法:P... 目录节假日数据获取存入jsON文件节假日数据读取封装完整代码项目系统内置的日历应用为了提升用户体验,

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio

MySQL INSERT语句实现当记录不存在时插入的几种方法

《MySQLINSERT语句实现当记录不存在时插入的几种方法》MySQL的INSERT语句是用于向数据库表中插入新记录的关键命令,下面:本文主要介绍MySQLINSERT语句实现当记录不存在时... 目录使用 INSERT IGNORE使用 ON DUPLICATE KEY UPDATE使用 REPLACE

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

Spring定时任务只执行一次的原因分析与解决方案

《Spring定时任务只执行一次的原因分析与解决方案》在使用Spring的@Scheduled定时任务时,你是否遇到过任务只执行一次,后续不再触发的情况?这种情况可能由多种原因导致,如未启用调度、线程... 目录1. 问题背景2. Spring定时任务的基本用法3. 为什么定时任务只执行一次?3.1 未启用

SpringBoot使用OkHttp完成高效网络请求详解

《SpringBoot使用OkHttp完成高效网络请求详解》OkHttp是一个高效的HTTP客户端,支持同步和异步请求,且具备自动处理cookie、缓存和连接池等高级功能,下面我们来看看SpringB... 目录一、OkHttp 简介二、在 Spring Boot 中集成 OkHttp三、封装 OkHttp