-
-
Notifications
You must be signed in to change notification settings - Fork 899
feat(core): add add_nodes API for batch node creation #667
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…add_nodes method to add multiple nodes efficiently in a single layout pass\n- Update legacy bundle accordingly\n- Add example/test_batch_add.html to demonstrate and benchmark batch addition\n\nRefs: performance optimization for bulk node insertion
hizzgdev
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Many thanks to @UmbraCi , leave few comments, PTAL!
src/jsmind.js
Outdated
| } | ||
|
|
||
| // Phase 2: Unified layout calculation and redraw (execute only once) | ||
| if (created_nodes.some(node => node !== null)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can just test !!created_nodes, because null-value won't be added in the list, it's checked at line 495
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
在使用库的custom_node_render方法自定义渲染节点的时候,若节点数据的topic为空值时,会直接走进custom_node_render方法渲染自定义的DOM,实际上有些节点在使用场景中,我需要渲染一些span标签用以展示状态,类似于一些UI库的label,为了解决topic为空不走进custom_node_render的问题,我不得不把传入jm.show的数据的空topic转换成 “ ”(中间有个空格),你觉得这个逻辑有必要修复吗
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
在使用库的custom_node_render方法自定义渲染节点的时候,若节点数据的topic为空值时,会直接走进custom_node_render方法渲染自定义的DOM,实际上有些节点在使用场景中,我需要渲染一些span标签用以展示状态,类似于一些UI库的label,为了解决topic为空不走进custom_node_render的问题,我不得不把传入jm.show的数据的空topic转换成 “ ”(中间有个空格),你觉得这个逻辑有必要修复吗
你最后提到的“这个逻辑” 是 “topic为空不走进custom_node_render” 吗?如果是的话,我不建议进行修改。如果 node.topic 不存在,说明这个 node 没有实际的语义,你需要展示状态的话,应该给这个 node 设定具体的语义,既然使用了 custom_node_render, 那把一个带有语义的文本写到 node.topic 里我感觉才比较合理。 @UmbraCi 这是我的想法。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
在使用库的custom_node_render方法自定义渲染节点的时候,若节点数据的topic为空值时,会直接走进custom_node_render方法渲染自定义的DOM,实际上有些节点在使用场景中,我需要渲染一些span标签用以展示状态,类似于一些UI库的label,为了解决topic为空不走进custom_node_render的问题,我不得不把传入jm.show的数据的空topic转换成 “ ”(中间有个空格),你觉得这个逻辑有必要修复吗
你最后提到的“这个逻辑” 是 “topic为空不走进custom_node_render” 吗?如果是的话,我不建议进行修改。如果 node.topic 不存在,说明这个 node 没有实际的语义,你需要展示状态的话,应该给这个 node 设定具体的语义,既然使用了 custom_node_render, 那把一个带有语义的文本写到 node.topic 里我感觉才比较合理。 @UmbraCi 这是我的想法。
基础版本的用法是让脑图节点显示文本,进阶玩法应该是让节点能够渲染类似于“富文本”之类的视图,比如一个超链接(可以点击,且显示自定义)、一个状态标签(label组件),这种节点其实是不想渲染出文本的,但是因为custom_node_render方法进入前校验了topic字段是否为空,会导致不渲染自定义节点的问题,为了拓展性,就算不处理,是否加个配置项要好一些呢?我的想法是,既然有custom_node_render这个方法,那是否渲染这个逻辑应该也可以交给它来判断,这个方法也是可以返回boolean值的
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
就算不处理,是否加个配置项要好一些呢
既然有custom_node_render这个方法,那是否渲染这个逻辑应该也可以交给它来判断,这个方法也是可以返回boolean值的
技术上可行。我这里考虑的主要是脑图本身数据对象的完整性。如果 node.topic 为空也能代表一定的意义的话,那这部分意义也应该体现在数据对象中。如果这部分意义无法体现在 node.topic 中,我们也可以设计出一个新的字段来代替 topic 去支持 richContent。 但无论如何,我们需要在数据对象中保留它的语义,而不能仅靠 custom_node_render 给节点赋予语义。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
就算不处理,是否加个配置项要好一些呢
既然有custom_node_render这个方法,那是否渲染这个逻辑应该也可以交给它来判断,这个方法也是可以返回boolean值的技术上可行。我这里考虑的主要是脑图本身数据对象的完整性。如果 node.topic 为空也能代表一定的意义的话,那这部分意义也应该体现在数据对象中。如果这部分意义无法体现在 node.topic 中,我们也可以设计出一个新的字段来代替 topic 去支持 richContent。 但无论如何,我们需要在数据对象中保留它的语义,而不能仅靠 custom_node_render 给节点赋予语义。
我的想法是:
给node对象增加一个属性,用以判断是否需要在topic为空的时候也走到richContent中,目前我的做法是遍历整个脑图数据结构,给有需要展示richContent的节点根据data里面的富文本要展示出来的字段来判断
if(node.topic === '' && node.data.label){
// 设置node.topic为一个空格符
}
其实跟你说的这个增加属性的办法殊途同归,只不过我是用空格符强行去满足Boolean(topic),题外话---其实在一些eslint规范中是不推荐直接使用if(Boolean( 字符串 ))判断的;
你看下是否有必要增加这样一个字段来在topic为空的时候让节点继续走到custom_node_render执行渲染呢
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这样的话,我们可以把这段逻辑修改成 node.topic has no value && node.data is empty , 你感觉如何?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这样的话,我们可以把这段逻辑修改成
node.topic has no value && node.data is empty, 你感觉如何?
是可以达到效果,直接用data对象是否为空来判断,有没有可能会影响到现有其他用户的正常业务逻辑,这一点我有担忧,如果有影响,用户更新库以后,也要修改原本“正常”的业务代码
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
是的,这样破坏兼容性了。那我们就加一个 content 字段吧,把它当做 topic 的升级版本。
node.content = {
type: 'plain',
value: 'topic'
}
node.content = {
type: 'html',
value: '<span>...</span>'
}
node.content = {
type: 'some-other-type',
value: any object
}jsmind 支持前两种,其它 type 需要用户自行渲染。
然后判断逻辑改为
if (topic has value or content has value ) {
custom_node_render();
}- Refactor add_node to use private helper methods _add_node_data and _refresh_node_ui - Add add_nodes method for optimized batch node creation - Improve performance by reducing layout calculations from O(n) to O(1) - Add unit tests for add_nodes functionality - Remove add_nodes from legacy version as suggested in PR feedback Addresses feedback from PR hizzgdev#667: - Split add_node into smaller, reusable methods - Simplify condition checking in add_nodes - Focus only on modern ES6 version in src/ directory - Add comprehensive unit tests
- Add 10 test cases covering various scenarios: - Error handling (not editable, parent not found, invalid input) - Core functionality (method calls, parameter passing) - Event handling and return values - Failed node creation scenarios - Use mocking to avoid DOM-related issues in test environment - Ensure proper testing of the batch node creation workflow - All tests pass successfully
- Add performance test for large-scale node creation (1000 nodes) - Add complex data structure test with Unicode and multilingual support - Add comprehensive direction handling test (13 different direction types) - Refactor create_fake_mind to accept options parameter for better flexibility - Remove default editable:true from create_fake_mind, require explicit declaration - Update all test cases to explicitly pass editable:true when needed - Ensure 100% test pass rate with improved test design and clarity Performance improvements verified: - Batch operations call _refresh_node_ui only once (O(1) vs O(n)) - Large node creation completes within 100ms performance threshold - Complex data structures and Unicode characters handled correctly Total test coverage: 13 test cases covering error handling, core functionality, performance optimization, data integrity, and edge cases.
| expect(result).toHaveLength(1000); | ||
| expect(jsmind._add_node_data).toHaveBeenCalledTimes(1000); | ||
| expect(jsmind._refresh_node_ui).toHaveBeenCalledTimes(1); // Key performance benefit | ||
| expect(end - start).toBeLessThan(100); // Should complete within 100ms |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool!
TBH, I don't think we have to check the performance here, because the methods _add_node_data and _refresh_node_ui are mocked. but let's keep it anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool! 凉! TBH, I don't think we have to check the performance here, because the methods
_add_node_dataand_refresh_node_uiare mocked. but let's keep it anyway.TBH,我认为我们不必在这里检查性能,因为_add_node_data和_refresh_node_ui的方法都被嘲笑了。但无论如何,我们还是保留它吧。
不必检查性能的原因是什么呢
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
因为这里测不出实际的性能, 真正的 _add_node_data 和 _refresh_node_ui 方法在测试中被 jest.fn 给替代了。
hizzgdev
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
|
@hizzgdev 是否需要先发版一次呢,npm仓库没更新 |
|
感谢提醒 @UmbraCi ,0.9.0 已经发布了 https://www.npmjs.com/package/jsmind |
This PR introduces a new public API add_nodes to efficiently add multiple nodes in one batch.\n\nKey changes:\n- Add add_nodes method in runtime to build nodes without repeated relayout/redraw\n- Update legacy bundle to expose the new API\n- Provide example/test_batch_add.html to benchmark and demonstrate batch addition\n\nWhy:\nAdding nodes one-by-one causes repeated layout and paint. This optimization significantly reduces the cost for bulk insert scenarios.\n\nNotes:\n- API surface follows existing naming and event conventions (fires edit:add_nodes)\n- Backward-compatible; no breaking change\n\nPlease let me know if additional docs or tests are required.