Skip to content

Commit 4c75930

Browse files
committed
reworked the matomo tracking feature
1 parent 9a2d15c commit 4c75930

27 files changed

Lines changed: 341 additions & 219 deletions

examples/local_files/data-config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ var data_config = {
1717
show_context: false,
1818
create_title_from_context: false,
1919

20+
share_modal: true,
21+
embed_modal: false,
22+
23+
enable_mouseover_evaluation: false,
24+
2025
files: [{
2126
title: "edu1",
2227
file: "./data/edu1.csv"

examples/local_files/index.html

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,31 @@
1717
<link type="text/css" rel="stylesheet" href="../../dist/headstart.css">
1818
</link>
1919
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700,800' rel='stylesheet' type='text/css'>
20-
<link rel="stylesheet" href="css/font-awesome.min.css" >
20+
<link rel="stylesheet" href="css/font-awesome.min.css">
2121
</link>
2222
<script type="text/javascript">
2323
headstart.start();
2424
</script>
2525
</body>
2626

27+
<!-- Matomo -->
28+
<script>
29+
// set this to true to enable Matomo tracking
30+
var enable_tracking = false;
31+
if (enable_tracking) {
32+
var _paq = window._paq = window._paq || [];
33+
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
34+
_paq.push(['trackPageView']);
35+
_paq.push(['enableLinkTracking']);
36+
(function () {
37+
var u = "//dev.openknowledgemaps.org/piwik_stats/";
38+
_paq.push(['setTrackerUrl', u + 'matomo.php']);
39+
_paq.push(['setSiteId', '1']);
40+
var d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];
41+
g.async = true; g.src = u + 'matomo.js'; s.parentNode.insertBefore(g, s);
42+
})();
43+
}
44+
</script>
45+
<!-- End Matomo Code -->
46+
2747
</html>

vis/js/components/Backlink.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,22 @@ import { STREAMGRAPH_MODE } from "../reducers/chartType";
66
import BacklinkTemplate from "../templates/Backlink";
77

88
import { createAnimationCallback } from "../utils/eventhandlers";
9+
import useMatomo from "../utils/useMatomo";
910

1011
export const Backlink = ({
1112
hidden = false,
1213
streamgraph = false,
1314
onClick,
1415
localization = {},
1516
}) => {
17+
const { trackEvent } = useMatomo();
18+
1619
if (hidden) {
1720
return null;
1821
}
1922

2023
const handleOnClick = () => {
24+
trackEvent("Heading", "Zoom out", "Backlink");
2125
if (onClick && typeof onClick === "function") {
2226
onClick();
2327
}

vis/js/components/ContextLine.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import SearchLang from "../templates/contextfeatures/SearchLang";
1717
import Timestamp from "../templates/contextfeatures/Timestamp";
1818
import MetadataQuality from "../templates/contextfeatures/MetadataQuality";
1919
import Modifier from "../templates/contextfeatures/Modifier";
20+
import { trackMatomoEvent } from "../utils/useMatomo";
2021

2122
const defined = (param) => param !== undefined && param !== null;
2223

@@ -104,9 +105,16 @@ class ContextLine extends React.Component {
104105

105106
const text = documentTypes.join(", ");
106107

108+
const trackMouseOver = () =>
109+
trackMatomoEvent("Heading", "Hover document types", "Context line");
110+
107111
return (
108112
<>
109-
<span id="document_types" className="context_item">
113+
<span
114+
id="document_types"
115+
className="context_item"
116+
onMouseOver={trackMouseOver}
117+
>
110118
<HoverPopover
111119
id="doctypes-popover"
112120
container={popoverContainer}

vis/js/components/KnowledgeMap.js

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Chart from "../templates/Chart";
77
import Paper from "../templates/Paper";
88

99
import { mapDispatchToMapEntriesProps } from "../utils/eventhandlers";
10+
import { trackMatomoEvent } from "../utils/useMatomo";
1011

1112
const KnowledgeMap = (props) => {
1213
const { data, areas, zoom, animation } = props;
@@ -17,31 +18,46 @@ const KnowledgeMap = (props) => {
1718
const { handleDeselectPaper, handleSelectPaper } = props;
1819
const { hoveredBubble, bubbleOrder, changeBubbleOrder } = props;
1920
const { hoveredPaper, paperOrder, changePaperOrder } = props;
21+
const { trackMouseOver } = props;
2022

2123
// bubble section
2224
const handleAreaMouseOver = (area) => {
2325
if (hoveredBubble === area.area_uri) {
2426
return;
2527
}
2628

29+
if (trackMouseOver) {
30+
trackMatomoEvent("Knowledge map", "Hover bubble", "Bubble");
31+
}
32+
2733
changeBubbleOrder(area.area_uri);
2834
};
2935

3036
const handleOtherAreaZoomIn = (bubble) => {
3137
handleDeselectPaper();
3238
handleZoomIn(bubble, true);
39+
trackMatomoEvent("Knowledge map", "Zoom in", "Bubble");
3340
};
3441

3542
const getBubbleZoomClickHandler = (bubble) => {
3643
if (zoomedBubbleUri === bubble.area_uri) {
37-
return handleDeselectPaper;
44+
if (!selectedPaperId) {
45+
return undefined;
46+
}
47+
return () => {
48+
handleDeselectPaper();
49+
trackMatomoEvent("Knowledge map", "Deselect paper", "Bubble");
50+
};
3851
}
3952

4053
if (zoom) {
4154
return () => handleOtherAreaZoomIn(bubble);
4255
}
4356

44-
return () => handleZoomIn(bubble);
57+
return () => {
58+
handleZoomIn(bubble);
59+
trackMatomoEvent("Knowledge map", "Zoom in", "Bubble");
60+
};
4561
};
4662

4763
const sortedAreas = sortAreasByIds(areas, bubbleOrder);
@@ -50,7 +66,10 @@ const KnowledgeMap = (props) => {
5066
let onClick = undefined;
5167
let onMouseOver = () => changeBubbleOrder(null);
5268
if (zoom) {
53-
onClick = handleZoomOut;
69+
onClick = () => {
70+
handleZoomOut();
71+
trackMatomoEvent("Knowledge map", "Zoom out", "Chart");
72+
};
5473
onMouseOver = undefined;
5574
}
5675

@@ -65,7 +84,10 @@ const KnowledgeMap = (props) => {
6584
}
6685
let onDoubleClick = undefined;
6786
if (zoomedBubbleUri === bubble.area_uri) {
68-
onDoubleClick = handleZoomOut;
87+
onDoubleClick = () => {
88+
handleZoomOut();
89+
trackMatomoEvent("Knowledge map", "Zoom out", "Bubble");
90+
};
6991
}
7092

7193
return { onClick, onMouseOver, onDoubleClick };
@@ -79,6 +101,7 @@ const KnowledgeMap = (props) => {
79101
handleZoomIn(
80102
areas.find((bubble) => bubble.area_uri === paper.area_uri)
81103
);
104+
trackMatomoEvent("Knowledge map", "Zoom in", "Bubble");
82105
return;
83106
}
84107

@@ -90,10 +113,15 @@ const KnowledgeMap = (props) => {
90113
// bubble click event
91114
event.stopPropagation();
92115
handleSelectPaper(paper);
116+
trackMatomoEvent("Knowledge map", "Select paper", "Paper");
93117
};
94118

95119
const handlePaperMouseOver = (newEnlargeFactor) => {
96120
changePaperOrder(paper.safe_id, newEnlargeFactor);
121+
122+
if (trackMouseOver) {
123+
trackMatomoEvent("Knowledge map", "Hover paper", "Paper");
124+
}
97125
};
98126

99127
const handlePaperMouseOut = () => {
@@ -193,6 +221,7 @@ const mapStateToProps = (state) => ({
193221
hoveredPaper: state.paperOrder.hoveredPaper,
194222
paperOrder: state.paperOrder.order,
195223
enlargeFactor: state.paperOrder.enlargeFactor,
224+
trackMouseOver: state.tracking.trackMouseOver,
196225
});
197226

198227
export default connect(

vis/js/headstart.js

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ HeadstartFSM.prototype = {
3232
}
3333
},
3434

35+
// TODO delete this completely
3536
recordAction: function(id, category, action, user, timestamp, additional_params, post_data) {
3637

3738
if(!config.is_evaluation) {
@@ -47,9 +48,6 @@ HeadstartFSM.prototype = {
4748
if (services.includes("log")) {
4849
this.recordActionLog(category, action, id, user, timestamp, additional_params, post_data);
4950
}
50-
if (services.includes("matomo")) {
51-
this.recordActionMatomo(category, action, id, user, timestamp, additional_params, post_data);
52-
}
5351
if (services.includes("ga")) {
5452
this.recordActionGA(category, action, id, user, timestamp, additional_params, post_data);
5553
}
@@ -83,12 +81,6 @@ HeadstartFSM.prototype = {
8381
});
8482
},
8583

86-
recordActionMatomo: function(category, action, id) {
87-
if(typeof _paq !== "undefined") {
88-
_paq.push(['trackEvent', category, action, id]);
89-
}
90-
},
91-
9284
recordActionGA: function(category, action, id) {
9385
//gtag.js
9486
if(typeof gtag === "function") {

vis/js/intermediate.js

Lines changed: 4 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,17 @@ import { sanitizeInputData } from "./utils/data";
3131
* This class should ideally only talk to the mediator and redux
3232
*/
3333
class Intermediate {
34-
constructor(rescaleCallback, recordActionCallback) {
34+
constructor(rescaleCallback) {
3535
this.actionQueue = [];
3636

37-
this.recordActionCallback = recordActionCallback;
38-
this.recordActionParams = {};
39-
4037
const middleware = applyMiddleware(
4138
createFileChangeMiddleware(),
4239
createActionQueueMiddleware(this),
4340
createScrollMiddleware(),
4441
createRepeatedInitializeMiddleware(this),
4542
createChartTypeMiddleware(),
4643
createRescaleMiddleware(rescaleCallback),
47-
createRecordActionMiddleware(
48-
this.recordAction.bind(this),
49-
this.recordActionParams
50-
)
44+
createRecordActionMiddleware()
5145
);
5246

5347
this.store = createStore(rootReducer, middleware);
@@ -68,14 +62,6 @@ class Intermediate {
6862
const { size, width, height } = getChartSize(config, context);
6963
const list = getListSize(config, context, size);
7064

71-
Object.assign(this.recordActionParams, {
72-
title: config.title,
73-
user: config.user_id,
74-
localization: config.localization[config.language],
75-
mouseoverEvaluation: config.enable_mouseover_evaluation,
76-
scaleLabel: config.scale_label,
77-
});
78-
7965
const sanitizedMapData = sanitizeInputData(mapData);
8066

8167
this.store.dispatch(
@@ -124,38 +110,6 @@ class Intermediate {
124110
this.forceLayoutParams
125111
);
126112
}
127-
128-
/**
129-
* Log an action using the mediator's function.
130-
*
131-
* @param {string} id usually some title, e.g. paper.title / default is the config.title
132-
* @param {string} category some static key, such as "List"
133-
* @param {string} action some static key, such as "show"
134-
* @param {string} type some static key, such as "open_embed_modal"
135-
* @param {object} timestamp optional object / default is null
136-
* @param {string} additionalParams optional string / default is null
137-
* @param {object} postData optional object / default is null
138-
*/
139-
recordAction(
140-
id,
141-
category,
142-
action,
143-
type,
144-
timestamp = null,
145-
additionalParams = null,
146-
postData = null
147-
) {
148-
this.recordActionCallback(
149-
id,
150-
category,
151-
action,
152-
this.recordActionParams.user,
153-
type,
154-
timestamp,
155-
additionalParams,
156-
postData
157-
);
158-
}
159113
}
160114

161115
/**
@@ -309,11 +263,11 @@ function createFileChangeMiddleware() {
309263
};
310264
}
311265

312-
function createRecordActionMiddleware(callback, params) {
266+
function createRecordActionMiddleware() {
313267
return function ({ getState }) {
314268
return (next) => (action) => {
315269
const state = getState();
316-
logAction(action, state, callback, params);
270+
logAction(action, state);
317271
return next(action);
318272
};
319273
};

vis/js/reducers/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import service from "./service";
2828
import streamgraph from "./streamgraph";
2929
import timespan from "./timespan";
3030
import toolbar from "./toolbar";
31+
import tracking from "./tracking";
3132
import zoom from "./zoom";
3233

3334
export default combineReducers({
@@ -61,5 +62,6 @@ export default combineReducers({
6162
streamgraph,
6263
timespan,
6364
toolbar,
65+
tracking,
6466
zoom,
6567
});

vis/js/reducers/tracking.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const tracking = (state = {}, action) => {
2+
if (action.canceled) {
3+
return state;
4+
}
5+
6+
switch (action.type) {
7+
case "INITIALIZE":
8+
return {
9+
...state,
10+
trackMouseOver: action.configObject.enable_mouseover_evaluation,
11+
};
12+
default:
13+
return state;
14+
}
15+
};
16+
17+
export default tracking;

vis/js/templates/ListToggle.jsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
import React from "react";
22

33
import { useLocalizationContext } from "../components/LocalizationProvider";
4+
import useMatomo from "../utils/useMatomo";
45

56
const ListToggle = ({ show, docsNumber, onClick }) => {
67
const localization = useLocalizationContext();
8+
const { trackEvent } = useMatomo();
9+
10+
const handleClick = () => {
11+
onClick();
12+
if (show) {
13+
trackEvent("List controls", "Hide list", "List toggle");
14+
} else {
15+
trackEvent("List controls", "Show list", "List toggle");
16+
}
17+
};
718

819
return (
920
// html template starts here
10-
<div id="show_hide_button" className="row" onClick={onClick}>
21+
<div id="show_hide_button" className="row" onClick={handleClick}>
1122
<div className="col-xs-2"></div>
1223
<div className="col-xs-8" id="show_hide_button_label">
1324
<span id="show_hide_label">

0 commit comments

Comments
 (0)