Skip to content

Commit 8290c56

Browse files
committed
Merge branch 'gh-pages' of https://github.com/LivelyKernel/lively4-core into gh-pages
2 parents dafa850 + d99522d commit 8290c56

File tree

6 files changed

+93
-16
lines changed

6 files changed

+93
-16
lines changed

src/client/lively.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,6 +1481,7 @@ export default class Lively {
14811481

14821482
return containerPromise.then(comp => {
14831483
if (existingFound) {
1484+
comp.parentElement.focus();
14841485
comp.focus();
14851486
return;
14861487
}

src/client/reactive/active-expression/active-expression.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ export const AExprRegistry = {
8181
},
8282

8383
eventListeners() {
84+
if(!this.listeners) return [];
8485
this.listeners = this.listeners.filter(listener => listener.reference);
8586
return this.listeners;
8687
}

src/client/reactive/components/basic/aexpr-timeline.html

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,34 +12,63 @@
1212
#content {
1313
background-color: gray;
1414
}
15+
td {
16+
border: 1px solid black;
17+
padding: 3px;
18+
}
19+
th {
20+
border: 2px solid black;
21+
padding: 2px;
22+
text-align: center;
23+
}
24+
#valuesOverTime {
25+
width: 100%;
26+
border-spacing: 0px;
27+
}
1528
.container {
1629
display: grid;
17-
grid-template-rows: auto 1fr auto;
30+
grid-template-rows: 1fr 3fr auto;
1831
align-items:stretch;
1932
justify-items:stretch;
2033
height: 100%;
34+
overflow: hidden;
2135
}
2236
.row {
2337
display: grid;
2438
grid-template-columns: 1fr 1fr;
2539
align-items:stretch;
2640
justify-items:stretch;
2741
width: 100%;
42+
overflow-y: hidden;
2843
}
2944
.pane {
3045
margin: 1px;
3146
border: 1px solid #d5d5d5;
47+
overflow-y: auto;
48+
}
49+
.variable {
50+
color: #0000FF
3251
}
3352
</style>
3453

3554
<div class="container">
3655
<div class="row">
37-
<div id="aeOverview" class="pane"></div>
38-
<div>
39-
Values over time
56+
<div class="pane">
57+
<h3> AE Overview </h3>
58+
<div id="aeOverview"></div>
59+
</div>
60+
<div class="pane">
61+
<h3> Values over time </h3>
62+
<table id="valuesOverTime">
63+
</table>
64+
Filter: <span class="variable">event</span> => {<input id="filterInput">}
65+
<button id="filterButton">Filter</button>
4066
</div>
4167
</div>
42-
<div id="diagram" class="pane"></div>
68+
<div class="pane">
69+
<h3> Timeline </h3>
70+
<div id="diagram"></div>
71+
</div>
4372
<div id="footer" class="pane">
4473
<p class="infos">
4574
<span id="numberEvents"></span> events <span class="light">found between</span> <br />

src/client/reactive/components/basic/aexpr-timeline.js

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -106,31 +106,44 @@ export default class EventDrops extends Morph {
106106
"themes": { "icons": false }
107107
}
108108
});
109-
109+
110110
this.aeChangedDebounced = (() => this.setAexprs(this.getDataFromSource())).debounce(10, 300);
111111
this.eventsChangedDebounced = (() => this.updateTimeline(this.getDataFromSource())).debounce(100, 1000);
112112
this.activeExpressionsChanged();
113113
//Register to AE changes
114114
AExprRegistry.addEventListener(this, (ae, event) => {
115-
if(event.type === "created" || event.type === "disposed") {
116-
this.activeExpressionsChanged()
115+
if (event.type === "created" || event.type === "disposed") {
116+
this.activeExpressionsChanged();
117117
} else {
118-
this.eventsChanged()
118+
this.eventsChanged();
119119
}
120120
});
121121
//Register to overview selection changes
122122
jQuery(this.aeOverview).on("changed.jstree", (e, data) => {
123123
this.eventsChanged();
124-
})
124+
}
125125
//Register to grouping change
126-
this.groupByLine.addEventListener('change', () => {
126+
);this.groupByLine.addEventListener('change', () => {
127127
if (this.groupByLine.checked) {
128128
this.groupingFunction = this.locationGrouping();
129129
} else {
130130
this.groupingFunction = this.instanceGrouping();
131131
}
132132
this.eventsChanged();
133133
});
134+
//Register to filter changes
135+
this.filterFunction = () => true;
136+
this.filterButton.addEventListener('click', () => {
137+
const inputValue = this.filterInput.value;
138+
if (!inputValue) {
139+
this.filterFunction = () => true;
140+
} else {
141+
this.filterFunction = event => {
142+
return eval(inputValue);
143+
};
144+
}
145+
this.eventsChanged();
146+
});
134147
}
135148

136149
humanizeEventData(event) {
@@ -178,7 +191,6 @@ export default class EventDrops extends Morph {
178191
getGroupingFunction() {
179192
return this.groupingFunction || this.locationGrouping();
180193
}
181-
182194

183195
activeExpressionsChanged() {
184196
this.aeChangedDebounced();
@@ -201,15 +213,19 @@ export default class EventDrops extends Morph {
201213
aexprs[i].timelineID = i;
202214
}
203215
this.updateOverview(aexprs);
204-
this.updateTimeline(aexprs)
216+
this.updateTimeline(aexprs);
205217
}
206218

207219
updateTimeline(aexprs) {
208220
const checkedIndices = jQuery(this.aeOverview).jstree(true).get_bottom_selected();
209221
const selectedAEs = checkedIndices.map(i => aexprs[i - 1]).filter(ae => ae);
222+
this.updateValuesOverTime(selectedAEs);
210223
let scrollBefore = this.diagram.scrollTop;
211224
let groups = selectedAEs.groupBy(this.getGroupingFunction());
212-
groups = Object.keys(groups).map(each => ({ name: each, data: groups[each].flatMap(ae => ae.meta().get('events')) }));
225+
groups = Object.keys(groups).map(each => ({
226+
name: each,
227+
data: groups[each].flatMap(ae => ae.meta().get('events')).filter(this.filterFunction)
228+
}));
213229
this.setData(groups);
214230
if (selectedAEs.length == 0) return;
215231

@@ -238,6 +254,23 @@ export default class EventDrops extends Morph {
238254
this.diagram.scrollTop = scrollBefore;
239255
}
240256

257+
updateValuesOverTime(aexprs) {
258+
const aeWithRelevantEvents = aexprs.map(ae => {
259+
return { ae, events: ae.meta().get('events').filter(event => event.type === "changed value").filter(this.filterFunction) };
260+
});
261+
this.valuesOverTime.innerHTML = "";
262+
263+
for(const {ae, events} of aeWithRelevantEvents) {
264+
if(events.length === 0) continue;
265+
let row = <tr><th>{ae.meta().get('id')}</th></tr>
266+
row.append(<td>{events[0].value.lastValue}</td>);
267+
for(const event of events) {
268+
row.append(<td>{event.value.value}</td>);
269+
}
270+
this.valuesOverTime.append(row);
271+
}
272+
}
273+
241274
updateOverview(aexprs) {
242275
jQuery(this.aeOverview).jstree(true).settings.core.data = this.generateOverviewJSON(aexprs);
243276
jQuery(this.aeOverview).jstree(true).refresh();
@@ -320,4 +353,17 @@ export default class EventDrops extends Morph {
320353
get aeOverview() {
321354
return this.get("#aeOverview");
322355
}
356+
357+
get filterInput() {
358+
return this.get("#filterInput");
359+
}
360+
361+
get filterButton() {
362+
return this.get("#filterButton");
363+
}
364+
365+
get valuesOverTime() {
366+
return this.get("#valuesOverTime");
367+
}
368+
323369
}

src/components/tools/lively-sync.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@
113113

114114

115115
#logContainer {
116-
background-color: rgb(155,155,155);
116+
background-color: rgb(230,230,230);
117117
}
118118

119119
#syncButton, #squashButton {

src/components/widgets/lively-code-mirror.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1402,7 +1402,7 @@ export default class LivelyCodeMirror extends HTMLElement {
14021402
}
14031403

14041404
async updateAExprDependencies() {
1405-
if(!this.isJavaScript) return;
1405+
if(!this.isJavaScript || !lively.query(this, "lively-container")) return;
14061406
await this.editor;
14071407
const dependencyGraph = await this.dependencyGraph();
14081408
if (!dependencyGraph.capabilities.canParse || !dependencyGraph.hasActiveExpressionsDirective) {

0 commit comments

Comments
 (0)