macrocosm 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 76445ada7fcdc46287d38ac1d9dc4d166902b4c982d2f196224bead9849b012a
4
+ data.tar.gz: 526dd7e53f547ffd2fdb5befd2e431a0e3b3181105341e28e36106f81c028844
5
+ SHA512:
6
+ metadata.gz: 3ed797084ecf85d3656ca721eb7a1592fc967f099b8af6b6c52eb5f622406379b30f02620ebd58f1daf62d3b4e8b79a067991b785fa2efb97aee17c757aa1438
7
+ data.tar.gz: 3105818cd35a18d01cdc92465bc388439e57ad8aef403730b837a858cd9b1ba0b0436ee4e8f8dce8abbcb4364a2e5ff1bbc4308d08c78e95017ea3f925ffe8c8
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ Gemfile.lock
10
+ *.gem
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.6.4
7
+ before_install: gem install bundler -v 2.0.2
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at block24block@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in macrocosm.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 ken
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,61 @@
1
+ # Macrocosm
2
+
3
+ Graph = iView + Echarts
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'macrocosm'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install macrocosm
20
+
21
+ ## Usage
22
+
23
+ ```
24
+ s = Macrocosm.new(curveness: 0.1)
25
+
26
+ s.add_node('p1', 'category E')
27
+ s.add_node('p2', 'category D')
28
+ s.add_node('p3', 'category F')
29
+ s.add_node('p4', 'category F')
30
+ s.add_node('p5', 'category G')
31
+ s.add_node('p6', 'category G')
32
+ s.add_node('p7', 'category G')
33
+
34
+ s.add_link('p1', 'p2')
35
+ s.add_link('p1', 'p3')
36
+ s.add_link('p2', 'p3', relation_in_list: 'has_one', relation_in_graph: '1 -> 1')
37
+ s.add_link('p4', 'p5')
38
+ s.add_link('p5', 'p6')
39
+ s.add_link('p6', 'p7')
40
+ s.add_link('p5', 'p7')
41
+
42
+ File.open(path, 'w'){ |f| f.puts s.to_s }
43
+ ```
44
+
45
+ ## Development
46
+
47
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
48
+
49
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
50
+
51
+ ## Contributing
52
+
53
+ Bug reports and pull requests are welcome on GitHub at https://github.com/turnon/macrocosm. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
54
+
55
+ ## License
56
+
57
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
58
+
59
+ ## Code of Conduct
60
+
61
+ Everyone interacting in the Macrocosm project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/turnon/macrocosm/blob/master/CODE_OF_CONDUCT.md).
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "macrocosm"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "pry"
14
+ pry
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,62 @@
1
+ require 'macrocosm/version'
2
+ require 'macrocosm/template'
3
+ require 'json'
4
+
5
+ class Macrocosm
6
+
7
+ NoCategory = 'no-category'
8
+
9
+ TemplateObj = Template.new
10
+
11
+ attr_reader :curveness
12
+
13
+ def initialize(curveness: 0)
14
+ category_index = -1
15
+ @categories = Hash.new{ |h, cate| h[cate] = (category_index += 1) }
16
+ @nodes = []
17
+ @links = []
18
+
19
+ @curveness = curveness
20
+ end
21
+
22
+ def add_node(name, category = nil)
23
+ category ||= NoCategory
24
+ idx = @categories[category]
25
+ @nodes << {
26
+ name: name,
27
+ category: idx
28
+ }
29
+ end
30
+
31
+ def add_link(source, target, relation_in_list: nil, relation_in_graph: nil)
32
+ link = {
33
+ source: source,
34
+ target: target
35
+ }
36
+ link[:relation_in_list] = relation_in_list if relation_in_list
37
+ link[:relation_in_graph] = relation_in_graph if relation_in_graph
38
+ @links << link
39
+ end
40
+
41
+ def to_s
42
+ TemplateObj.render(binding)
43
+ end
44
+
45
+ def graph
46
+ JSON.pretty_generate({
47
+ nodes: @nodes,
48
+ links: @links,
49
+ categories: @categories.keys.map{ |name| {name: name} }
50
+ })
51
+ end
52
+
53
+ private
54
+
55
+ def to_json
56
+ JSON.pretty_generate({
57
+ nodes: @nodes,
58
+ links: @links,
59
+ categories: @categories.keys.map{ |name| {name: name} }
60
+ })
61
+ end
62
+ end
@@ -0,0 +1,451 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+
4
+ <head>
5
+ <meta charset="utf-8">
6
+ <link rel="stylesheet" type="text/css" href="http://unpkg.com/view-design/dist/styles/iview.css">
7
+ <style>
8
+ html,
9
+ body,
10
+ #app {
11
+ height: 100%;
12
+ overflow: hidden;
13
+ }
14
+
15
+ #switch {
16
+ position: fixed;
17
+ bottom: 4%;
18
+ right: 2%;
19
+ }
20
+
21
+ button.filter-switch {
22
+ position: fixed;
23
+ top: 3%;
24
+ left: 2%;
25
+ }
26
+
27
+ a.ivu-drawer-close {
28
+ margin-top: 7px;
29
+ right: 20px;
30
+ }
31
+
32
+ .ivu-drawer-body {
33
+ overflow-y: scroll;
34
+ }
35
+
36
+ .highlight {
37
+ background-color: yellow;
38
+ }
39
+ </style>
40
+ <script type="text/javascript" src="http://vuejs.org/js/vue.min.js"></script>
41
+ <script type="text/javascript" src="http://unpkg.com/view-design/dist/iview.min.js"></script>
42
+
43
+ <script src="https://cdn.jsdelivr.net/npm/echarts@4.8.0/dist/echarts.min.js"></script>
44
+ <script src="https://cdn.jsdelivr.net/npm/vue-echarts@4.0.2/dist/vue-echarts.min.js"></script>
45
+ </head>
46
+
47
+ <body>
48
+ <div id="app">
49
+ <Drawer placement="left" v-model="filter" :mask-closable="false" :mask="false" :draggable="true" :transfer="false">
50
+ <i-input v-model="keyword" style="width: calc(100% - 27px); margin-bottom: 10px;"></i-input>
51
+ <Tree :data="relations" show-checkbox @on-check-change="selectRelation($event)" ref="filter-panel" />
52
+ </Drawer>
53
+
54
+ <v-chart :options="opts" theme="light" autoresize @click="handleClick($event)"></v-chart>
55
+
56
+ <i-button @click="filter = !filter" type="info" class="filter-switch">
57
+ filter
58
+ <Icon type="ios-arrow-forward" />
59
+ </i-button>
60
+
61
+ <div id="switch">
62
+ node-label&nbsp;<Checkbox v-model="opts.series[0].label.show"></Checkbox>&nbsp;&nbsp;
63
+ edge-label&nbsp;<Checkbox v-model="edge_label" @on-change="switch_edge_label"></Checkbox>
64
+ </div>
65
+ </div>
66
+
67
+ <script>
68
+ // (function () {
69
+
70
+ let graph =
71
+ /* start-graph */
72
+ {
73
+ "nodes": [{
74
+ "name": "n1",
75
+ "category": 0
76
+ }, {
77
+ "name": "n2",
78
+ "category": 1
79
+ }, {
80
+ "name": "n3",
81
+ "category": 2
82
+ }, {
83
+ "name": "n4",
84
+ "category": 2
85
+ }],
86
+ "links": [{
87
+ "relation_in_graph": "n1 ==> n2",
88
+ "source": "n1",
89
+ "target": "n2"
90
+ }, {
91
+ "relation_in_graph": "n2 ==> n3",
92
+ "source": "n2",
93
+ "target": "n3"
94
+ }, {
95
+ "relation_in_graph": "n3 ==> n1",
96
+ "source": "n3",
97
+ "target": "n1"
98
+ }, {
99
+ "relation_in_graph": "n3 ==> n4",
100
+ "source": "n3",
101
+ "target": "n4"
102
+ }],
103
+ "categories": [{
104
+ "name": "/A"
105
+ }, {
106
+ "name": "/B"
107
+ }, {
108
+ "name": "/C"
109
+ }]
110
+ }
111
+ /* end-graph */
112
+
113
+ let source_checkboxes = {},
114
+ target_checkboxes = [],
115
+ child_renderer = (h, { data }) => {
116
+ let text = data.relation_in_list ? `${data.relation_in_list} ${data.title}` : data.title
117
+ return h('span', text);
118
+ },
119
+ relation_in_graph_formatter = (params) => {
120
+ return params.data.relation_in_graph || " "
121
+ },
122
+ add_to_checkboxs_tree = (link, i) => {
123
+ if (!source_checkboxes[link.source]) {
124
+ source_checkboxes[link.source] = {
125
+ title: link.source,
126
+ expand: true,
127
+ checked: false,
128
+ indeterminate: false,
129
+ children: []
130
+ }
131
+ }
132
+
133
+ let child_checkbox = {
134
+ link_idx: i,
135
+ title: link.target,
136
+ relation_in_list: link.relation_in_list,
137
+ render: child_renderer,
138
+ checked: false
139
+ }
140
+ target_checkboxes[i] = child_checkbox
141
+ source_checkboxes[link.source].children.push(child_checkbox)
142
+ }
143
+
144
+ graph.links.forEach((link, i) => {
145
+ link.idx = i
146
+ link.label = {
147
+ show: false,
148
+ formatter: relation_in_graph_formatter
149
+ }
150
+ link.lineStyle = {
151
+ opacity: 0.5,
152
+ width: 1
153
+ }
154
+
155
+ add_to_checkboxs_tree(link, i)
156
+ })
157
+
158
+ let node_tooltip = {
159
+ formatter({ data }) {
160
+ return data.schema.join("<br>")
161
+ // let schema = data.schema.join("<br>")
162
+ // let idx = data.indexes.map((idx) => {
163
+ // let cols = `[${idx.cols.join(', ')}]`
164
+ // return idx.uniq ? `${cols}:uniq` : cols
165
+ // }).join("<br>")
166
+ // return `${schema}<br>${idx}`
167
+ }
168
+ }
169
+ graph.nodes.forEach((node, i) => {
170
+ // node.tooltip = node_tooltip
171
+ node.itemStyle = {
172
+ opacity: 1
173
+ }
174
+ })
175
+
176
+ let relations = Object.values(source_checkboxes)
177
+ // console.log(relations)
178
+
179
+
180
+ let opts = {
181
+ // title: {
182
+ // text: 'Les Miserables',
183
+ // subtext: 'Default layout',
184
+ // top: 'bottom',
185
+ // left: 'right'
186
+ // },
187
+ tooltip: {},
188
+ legend: [{
189
+ // selectedMode: 'single',
190
+ top: "3%",
191
+ right: "2%",
192
+ orient: "vertical",
193
+ align: "right",
194
+ data: graph.categories.map(function (a) {
195
+ return a.name;
196
+ })
197
+ }],
198
+ animationDuration: 1500,
199
+ animationEasingUpdate: 'quinticInOut',
200
+ series: [{
201
+ type: 'graph',
202
+ layout: 'force',
203
+ data: graph.nodes,
204
+ links: graph.links,
205
+ categories: graph.categories,
206
+ roam: true,
207
+ // focusNodeAdjacency: true,
208
+ itemStyle: {
209
+ borderColor: '#fff',
210
+ borderWidth: 1,
211
+ shadowBlur: 10,
212
+ shadowColor: 'rgba(0, 0, 0, 0.3)'
213
+ },
214
+ label: {
215
+ show: false,
216
+ position: 'right',
217
+ formatter: '{b}'
218
+ },
219
+ lineStyle: {
220
+ color: 'source',
221
+ curveness: /* start-curveness */ 0.3 /* end-curveness */,
222
+ },
223
+ edgeSymbolSize: 15,
224
+ emphasis: {
225
+ lineStyle: {
226
+ width: 10
227
+ }
228
+ }
229
+ }]
230
+ }
231
+
232
+ let checked_links = new Set(),
233
+ checked_nodes = new Set()
234
+
235
+ Vue.component('v-chart', VueECharts)
236
+ new Vue({
237
+ el: '#app',
238
+ data: {
239
+ keyword: "",
240
+ filter: false,
241
+ opts: opts,
242
+ edge_label: false,
243
+ relations: relations
244
+ },
245
+ watch: {
246
+ keyword() {
247
+ tree.search(this.keyword)
248
+ }
249
+ },
250
+ methods: {
251
+ switch_edge_label(){
252
+ if (checked_nodes.size === 0) {
253
+ graph.links.forEach((link, i) => {
254
+ link.label.show = this.edge_label
255
+ })
256
+ return
257
+ }
258
+
259
+ graph.links.forEach((link, i) => {
260
+ if (checked_links.has(i) && this.edge_label) {
261
+ link.label.show = true
262
+ } else {
263
+ link.label.show = false
264
+ }
265
+ })
266
+ },
267
+
268
+ selectRelation(checkeds) {
269
+ checked_links = new Set()
270
+ checked_nodes = new Set()
271
+
272
+ checkeds.forEach((c) => {
273
+ if (c.link_idx !== undefined) {
274
+ checked_links.add(c.link_idx)
275
+ checked_nodes.add(graph.links[c.link_idx].source)
276
+ }
277
+ checked_nodes.add(c.title)
278
+ })
279
+
280
+ this.switch_edge_label()
281
+
282
+ if (checked_nodes.size === 0) {
283
+ graph.links.forEach((link) => {
284
+ link.lineStyle.width = 1
285
+ link.lineStyle.opacity = 1
286
+ })
287
+ graph.nodes.forEach((node) => {
288
+ node.itemStyle.opacity = 1
289
+ })
290
+ return
291
+ }
292
+
293
+ graph.links.forEach((link, i) => {
294
+ if (checked_links.has(i)) {
295
+ link.lineStyle.width = 10
296
+ link.lineStyle.opacity = 1
297
+ } else {
298
+ link.lineStyle.width = 1
299
+ link.lineStyle.opacity = 0.1
300
+ }
301
+ })
302
+
303
+ graph.nodes.forEach((node, i) => {
304
+ if (checked_nodes.has(node.name)) {
305
+ node.itemStyle.opacity = 1
306
+ } else {
307
+ node.itemStyle.opacity = 0.1
308
+ }
309
+ })
310
+ },
311
+ handleClick(e) {
312
+ let link = e.data,
313
+ target_box = target_checkboxes[link.idx],
314
+ source_box = source_checkboxes[link.source]
315
+
316
+ target_box.checked = !target_box.checked
317
+
318
+ let checked_targets_count = source_box.children.reduce((count, c) => {
319
+ count = c.checked ? count + 1 : count
320
+ return count
321
+ }, 0)
322
+
323
+ if (checked_targets_count === 0) {
324
+ source_box.checked = false
325
+ source_box.indeterminate = false
326
+ } else if (checked_targets_count === source_box.children.length) {
327
+ source_box.checked = true
328
+ source_box.indeterminate = false
329
+ } else {
330
+ source_box.checked = false
331
+ source_box.indeterminate = true
332
+ }
333
+
334
+ this.$nextTick(() => {
335
+ let checkeds = this.$refs['filter-panel'].getCheckedAndIndeterminateNodes()
336
+ this.selectRelation(checkeds)
337
+ })
338
+ }
339
+ }
340
+ });
341
+
342
+ const Tree = (function () {
343
+ const node_class_name = "ivu-tree-children",
344
+ node_class = "." + node_class_name,
345
+ text_class = ".ivu-tree-title",
346
+ highlight_html = '<span class="highlight">$1</span>'
347
+
348
+ class Tree {
349
+ constructor(selector) {
350
+ let n = document.querySelector(selector + " " + node_class)
351
+ this.roots = n ? (new Node(n).this_and_siblings()) : []
352
+ }
353
+
354
+ search(keyword) {
355
+ let kw = keyword === "" ? /./ : new RegExp(keyword)
356
+ this.show_only_when_match((txt) => { return txt.match(kw) })
357
+
358
+ if (keyword !== "") {
359
+ let repl = new RegExp('(' + keyword + ')')
360
+ this.highlight((txt) => { return txt.replace(repl, highlight_html) })
361
+ } else {
362
+ document.querySelectorAll('.highlight').forEach((n) => { n.parentNode.innerText = n.parentNode.innerText })
363
+ }
364
+ }
365
+
366
+ show_only_when_match(fn) {
367
+ this.roots.forEach((n) => { n.show_only_when_match(fn) })
368
+ }
369
+
370
+ highlight(fn) {
371
+ this.roots.forEach((n) => { n.highlight(fn) })
372
+ }
373
+ }
374
+
375
+ class Node {
376
+ constructor(node) {
377
+ this.raw_node = node
378
+ this.visible = true
379
+
380
+ let child = this.raw_node.querySelector(node_class)
381
+ this.children = child ? (new Node(child).this_and_siblings()) : []
382
+ }
383
+
384
+ this_and_siblings() {
385
+ let ss = [this],
386
+ s = this.raw_node.nextSibling
387
+
388
+ while (s && s.getAttribute && (s.getAttribute('class') === node_class_name)) {
389
+ ss.push(new Node(s))
390
+ s = s.nextSibling
391
+ }
392
+ return ss
393
+ }
394
+
395
+ highlight(fn) {
396
+ if (!this.visible) {
397
+ return
398
+ }
399
+ this.title_node().innerHTML = fn(this.title_node().innerText)
400
+ this.children.forEach((c) => { c.highlight(fn) })
401
+ }
402
+
403
+ title_node() {
404
+ return this.raw_node.querySelector(text_class)
405
+ }
406
+
407
+ show_only_when_match(fn) {
408
+ let text = this.title_node().innerText
409
+ if (fn(text)) {
410
+ this.set_sub_tree_visible()
411
+ return
412
+ }
413
+ this.children.forEach((c) => {
414
+ c.show_only_when_match(fn)
415
+ })
416
+ if (this.children.some((c) => { return c.visible })) {
417
+ this.set_display(true)
418
+ return
419
+ }
420
+ this.set_display(false)
421
+ }
422
+
423
+ set_display(vi) {
424
+ this.visible = vi
425
+ this.raw_node.style.display = (vi ? "block" : "none")
426
+
427
+ }
428
+
429
+ set_sub_tree_visible() {
430
+ this.set_display(true)
431
+ this.children.forEach((c) => {
432
+ c.set_sub_tree_visible()
433
+ })
434
+ }
435
+ }
436
+
437
+ return Tree
438
+ })()
439
+
440
+ let tree = new Tree('#app')
441
+
442
+ setTimeout(() => {
443
+ let chart = document.querySelector(".echarts")
444
+ chart.style.width = "100%"
445
+ chart.style.height = "100%"
446
+ })
447
+ // })()
448
+ </script>
449
+ </body>
450
+
451
+ </html>
@@ -0,0 +1,49 @@
1
+ require 'erb'
2
+
3
+ class Macrocosm
4
+
5
+ class Template
6
+
7
+ class Position
8
+ attr_reader :name
9
+
10
+ def initialize(name)
11
+ @name = name
12
+ end
13
+
14
+ def regexp
15
+ @regexp ||= Regexp.new("\\/\\*.*?start-#{name}.*end-#{name}.*?\\*\\/", Regexp::MULTILINE)
16
+ end
17
+
18
+ def mark
19
+ "<%= #{name} %>"
20
+ end
21
+ end
22
+
23
+ attr_reader :raw
24
+
25
+ def initialize
26
+ @raw = File.read(File.join(__dir__, 'template.html'))
27
+ end
28
+
29
+ def positions
30
+ @positions ||= @raw.scan(/\/\*.*?start-.*?\*\//).map do |s|
31
+ name = s.match(/-(.+)\s+\*/)[1]
32
+ Position.new(name)
33
+ end
34
+ end
35
+
36
+ def erb
37
+ return @erb if @erb
38
+ file = positions.reduce(@raw) do |file, pos|
39
+ file.sub(pos.regexp, pos.mark)
40
+ end
41
+ @erb = ERB.new(file)
42
+ end
43
+
44
+ def render(b)
45
+ erb.result(b)
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,3 @@
1
+ class Macrocosm
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,30 @@
1
+ lib = File.expand_path("lib", __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "macrocosm/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "macrocosm"
7
+ spec.version = Macrocosm::VERSION
8
+ spec.authors = ["ken"]
9
+ spec.email = ["block24block@gmail.com"]
10
+
11
+ spec.summary = %q{iview & echarts-graph}
12
+ spec.homepage = "https://github.com/turnon/macrocosm"
13
+ spec.license = "MIT"
14
+
15
+ spec.metadata["homepage_uri"] = spec.homepage
16
+
17
+ # Specify which files should be added to the gem when it is released.
18
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
19
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
20
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
+ end
22
+ spec.bindir = "exe"
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ["lib"]
25
+
26
+ spec.add_development_dependency "bundler", "~> 2.0"
27
+ spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "minitest", "~> 5.0"
29
+ spec.add_development_dependency "pry"
30
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: macrocosm
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - ken
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-08-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description:
70
+ email:
71
+ - block24block@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".travis.yml"
78
+ - CODE_OF_CONDUCT.md
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - bin/console
84
+ - bin/setup
85
+ - lib/macrocosm.rb
86
+ - lib/macrocosm/template.html
87
+ - lib/macrocosm/template.rb
88
+ - lib/macrocosm/version.rb
89
+ - macrocosm.gemspec
90
+ homepage: https://github.com/turnon/macrocosm
91
+ licenses:
92
+ - MIT
93
+ metadata:
94
+ homepage_uri: https://github.com/turnon/macrocosm
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ requirements: []
110
+ rubygems_version: 3.0.3
111
+ signing_key:
112
+ specification_version: 4
113
+ summary: iview & echarts-graph
114
+ test_files: []