Initial Release
This commit is contained in:
parent
0cc1bebf18
commit
5cc0ae8c18
202
LICENSE.txt
Normal file
202
LICENSE.txt
Normal file
|
@ -0,0 +1,202 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2020 Ekta Sood
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
48
README.md
48
README.md
|
@ -1 +1,47 @@
|
|||
Tool will be available soon.
|
||||
## Viz-Tool for Fixations
|
||||
|
||||
### Usage
|
||||
|
||||
1. Install dependencies with `npm i`.
|
||||
2. Run a local server with `./start.sh`.
|
||||
3. Load a file with fixations and its corresponding image of the text. There are some examples in the `example_data` folder.
|
||||
|
||||
![fig/menu.png](fig/menu.png)
|
||||
|
||||
4. You can also enter split screen mode via the button in the bottom left.
|
||||
|
||||
![fig/split_screen.png](fig/split_screen.png)
|
||||
|
||||
### Deployment
|
||||
|
||||
1. Run `npm run build` to generate bundle files in public folder
|
||||
2. Copy the entire public directory to your web root, you may also need a reverse proxy (nginx, apache)
|
||||
|
||||
## Data format explanation
|
||||
|
||||
Fixation data has to be provided in csv format with the following headers
|
||||
|
||||
|Header|Example|
|
||||
|---------|---------|
|
||||
| x y duration word_id word |646.0 284.0 675 74 exonerated|
|
||||
|
||||
## Citing Viz-Tool
|
||||
|
||||
```bibtex
|
||||
@inproceedings{sood-etal-2020-interpreting,
|
||||
title = "Interpreting Attention Models with Human Visual Attention in Machine Reading Comprehension",
|
||||
author = "Sood, Ekta and
|
||||
Tannert, Simon and
|
||||
Frassinelli, Diego and
|
||||
Bulling, Andreas and
|
||||
Vu, Ngoc Thang",
|
||||
booktitle = "Proceedings of the 24th Conference on Computational Natural Language Learning",
|
||||
month = nov,
|
||||
year = "2020",
|
||||
address = "Online",
|
||||
publisher = "Association for Computational Linguistics",
|
||||
url = "https://www.aclweb.org/anthology/2020.conll-1.2",
|
||||
pages = "12--25",
|
||||
abstract = "While neural networks with attention mechanisms have achieved superior performance on many natural language processing tasks, it remains unclear to which extent learned attention resembles human visual attention. In this paper, we propose a new method that leverages eye-tracking data to investigate the relationship between human visual attention and neural attention in machine reading comprehension. To this end, we introduce a novel 23 participant eye tracking dataset - MQA-RC, in which participants read movie plots and answered pre-defined questions. We compare state of the art networks based on long short-term memory (LSTM), convolutional neural models (CNN) and XLNet Transformer architectures. We find that higher similarity to human attention and performance significantly correlates to the LSTM and CNN models. However, we show this relationship does not hold true for the XLNet models {--} despite the fact that the XLNet performs best on this challenging task. Our results suggest that different architectures seem to learn rather different neural attention strategies and similarity of neural to human attention does not guarantee best performance.",
|
||||
}
|
||||
```
|
||||
|
|
163
example_data/317.txt_wrapped.txt
Normal file
163
example_data/317.txt_wrapped.txt
Normal file
|
@ -0,0 +1,163 @@
|
|||
# 317.txt_wrapped.txt.c
|
||||
x y dur word_id word
|
||||
916.0 529.0 3755 170 the
|
||||
715.0 131.0 117 37 field,
|
||||
593.0 65.0 280 0 When
|
||||
640.0 58.0 348 1 Don
|
||||
709.0 48.0 250 3 her
|
||||
818.0 35.0 302 5 she
|
||||
926.0 32.0 280
|
||||
989.0 23.0 318
|
||||
1121.0 38.0 210 12 which
|
||||
1086.0 34.0 282 12 which
|
||||
1147.0 44.0 210 13 results
|
||||
1215.0 54.0 270 14 in
|
||||
635.0 102.0 167 18 biker
|
||||
598.0 112.0 465 18 biker
|
||||
672.0 104.0 87 19 friends
|
||||
754.0 99.0 413 20 punching
|
||||
683.0 102.0 280 19 friends
|
||||
784.0 91.0 532 21 Don
|
||||
898.0 80.0 173 24 next
|
||||
862.0 90.0 267 23 The
|
||||
930.0 80.0 238 25 morning,
|
||||
1013.0 76.0 278 10 becomes
|
||||
1087.0 74.0 233 12 which
|
||||
1017.0 77.0 148 11 enraged,
|
||||
1166.0 92.0 100 30 his
|
||||
1175.0 89.0 98 30 his
|
||||
615.0 159.0 177 34 middle
|
||||
582.0 159.0 217
|
||||
816.0 131.0 198 40 nasty
|
||||
753.0 145.0 392 38 with
|
||||
728.0 147.0 210 37 field,
|
||||
570.0 205.0 270
|
||||
632.0 198.0 228 46 Later,
|
||||
673.0 194.0 235 47 Don
|
||||
752.0 187.0 230 50 a
|
||||
836.0 179.0 397 52 to
|
||||
979.0 171.0 200 55 from
|
||||
939.0 173.0 243 54 flowers
|
||||
1026.0 168.0 258 45 eye.
|
||||
1100.0 164.0 373
|
||||
1148.0 178.0 232 59 named
|
||||
1166.0 188.0 128 60 Sun
|
||||
1232.0 192.0 117 62 who
|
||||
1241.0 162.0 162
|
||||
1225.0 194.0 225 61 Green
|
||||
591.0 257.0 203 64 his
|
||||
562.0 255.0 322
|
||||
675.0 239.0 225 66 Don
|
||||
599.0 244.0 118 64 his
|
||||
1258.0 200.0 338 62 who
|
||||
582.0 255.0 350
|
||||
608.0 251.0 200 64 his
|
||||
672.0 243.0 407 66 Don
|
||||
718.0 239.0 237 67 leaves
|
||||
826.0 231.0 175 69 flowers
|
||||
951.0 221.0 252 73 of
|
||||
648.0 244.0 240 65 cut.
|
||||
987.0 226.0 232 74 the
|
||||
1084.0 216.0 287 76 woman,
|
||||
1123.0 214.0 197 59 named
|
||||
1174.0 229.0 317 77 Michelle
|
||||
1217.0 237.0 523 78 Pepe,
|
||||
914.0 233.0 155 72 grave
|
||||
1204.0 231.0 265 78 Pepe,
|
||||
577.0 290.0 1215
|
||||
625.0 281.0 275 81 originally
|
||||
768.0 277.0 223 83 might
|
||||
870.0 250.0 155 71 the
|
||||
834.0 261.0 198 85 the
|
||||
921.0 257.0 253 72 grave
|
||||
889.0 261.0 125 86 mother
|
||||
964.0 243.0 110 73 of
|
||||
1065.0 257.0 223 76 woman,
|
||||
1121.0 266.0 197 92 died
|
||||
1187.0 275.0 143 93 five
|
||||
595.0 340.0 362 96 Finally,
|
||||
574.0 338.0 200
|
||||
703.0 332.0 257 98 returns
|
||||
833.0 315.0 215 100 where
|
||||
929.0 316.0 380 103 a
|
||||
1063.0 312.0 423 106 from
|
||||
1147.0 320.0 310 108 admitting
|
||||
1217.0 319.0 180 109 she
|
||||
589.0 392.0 202
|
||||
542.0 395.0 317
|
||||
638.0 432.0 128 127 have
|
||||
646.0 403.0 258 127 have
|
||||
735.0 393.0 193 114 discusses
|
||||
660.0 392.0 183 112 him.
|
||||
759.0 379.0 592 114 discusses
|
||||
853.0 384.0 513 116 trip
|
||||
932.0 387.0 242 118 second
|
||||
836.0 381.0 265 116 trip
|
||||
949.0 374.0 232 119 letter
|
||||
1019.0 372.0 195 120 with
|
||||
1095.0 370.0 300 121 Winston,
|
||||
1181.0 367.0 375 123 theorizes
|
||||
1128.0 368.0 298 122 who
|
||||
1197.0 367.0 247 123 theorizes
|
||||
560.0 426.0 177
|
||||
533.0 433.0 292
|
||||
631.0 444.0 187 143 letters.
|
||||
604.0 438.0 215 126 might
|
||||
690.0 437.0 347 128 written
|
||||
752.0 435.0 280 129 the
|
||||
831.0 440.0 113 148 young
|
||||
1013.0 421.0 213 135 He
|
||||
974.0 417.0 320 134 hoax.
|
||||
1045.0 415.0 388 136 then
|
||||
1111.0 420.0 255 138 home
|
||||
1169.0 420.0 518 140 compare
|
||||
586.0 478.0 188
|
||||
553.0 476.0 232
|
||||
629.0 472.0 257 143 letters.
|
||||
704.0 469.0 238 145 then
|
||||
670.0 471.0 225 144 Don
|
||||
765.0 466.0 270 146 meets
|
||||
874.0 465.0 183 149 man
|
||||
847.0 467.0 207 149 man
|
||||
984.0 462.0 625 152 street
|
||||
1114.0 465.0 438 155 suspects
|
||||
1227.0 451.0 268 159 son.
|
||||
557.0 513.0 272
|
||||
652.0 520.0 160 164 meal,
|
||||
649.0 522.0 187 164 meal,
|
||||
745.0 518.0 267 166 when
|
||||
873.0 517.0 212 169 that
|
||||
740.0 525.0 278 166 when
|
||||
866.0 513.0 217 169 that
|
||||
942.0 518.0 280 171 young
|
||||
1022.0 510.0 225 173 believes
|
||||
1081.0 519.0 197 174 that
|
||||
1145.0 501.0 225 176 is
|
||||
1207.0 495.0 150 178 father,
|
||||
590.0 558.0 160 180 young
|
||||
540.0 561.0 205
|
||||
546.0 561.0 95
|
||||
617.0 553.0 187 180 young
|
||||
615.0 558.0 63 180 young
|
||||
689.0 557.0 335 182 becomes
|
||||
780.0 573.0 95 183 agitated
|
||||
515.0 785.0 187
|
||||
610.0 766.0 192
|
||||
541.0 770.0 102
|
||||
535.0 759.0 115
|
||||
650.0 749.0 268 187 does
|
||||
708.0 739.0 103 189 suspect
|
||||
716.0 736.0 103 189 suspect
|
||||
812.0 737.0 242 190 about
|
||||
887.0 732.0 355 192 young
|
||||
950.0 727.0 370 195 meets
|
||||
619.0 845.0 327 206 That
|
||||
667.0 847.0 148 207 he
|
||||
549.0 852.0 237
|
||||
589.0 837.0 330
|
||||
549.0 824.0 90
|
||||
651.0 825.0 238 200 That
|
||||
615.0 824.0 185 200 That
|
||||
543.0 821.0 160
|
||||
1808.0 1003.0 163
|
||||
1804.0 1008.0 1577
|
BIN
example_data/317.txt_wrapped.txt.c_dotsmap.png
Normal file
BIN
example_data/317.txt_wrapped.txt.c_dotsmap.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 86 KiB |
182
example_data/66.txt_wrapped.txt
Normal file
182
example_data/66.txt_wrapped.txt
Normal file
|
@ -0,0 +1,182 @@
|
|||
# 66.txt_wrapped.txt.c
|
||||
x y dur word_id word
|
||||
912.0 547.0 1822 162 eventually
|
||||
603.0 66.0 415 0 When
|
||||
574.0 71.0 220
|
||||
637.0 70.0 260 1 Mrs
|
||||
706.0 67.0 272 2 Moore
|
||||
795.0 60.0 348 5 clear
|
||||
892.0 49.0 207 7 she
|
||||
851.0 56.0 175 6 that
|
||||
820.0 63.0 185 5 clear
|
||||
934.0 52.0 247 8 firmly
|
||||
985.0 52.0 187 9 believes
|
||||
1056.0 53.0 428 11 Aziz's
|
||||
1127.0 50.0 318 12 innocence
|
||||
1215.0 67.0 200 13 and
|
||||
603.0 116.0 598 16 testify
|
||||
801.0 111.0 195 20 is
|
||||
759.0 129.0 287 34 during
|
||||
855.0 114.0 248 21 decided
|
||||
815.0 115.0 235 21 decided
|
||||
920.0 102.0 227 23 should
|
||||
1008.0 102.0 302 24 return
|
||||
927.0 107.0 297 23 should
|
||||
1003.0 104.0 342 24 return
|
||||
1022.0 127.0 107 40 at
|
||||
1128.0 83.0 358 27 She
|
||||
1152.0 70.0 165 12 innocence
|
||||
1227.0 93.0 172 28 subsequently
|
||||
642.0 140.0 145 31 fatal
|
||||
596.0 154.0 302 30 a
|
||||
661.0 146.0 345 32 heart
|
||||
725.0 142.0 288 33 attack
|
||||
767.0 137.0 270 34 during
|
||||
853.0 130.0 325 36 voyage
|
||||
937.0 123.0 450 23 should
|
||||
1000.0 121.0 223 24 return
|
||||
636.0 191.0 263 43 the
|
||||
614.0 195.0 208 43 the
|
||||
703.0 182.0 178 44 consternation
|
||||
789.0 175.0 285 46 her
|
||||
870.0 170.0 253 48 and
|
||||
790.0 179.0 237 46 her
|
||||
826.0 174.0 158 47 fianc
|
||||
906.0 171.0 252 49 friends,
|
||||
972.0 169.0 553 39 buried
|
||||
1063.0 168.0 230 41 sea.
|
||||
1004.0 171.0 235 50 Adela
|
||||
1115.0 161.0 255
|
||||
1162.0 173.0 157 55 heart
|
||||
1212.0 175.0 303 56 and
|
||||
1247.0 182.0 125 57 clears
|
||||
1206.0 175.0 308 56 and
|
||||
590.0 249.0 215 59 in
|
||||
564.0 246.0 250
|
||||
694.0 225.0 448 61 The
|
||||
779.0 224.0 278 62 Colonials
|
||||
823.0 220.0 198 64 forced
|
||||
920.0 216.0 312 66 an
|
||||
1009.0 219.0 188 67 ignominious
|
||||
1053.0 215.0 498 68 retreat
|
||||
1142.0 221.0 313 70 the
|
||||
1082.0 223.0 255 68 retreat
|
||||
1208.0 227.0 432 71 Indians
|
||||
583.0 298.0 522
|
||||
646.0 284.0 675 74 exonerated
|
||||
814.0 266.0 225 78 courtroom
|
||||
793.0 274.0 212 78 courtroom
|
||||
937.0 267.0 253 81 shoulders,
|
||||
1051.0 267.0 128 82 cheering
|
||||
1023.0 267.0 260 82 cheering
|
||||
1095.0 288.0 138 83 wildly.
|
||||
1140.0 273.0 87 83 wildly.
|
||||
1150.0 249.0 155 70 the
|
||||
1209.0 272.0 382 84 Fielding
|
||||
1195.0 313.0 72 101 leaves
|
||||
1111.0 317.0 328 99 aftermath,
|
||||
551.0 360.0 150
|
||||
593.0 336.0 317 86 after
|
||||
561.0 336.0 207
|
||||
637.0 329.0 315 86 after
|
||||
702.0 327.0 247 88 since
|
||||
661.0 332.0 292 87 Adela
|
||||
866.0 320.0 235 93 else
|
||||
928.0 314.0 167 95 turn
|
||||
1027.0 314.0 237 98 the
|
||||
1095.0 315.0 158 99 aftermath,
|
||||
1135.0 320.0 210 100 Adela
|
||||
1192.0 313.0 255 101 leaves
|
||||
1168.0 317.0 153 100 Adela
|
||||
582.0 385.0 935
|
||||
647.0 375.0 222 104 Dr
|
||||
734.0 365.0 225 106 feeling
|
||||
705.0 369.0 257 105 Aziz,
|
||||
865.0 363.0 215 108 by
|
||||
831.0 367.0 213 107 betrayed
|
||||
951.0 367.0 512 110 friend
|
||||
1052.0 369.0 263 112 abandons
|
||||
1031.0 371.0 338 111 Fielding,
|
||||
1120.0 360.0 343 113 his
|
||||
1189.0 361.0 340 114 Western
|
||||
1242.0 369.0 155 115 attire,
|
||||
604.0 438.0 195 117 traditional
|
||||
575.0 424.0 252
|
||||
767.0 405.0 508 119 and
|
||||
873.0 407.0 308 121 from
|
||||
924.0 413.0 273 122 ex-pat
|
||||
1030.0 411.0 482 124 opening
|
||||
1132.0 405.0 175 126 clinic
|
||||
1181.0 413.0 345 127 in
|
||||
1239.0 419.0 135 128 Kashmir
|
||||
615.0 466.0 183 131 Himalayas.
|
||||
566.0 463.0 363
|
||||
656.0 469.0 523 131 Himalayas.
|
||||
759.0 463.0 298 132 Meanwhile,
|
||||
808.0 476.0 100 133 through
|
||||
888.0 457.0 227 135 Fielding
|
||||
944.0 469.0 252 135 Fielding
|
||||
921.0 463.0 238 135 Fielding
|
||||
1020.0 459.0 287 137 married
|
||||
1083.0 457.0 273 138 Stella
|
||||
1148.0 463.0 502 139 Moore,
|
||||
1070.0 467.0 218 138 Stella
|
||||
1139.0 464.0 217 139 Moore,
|
||||
585.0 508.0 182
|
||||
543.0 504.0 275
|
||||
707.0 511.0 285 144 second
|
||||
1027.0 501.0 247 150 first
|
||||
1138.0 509.0 412 152 child.
|
||||
1193.0 519.0 490 153 While
|
||||
623.0 557.0 195 156 angry
|
||||
544.0 562.0 272
|
||||
657.0 564.0 262 157 and
|
||||
761.0 568.0 290 160 years,
|
||||
855.0 548.0 702 162 eventually
|
||||
961.0 543.0 255 163 reconciles
|
||||
1085.0 548.0 480 165 Fielding
|
||||
1169.0 557.0 368 166 and
|
||||
1238.0 574.0 70 168 to
|
||||
574.0 611.0 403
|
||||
656.0 620.0 135
|
||||
776.0 615.0 183 174 and
|
||||
594.0 759.0 213
|
||||
548.0 760.0 168
|
||||
619.0 750.0 243 176 Does
|
||||
660.0 750.0 250 177 Aziz
|
||||
668.0 752.0 92 177 Aziz
|
||||
657.0 753.0 153 177 Aziz
|
||||
712.0 756.0 65
|
||||
802.0 749.0 160 179 Fielding
|
||||
906.0 727.0 207 183 of
|
||||
697.0 747.0 225 178 forgive
|
||||
605.0 740.0 212 176 Does
|
||||
561.0 749.0 95
|
||||
642.0 734.0 298 177 Aziz
|
||||
732.0 735.0 287 178 forgive
|
||||
836.0 735.0 337 181 the
|
||||
673.0 615.0 292 172 his
|
||||
796.0 566.0 245 160 years,
|
||||
1133.0 549.0 313 165 Fielding
|
||||
1062.0 550.0 200 164 with
|
||||
919.0 544.0 320 162 eventually
|
||||
986.0 541.0 130 163 reconciles
|
||||
605.0 863.0 177 192 2:
|
||||
573.0 856.0 200
|
||||
571.0 911.0 282
|
||||
532.0 909.0 235
|
||||
633.0 826.0 282 187 No,
|
||||
696.0 819.0 180 189 he
|
||||
741.0 820.0 233 190 forgives
|
||||
602.0 850.0 155 192 2:
|
||||
619.0 822.0 232 187 No,
|
||||
677.0 815.0 253 188 but
|
||||
603.0 904.0 238 194 3:
|
||||
549.0 938.0 197
|
||||
1244.0 886.0 67
|
||||
1803.0 1029.0 67
|
||||
1420.0 1292.0 68
|
||||
1385.0 1289.0 105
|
||||
1426.0 1280.0 132
|
||||
1804.0 999.0 80
|
||||
1405.0 1281.0 278
|
BIN
example_data/66.txt_wrapped.txt.c_dotsmap.png
Normal file
BIN
example_data/66.txt_wrapped.txt.c_dotsmap.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 89 KiB |
199
example_data/848.txt_wrapped.txt
Normal file
199
example_data/848.txt_wrapped.txt
Normal file
|
@ -0,0 +1,199 @@
|
|||
# 848.txt_wrapped.txt.c
|
||||
x y dur word_id word
|
||||
920.0 530.0 213 169 as
|
||||
644.0 475.0 108 143 clutching
|
||||
613.0 73.0 222 0 Whale
|
||||
583.0 72.0 428
|
||||
637.0 67.0 292 0 Whale
|
||||
697.0 63.0 455 2 only
|
||||
774.0 62.0 288 5 sweater,
|
||||
842.0 53.0 318 6 so
|
||||
902.0 43.0 493 7 Boone
|
||||
933.0 45.0 178 8 wears
|
||||
909.0 48.0 182 7 Boone
|
||||
987.0 44.0 322 10 towel
|
||||
1039.0 39.0 287 11 wrapped
|
||||
1130.0 38.0 297 12 around
|
||||
1076.0 37.0 203 11 wrapped
|
||||
1177.0 50.0 185 14 waist.
|
||||
1211.0 56.0 198 14 waist.
|
||||
664.0 87.0 152 17 to
|
||||
571.0 105.0 250
|
||||
657.0 107.0 142 17 to
|
||||
693.0 87.0 130 18 try
|
||||
724.0 103.0 72 19 to
|
||||
746.0 102.0 427 20 sketch
|
||||
827.0 95.0 308 21 Boone
|
||||
885.0 87.0 220 23 more
|
||||
990.0 82.0 255 25 After
|
||||
959.0 85.0 223 25 After
|
||||
1054.0 82.0 202 27 minutes,
|
||||
1145.0 98.0 312 29 shows
|
||||
1215.0 102.0 268 30 his
|
||||
626.0 160.0 188 33 Boone,
|
||||
567.0 163.0 365
|
||||
657.0 154.0 620 34 disclosing
|
||||
798.0 143.0 255 37 has
|
||||
884.0 128.0 368 39 his
|
||||
1002.0 120.0 228 25 After
|
||||
1087.0 125.0 228 44 Boone
|
||||
1035.0 126.0 228 42 draw.
|
||||
1122.0 132.0 280 44 Boone
|
||||
1197.0 143.0 175 46 his
|
||||
590.0 200.0 608 49 pose
|
||||
690.0 191.0 502 51 Whale
|
||||
647.0 197.0 313 50 nude,
|
||||
729.0 190.0 240 52 makes
|
||||
827.0 184.0 253 54 wear
|
||||
799.0 196.0 157 53 him
|
||||
878.0 190.0 167 56 World
|
||||
785.0 197.0 257 53 him
|
||||
961.0 187.0 467 59 gas
|
||||
1127.0 201.0 208 63 uses
|
||||
1066.0 189.0 342 62 then
|
||||
1196.0 198.0 178 65 opportunity
|
||||
585.0 255.0 208
|
||||
666.0 242.0 192 69 sexual
|
||||
721.0 242.0 272 70 advance
|
||||
791.0 242.0 225 72 Boone,
|
||||
842.0 245.0 238 72 Boone,
|
||||
939.0 233.0 355 74 his
|
||||
897.0 232.0 175 73 kissing
|
||||
1022.0 226.0 287 76 Boone
|
||||
1089.0 225.0 573 77 becomes
|
||||
1165.0 236.0 172 78 enraged
|
||||
1213.0 240.0 273 79 and
|
||||
640.0 295.0 233 81 Whale,
|
||||
591.0 295.0 375 81 Whale,
|
||||
656.0 296.0 270 82 who
|
||||
740.0 288.0 250 83 confesses
|
||||
844.0 275.0 242 86 had
|
||||
926.0 279.0 242 88 his
|
||||
1024.0 272.0 262 91 begs
|
||||
1002.0 270.0 178 90 and
|
||||
1106.0 266.0 285 93 to
|
||||
1197.0 278.0 307 95 him
|
||||
1221.0 275.0 120 96 to
|
||||
616.0 341.0 452 100 his
|
||||
744.0 330.0 285 102 Boone
|
||||
717.0 335.0 162 101 suffering.
|
||||
801.0 326.0 155 103 refuses,
|
||||
882.0 325.0 268 104 puts
|
||||
853.0 333.0 307 103 refuses,
|
||||
992.0 321.0 333 107 bed,
|
||||
924.0 322.0 125 105 Whale
|
||||
1052.0 317.0 272 109 sleeps
|
||||
1121.0 319.0 152 110 downstairs.
|
||||
1021.0 320.0 263 108 then
|
||||
1206.0 322.0 428 111 The
|
||||
709.0 369.0 173 114 Hanna
|
||||
610.0 377.0 190 113 morning,
|
||||
585.0 375.0 197
|
||||
671.0 370.0 338 114 Hanna
|
||||
758.0 376.0 213 116 alarmed
|
||||
891.0 375.0 425 119 can't
|
||||
964.0 369.0 170 121 Whale,
|
||||
1033.0 367.0 383 122 prompting
|
||||
1132.0 365.0 318 124 search
|
||||
1094.0 365.0 177 123 a
|
||||
669.0 425.0 232 129 Boone
|
||||
627.0 424.0 170 128 Hanna.
|
||||
721.0 425.0 208 130 finds
|
||||
828.0 423.0 330 132 floating
|
||||
896.0 413.0 185 133 dead
|
||||
1031.0 423.0 362 138 a
|
||||
1133.0 416.0 232 139 distraught
|
||||
1164.0 415.0 138 140 Hanna
|
||||
604.0 472.0 277 143 clutching
|
||||
672.0 473.0 312 144 a
|
||||
816.0 471.0 93 147 Boone
|
||||
837.0 467.0 197 147 Boone
|
||||
955.0 474.0 208 150 agree
|
||||
1042.0 470.0 168 152 Boone
|
||||
1132.0 459.0 277 154 disappear
|
||||
1230.0 455.0 185 155 from
|
||||
600.0 515.0 152 158 to
|
||||
584.0 520.0 313
|
||||
670.0 532.0 215 164 closes
|
||||
596.0 552.0 435 162 The
|
||||
705.0 590.0 333 180 Frankenstein
|
||||
649.0 594.0 172 179 of
|
||||
574.0 604.0 192
|
||||
673.0 541.0 363 164 closes
|
||||
719.0 546.0 168 165 roughly
|
||||
807.0 548.0 480 167 decade
|
||||
906.0 549.0 282 169 as
|
||||
1016.0 562.0 260 172 his
|
||||
1103.0 558.0 302 174 son,
|
||||
1182.0 542.0 227 175 Michael,
|
||||
601.0 603.0 190 178 Bride
|
||||
553.0 606.0 197
|
||||
736.0 586.0 325 180 Frankenstein
|
||||
616.0 557.0 340 162 The
|
||||
849.0 543.0 212 167 decade
|
||||
724.0 544.0 170 165 roughly
|
||||
665.0 556.0 237 164 closes
|
||||
603.0 561.0 138 162 The
|
||||
605.0 570.0 112 162 The
|
||||
680.0 558.0 187 164 closes
|
||||
754.0 575.0 153 180 Frankenstein
|
||||
707.0 572.0 68 164 closes
|
||||
707.0 566.0 82 164 closes
|
||||
804.0 569.0 142 167 decade
|
||||
742.0 570.0 63 165 roughly
|
||||
741.0 591.0 73 180 Frankenstein
|
||||
819.0 589.0 278 182 television.
|
||||
922.0 563.0 217 169 as
|
||||
985.0 569.0 390 171 and
|
||||
1085.0 562.0 203 173 young
|
||||
1170.0 542.0 215 175 Michael,
|
||||
644.0 657.0 205
|
||||
589.0 611.0 167
|
||||
565.0 614.0 195
|
||||
558.0 778.0 92
|
||||
552.0 778.0 190
|
||||
644.0 762.0 322
|
||||
544.0 772.0 85
|
||||
520.0 778.0 177
|
||||
630.0 755.0 183
|
||||
709.0 748.0 203 185 Whale's
|
||||
525.0 872.0 188
|
||||
684.0 753.0 245 185 Whale's
|
||||
824.0 428.0 220 132 floating
|
||||
790.0 489.0 168
|
||||
776.0 470.0 142 146 note.
|
||||
805.0 398.0 275 132 floating
|
||||
880.0 413.0 265 133 dead
|
||||
1094.0 422.0 202 139 distraught
|
||||
1030.0 363.0 248 122 prompting
|
||||
916.0 339.0 275 105 Whale
|
||||
923.0 371.0 250 120 find
|
||||
1023.0 369.0 260 122 prompting
|
||||
1127.0 362.0 195 124 search
|
||||
1101.0 362.0 233 123 a
|
||||
1165.0 366.0 172 124 search
|
||||
1182.0 335.0 178 110 downstairs.
|
||||
602.0 384.0 362 113 morning,
|
||||
746.0 380.0 242 116 alarmed
|
||||
713.0 392.0 202 115 is
|
||||
888.0 460.0 312 149 Hanna
|
||||
960.0 422.0 175 136 pool,
|
||||
1052.0 416.0 312 139 distraught
|
||||
1108.0 371.0 363 123 a
|
||||
716.0 424.0 287 130 finds
|
||||
651.0 424.0 218 129 Boone
|
||||
766.0 416.0 192 131 Whale
|
||||
682.0 460.0 323 144 a
|
||||
586.0 452.0 103
|
||||
1024.0 420.0 280 137 as
|
||||
999.0 423.0 178 136 pool,
|
||||
1115.0 428.0 202 139 distraught
|
||||
1156.0 414.0 280 140 Hanna
|
||||
595.0 476.0 178 143 clutching
|
||||
556.0 851.0 335
|
||||
570.0 898.0 145
|
||||
543.0 876.0 183
|
||||
568.0 880.0 148
|
||||
1685.0 918.0 88
|
||||
1846.0 1003.0 357
|
||||
1817.0 999.0 915
|
BIN
example_data/848.txt_wrapped.txt.c_dotsmap.png
Normal file
BIN
example_data/848.txt_wrapped.txt.c_dotsmap.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 83 KiB |
BIN
fig/menu.png
Normal file
BIN
fig/menu.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
BIN
fig/split_screen.png
Normal file
BIN
fig/split_screen.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 538 KiB |
22
package.json
Normal file
22
package.json
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "svelte-app",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"build": "rollup -c",
|
||||
"dev": "rollup -c -w",
|
||||
"start": "sirv public"
|
||||
},
|
||||
"devDependencies": {
|
||||
"rollup": "^1.12.0",
|
||||
"rollup-plugin-commonjs": "^10.0.0",
|
||||
"rollup-plugin-livereload": "^1.0.0",
|
||||
"rollup-plugin-node-resolve": "^5.2.0",
|
||||
"rollup-plugin-svelte": "~6.1.1",
|
||||
"rollup-plugin-terser": "^5.1.2",
|
||||
"rollup-plugin-css-only": "^1.0.0",
|
||||
"svelte": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"sirv-cli": "^0.4.4"
|
||||
}
|
||||
}
|
6
public/base.css
Normal file
6
public/base.css
Normal file
|
@ -0,0 +1,6 @@
|
|||
html, body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
18
public/index.html
Normal file
18
public/index.html
Normal file
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<meta name='viewport' content='width=device-width,initial-scale=1'>
|
||||
|
||||
<title>Fixation Visualization Tool</title>
|
||||
|
||||
<link rel="stylesheet" href="base.css">
|
||||
<link rel='stylesheet' href='/build/bundle.css'>
|
||||
<link rel='stylesheet' href='/build/vendor.css'>
|
||||
|
||||
<script defer src='/build/bundle.js'></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
74
rollup.config.js
Normal file
74
rollup.config.js
Normal file
|
@ -0,0 +1,74 @@
|
|||
import svelte from 'rollup-plugin-svelte';
|
||||
import resolve from 'rollup-plugin-node-resolve';
|
||||
import commonjs from 'rollup-plugin-commonjs';
|
||||
import livereload from 'rollup-plugin-livereload';
|
||||
import { terser } from 'rollup-plugin-terser';
|
||||
import css from 'rollup-plugin-css-only';
|
||||
|
||||
const production = !process.env.ROLLUP_WATCH;
|
||||
|
||||
export default {
|
||||
input: 'src/main.js',
|
||||
output: {
|
||||
sourcemap: true,
|
||||
format: 'iife',
|
||||
name: 'app',
|
||||
file: 'public/build/bundle.js'
|
||||
},
|
||||
plugins: [
|
||||
svelte({
|
||||
// enable run-time checks when not in production
|
||||
dev: !production,
|
||||
// we'll extract any component CSS out into
|
||||
// a separate file — better for performance
|
||||
css: css => {
|
||||
css.write('bundle.css');
|
||||
}
|
||||
}),
|
||||
|
||||
css({ output: 'public/build/vendor.css' }),
|
||||
|
||||
// If you have external dependencies installed from
|
||||
// npm, you'll most likely need these plugins. In
|
||||
// some cases you'll need additional configuration —
|
||||
// consult the documentation for details:
|
||||
// https://github.com/rollup/rollup-plugin-commonjs
|
||||
resolve({
|
||||
browser: true,
|
||||
dedupe: importee => importee === 'svelte' || importee.startsWith('svelte/')
|
||||
}),
|
||||
commonjs(),
|
||||
|
||||
// In dev mode, call `npm run start` once
|
||||
// the bundle has been generated
|
||||
!production && serve(),
|
||||
|
||||
// Watch the `public` directory and refresh the
|
||||
// browser on changes when not in production
|
||||
!production && livereload('public'),
|
||||
|
||||
// If we're building for production (npm run build
|
||||
// instead of npm run dev), minify
|
||||
production && terser()
|
||||
],
|
||||
watch: {
|
||||
clearScreen: false
|
||||
}
|
||||
};
|
||||
|
||||
function serve() {
|
||||
let started = false;
|
||||
|
||||
return {
|
||||
writeBundle() {
|
||||
if (!started) {
|
||||
started = true;
|
||||
|
||||
require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
|
||||
stdio: ['ignore', 'inherit', 'inherit'],
|
||||
shell: true
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
127
src/App.svelte
Normal file
127
src/App.svelte
Normal file
|
@ -0,0 +1,127 @@
|
|||
<script>
|
||||
|
||||
import Visualization from './Visualization.svelte';
|
||||
import { config } from './stores.js';
|
||||
|
||||
import './vendor/normalize.css';
|
||||
import './vendor/milligram.min.css';
|
||||
|
||||
let isAnimated = false;
|
||||
let splitscreen = false;
|
||||
let controlsOpen = false;
|
||||
let left, right;
|
||||
|
||||
function handleKeyboard(event) {
|
||||
switch (event.code) {
|
||||
case 'ArrowLeft':
|
||||
//i = (i>0) ? i-1 : data.length-1;
|
||||
event.preventDefault();
|
||||
break;
|
||||
|
||||
case 'ArrowRight':
|
||||
//i = (i<data.length-1) ? i+1 : 0;
|
||||
event.preventDefault();
|
||||
break;
|
||||
|
||||
case 'ArrowUp':
|
||||
$config.speed += 10;
|
||||
event.preventDefault();
|
||||
break;
|
||||
|
||||
case 'ArrowDown':
|
||||
$config.speed -= 10;
|
||||
event.preventDefault();
|
||||
break;
|
||||
|
||||
case 'Space':
|
||||
isAnimated = !isAnimated;
|
||||
event.preventDefault();
|
||||
break;
|
||||
}
|
||||
//log current index on the lower right
|
||||
}
|
||||
|
||||
function reset() {
|
||||
left.reset();
|
||||
if (splitscreen) {
|
||||
right.reset();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<svelte:window on:keydown={handleKeyboard} />
|
||||
|
||||
<main>
|
||||
<Visualization bind:this={left} {isAnimated}/>
|
||||
{#if splitscreen}<Visualization bind:this={right} {isAnimated}/>{/if}
|
||||
</main>
|
||||
<aside class:open={controlsOpen}>
|
||||
<label class="hideCheckbox toggle" title="Open Controls">⚙<input type="checkbox" bind:checked={controlsOpen}></label>
|
||||
<div id="controls">
|
||||
<h3>Controls</h3>
|
||||
<p><small>Press Space to pause and use arrow keys to skip or change speed</small></p>
|
||||
<label>Zoom:<br/><input type="number" id="zoom" step="1" value={$config.zoom} on:change={e => $config.zoom = e.target.value}></label>
|
||||
<label>Speed:<br/><input type="number" id="speed" step="1" value={$config.speed} on:change={e => $config.speed = e.target.value}></label>
|
||||
<label>Duration Multiplier:<br/><input type="number" id="duration_multiplier" step="0.1" value={$config.duration_multiplier} on:change={e => $config.duration_multiplier = e.target.value}></label>
|
||||
<label>Trace Length:<br/><input type="number" id="trace_length" step="1" value={$config.trace_length} on:change={e => $config.trace_length = e.target.value}></label>
|
||||
<label>Duration Function Exponent:<br/><input type="number" id="exp" step="0.1" value={$config.duration_exponent} on:change={e => $config.duration_exponent = e.target.value}></label>
|
||||
</div>
|
||||
<label id="run" class="hideCheckbox toggle" title="Run Animation">{#if !isAnimated}▶{:else}⏸{/if}<input type="checkbox" bind:checked={isAnimated}></label>
|
||||
<label id="split" class="hideCheckbox toggle" title="Make Splitscreen">{#if !splitscreen}🗖{:else}🗗{/if}<input type="checkbox" bind:checked={splitscreen}></label>
|
||||
<span id="reset" class="toggle" title="Reset Animation" on:click={reset}>↶</span>
|
||||
</aside>
|
||||
|
||||
<style>
|
||||
|
||||
main {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
aside {
|
||||
position: absolute;
|
||||
left: -20vw;
|
||||
transition: left 0.5s;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 20vw;
|
||||
padding: 20px;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.open {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.toggle {
|
||||
position: absolute;
|
||||
right: -30px;
|
||||
width: 20px;
|
||||
font-size: 20px;
|
||||
line-height: 20px;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
transition: left 0.5s;
|
||||
margin: 0;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.hideCheckbox > input {
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
}
|
||||
|
||||
#run {
|
||||
bottom: 100px;
|
||||
}
|
||||
|
||||
#split {
|
||||
bottom: 60px;
|
||||
}
|
||||
|
||||
#reset {
|
||||
bottom: 20px;
|
||||
}
|
||||
</style>
|
52
src/FilePicker.svelte
Normal file
52
src/FilePicker.svelte
Normal file
|
@ -0,0 +1,52 @@
|
|||
<script>
|
||||
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { readFileAsync } from './helpers';
|
||||
import Papa from './vendor/papaparse.min.js';
|
||||
|
||||
let datafiles, imagefiles, isValid, fixation_data, sequential_fixation_data;
|
||||
const image = new Image();
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
$: isValid = datafiles && imagefiles && datafiles[0] && imagefiles[0];
|
||||
|
||||
async function visualize() {
|
||||
|
||||
image.src = await readFileAsync(imagefiles[0]);
|
||||
|
||||
let parsing = new Promise( resolve => {
|
||||
Papa.parse(datafiles[0], {
|
||||
comments: '#',
|
||||
header: true,
|
||||
dynamicTyping: true,
|
||||
complete: results => {
|
||||
if (!results.data[0].x || !results.data[0].y || !results.data[0].dur || !results.data[0].word_id || !results.data[0].word) {
|
||||
throw Error('Data malformed. Please use csv style tab-separated format with headers x,y,dur,word_id, word as first line.');
|
||||
}
|
||||
fixation_data = results.data;
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
parsing.then( () => {
|
||||
dispatch('load', {image, fixation_data})
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<div id="overlay">
|
||||
<h1>Choose Fixation Data and Image</h1>
|
||||
<label>Fixation Data<br/><input bind:files={datafiles} type="file" accept=".txt" /></label>
|
||||
<label>Image<br /><input bind:files={imagefiles} type="file" accept=".png, .jpg" /></label>
|
||||
<button id="run-button" class="button" on:click={visualize} disabled={!isValid}>Visualize!</button>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
#overlay {
|
||||
width: 400px;
|
||||
height: 200px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
203
src/Visualization.svelte
Normal file
203
src/Visualization.svelte
Normal file
|
@ -0,0 +1,203 @@
|
|||
<script>
|
||||
export let isAnimated = false;
|
||||
|
||||
import FilePicker from './FilePicker.svelte';
|
||||
|
||||
import { onMount, onDestroy, tick as nextTick } from 'svelte';
|
||||
import { config } from './stores.js';
|
||||
import { aggregateWordFixations } from './helpers';
|
||||
|
||||
let observer, canvas, progress, ctx, show_sequential, fixation_data, sequential_fixation_data, fixation_backdrop, data, container;
|
||||
|
||||
$: {
|
||||
data = (show_sequential) ? sequential_fixation_data : fixation_data;
|
||||
reset();
|
||||
}
|
||||
|
||||
let i = 0, t = null, isInitialized = false;
|
||||
|
||||
onMount(() => {
|
||||
ctx = canvas.getContext('2d');
|
||||
observer = new ResizeObserver( entries => {
|
||||
canvas.height = entries[0].contentRect.height;
|
||||
canvas.width = entries[0].contentRect.width;
|
||||
});
|
||||
observer.observe(container);
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
observer.disconnect();
|
||||
});
|
||||
|
||||
async function onLoad(event) {
|
||||
fixation_data = event.detail.fixation_data;
|
||||
sequential_fixation_data = aggregateWordFixations(event.detail.fixation_data);
|
||||
fixation_backdrop = event.detail.image;
|
||||
isInitialized = true;
|
||||
await nextTick();
|
||||
//config.update(c => {c.$config.zoom = canvas.width/fixation_backdrop.width; return c;});
|
||||
requestAnimationFrame(tick);
|
||||
}
|
||||
|
||||
function tick(time) {
|
||||
if (!data || !fixation_backdrop) {
|
||||
requestAnimationFrame(tick);
|
||||
return;
|
||||
}
|
||||
|
||||
let dt;
|
||||
|
||||
if (isAnimated){
|
||||
if (t == null) t = time;
|
||||
dt = (time - t)*$config.speed/100
|
||||
if (dt > data[i].dur) {
|
||||
i = (i<data.length-1)?i+1:0;
|
||||
t = time;
|
||||
progress.style.width = (100/data.length*i)+'%';
|
||||
}
|
||||
} else {
|
||||
dt = data[i].dur;
|
||||
progress.style.width = (100/data.length*i)+'%';
|
||||
}
|
||||
|
||||
ctx.clearRect(0, 0, 5000, 5000);
|
||||
ctx.save();
|
||||
|
||||
drawBackdrop();
|
||||
drawFixation(data[i], dt);
|
||||
drawTrace(data.slice((i-$config.trace_length>0)?i-$config.trace_length:0,i+1))
|
||||
ctx.restore();
|
||||
|
||||
requestAnimationFrame(tick);
|
||||
}
|
||||
|
||||
export function reset() {
|
||||
i = 0;
|
||||
t = null;
|
||||
}
|
||||
|
||||
function transform({ x, y }) {
|
||||
// transforms coordinates from image space into drawing space
|
||||
return [$config.zoom/100 * x + $config.translatex, $config.zoom/100 * y + $config.translatey]
|
||||
}
|
||||
|
||||
function drawBackdrop() {
|
||||
ctx.drawImage(fixation_backdrop, $config.translatex, $config.translatey, $config.zoom/100*fixation_backdrop.width, $config.zoom/100*fixation_backdrop.height);
|
||||
}
|
||||
|
||||
function drawFixation({ x, y, dur }, dt) {
|
||||
ctx.save();
|
||||
ctx.beginPath();
|
||||
let radius = Math.pow(dt/dur, $config.duration_exponent)*dur*$config.duration_multiplier;
|
||||
let [xt, yt] = transform({x, y});
|
||||
let gradient;
|
||||
try {
|
||||
gradient = ctx.createRadialGradient(xt,yt,0, xt,yt,radius);
|
||||
} catch(e) {
|
||||
console.error(e);
|
||||
return;
|
||||
}
|
||||
gradient.addColorStop(0, 'rgb(200, 0, 0, 0.5)');
|
||||
gradient.addColorStop(1, 'rgb(200, 0, 0, 0)');
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.arc(xt, yt, radius, 0, Math.PI*2, true);
|
||||
ctx.fill();
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
function drawTrace(trace) {
|
||||
ctx.save()
|
||||
ctx.lineWidth = $config.trace_width;
|
||||
let alpha = 0.2 + 0.8/$config.trace_length;
|
||||
let i=0, xt, yt, xtn, ytn;
|
||||
for (i; i<trace.length-1; i++) {
|
||||
let { x, y } = trace[i];
|
||||
let { x:xn, y:yn } = trace[i+1];
|
||||
[xt, yt] = transform({x, y});
|
||||
[xtn, ytn] = transform({x:xn, y:yn});
|
||||
ctx.strokeStyle = `rgba(0,0,0,${alpha}`;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(xt, yt);
|
||||
ctx.arc(xt, yt, $config.trace_radius, 0, Math.PI*2, true);
|
||||
ctx.lineTo(xtn, ytn);
|
||||
ctx.stroke();
|
||||
alpha += 0.8/$config.trace_length;
|
||||
}
|
||||
ctx.beginPath();
|
||||
ctx.arc(xt, yt, $config.trace_radius, 0, Math.PI*2, true);
|
||||
ctx.stroke();
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
function translate(e) {
|
||||
if (e.buttons == 1) {
|
||||
$config.translatex += e.movementX;
|
||||
$config.translatey += e.movementY;
|
||||
}
|
||||
}
|
||||
|
||||
function setZoom(e) {
|
||||
$config.zoom += (e.deltaY > 0) ? -1 : 1;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div bind:this={container} id="container">
|
||||
{#if !isInitialized}
|
||||
<FilePicker on:load={onLoad} />
|
||||
{/if}
|
||||
<span id="loadFile" class:hide={!isInitialized} title="Close and load other files" on:click={() => isInitialized = false}>🞩</span>
|
||||
<div id="controls" class:hide={!isInitialized}>
|
||||
<label title="Aggregates multiple (re-)visits into one fixation per word. Averages the fixation position and plays back in word order. Use to compare to fixation prediction models."><input type="checkbox" bind:checked={show_sequential}> As sequential word fixations</label>
|
||||
</div>
|
||||
<canvas class:hide={!isInitialized} bind:this={canvas} on:mousemove={translate} on:wheel|preventDefault={setZoom} height="1080" width="1920">This browser does not support canvas animations, which are required to render the visualization.</canvas>
|
||||
<div id="progress" bind:this={progress}></div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
canvas {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#loadFile {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
cursor: pointer;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
#container {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#progress {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 0;
|
||||
height: 20px;
|
||||
background: #9b4dca;
|
||||
}
|
||||
|
||||
#controls {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
text-align: right;
|
||||
background: rgba(255,255,255,0.5);
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
40
src/helpers.js
Normal file
40
src/helpers.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
export function readFileAsync(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
resolve(reader.result);
|
||||
};
|
||||
reader.onerror = reject;
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
}
|
||||
|
||||
export function aggregateWordFixations(data) {
|
||||
//slicing off first fixation since it is the calibration in center
|
||||
let sorted = data.filter( item => item.word_id ).slice(1).sort((a,b) => a.word_id-b.word_id);
|
||||
//add first back in
|
||||
sorted.unshift(data[0]);
|
||||
//aggregate fixations for same words in bags
|
||||
let aggregate = sorted.reduce( (acc, val) => {
|
||||
if (acc[0].length == 0 || val.word_id == acc[acc.length-1][0].word_id) {
|
||||
acc[acc.length-1].push(val)
|
||||
} else {
|
||||
acc.push([val]);
|
||||
}
|
||||
return acc;
|
||||
}, [[]]);
|
||||
//average fixation coordinates and sum duration for each bag
|
||||
return aggregate.map( bag => {
|
||||
let word = bag[0].word;
|
||||
let word_id = bag[0].word_id;
|
||||
let x=0;
|
||||
let y=0;
|
||||
let dur=0;
|
||||
for (let fixation of bag) {
|
||||
x += fixation.x/bag.length;
|
||||
y += fixation.y/bag.length;
|
||||
dur += fixation.dur;
|
||||
}
|
||||
return {x, y, dur, word_id, word};
|
||||
});
|
||||
}
|
9
src/main.js
Normal file
9
src/main.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
import App from './App.svelte';
|
||||
|
||||
const app = new App({
|
||||
target: document.body,
|
||||
props: {
|
||||
}
|
||||
});
|
||||
|
||||
export default app;
|
41
src/stores.js
Normal file
41
src/stores.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
import { writable } from 'svelte/store';
|
||||
|
||||
export const config = writable({
|
||||
zoom: 100,
|
||||
translatex: 0,
|
||||
translatey: 0,
|
||||
duration_multiplier: 0.1,
|
||||
duration_exponent: 0.2,
|
||||
speed: 100,
|
||||
show_sequential: false,
|
||||
trace_length: 3,
|
||||
trace_radius: 5,
|
||||
trace_width: 2,
|
||||
canvas_width: 1920,
|
||||
canvas_height: 1080
|
||||
});
|
||||
|
||||
|
||||
|
||||
// export const time = readable(new Date(), function start(set) {
|
||||
// const interval = setInterval(() => {
|
||||
// set(new Date());
|
||||
// }, 1000);
|
||||
|
||||
// return function stop() {
|
||||
// clearInterval(interval);
|
||||
// };
|
||||
// });
|
||||
|
||||
// function tickGenerator() {
|
||||
// const { subscribe, set, update } = writable(0);
|
||||
// let interval;
|
||||
|
||||
// return {
|
||||
// subscribe,
|
||||
// start: () => setInterval(),
|
||||
// stop: () => update(n => n - 1),
|
||||
// reset: () => set(0)
|
||||
// };
|
||||
// }
|
||||
//export const count = createCount();
|
11
src/vendor/milligram.min.css
vendored
Normal file
11
src/vendor/milligram.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
349
src/vendor/normalize.css
vendored
Normal file
349
src/vendor/normalize.css
vendored
Normal file
|
@ -0,0 +1,349 @@
|
|||
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
|
||||
|
||||
/* Document
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* 1. Correct the line height in all browsers.
|
||||
* 2. Prevent adjustments of font size after orientation changes in iOS.
|
||||
*/
|
||||
|
||||
html {
|
||||
line-height: 1.15; /* 1 */
|
||||
-webkit-text-size-adjust: 100%; /* 2 */
|
||||
}
|
||||
|
||||
/* Sections
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove the margin in all browsers.
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the `main` element consistently in IE.
|
||||
*/
|
||||
|
||||
main {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the font size and margin on `h1` elements within `section` and
|
||||
* `article` contexts in Chrome, Firefox, and Safari.
|
||||
*/
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
|
||||
/* Grouping content
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* 1. Add the correct box sizing in Firefox.
|
||||
* 2. Show the overflow in Edge and IE.
|
||||
*/
|
||||
|
||||
hr {
|
||||
box-sizing: content-box; /* 1 */
|
||||
height: 0; /* 1 */
|
||||
overflow: visible; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||
* 2. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
|
||||
pre {
|
||||
font-family: monospace, monospace; /* 1 */
|
||||
font-size: 1em; /* 2 */
|
||||
}
|
||||
|
||||
/* Text-level semantics
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove the gray background on active links in IE 10.
|
||||
*/
|
||||
|
||||
a {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Remove the bottom border in Chrome 57-
|
||||
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
|
||||
*/
|
||||
|
||||
abbr[title] {
|
||||
border-bottom: none; /* 1 */
|
||||
text-decoration: underline; /* 2 */
|
||||
text-decoration: underline dotted; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct font weight in Chrome, Edge, and Safari.
|
||||
*/
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||
* 2. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: monospace, monospace; /* 1 */
|
||||
font-size: 1em; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct font size in all browsers.
|
||||
*/
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent `sub` and `sup` elements from affecting the line height in
|
||||
* all browsers.
|
||||
*/
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
/* Embedded content
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove the border on images inside links in IE 10.
|
||||
*/
|
||||
|
||||
img {
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
/* Forms
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* 1. Change the font styles in all browsers.
|
||||
* 2. Remove the margin in Firefox and Safari.
|
||||
*/
|
||||
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit; /* 1 */
|
||||
font-size: 100%; /* 1 */
|
||||
line-height: 1.15; /* 1 */
|
||||
margin: 0; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the overflow in IE.
|
||||
* 1. Show the overflow in Edge.
|
||||
*/
|
||||
|
||||
button,
|
||||
input { /* 1 */
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inheritance of text transform in Edge, Firefox, and IE.
|
||||
* 1. Remove the inheritance of text transform in Firefox.
|
||||
*/
|
||||
|
||||
button,
|
||||
select { /* 1 */
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the inability to style clickable types in iOS and Safari.
|
||||
*/
|
||||
|
||||
button,
|
||||
[type="button"],
|
||||
[type="reset"],
|
||||
[type="submit"] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inner border and padding in Firefox.
|
||||
*/
|
||||
|
||||
button::-moz-focus-inner,
|
||||
[type="button"]::-moz-focus-inner,
|
||||
[type="reset"]::-moz-focus-inner,
|
||||