├── .gitignore
├── make-jsdoc.sh
├── index.html
├── test
├── test-load.js
├── index.html
├── test-types.js
├── test-column.js
├── test-row.js
├── test-static.js
├── test-tagpattern.js
├── test-dataset.js
└── test-filters.js
├── lib
├── qunit.LICENSE
├── papaparse.LICENSE
├── qunit-1.17.1.css
└── papaparse.min.js
├── LICENSE.md
├── CHANGELOG
├── hxl-parse-hashtag.js
├── jsdoc
├── files.html
├── symbols
│ ├── _global_.html
│ ├── hxl.classes.html
│ ├── hxl.classes.CacheFilter.html
│ ├── hxl.classes.IndexFilter.html
│ ├── hxl.classes.BaseFilter.html
│ ├── hxl.classes.RenameFilter.html
│ ├── hxl.classes.ColumnFilter.html
│ ├── hxl.classes.RowFilter.html
│ ├── hxl.classes.CountFilter.html
│ ├── hxl.classes.Row.html
│ ├── hxl.classes.Column.html
│ ├── hxl.classes.Dataset.html
│ └── hxl.classes.TagPattern.html
└── index.html
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/make-jsdoc.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | rm -rf jsdoc
4 | mkdir jsdoc
5 | jsdoc --directory=jsdoc hxl.js
6 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
25 |
--------------------------------------------------------------------------------
/CHANGELOG:
--------------------------------------------------------------------------------
1 | 2021-05-25 Release 0.6
2 | - add support for object-style JSON
3 | - remove Source.getMatchingColumns()
4 | - add Source.getColumnIndex() and Source.getColumnIndices()
5 | - many speed optimisations
6 |
7 | 2021-05-07 Release 0.5
8 | - updated to eliminate complaints from ESLint
9 | - added getRawValues() method to get all the values in a dataset column (not just unique)
10 |
11 | 2021-04-27 Release 0.4.1
12 | - bug fix for reverse in sort filter
13 |
14 | 2021-04-27 Release 0.4
15 | - added standalone hxl-parse-hashtag.js module for visualisations, etc
16 | - added SortFilter and PreviewFilter, and corresponding hxl.Source.sort() and hxl.Source.preview() methods
17 | - added hxl.Source.sum() aggregation method
18 |
19 | 2019-03-29 Release 0.3
20 | - added hxl.Source.exportArray() to export data as an array
21 | including hashtags (and optionally, headers)
22 | - fix bug with null columns when there's no hashtag
23 | - start adding data typing methods
24 | - add support for wildcard tag patterns (e.g. "#*+f")
25 | - add support for absolute tag patterns (e.g. "#affected+children")
26 | - make hashtag specs and tag patterns case insensitive
27 | - added matchList() method to TagPattern class
28 | - add hxl.match() and hxl.matchList() convenience functions for
29 | matching tag patterns
30 |
--------------------------------------------------------------------------------
/test/test-column.js:
--------------------------------------------------------------------------------
1 | /**
2 | * hxl.classes.Column tests
3 | */
4 |
5 | QUnit.module("hxl.classes.Column", {
6 | setup: function () {
7 | this.column = hxl.classes.Column.parse("#adm1+code+pcode", "Region");
8 | }
9 | });
10 |
11 | QUnit.test("column created", function(assert) {
12 | assert.ok(this.column);
13 | });
14 |
15 | QUnit.test("header ok", function(assert) {
16 | assert.equal(this.column.header, "Region");
17 | });
18 |
19 | QUnit.test("tag parsed", function(assert) {
20 | assert.equal(this.column.tag, "#adm1");
21 | });
22 |
23 | QUnit.test("attributes ok", function(assert) {
24 | assert.equal(this.column.attributes.length, 2);
25 | assert.ok(this.column.attributes.indexOf("code") > -1);
26 | assert.ok(this.column.attributes.indexOf("pcode") > -1);
27 | });
28 |
29 | QUnit.test("display tag", function(assert) {
30 | assert.equal(this.column.displayTag, "#adm1+code+pcode");
31 | });
32 |
33 | QUnit.test("bad tag", function(assert) {
34 | // no exception
35 | assert.ok(hxl.classes.Column.parse("#0abc"));
36 | // exception
37 | var seen_exception = false;
38 | try {
39 | hxl.classes.Column.parse("#0abc", null, true);
40 | } catch (e) {
41 | seen_exception = true;
42 | }
43 | assert.ok(seen_exception);
44 | });
45 |
46 |
47 | // end
48 |
--------------------------------------------------------------------------------
/test/test-row.js:
--------------------------------------------------------------------------------
1 | /**
2 | * hxl.classes.Row tests
3 | */
4 |
5 | QUnit.module("hxl.classes.Row", {
6 | setup: function () {
7 | this.columns = ["#org+funder", "#org+impl", "#adm1+code"];
8 | this.values = ["Donor", "NGO", "Region"];
9 | this.dataset = new hxl.classes.Dataset([this.columns, this.values]);
10 | this.row = new hxl.classes.Row(this.values, this.dataset.columns, this.dataset);
11 | }
12 | });
13 |
14 | QUnit.test("row created", function(assert) {
15 | assert.ok(this.row);
16 | });
17 |
18 | QUnit.test("values", function(assert) {
19 | assert.deepEqual(this.row.values, this.values);
20 | });
21 |
22 | QUnit.test("columns", function(assert) {
23 | assert.deepEqual(this.row.columns.map(function(col) { return col.displayTag; }), this.columns);
24 | });
25 |
26 | QUnit.test("get one value", function(assert) {
27 | assert.equal(this.row.get("#org"), "Donor");
28 | assert.equal(this.row.get("#org+funder"), "Donor");
29 | assert.equal(this.row.get("#org-funder"), "NGO");
30 | assert.equal(this.row.get("#org+impl"), "NGO");
31 | assert.equal(this.row.get("#org-impl"), "Donor");
32 | });
33 |
34 | QUnit.test("get all values", function(assert) {
35 | assert.deepEqual(this.row.getAll("#org"), ["Donor", "NGO"]);
36 | assert.deepEqual(this.row.getAll("#org+impl"), ["NGO"]);
37 | assert.deepEqual(this.row.getAll("#org-impl"), ["Donor"]);
38 | });
39 |
40 | // end
41 |
--------------------------------------------------------------------------------
/test/test-static.js:
--------------------------------------------------------------------------------
1 | /**
2 | * static methods tests
3 | */
4 |
5 | QUnit.module("hxl", {});
6 |
7 | QUnit.test("normalise whitespace", function(assert) {
8 | assert.equal("xx YY", hxl.normaliseSpace(" xx\n YY\t"));
9 | });
10 |
11 | QUnit.test("normalise string", function(assert) {
12 | assert.equal("xx yy", hxl.normaliseString(" xx\n YY\t"));
13 | });
14 |
15 | QUnit.test("normalise year", function(assert) {
16 | assert.equal('2017', hxl.normaliseDate('2017'));
17 | });
18 |
19 | QUnit.test("normalise year-month", function(assert) {
20 | assert.equal('2017-01', hxl.normaliseDate('2017-01'));
21 | });
22 |
23 | QUnit.test("normalise quarter", function(assert) {
24 | assert.equal('2017Q1', hxl.normaliseDate('2017Q1'));
25 | });
26 |
27 | QUnit.test("normalise mm-dd date", function(assert) {
28 | assert.equal('2017-01-13', hxl.normaliseDate('1/13/17'));
29 | });
30 |
31 | QUnit.test("normalise dd-mm date", function(assert) {
32 | assert.equal('2017-01-13', hxl.normaliseDate('13/1/17'));
33 | });
34 |
35 | QUnit.test("force dd-mm date", function(assert) {
36 | assert.equal('2017-01-02', hxl.normaliseDate('2/1/17', true));
37 | });
38 |
39 | QUnit.test("force mm-dd date", function(assert) {
40 | assert.equal('2017-02-01', hxl.normaliseDate('2/1/17', false));
41 | });
42 |
43 | QUnit.test("month name", function(assert) {
44 | assert.equal('2017-01-02', hxl.normaliseDate('2 Jan/17'));
45 | });
46 |
47 | // end
48 |
--------------------------------------------------------------------------------
/hxl-parse-hashtag.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Stand-alone function to parse a HXL hashtag and attributes
3 | *
4 | * The result will be an object with two properties, "tag" for the
5 | * hashtag, and "atts" for an array of attributes. For example,
6 | * #affected+refugees+children+f will parse to
7 | *
8 | * {
9 | * tag: "affected",
10 | * atts: ["refugees", "children", "f"]
11 | * }
12 | *
13 | * Note that the parser removes "#" from the hashtag, and "+" from the
14 | * attribute names. It also normalised all names to lower case.
15 | *
16 | * To check for an attribute:
17 | *
18 | * p = hxl_parse_hashtag("#affected +refugees +children +f");
19 | * p.atts.includes("refugees"); // true
20 | * p.atts.includes("idps"); // false
21 | *
22 | * @param s The hashtag and attributes (may contain whitespace)
23 | * @returns The parsed object, or False if the hashtag spec was
24 | * unparseable.
25 | */
26 | function hxl_parse_hashtag (s) {
27 |
28 | var parsed = s.match(/^\s*(#[A-Za-z][A-Za-z0-9_]*)((\s*\+[A-Za-z][A-Za-z0-9_]*)*)?\s*$/);
29 |
30 | if (parsed) {
31 | var attributes = [];
32 | if (parsed[2]) {
33 | attributes = parsed[2].split(/\s*\+/).filter(attribute => attribute.toLowerCase());
34 | }
35 | return {
36 | tag: parsed[1].toLowerCase().substring(1),
37 | atts: attributes
38 | };
39 |
40 | } else {
41 | return False;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/test/test-tagpattern.js:
--------------------------------------------------------------------------------
1 | /**
2 | * hxl.classes.TagPattern tests
3 | */
4 |
5 | QUnit.module("hxl.classes.TagPattern", {
6 | setup: function () {
7 | this.pattern = hxl.classes.TagPattern.parse("#adm1+code-iso");
8 | this.column = hxl.classes.Column.parse("#adm1+code+pcode", "Region");
9 | }
10 | });
11 |
12 | QUnit.test("pattern created", function(assert) {
13 | assert.ok(this.pattern);
14 | });
15 |
16 | QUnit.test("tag ok", function(assert) {
17 | assert.equal(this.pattern.tag, "#adm1");
18 | });
19 |
20 | QUnit.test("include ok", function(assert) {
21 | assert.deepEqual(this.pattern.includeAttributes, ['code']);
22 | });
23 |
24 | QUnit.test("exclude ok", function(assert) {
25 | assert.deepEqual(this.pattern.excludeAttributes, ['iso']);
26 | });
27 |
28 | QUnit.test("positive match", function(assert) {
29 | assert.ok(this.pattern.match(this.column));
30 | });
31 |
32 | QUnit.test("embedded whitespace", function(assert) {
33 | assert.ok(hxl.classes.TagPattern.parse('#adm1 +foo'));
34 | assert.ok(hxl.classes.TagPattern.parse(' #adm1+foo'));
35 | assert.ok(hxl.classes.TagPattern.parse(' #adm1+foo '));
36 | assert.ok(hxl.classes.TagPattern.parse(' #adm1+foo '));
37 | });
38 |
39 | QUnit.test("bad pattern", function(assert) {
40 | // no exception
41 | assert.ok(hxl.classes.TagPattern.parse("#abc+x=y") === null);
42 | // exception requested
43 | var seen_exception = false;
44 | try {
45 | hxl.classes.TagPattern.parse("#abc+x=y", true);
46 | } catch (e) {
47 | seen_exception = true;
48 | }
49 | assert.ok(seen_exception);
50 | });
51 |
52 | QUnit.test("absolute pattern", function(assert) {
53 | var pattern = hxl.classes.TagPattern.parse("#foo+x!");
54 | assert.ok(pattern);
55 | assert.ok(pattern.match("#foo+x"));
56 | assert.ok(!pattern.match("#foo+y+x"))
57 | });
58 |
59 | QUnit.test("wildcard pattern", function(assert) {
60 | var pattern = hxl.classes.TagPattern.parse("#*+x");
61 | assert.ok(pattern);
62 | assert.ok(pattern.match("#foo+x"));
63 | assert.ok(!pattern.match("#foo"));
64 | });
65 |
66 | QUnit.test("find in list", function(assert) {
67 | var pattern = hxl.classes.TagPattern.parse("#foo+x");
68 | assert.ok(pattern.matchList(["#xxx", "#foo+y+x", "#yyy"]));
69 | assert.ok(!pattern.matchList(["#xxx", "#foo+y", "#yyy"]));
70 | });
71 |
72 | // end
73 |
--------------------------------------------------------------------------------
/test/test-dataset.js:
--------------------------------------------------------------------------------
1 | /**
2 | * hxl.classes.Dataset tests
3 | */
4 |
5 | QUnit.module("hxl.classes.Dataset", {
6 | setup: function () {
7 | this.test_data = [
8 | ['Pointless header'],
9 | ['Organisation', 'Second organisation', 'Sector', 'Province', 'Number reached'],
10 | ['#org', '#org', '#sector+cluster', '#adm1', '#reached'],
11 | ['Org 1', 'Org 1b', 'WASH', 'Coastal Province', '200'],
12 | ['Org 2', '', 'Health', 'Mountain Province', '300'],
13 | ['Org 3', '', 'Protection', 'Coastal Province', '400']
14 | ];
15 | this.dataset = new hxl.wrap(this.test_data);
16 | }
17 | });
18 |
19 | QUnit.test("dataset created", function(assert) {
20 | assert.ok(this.dataset);
21 | });
22 |
23 | QUnit.test("object-style JSON", function(assert) {
24 | let data = [
25 | {'#org': 'Org 1', '#sector+cluster': 'WASH', '#adm1': 'Coastal Province', '#reached': '200'},
26 | {'#org': 'Org 2', '#adm1': 'Mountain Province', '#reached': '300'},
27 | {'#org': 'Org 3', '#reached': '400', '#sector+cluster': 'Protection', '#adm1': 'Coastal Province'}
28 | ];
29 | dataset = hxl.wrap(data);
30 | assert.deepEqual(dataset.displayTags, ['#org', '#sector+cluster', '#adm1', '#reached']);
31 | assert.deepEqual(dataset.rawData, [
32 | ["Org 1", "WASH", "Coastal Province", "200"],
33 | ["Org 2", "", "Mountain Province", "300"],
34 | ["Org 3", "Protection", "Coastal Province", "400"]
35 | ]);
36 | });
37 |
38 | QUnit.test("headers", function(assert) {
39 | assert.deepEqual(this.dataset.headers, this.test_data[1]);
40 | });
41 |
42 | QUnit.test("tags", function(assert) {
43 | assert.notDeepEqual(this.dataset.tags, this.test_data[2]);
44 | assert.deepEqual(this.dataset.displayTags, this.test_data[2]);
45 | });
46 |
47 | QUnit.test("columns", function(assert) {
48 | assert.deepEqual(this.dataset.columns.map(function (col) { return col.header; }), this.test_data[1]);
49 | assert.deepEqual(this.dataset.columns.map(function (col) { return col.displayTag; }), this.test_data[2]);
50 | });
51 |
52 | QUnit.test("dataset export", function(assert) {
53 | assert.deepEqual(this.dataset.exportArray(), this.test_data.slice(1));
54 | assert.deepEqual(this.dataset.exportArray(false), this.test_data.slice(1));
55 | assert.deepEqual(this.dataset.exportArray(true), this.test_data.slice(2));
56 | });
57 |
58 | QUnit.test("partly-tagged dataset", function(assert) {
59 | // confirm no null columns when not tagged
60 | var dataset = hxl.wrap([
61 | ['header', 'header', 'header'],
62 | ['#tag', '', '#tag'],
63 | ['a', 'b', 'c'],
64 | ['d', 'e', 'f']
65 | ]);
66 | dataset.columns.forEach((column) => {
67 | assert.ok(column);
68 | });
69 | });
70 |
71 | QUnit.test("rows", function(assert) {
72 | assert.deepEqual(this.dataset.rows.map(function (row) { return row.values; }), this.test_data.slice(3));
73 | });
74 |
75 | QUnit.test("raw data", function(assert) {
76 | assert.deepEqual(this.test_data.slice(3), this.dataset.rawData);
77 | });
78 |
79 | QUnit.test("iterator", function(assert) {
80 | var iterator = this.dataset.iterator();
81 | var index = 3;
82 | var row = null;
83 | while (row = iterator.next()) {
84 | assert.deepEqual(row.values, this.test_data[index]);
85 | index++;
86 | }
87 | });
88 |
89 | QUnit.test("each", function(assert) {
90 | var test_data = this.test_data;
91 | assert.equal(this.dataset.each(function (row, dataset, rowNumber) {
92 | assert.deepEqual(row.values, test_data[rowNumber + 3]);
93 | }), 3);
94 | });
95 |
96 | QUnit.test("min", function(assert) {
97 | assert.equal(this.dataset.getMin('#reached'), 200);
98 | });
99 |
100 | QUnit.test("max", function(assert) {
101 | assert.equal(this.dataset.getMax('#reached'), 400);
102 | });
103 |
104 | QUnit.test("sum", function(assert) {
105 | assert.equal(this.dataset.getSum('#reached'), 900);
106 | });
107 |
108 | QUnit.test("unique values", function(assert) {
109 | assert.deepEqual(this.dataset.getValues('#adm1'), ['Coastal Province', 'Mountain Province']);
110 | });
111 |
112 | QUnit.test("raw values", function(assert) {
113 | assert.deepEqual(this.dataset.getRawValues('#adm1'), ['Coastal Province', 'Mountain Province', 'Coastal Province']);
114 | });
115 |
116 | QUnit.test("numbery", function(assert) {
117 | assert.ok(!this.dataset.isNumbery('#org'));
118 | assert.ok(this.dataset.isNumbery('#reached'));
119 | });
120 |
121 | // end
122 |
--------------------------------------------------------------------------------
/jsdoc/files.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 | JsDoc Reference - File Index
8 |
9 |
10 |
174 |
175 |
176 |
177 |
179 |
180 |
181 |
183 |
184 |
Classes
185 |
218 |
219 |
220 |
221 |
222 |
File Index
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 | Documentation generated by
JsDoc Toolkit 2.4.0 on Sat Jun 30 2018 17:05:53 GMT-0400 (EDT)
242 |
243 |
244 |
--------------------------------------------------------------------------------
/lib/qunit-1.17.1.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * QUnit 1.17.1
3 | * http://qunitjs.com/
4 | *
5 | * Copyright jQuery Foundation and other contributors
6 | * Released under the MIT license
7 | * http://jquery.org/license
8 | *
9 | * Date: 2015-01-20T19:39Z
10 | */
11 |
12 | /** Font Family and Sizes */
13 |
14 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
15 | font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
16 | }
17 |
18 | #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
19 | #qunit-tests { font-size: smaller; }
20 |
21 |
22 | /** Resets */
23 |
24 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
25 | margin: 0;
26 | padding: 0;
27 | }
28 |
29 |
30 | /** Header */
31 |
32 | #qunit-header {
33 | padding: 0.5em 0 0.5em 1em;
34 |
35 | color: #8699A4;
36 | background-color: #0D3349;
37 |
38 | font-size: 1.5em;
39 | line-height: 1em;
40 | font-weight: 400;
41 |
42 | border-radius: 5px 5px 0 0;
43 | }
44 |
45 | #qunit-header a {
46 | text-decoration: none;
47 | color: #C2CCD1;
48 | }
49 |
50 | #qunit-header a:hover,
51 | #qunit-header a:focus {
52 | color: #FFF;
53 | }
54 |
55 | #qunit-testrunner-toolbar label {
56 | display: inline-block;
57 | padding: 0 0.5em 0 0.1em;
58 | }
59 |
60 | #qunit-banner {
61 | height: 5px;
62 | }
63 |
64 | #qunit-testrunner-toolbar {
65 | padding: 0.5em 1em 0.5em 1em;
66 | color: #5E740B;
67 | background-color: #EEE;
68 | overflow: hidden;
69 | }
70 |
71 | #qunit-userAgent {
72 | padding: 0.5em 1em 0.5em 1em;
73 | background-color: #2B81AF;
74 | color: #FFF;
75 | text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
76 | }
77 |
78 | #qunit-modulefilter-container {
79 | float: right;
80 | padding: 0.2em;
81 | }
82 |
83 | .qunit-url-config {
84 | display: inline-block;
85 | padding: 0.1em;
86 | }
87 |
88 | .qunit-filter {
89 | display: block;
90 | float: right;
91 | margin-left: 1em;
92 | }
93 |
94 | /** Tests: Pass/Fail */
95 |
96 | #qunit-tests {
97 | list-style-position: inside;
98 | }
99 |
100 | #qunit-tests li {
101 | padding: 0.4em 1em 0.4em 1em;
102 | border-bottom: 1px solid #FFF;
103 | list-style-position: inside;
104 | }
105 |
106 | #qunit-tests > li {
107 | display: none;
108 | }
109 |
110 | #qunit-tests li.running,
111 | #qunit-tests li.pass,
112 | #qunit-tests li.fail,
113 | #qunit-tests li.skipped {
114 | display: list-item;
115 | }
116 |
117 | #qunit-tests.hidepass li.running,
118 | #qunit-tests.hidepass li.pass {
119 | display: none;
120 | }
121 |
122 | #qunit-tests li strong {
123 | cursor: pointer;
124 | }
125 |
126 | #qunit-tests li.skipped strong {
127 | cursor: default;
128 | }
129 |
130 | #qunit-tests li a {
131 | padding: 0.5em;
132 | color: #C2CCD1;
133 | text-decoration: none;
134 | }
135 | #qunit-tests li a:hover,
136 | #qunit-tests li a:focus {
137 | color: #000;
138 | }
139 |
140 | #qunit-tests li .runtime {
141 | float: right;
142 | font-size: smaller;
143 | }
144 |
145 | .qunit-assert-list {
146 | margin-top: 0.5em;
147 | padding: 0.5em;
148 |
149 | background-color: #FFF;
150 |
151 | border-radius: 5px;
152 | }
153 |
154 | .qunit-collapsed {
155 | display: none;
156 | }
157 |
158 | #qunit-tests table {
159 | border-collapse: collapse;
160 | margin-top: 0.2em;
161 | }
162 |
163 | #qunit-tests th {
164 | text-align: right;
165 | vertical-align: top;
166 | padding: 0 0.5em 0 0;
167 | }
168 |
169 | #qunit-tests td {
170 | vertical-align: top;
171 | }
172 |
173 | #qunit-tests pre {
174 | margin: 0;
175 | white-space: pre-wrap;
176 | word-wrap: break-word;
177 | }
178 |
179 | #qunit-tests del {
180 | background-color: #E0F2BE;
181 | color: #374E0C;
182 | text-decoration: none;
183 | }
184 |
185 | #qunit-tests ins {
186 | background-color: #FFCACA;
187 | color: #500;
188 | text-decoration: none;
189 | }
190 |
191 | /*** Test Counts */
192 |
193 | #qunit-tests b.counts { color: #000; }
194 | #qunit-tests b.passed { color: #5E740B; }
195 | #qunit-tests b.failed { color: #710909; }
196 |
197 | #qunit-tests li li {
198 | padding: 5px;
199 | background-color: #FFF;
200 | border-bottom: none;
201 | list-style-position: inside;
202 | }
203 |
204 | /*** Passing Styles */
205 |
206 | #qunit-tests li li.pass {
207 | color: #3C510C;
208 | background-color: #FFF;
209 | border-left: 10px solid #C6E746;
210 | }
211 |
212 | #qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
213 | #qunit-tests .pass .test-name { color: #366097; }
214 |
215 | #qunit-tests .pass .test-actual,
216 | #qunit-tests .pass .test-expected { color: #999; }
217 |
218 | #qunit-banner.qunit-pass { background-color: #C6E746; }
219 |
220 | /*** Failing Styles */
221 |
222 | #qunit-tests li li.fail {
223 | color: #710909;
224 | background-color: #FFF;
225 | border-left: 10px solid #EE5757;
226 | white-space: pre;
227 | }
228 |
229 | #qunit-tests > li:last-child {
230 | border-radius: 0 0 5px 5px;
231 | }
232 |
233 | #qunit-tests .fail { color: #000; background-color: #EE5757; }
234 | #qunit-tests .fail .test-name,
235 | #qunit-tests .fail .module-name { color: #000; }
236 |
237 | #qunit-tests .fail .test-actual { color: #EE5757; }
238 | #qunit-tests .fail .test-expected { color: #008000; }
239 |
240 | #qunit-banner.qunit-fail { background-color: #EE5757; }
241 |
242 | /*** Skipped tests */
243 |
244 | #qunit-tests .skipped {
245 | background-color: #EBECE9;
246 | }
247 |
248 | #qunit-tests .qunit-skipped-label {
249 | background-color: #F4FF77;
250 | display: inline-block;
251 | font-style: normal;
252 | color: #366097;
253 | line-height: 1.8em;
254 | padding: 0 0.5em;
255 | margin: -0.4em 0.4em -0.4em 0;
256 | }
257 |
258 | /** Result */
259 |
260 | #qunit-testresult {
261 | padding: 0.5em 1em 0.5em 1em;
262 |
263 | color: #2B81AF;
264 | background-color: #D2E0E6;
265 |
266 | border-bottom: 1px solid #FFF;
267 | }
268 | #qunit-testresult .module-name {
269 | font-weight: 700;
270 | }
271 |
272 | /** Fixture */
273 |
274 | #qunit-fixture {
275 | position: absolute;
276 | top: -10000px;
277 | left: -10000px;
278 | width: 1000px;
279 | height: 1000px;
280 | }
281 |
--------------------------------------------------------------------------------
/jsdoc/symbols/_global_.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 | JsDoc Reference - _global_
9 |
10 |
174 |
175 |
176 |
177 |
178 |
179 |
181 |
182 |
183 |
184 |
185 |
186 |
188 |
189 |
Classes
190 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 | Built-In Namespace _global_
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 | Documentation generated by
JsDoc Toolkit 2.4.0 on Sat Jun 30 2018 17:05:52 GMT-0400 (EDT)
275 |
276 |
277 |
278 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | libhxl-js
2 | =========
3 |
4 | JavaScript support library for the Humanitarian Exchange Language (HXL) data standard.
5 |
6 | http://hxlstandard.org
7 |
8 | ## Overview
9 |
10 | This library supports high-level filtering and aggregation operations
11 | on HXL datasets. Auto-generated API documentation (which may or may
12 | not be up to date) is available at https://hxlstandard.github.io/libhxl-js/
13 |
14 | ## Usage
15 |
16 | ### Load a CSV dataset from the web:
17 |
18 | Requires that the Papa Parse CSV library be loaded before HXL (there
19 | is a copy bundled in lib/, with permission):
20 |
21 | hxl.load('http://example.org/dataset.csv', function (dataset) {
22 | console.log('Dataset has ' + dataset.columns.length + ' columns.');
23 | });
24 |
25 | The HXL library will soon also support autodetecting the availability
26 | of D3 and JQuery-based CSV parsing.
27 |
28 | ### Create a dataset from array data
29 |
30 | var rawData = [
31 | [ "Organisation", "Cluster", "Province" ],
32 | [ "#org", "#sector", "#adm1" ],
33 | [ "Org A", "WASH", "Coastal Province" ],
34 | [ "Org B", "Health", "Mountain Province" ],
35 | [ "Org C", "Education", "Coastal Province" ],
36 | [ "Org A", "WASH", "Plains Province" ],
37 | ];
38 |
39 | var dataset = hxl.wrap(rawData);
40 | console.log('Dataset has ' + dataset.columns.length + ' columns');
41 |
42 | ### Read a remote JSON-encoded HXL dataset
43 |
44 | fetch("http://example.org/data/sample.hxl.json").then(r => {
45 | r.json().then(rawData => {
46 | let dataset = hxl.wrap(rawData);
47 | console.log('Dataset has ' + dataset.columns.length + ' columns');
48 | });
49 | });
50 |
51 | ## Classes
52 |
53 | ### hxl.classes.Source
54 |
55 | *Note:* Any method that takes a hxl.classes.TagPattern as an argument can accept a
56 | string representation instead (e.g. "#affected+f-adults"). Any method
57 | that takes a list of TagPatterns as an argument can accept a single
58 | pattern (as above) or list of patterns.
59 |
60 | #### Properties
61 |
62 | Property | Data type | Description
63 | -- | -- | --
64 | columns | array of hxl.classes.Column | All the column objects for the dataset
65 | rows | array of hxl.classes.Row | All the row objects for the dataset (excluding header and hashtag row)
66 | rawData | array of arrays | Get all the raw row data for the dataset (excluding header and hashtag row)
67 | headers | array of strings | Get all the text headers as strings
68 | tags | array of strings | Get all the hashtags (without attributes) as strings
69 | displayTags | array of strings | Get all the hasthag specs (with attributes) as strings
70 |
71 | #### Row iteration methods
72 |
73 | Method | Description
74 | -- | -- | --
75 | each(callback) | iterator through each row of the dataset, invoking _callback_ with the row, dataset, and row number as arguments
76 | forEach(callback) | synonym for _each()_
77 | iterator() | return a simple iterator with a next() function (but not done(); it returns null when finished)
78 |
79 | #### Aggregate methods
80 |
81 | Use these methods to extract aggregate values from the dataset.
82 |
83 | Method | Result | Description
84 | -- | -- | --
85 | getSum(tagPattern) | number | Sum of all numeric values in the first column matching _tagPattern_
86 | getMin(tagPattern) | number | Lowest of all numeric values in the first column matching _tagPattern_
87 | getMax(tagPattern) | number | Highest of all numeric values in the first column matching _tagPattern_
88 | getValues(tagPattern) | array | List of unique values in the first column matching _tagPattern_
89 | getRawValues(tagPattern) | array | List of all values in the first column matching _tagPattern_ (including repetitions and nulls), in the original order
90 |
91 | #### Filter methods
92 |
93 | The return value from a filter is always a new (virtual) dataset with the filter applied.
94 |
95 | Method | Description
96 | -- | --
97 | withRows(predicates) | Include only rows matching (any of) _predicates_
98 | withoutRows(predicates) | Include only rows _not_ matching (any of) _predicates_
99 | withColumns(tagPatterns) | Include only columns matching (any of) _tagPatterns_
100 | withoutColumns(tagPatterns) | Include only columns _not_ matching (any of) _tagPatterns_
101 | count(tagPatterns, aggregate=null) | Aggregate data (like in a pivot table) for the columns matching _tagPatterns,_ and optionally produce aggregate values for the first column matching the tag pattern _aggregate_
102 | rename(tagPattern, spec, header=null, index=0) | Rename the _index_ column matching _tagPattern_ to use the hashtag and attributes _spec_ and optionally the new header _header_
103 | sort(tagPatterns, reverse=false) | Sort the dataset using columns matching tagPatterns as keys, with numeric comparison where possible
104 | preview(maxRows=10) | Filter to a maximum of _maxRows_ rows.
105 | catch() | Create a permanent copy of the data at this point in the pipeline, so that earlier filters don't have to be rerun.
106 | index() | Number repeated tag specs by adding the attributes +i0, +i1, etc to simplify processing.
107 |
108 | #### Other methods
109 |
110 | Method | Result | Description
111 | -- | -- | --
112 | isNumbery(tagPattern) | boolean | Return true if the first column matching _tagPattern_ contains mainly numbers
113 | iterator() | object | Return a simple iterator with a next() method for reading through the rows (returns null at the end)
114 | exportArray() | array of arrays | Export the whole dataset as an array of arrays (including the headers and hashtag row)
115 | hasColumn(tagPattern) | boolean | true if the dataset has at least one column matching _tagPattern_
116 | getMatchingColumns(tagPattern) | array of int | List of 0-based indices for columns matching _tagPattern_
117 |
118 |
119 | ## Filter examples
120 |
121 | Filters create a new virtual version of the dataset, on the fly. The
122 | original dataset is unmodified.
123 |
124 | ### Column filtering
125 |
126 | #### Include only specific columns
127 |
128 | dataset.withColumns(['#org', '#sector', '#adm1']).each(...);
129 |
130 | #### Remove specific columns
131 |
132 | dataset.withoutColumns('#contact+email').each(...);
133 |
134 | ### Row filtering
135 |
136 | #### Include only specific rows
137 |
138 | dataset.withRows('#sector=WASH').each(...);
139 |
140 | #### Remove specific rows
141 |
142 | dataset.withoutRows('#status=Unreleased').each(...);
143 |
144 | #### Test an entire row
145 |
146 | dataset.withRows(function (row) {
147 | return row.get('#population+targeted+num') < row.get('#population+affected+num');
148 | }).each(...);
149 |
150 | ### Aggregation
151 |
152 | #### Count values of #adm1
153 |
154 | dataset.count('#adm1').each(...);
155 |
156 | #### Count combinations of #adm1 and #sector
157 |
158 | dataset.count(['#adm1', '#sector']).each(...);
159 |
160 | ### Chain filters together
161 |
162 | Count #adm only in the WASH sector:
163 |
164 | dataset.withRows('#sector=WASH').count('#adm1').each(row => {
165 | // do something with each row
166 | });
167 |
168 | or
169 |
170 | var iterator = dataset.iterator();
171 | var row = iterator.next();
172 | while (row != null) {
173 | // do something with each row
174 | row = iterator.next();
175 | }
176 |
177 |
178 | ## Tests
179 |
180 | To run the unit tests, open the file tests/index.html in a modern web browser. You may need to install them in a web server to avoid cross-domain errors in browsers with strict security models.
181 |
--------------------------------------------------------------------------------
/jsdoc/index.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 | JsDoc Reference - Index
8 |
9 |
10 |
174 |
175 |
176 |
177 |
179 |
180 |
181 |
183 |
184 |
Classes
185 |
218 |
219 |
220 |
221 |
222 |
Class Index
223 |
224 |
225 |
229 |
230 |
231 |
235 |
236 |
237 |
241 |
242 |
243 |
247 |
248 |
249 |
253 |
254 |
255 |
259 |
260 |
261 |
265 |
266 |
267 |
271 |
272 |
273 |
277 |
278 |
279 |
283 |
284 |
285 |
289 |
290 |
291 |
295 |
296 |
297 |
301 |
302 |
303 |
307 |
308 |
309 |
313 |
314 |
315 |
316 |
317 |
318 |
319 | Documentation generated by
JsDoc Toolkit 2.4.0 on Sat Jun 30 2018 17:05:53 GMT-0400 (EDT)
320 |
321 |
322 |
--------------------------------------------------------------------------------
/jsdoc/symbols/hxl.classes.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 | JsDoc Reference - hxl.classes
9 |
10 |
174 |
175 |
176 |
177 |
178 |
179 |
181 |
182 |
183 |
184 |
185 |
186 |
188 |
189 |
Classes
190 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 | Namespace hxl.classes
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
Defined in: hxl.js.
243 |
244 |
245 |
246 |
247 |
248 |
249 | Namespace Summary
250 |
251 |
252 | | Constructor Attributes |
253 | Constructor Name and Description |
254 |
255 |
256 |
257 |
258 | | |
259 |
260 |
263 |
264 | |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 | Namespace Detail
283 |
284 |
285 |
286 | hxl.classes
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 | Documentation generated by
JsDoc Toolkit 2.4.0 on Sat Jun 30 2018 17:05:52 GMT-0400 (EDT)
325 |
326 |
327 |
328 |
--------------------------------------------------------------------------------
/jsdoc/symbols/hxl.classes.CacheFilter.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 | JsDoc Reference - hxl.classes.CacheFilter
9 |
10 |
174 |
175 |
176 |
177 |
178 |
179 |
181 |
182 |
183 |
184 |
185 |
186 |
188 |
189 |
Classes
190 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 | Class hxl.classes.CacheFilter
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
Defined in: hxl.js.
243 |
244 |
245 |
246 |
247 |
248 |
249 | Class Summary
250 |
251 |
252 | | Constructor Attributes |
253 | Constructor Name and Description |
254 |
255 |
256 |
257 |
258 | | |
259 |
260 |
263 | HXL filter to save a copy of a transformed HXL dataset.
264 | |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 | Class Detail
283 |
284 |
285 |
286 | hxl.classes.CacheFilter(source)
287 |
288 |
289 |
290 | HXL filter to save a copy of a transformed HXL dataset.
291 |
292 | This filter stops the chain, so that any future requests won't
293 | go back and repeat earlier transformations. You should use it
294 | when there are some expensive operations earlier in the chain
295 | that you don't want to repeat.
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 | - Parameters:
305 |
306 | -
307 | {hxl.classes.Source} source
308 |
309 |
310 | - the hxl.classes.Source
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 | Documentation generated by
JsDoc Toolkit 2.4.0 on Sat Jun 30 2018 17:05:53 GMT-0400 (EDT)
341 |
342 |
343 |
344 |
--------------------------------------------------------------------------------
/jsdoc/symbols/hxl.classes.IndexFilter.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 | JsDoc Reference - hxl.classes.IndexFilter
9 |
10 |
174 |
175 |
176 |
177 |
178 |
179 |
181 |
182 |
183 |
184 |
185 |
186 |
188 |
189 |
Classes
190 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 | Class hxl.classes.IndexFilter
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
Defined in: hxl.js.
243 |
244 |
245 |
246 |
247 |
248 |
249 | Class Summary
250 |
251 |
252 | | Constructor Attributes |
253 | Constructor Name and Description |
254 |
255 |
256 |
257 |
258 | | |
259 |
260 |
263 | Add index attributes (+i0, +i1, etc.
264 | |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 | Class Detail
283 |
284 |
285 |
286 | hxl.classes.IndexFilter(source, pattern)
287 |
288 |
289 |
290 | Add index attributes (+i0, +i1, etc.) to a repeated tag.
291 |
292 | This is useful for query-type processing, where it's not otherwise
293 | easy to work with order. Normally, it's better to use semantic
294 | attributes like #org+funder, #org+impl, etc., but in some cases,
295 | that's not available, so you can automatically number the tags
296 | as #org+i0, #org+i1, etc., from left to right.
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 | - Parameters:
306 |
307 | -
308 | {hxl.classes.Source} source
309 |
310 |
311 | - the hxl.classes.Source
312 |
313 | -
314 | {string} pattern
315 |
316 |
317 | - the tag pattern to replace (see hxl.classes.TagPattern).
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 | Documentation generated by
JsDoc Toolkit 2.4.0 on Sat Jun 30 2018 17:05:53 GMT-0400 (EDT)
348 |
349 |
350 |
351 |
--------------------------------------------------------------------------------
/jsdoc/symbols/hxl.classes.BaseFilter.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 | JsDoc Reference - hxl.classes.BaseFilter
9 |
10 |
174 |
175 |
176 |
177 |
178 |
179 |
181 |
182 |
183 |
184 |
185 |
186 |
188 |
189 |
Classes
190 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 | Class hxl.classes.BaseFilter
232 |
233 |
234 |
235 |
236 |
237 |
Extends
238 | hxl.classes.Source.
239 |
240 |
241 |
242 |
243 |
244 |
Defined in: hxl.js.
245 |
246 |
247 |
248 |
249 |
250 |
251 | Class Summary
252 |
253 |
254 | | Constructor Attributes |
255 | Constructor Name and Description |
256 |
257 |
258 |
259 |
260 | | |
261 |
262 |
265 | Abstract class for a HXL filter.
266 | |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 | - Fields borrowed from class hxl.classes.Source:
- columns, displayTags, headers, rows, tags
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 | - Methods borrowed from class hxl.classes.Source:
- cache, count, each, forEach, getColumns, getDisplayTags, getHeaders, getMatchingColumns, getMax, getMin, getRows, getTags, getValues, hasColumn, index, isNumbery, iterator, rename, withColumns, withoutColumns, withoutRows, withRows
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 | Class Detail
303 |
304 |
305 |
306 | hxl.classes.BaseFilter(source)
307 |
308 |
309 |
310 | Abstract class for a HXL filter.
311 |
312 | Provide basic scaffolding for creating a class that reads from
313 | a HXL source, transforms the data on the fly, then sends out a new
314 | stream of HXL data.
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 | - Parameters:
324 |
325 | -
326 | {hxl.classes.Source} source
327 |
328 |
329 | - Another HXL data source to read from.
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 | Documentation generated by
JsDoc Toolkit 2.4.0 on Sat Jun 30 2018 17:05:52 GMT-0400 (EDT)
360 |
361 |
362 |
363 |
--------------------------------------------------------------------------------
/jsdoc/symbols/hxl.classes.RenameFilter.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 | JsDoc Reference - hxl.classes.RenameFilter
9 |
10 |
174 |
175 |
176 |
177 |
178 |
179 |
181 |
182 |
183 |
184 |
185 |
186 |
188 |
189 |
Classes
190 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 | Class hxl.classes.RenameFilter
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
Defined in: hxl.js.
243 |
244 |
245 |
246 |
247 |
248 |
249 | Class Summary
250 |
251 |
252 | | Constructor Attributes |
253 | Constructor Name and Description |
254 |
255 |
256 |
257 |
258 | | |
259 |
260 |
263 | HXL filter to rename a column (new header and tag).
264 | |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 | Method Summary
279 |
280 |
281 | | Method Attributes |
282 | Method Name and Description |
283 |
284 |
285 |
286 |
287 |
288 | | |
289 |
290 |
292 | Get the renamed columns.
293 | |
294 |
295 |
296 |
297 | | |
298 |
299 |
301 | Return copies of the rows with the new columns.
302 | |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 | Class Detail
319 |
320 |
321 |
322 | hxl.classes.RenameFilter(source, pattern, newTag, newHeader, index)
323 |
324 |
325 |
326 | HXL filter to rename a column (new header and tag).
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 | - Parameters:
336 |
337 | -
338 | source
339 |
340 |
341 | - the hxl.classes.Source
342 |
343 | -
344 | pattern
345 |
346 |
347 | - the tag pattern to replace
348 |
349 | -
350 | newTag
351 |
352 |
353 | - the new HXL tag (with attributes)
354 |
355 | -
356 | newHeader
357 |
358 |
359 | - (optional) the new text header. If undefined or
360 | null or false, don't change the existing header.
361 |
362 | -
363 | index
364 |
365 |
366 | - the zero-based index of the match to replace. If
367 | undefined or null or false, replace *all* matches.
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 | Method Detail
388 |
389 |
390 |
391 |
392 |
393 |
394 | getColumns()
395 |
396 |
397 |
398 | Get the renamed columns.
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 | iterator()
420 |
421 |
422 |
423 | Return copies of the rows with the new columns.
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 | Documentation generated by
JsDoc Toolkit 2.4.0 on Sat Jun 30 2018 17:05:53 GMT-0400 (EDT)
453 |
454 |
455 |
456 |
--------------------------------------------------------------------------------
/jsdoc/symbols/hxl.classes.ColumnFilter.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 | JsDoc Reference - hxl.classes.ColumnFilter
9 |
10 |
174 |
175 |
176 |
177 |
178 |
179 |
181 |
182 |
183 |
184 |
185 |
186 |
188 |
189 |
Classes
190 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 | Class hxl.classes.ColumnFilter
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
Defined in: hxl.js.
243 |
244 |
245 |
246 |
247 |
248 |
249 | Class Summary
250 |
251 |
252 | | Constructor Attributes |
253 | Constructor Name and Description |
254 |
255 |
256 |
257 |
258 | | |
259 |
260 |
263 | HXL filter class to remove columns from a dataset.
264 | |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 | Method Summary
279 |
280 |
281 | | Method Attributes |
282 | Method Name and Description |
283 |
284 |
285 |
286 |
287 |
288 | | |
289 |
290 |
292 | Override hxl.classes.BaseFilter.getColumns to return only the allowed columns.
293 | |
294 |
295 |
296 |
297 | | |
298 |
299 |
301 | Override hxl.classes.BaseFilter.iterator to get data with some columns removed.
302 | |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 | Class Detail
319 |
320 |
321 |
322 | hxl.classes.ColumnFilter(source, patterns, invert)
323 |
324 |
325 |
326 | HXL filter class to remove columns from a dataset.
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 | - Parameters:
336 |
337 | -
338 | source
339 |
340 |
341 | - the HXL data source (may be another filter).
342 |
343 | -
344 | patterns
345 |
346 |
347 | - a list of HXL tag patterns to include (or exclude).
348 |
349 | -
350 | invert
351 |
352 |
353 | - if true, exclude matching columns rather than including them (blacklist).
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 | Method Detail
374 |
375 |
376 |
377 |
378 |
379 |
380 | getColumns()
381 |
382 |
383 |
384 | Override hxl.classes.BaseFilter.getColumns to return only the allowed columns.
385 |
386 | This method triggers lazy processing that also saves the indices for
387 | slicing the data itself.
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 | - Returns:
401 |
402 | - a list of hxl.classes.Column objects.
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 | iterator()
416 |
417 |
418 |
419 | Override hxl.classes.BaseFilter.iterator to get data with some columns removed.
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 | - Returns:
433 |
434 | - an iterator object to read the modified data rows.
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 | Documentation generated by
JsDoc Toolkit 2.4.0 on Sat Jun 30 2018 17:05:53 GMT-0400 (EDT)
456 |
457 |
458 |
459 |
--------------------------------------------------------------------------------
/jsdoc/symbols/hxl.classes.RowFilter.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 | JsDoc Reference - hxl.classes.RowFilter
9 |
10 |
174 |
175 |
176 |
177 |
178 |
179 |
181 |
182 |
183 |
184 |
185 |
186 |
188 |
189 |
Classes
190 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 | Class hxl.classes.RowFilter
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
Defined in: hxl.js.
243 |
244 |
245 |
246 |
247 |
248 |
249 | Class Summary
250 |
251 |
252 | | Constructor Attributes |
253 | Constructor Name and Description |
254 |
255 |
256 |
257 |
258 | | |
259 |
260 |
263 | HXL filter class to select rows from a source.
264 | |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 | Field Summary
276 |
277 |
278 | | Field Attributes |
279 | Field Name and Description |
280 |
281 |
282 |
283 |
284 |
285 | | <static> |
286 |
287 |
290 | Operator functions.
291 | |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 | Method Summary
307 |
308 |
309 | | Method Attributes |
310 | Method Name and Description |
311 |
312 |
313 |
314 |
315 |
316 | | |
317 |
318 |
320 | Override HXLFIlter.iterator to return only select rows.
321 | |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 | Class Detail
338 |
339 |
340 |
341 | hxl.classes.RowFilter(source, predicates, invert)
342 |
343 |
344 |
345 | HXL filter class to select rows from a source.
346 |
347 | Usage:
348 |
349 | // select all rows where #adm1 is the Coastal Region
350 | // *or* the population is greater than 1,000
351 | var filter = new hxl.classes.RowFilter(source,
352 | { pattern: '#adm1', test: 'Coastal Region' },
353 | { pattern: '#people_num', test: function(v) { return v > 1000; } }
354 | ]);
355 |
356 | Predicates are always "OR"'d together. If you need
357 | a logical "AND", then chain another select filter.
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 | - Parameters:
367 |
368 | -
369 | source
370 |
371 |
372 | - the hxl.classes.Source
373 |
374 | -
375 | predicates
376 |
377 |
378 | - a list of predicates, each of
379 | has a "test" property (and optionally, a "pattern" property).
380 |
381 | -
382 | invert
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 | Field Detail
403 |
404 |
405 |
406 |
<static>
407 |
408 |
409 | hxl.classes.RowFilter.OPERATORS
410 |
411 |
412 |
413 | Operator functions.
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 | Method Detail
433 |
434 |
435 |
436 |
437 |
438 |
439 | iterator()
440 |
441 |
442 |
443 | Override HXLFIlter.iterator to return only select rows.
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 | - Returns:
457 |
458 | - an iterator object that will skip rows that fail to pass at
459 | least one of the predicates.
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 | Documentation generated by
JsDoc Toolkit 2.4.0 on Sat Jun 30 2018 17:05:53 GMT-0400 (EDT)
481 |
482 |
483 |
484 |
--------------------------------------------------------------------------------
/jsdoc/symbols/hxl.classes.CountFilter.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 | JsDoc Reference - hxl.classes.CountFilter
9 |
10 |
174 |
175 |
176 |
177 |
178 |
179 |
181 |
182 |
183 |
184 |
185 |
186 |
188 |
189 |
Classes
190 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 | Class hxl.classes.CountFilter
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
Defined in: hxl.js.
243 |
244 |
245 |
246 |
247 |
248 |
249 | Class Summary
250 |
251 |
252 | | Constructor Attributes |
253 | Constructor Name and Description |
254 |
255 |
256 |
257 |
258 | | |
259 |
260 |
263 | HXL filter to count and aggregate data.
264 | |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 | Method Summary
279 |
280 |
281 | | Method Attributes |
282 | Method Name and Description |
283 |
284 |
285 |
286 |
287 |
288 | | |
289 |
290 |
292 | Override hxl.classes.BaseFilter.getColumns to return only the columns for the aggregation report.
293 | |
294 |
295 |
296 |
297 | | |
298 |
299 |
301 | Override hxl.classes.BaseFilter.iterator to return a set of rows with aggregated values.
302 | |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 | Class Detail
319 |
320 |
321 |
322 | hxl.classes.CountFilter(source, patterns, aggregate)
323 |
324 |
325 |
326 | HXL filter to count and aggregate data.
327 |
328 | By default, this filter put out a dataset with the selected tags
329 | and a new tag #meta+count giving the number of times each
330 | combination of values appears. If the aggregate tag pattern is
331 | present, the filter will also produce a column with the sum,
332 | average (mean), minimum, and maximum values for the tag, attaching
333 | the attributes +sum, +avg, +min, and +max to the core tag.
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 | - Parameters:
343 |
344 | -
345 | source
346 |
347 |
348 | - the HXL data source (may be another filter).
349 |
350 | -
351 | patterns
352 |
353 |
354 | - a list of tag patterns (strings or hxl.classes.TagPattern
355 | objects) whose values make up a shared key.
356 |
357 | -
358 | aggregate
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 | Method Detail
382 |
383 |
384 |
385 |
386 |
387 |
388 | getColumns()
389 |
390 |
391 |
392 | Override hxl.classes.BaseFilter.getColumns to return only the columns for the aggregation report.
393 |
394 | Will list the tags that match the patterns provided in the
395 | constructor, as well as a #meta+count tag, and aggregation tags if
396 | the aggregation parameter was included.
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 | - Returns:
410 |
411 | - a list of hxl.classes.Column objects
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 | iterator()
425 |
426 |
427 |
428 | Override hxl.classes.BaseFilter.iterator to return a set of rows with aggregated values.
429 |
430 | Each row represents a unique set of values and the number of times
431 | it occurs.
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 | - Returns:
445 |
446 | - an iterator over the aggregated data.
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 | Documentation generated by
JsDoc Toolkit 2.4.0 on Sat Jun 30 2018 17:05:53 GMT-0400 (EDT)
468 |
469 |
470 |
471 |
--------------------------------------------------------------------------------
/jsdoc/symbols/hxl.classes.Row.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 | JsDoc Reference - hxl.classes.Row
9 |
10 |
174 |
175 |
176 |
177 |
178 |
179 |
181 |
182 |
183 |
184 |
185 |
186 |
188 |
189 |
Classes
190 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 | Class hxl.classes.Row
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
Defined in: hxl.js.
243 |
244 |
245 |
246 |
247 |
248 |
249 | Class Summary
250 |
251 |
252 | | Constructor Attributes |
253 | Constructor Name and Description |
254 |
255 |
256 |
257 |
258 | | |
259 |
260 |
263 | Wrapper for a row of HXL data.
264 | |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 | Method Summary
279 |
280 |
281 | | Method Attributes |
282 | Method Name and Description |
283 |
284 |
285 |
286 |
287 |
288 | | |
289 |
290 |
292 | Make a deep copy of a row's values (not the columns).
293 | |
294 |
295 |
296 |
297 | | |
298 |
299 |
301 | Look up the first value that matches a tag pattern.
302 | |
303 |
304 |
305 |
306 | | |
307 |
308 |
310 | Look up all values that match a tag pattern.
311 | |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 | Class Detail
328 |
329 |
330 |
331 | hxl.classes.Row(values, columns)
332 |
333 |
334 |
335 | Wrapper for a row of HXL data.
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 | - Parameters:
345 |
346 | -
347 | values
348 |
349 |
350 |
351 |
352 | -
353 | columns
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 | Method Detail
377 |
378 |
379 |
380 |
386 |
387 | Make a deep copy of a row's values (not the columns).
388 |
389 | This method is especially useful for filters.
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 | - Returns:
403 |
404 | - {hxl.classes.Row} a new row object.
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 | get(pattern)
418 |
419 |
420 |
421 | Look up the first value that matches a tag pattern.
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 | - Parameters:
431 |
432 | -
433 | pattern
434 |
435 |
436 | - The tag pattern to use.
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 | - Returns:
446 |
447 | - a string value, or null if none found.
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 | getAll(pattern)
461 |
462 |
463 |
464 | Look up all values that match a tag pattern.
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 | - Parameters:
474 |
475 | -
476 | pattern
477 |
478 |
479 | - The tag pattern to use.
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 | - Returns:
489 |
490 | - a possibly-empty array of string values (or nulls).
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 | Documentation generated by
JsDoc Toolkit 2.4.0 on Sat Jun 30 2018 17:05:53 GMT-0400 (EDT)
512 |
513 |
514 |
515 |
--------------------------------------------------------------------------------
/jsdoc/symbols/hxl.classes.Column.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 | JsDoc Reference - hxl.classes.Column
9 |
10 |
174 |
175 |
176 |
177 |
178 |
179 |
181 |
182 |
183 |
184 |
185 |
186 |
188 |
189 |
Classes
190 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 | Class hxl.classes.Column
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
Defined in: hxl.js.
243 |
244 |
245 |
246 |
247 |
248 |
249 | Class Summary
250 |
251 |
252 | | Constructor Attributes |
253 | Constructor Name and Description |
254 |
255 |
256 |
257 |
258 | | |
259 |
260 |
263 | Wrapper for a HXL column definition.
264 | |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 | Method Summary
279 |
280 |
281 | | Method Attributes |
282 | Method Name and Description |
283 |
284 |
285 |
286 |
287 |
288 | | |
289 |
290 |
292 | Create a deep copy of this column spec.
293 | |
294 |
295 |
296 |
297 | | |
298 |
299 |
301 | Create a display tagspec for the column.
302 | |
303 |
304 |
305 |
306 | | <static> |
307 |
308 | hxl.classes.Column. parse(spec, header, useException)
309 |
310 | Parse a tag spec into its parts.
311 | |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 | Class Detail
328 |
329 |
330 |
331 | hxl.classes.Column(tag, attributes, header)
332 |
333 |
334 |
335 | Wrapper for a HXL column definition.
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 | - Parameters:
345 |
346 | -
347 | tag
348 |
349 |
350 |
351 |
352 | -
353 | attributes
354 |
355 |
356 |
357 |
358 | -
359 | header
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 | - See:
374 |
375 | - hxl.classes.TagPattern
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 | Method Detail
390 |
391 |
392 |
393 |
399 |
400 | Create a deep copy of this column spec.
401 |
402 | This method is mainly useful for filters that want to modify a column.
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 | - Returns:
416 |
417 | - {hxl.classes.Column} A deep copy of this columns spec.
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 | getDisplayTag()
431 |
432 |
433 |
434 | Create a display tagspec for the column.
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
<static>
453 |
454 |
455 | hxl.classes.Column.parse(spec, header, useException)
456 |
457 |
458 |
459 | Parse a tag spec into its parts.
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 | - Parameters:
469 |
470 | -
471 | spec
472 |
473 |
474 |
475 |
476 | -
477 | header
478 |
479 |
480 |
481 |
482 | -
483 | useException
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 | Documentation generated by
JsDoc Toolkit 2.4.0 on Sat Jun 30 2018 17:05:53 GMT-0400 (EDT)
512 |
513 |
514 |
515 |
--------------------------------------------------------------------------------
/jsdoc/symbols/hxl.classes.Dataset.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 | JsDoc Reference - hxl.classes.Dataset
9 |
10 |
174 |
175 |
176 |
177 |
178 |
179 |
181 |
182 |
183 |
184 |
185 |
186 |
188 |
189 |
Classes
190 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 | Class hxl.classes.Dataset
232 |
233 |
234 |
235 |
236 |
237 |
Extends
238 | hxl.classes.Source.
239 |
240 |
241 |
242 |
243 |
244 |
Defined in: hxl.js.
245 |
246 |
247 |
248 |
249 |
250 |
251 | Class Summary
252 |
253 |
254 | | Constructor Attributes |
255 | Constructor Name and Description |
256 |
257 |
258 |
259 |
260 | | |
261 |
262 |
265 | An original HXL dataset (including the raw data)
266 | Derived from hxl.classes.Source
267 | |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 | - Fields borrowed from class hxl.classes.Source:
- columns, displayTags, headers, rows, tags
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 | Method Summary
291 |
292 |
293 | | Method Attributes |
294 | Method Name and Description |
295 |
296 |
297 |
298 |
299 |
300 | | |
301 |
302 |
304 | Get an array of column definitions.
305 | |
306 |
307 |
308 |
309 | | |
310 |
311 |
313 | Get an iterator through all the rows in the dataset.
314 | |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 | - Methods borrowed from class hxl.classes.Source:
- cache, count, each, forEach, getDisplayTags, getHeaders, getMatchingColumns, getMax, getMin, getRows, getTags, getValues, hasColumn, index, isNumbery, rename, withColumns, withoutColumns, withoutRows, withRows
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 | Class Detail
335 |
336 |
337 |
338 | hxl.classes.Dataset(rawData)
339 |
340 |
341 |
342 | An original HXL dataset (including the raw data)
343 | Derived from hxl.classes.Source
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 | - Parameters:
353 |
354 | -
355 | {array} rawData
356 |
357 |
358 | - An array of arrays of raw strings (tabular).
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 | Method Detail
379 |
380 |
381 |
382 |
383 |
384 |
385 | getColumns()
386 |
387 |
388 |
389 | Get an array of column definitions.
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 | iterator()
411 |
412 |
413 |
414 | Get an iterator through all the rows in the dataset.
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 | Documentation generated by
JsDoc Toolkit 2.4.0 on Sat Jun 30 2018 17:05:53 GMT-0400 (EDT)
444 |
445 |
446 |
447 |
--------------------------------------------------------------------------------
/test/test-filters.js:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////////////////
2 | // Test various HXL filters
3 | ////////////////////////////////////////////////////////////////////////
4 |
5 | //
6 | // hxl.classes.BaseFilter
7 | //
8 |
9 | QUnit.module("hxl.classes.BaseFilters", {
10 | setup: function () {
11 | this.test_data = [
12 | ['Pointless header'],
13 | ['Organisation', 'Second organisation', 'Sector', 'Province', 'Targeted'],
14 | ['#org', '#org', '#sector+cluster', '#adm1+name', '#population+num'],
15 | ['Org 1', 'Org 1a', 'WASH', 'Coastal Province', '300'],
16 | ['Org 2', '', 'Health', 'Mountain Province', '400'],
17 | ['Org 3', '', 'Protection', 'Coastal Province', '500']
18 | ];
19 | this.dataset = hxl.wrap(this.test_data);
20 | }
21 | });
22 |
23 | QUnit.test("identity filter", function(assert) {
24 | var filter = new hxl.classes.BaseFilter(this.dataset);
25 | assert.deepEqual(filter.columns, this.dataset.columns);
26 | assert.deepEqual(filter.rows, this.dataset.rows);
27 | });
28 |
29 |
30 | //
31 | // hxl.classes.RowFilter
32 | //
33 |
34 | QUnit.test("row filter value string predicate", function(assert) {
35 | var predicates = [
36 | { pattern: '#adm1-code', test: 'Coastal Province'}
37 | ];
38 | var filter = new hxl.classes.RowFilter(this.dataset, predicates);
39 | assert.deepEqual(filter.columns, this.dataset.columns);
40 | assert.equal(filter.rows.length, 2);
41 | assert.deepEqual(filter.getValues('#adm1'), ['Coastal Province']);
42 |
43 | // test convenience methods
44 | assert.deepEqual(filter.columns, this.dataset.withRows(predicates).columns);
45 | assert.deepEqual(filter.rows, this.dataset.withRows(predicates).rows);
46 | });
47 |
48 | QUnit.test("row filter predicate parsing", function(assert) {
49 | assert.deepEqual(
50 | this.dataset.withRows(' #adm1-foo =Coastal Province').getValues('#adm1'),
51 | ['Coastal Province']
52 | );
53 | assert.deepEqual(
54 | this.dataset.withRows('#adm1+name!=Coastal Province').getValues('#adm1'),
55 | ['Mountain Province']
56 | );
57 | assert.deepEqual(
58 | this.dataset.withRows('#population<400').getValues('#org'),
59 | ['Org 1']
60 | );
61 | assert.deepEqual(
62 | this.dataset.withRows('#population<=400').getValues('#org'),
63 | ['Org 1', 'Org 2']
64 | );
65 | assert.deepEqual(
66 | this.dataset.withRows('#population>400').getValues('#org'),
67 | ['Org 3']
68 | );
69 | assert.deepEqual(
70 | this.dataset.withRows('#population>=400').getValues('#org'),
71 | ['Org 2', 'Org 3']
72 | );
73 | assert.deepEqual(
74 | this.dataset.withRows('#adm1~^Coast').getValues('#org'),
75 | ['Org 1', 'Org 3']
76 | );
77 | assert.deepEqual(
78 | this.dataset.withRows('#adm1!~^Coast').getValues('#org'),
79 | ['Org 2']
80 | );
81 | });
82 |
83 | QUnit.test("row filter invert", function(assert) {
84 | var predicates = [
85 | { pattern: '#adm1', test: 'Coastal Province'}
86 | ];
87 | var filter = new hxl.classes.RowFilter(this.dataset, predicates, true);
88 | assert.deepEqual(filter.columns, this.dataset.columns);
89 | assert.equal(filter.rows.length, 1);
90 | assert.deepEqual(filter.getValues('#adm1'), ['Mountain Province']);
91 |
92 | // test convenience methods
93 | assert.deepEqual(filter.columns, this.dataset.withoutRows(predicates).columns);
94 | assert.deepEqual(filter.rows, this.dataset.withoutRows(predicates).rows);
95 | });
96 |
97 | QUnit.test("row filter normalised strings", function(assert) {
98 | assert.deepEqual(this.dataset.withRows('#adm1= coastal province ').getValues('#org'), ['Org 1', 'Org 3']);
99 | });
100 |
101 | QUnit.test("row filter value function predicate", function(assert) {
102 | var test_function = function(value) { return value != 'Protection'; };
103 | var predicates = [
104 | {
105 | pattern: '#sector+cluster',
106 | test: test_function
107 | }
108 | ];
109 | var filter = new hxl.classes.RowFilter(this.dataset, predicates);
110 | assert.equal(filter.rows.length, 2);
111 | assert.deepEqual(filter.getValues('#sector'), ['WASH', 'Health']);
112 |
113 | // test convenience methods
114 | assert.deepEqual(filter.columns, this.dataset.withRows(predicates).columns);
115 | assert.deepEqual(filter.rows, this.dataset.withRows(predicates).rows);
116 | });
117 |
118 | QUnit.test("row filter row predicate", function(assert) {
119 | var test_function = function(row) { return (row.get('#org') == 'Org 1' && row.get('#adm1') == 'Coastal Province'); };
120 | var predicates = [
121 | {
122 | test: test_function
123 | }
124 | ];
125 | var filter = new hxl.classes.RowFilter(this.dataset, predicates);
126 | assert.equal(filter.rows.length, 1);
127 |
128 | // test convenience methods
129 | assert.deepEqual(filter.columns, this.dataset.withRows(predicates).columns);
130 | assert.deepEqual(filter.rows, this.dataset.withRows(predicates).rows);
131 | assert.deepEqual(filter.columns, this.dataset.withRows(test_function).columns);
132 | assert.deepEqual(filter.rows, this.dataset.withRows(test_function).rows);
133 | });
134 |
135 |
136 | //
137 | // hxl.classes.ColumnFilter
138 | //
139 |
140 | QUnit.test("column filter whitelist", function(assert) {
141 | var patterns = ['#sector'];
142 | var filter = new hxl.classes.ColumnFilter(this.dataset, patterns);
143 | assert.deepEqual(filter.columns.map(function (col) {
144 | return col.displayTag;
145 | }), ['#sector+cluster']);
146 | assert.deepEqual(filter.rows.map(function (row) {
147 | return row.values;
148 | }), this.test_data.slice(3).map(function (data) {
149 | return [data[2]];
150 | }));
151 |
152 | // test that the convenience methods work
153 | assert.deepEqual(filter.columns, this.dataset.withColumns(patterns).columns);
154 | assert.deepEqual(filter.values, this.dataset.withColumns(patterns).values);
155 | assert.deepEqual(filter.values, this.dataset.withColumns('#sector').values);
156 | });
157 |
158 | QUnit.test("column filter blacklist", function(assert) {
159 | var patterns = ['#sector'];
160 | var filter = new hxl.classes.ColumnFilter(this.dataset, patterns, true);
161 | assert.deepEqual(filter.columns.map(function (col) {
162 | return col.displayTag;
163 | }), ['#org', '#org', '#adm1+name', '#population+num']);
164 | assert.deepEqual(filter.rows.map(function (row) {
165 | return row.values;
166 | }), this.test_data.slice(3).map(function (data) {
167 | return [data[0], data[1], data[3], data[4]];
168 | }));
169 |
170 | // test that the convenience methods work
171 | assert.deepEqual(filter.columns, this.dataset.withoutColumns(patterns).columns);
172 | assert.deepEqual(filter.rows, this.dataset.withoutColumns(patterns).rows);
173 | assert.deepEqual(filter.rows, this.dataset.withoutColumns('#sector').rows);
174 | });
175 |
176 |
177 | //
178 | // hxl.classes.CountFilter
179 | //
180 |
181 | QUnit.test("count filter single column", function(assert) {
182 | var patterns = ['#adm1'];
183 | var filter = new hxl.classes.CountFilter(this.dataset, patterns);
184 | assert.equal(filter.rows.length, 2);
185 | assert.deepEqual(filter.columns.map(
186 | function (col) { return col.displayTag; }
187 | ), ['#adm1+name', '#meta+count']);
188 |
189 | // test that the convenience methods work
190 | assert.deepEqual(filter.displayTags, this.dataset.count(patterns).displayTags);
191 | assert.deepEqual(filter.rawData, this.dataset.count(patterns).rawData);
192 | assert.deepEqual(filter.rawData, this.dataset.count('#adm1').rawData);
193 | });
194 |
195 | QUnit.test("count filter multiple columns", function(assert) {
196 | var patterns = ['#sector', '#adm1'];
197 | var filter = new hxl.classes.CountFilter(this.dataset, patterns);
198 | assert.equal(filter.rows.length, 3);
199 | assert.deepEqual(filter.columns.map(
200 | function (col) { return col.displayTag; }
201 | ), ['#sector+cluster', '#adm1+name', '#meta+count']);
202 |
203 | // test that the convenience methods work
204 | assert.deepEqual(filter.displayTags, this.dataset.count(patterns).displayTags);
205 | assert.deepEqual(filter.rawValues, this.dataset.count(patterns).rawValues);
206 | });
207 |
208 | QUnit.test("test numeric aggregation", function(assert) {
209 | var source = new hxl.classes.CountFilter(this.dataset, ['#sector', '#adm1']);
210 | var patterns = ['#adm1'];
211 | var aggregate = '#meta+count';
212 | var filter = new hxl.classes.CountFilter(source, patterns, aggregate);
213 | assert.equal(filter.rows.length, 2);
214 | assert.deepEqual(filter.rows.map(function (row) { return row.values; }), [
215 | ['Coastal Province', 2, 2, 1, 1, 1],
216 | ['Mountain Province', 1, 1, 1, 1, 1]
217 | ]);
218 | assert.deepEqual(filter.columns.map(
219 | function (col) { return col.displayTag; }
220 | ), ['#adm1+name', '#meta+count', '#meta+sum', '#meta+avg', '#meta+min', '#meta+max']);
221 |
222 | // test that the convenience methods work
223 | assert.deepEqual(filter.displayTags, source.count(patterns, aggregate).displayTags);
224 | assert.deepEqual(filter.rawValues, source.count(patterns, aggregate).rawValues);
225 | });
226 |
227 |
228 | //
229 | // HXL.classes.RenameFilter
230 | //
231 |
232 | QUnit.test("replace all matches", function(assert) {
233 | var expectedTags = ['#org+foo', '#org+foo', '#sector+cluster', '#adm1+name', '#population+num'];
234 | // test class directly
235 | var filter = new hxl.classes.RenameFilter(this.dataset, '#org', '#org+foo');
236 | assert.deepEqual(filter.displayTags, expectedTags);
237 | // test filter function
238 | filter = this.dataset.rename('#org', '#org+foo');
239 | assert.deepEqual(filter.displayTags, expectedTags);
240 | });
241 |
242 | QUnit.test("confirm changed columns set in rows", function(assert) {
243 | var expectedTags = ['#org+foo', '#org+foo', '#sector+cluster', '#adm1+name', '#population+num'];
244 | var actualTags = []
245 | filter = this.dataset.rename('#org', '#org+foo');
246 | filter.forEach(function (row) {
247 | actualTags = [];
248 | row.columns.forEach(function (col) {
249 | actualTags.push(col.displayTag);
250 | });
251 | assert.deepEqual(actualTags, expectedTags);
252 | });
253 | });
254 |
255 | QUnit.test("replace only one match", function(assert) {
256 | var expectedTags = ['#org', '#org+foo', '#sector+cluster', '#adm1+name', '#population+num'];
257 | // test class directly
258 | var filter = new hxl.classes.RenameFilter(this.dataset, '#org', '#org+foo', undefined, 1);
259 | assert.deepEqual(filter.displayTags, expectedTags);
260 | // test filter function
261 | filter = this.dataset.rename('#org', '#org+foo', undefined, 1);
262 | assert.deepEqual(filter.displayTags, expectedTags);
263 | });
264 |
265 |
266 | //
267 | // HXL.classes.SortFilter
268 | //
269 |
270 | QUnit.test("basic sort", function(assert) {
271 | var filter = new hxl.classes.SortFilter(this.dataset, "#sector");
272 | assert.equal("Health", filter.getRows()[0].get("#sector"));
273 | });
274 |
275 | QUnit.test("inverse sort", function(assert) {
276 | var filter = this.dataset.sort("#population", true);
277 | assert.equal("500", filter.getRows()[0].get("#population"));
278 | });
279 |
280 | QUnit.test("multi-column sort", function(assert) {
281 | var filter = this.dataset.sort(["#sector", "#population"]);
282 | assert.equal("Health", filter.getRows()[0].get("#sector"));
283 | assert.equal("400", filter.getRows()[0].get("#population"));
284 |
285 | // flip order of key columns
286 | filter = this.dataset.sort(["#population", "#sector"]);
287 | assert.equal("300", filter.getRows()[0].get("#population"));
288 | assert.equal("WASH", filter.getRows()[0].get("#sector"));
289 | });
290 |
291 |
292 | //
293 | // HXL.classes.PreviewFilter
294 | //
295 |
296 | QUnit.test("preview the initial rows", function(assert) {
297 | var filter = new hxl.classes.PreviewFilter(this.dataset, 2);
298 | assert.equal(2, filter.getRows().length);
299 |
300 | filter = this.dataset.preview(1);
301 | assert.equal(1, filter.getRows().length);
302 | });
303 |
304 |
305 | //
306 | // HXL.classes.CacheFilter
307 | //
308 |
309 | QUnit.test("cache the parsing stream", function(assert) {
310 | // not testing for actual caching; just that the filter passes through
311 | var filter = new hxl.classes.CacheFilter(this.dataset.withColumns('#sector'));
312 | assert.deepEqual(filter.displayTags, ['#sector+cluster'])
313 | filter = this.dataset.withColumns('#sector').cache();
314 | assert.deepEqual(filter.displayTags, ['#sector+cluster']);
315 | });
316 |
317 |
318 | //
319 | // HXL.classes.IndexFilter
320 | //
321 |
322 | QUnit.test("Add index attributes to repeated tags", function(assert) {
323 | var expectedTags = ['#org+i0', '#org+i1', '#sector+cluster', '#adm1+name', '#population+num'];
324 | var filter = new hxl.classes.IndexFilter(this.dataset, '#org');
325 | assert.deepEqual(filter.displayTags, expectedTags);
326 | filter = this.dataset.index('org');
327 | assert.deepEqual(filter.displayTags, expectedTags);
328 | });
329 |
330 | // end
331 |
--------------------------------------------------------------------------------
/lib/papaparse.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | Papa Parse
3 | v4.1.0
4 | https://github.com/mholt/PapaParse
5 | */
6 | !(function(e){"use strict";function u(t,n){n=n||{};if(n.worker&&Papa.WORKERS_SUPPORTED){var r=m();r.userStep=n.step;r.userChunk=n.chunk;r.userComplete=n.complete;r.userError=n.error;n.step=x(n.step);n.chunk=x(n.chunk);n.complete=x(n.complete);n.error=x(n.error);delete n.worker;r.postMessage({input:t,config:n,workerId:r.id});return}var i=null;if(typeof t==="string"){if(n.download)i=new l(n);else i=new h(n)}else if(e.File&&t instanceof File||t instanceof Object)i=new c(n);return i.stream(t)}function a(t,n){function a(){if(typeof n!=="object")return;if(typeof n.delimiter==="string"&&n.delimiter.length==1&&e.Papa.BAD_DELIMITERS.indexOf(n.delimiter)==-1){o=n.delimiter}if(typeof n.quotes==="boolean"||n.quotes instanceof Array)s=n.quotes;if(typeof n.newline==="string")u=n.newline}function f(e){if(typeof e!=="object")return[];var t=[];for(var n in e)t.push(n);return t}function l(e,t){var n="";if(typeof e==="string")e=JSON.parse(e);if(typeof t==="string")t=JSON.parse(t);var r=e instanceof Array&&e.length>0;var i=!(t[0]instanceof Array);if(r){for(var s=0;s0)n+=o;n+=c(e[s],s)}if(t.length>0)n+=u}for(var a=0;a0)n+=o;var h=r&&i?e[l]:l;n+=c(t[a][h],l)}if(a-1||t.charAt(0)==" "||t.charAt(t.length-1)==" ";return r?'"'+t+'"':t}function h(e,t){for(var n=0;n-1)return true;return false}var r="";var i=[];var s=false;var o=",";var u="\r\n";a();if(typeof t==="string")t=JSON.parse(t);if(t instanceof Array){if(!t.length||t[0]instanceof Array)return l(null,t);else if(typeof t[0]==="object")return l(f(t[0]),t)}else if(typeof t==="object"){if(typeof t.data==="string")t.data=JSON.parse(t.data);if(t.data instanceof Array){if(!t.fields)t.fields=t.data[0]instanceof Array?t.fields:f(t.data[0]);if(!(t.data[0]instanceof Array)&&typeof t.data[0]!=="object")t.data=[t.data]}return l(t.fields||[],t.data||[])}throw"exception: Unable to serialize unrecognized input"}function f(n){function r(e){var t=E(e);t.chunkSize=parseInt(t.chunkSize);this._handle=new p(t);this._handle.streamer=this;this._config=t}this._handle=null;this._paused=false;this._finished=false;this._input=null;this._baseIndex=0;this._partialLine="";this._rowCount=0;this._start=0;this._nextChunk=null;r.call(this,n);this.parseChunk=function(n){var r=this._partialLine+n;this._partialLine="";var i=this._handle.parse(r,this._baseIndex,!this._finished);if(this._handle.paused())return;var s=i.meta.cursor;if(!this._finished){this._partialLine=r.substring(s-this._baseIndex);this._baseIndex=s}if(i&&i.data)this._rowCount+=i.data.length;var o=this._finished||this._config.preview&&this._rowCount>=this._config.preview;if(t){e.postMessage({results:i,workerId:Papa.WORKER_ID,finished:o})}else if(x(this._config.chunk)){this._config.chunk(i,this._handle);if(this._paused)return;i=undefined}if(o&&x(this._config.complete)&&(!i||!i.meta.aborted))this._config.complete(i);if(!o&&(!i||!i.meta.paused))this._nextChunk();return i};this._sendError=function(n){if(x(this._config.error))this._config.error(n);else if(t&&this._config.error){e.postMessage({workerId:Papa.WORKER_ID,error:n,finished:false})}}}function l(e){function r(e){var t=e.getResponseHeader("Content-Range");return parseInt(t.substr(t.lastIndexOf("/")+1))}e=e||{};if(!e.chunkSize)e.chunkSize=Papa.RemoteChunkSize;f.call(this,e);var n;if(t){this._nextChunk=function(){this._readChunk();this._chunkLoaded()}}else{this._nextChunk=function(){this._readChunk()}}this.stream=function(e){this._input=e;this._nextChunk()};this._readChunk=function(){if(this._finished){this._chunkLoaded();return}n=new XMLHttpRequest;if(!t){n.onload=S(this._chunkLoaded,this);n.onerror=S(this._chunkError,this)}n.open("GET",this._input,!t);if(this._config.step||this._config.chunk){var e=this._start+this._config.chunkSize-1;n.setRequestHeader("Range","bytes="+this._start+"-"+e);n.setRequestHeader("If-None-Match","webkit-no-cache")}try{n.send()}catch(r){this._chunkError(r.message)}if(t&&n.status==0)this._chunkError();else this._start+=this._config.chunkSize};this._chunkLoaded=function(){if(n.readyState!=4)return;if(n.status<200||n.status>=400){this._chunkError();return}this._finished=!this._config.step&&!this._config.chunk||this._start>r(n);this.parseChunk(n.responseText)};this._chunkError=function(e){var t=n.statusText||e;this._sendError(t)}}function c(e){e=e||{};if(!e.chunkSize)e.chunkSize=Papa.LocalChunkSize;f.call(this,e);var t,n;var r=typeof FileReader!=="undefined";this.stream=function(e){this._input=e;n=e.slice||e.webkitSlice||e.mozSlice;if(r){t=new FileReader;t.onload=S(this._chunkLoaded,this);t.onerror=S(this._chunkError,this)}else t=new FileReaderSync;this._nextChunk()};this._nextChunk=function(){if(!this._finished&&(!this._config.preview||this._rowCount=this._input.size;this.parseChunk(e.target.result)};this._chunkError=function(){this._sendError(t.error)}}function h(e){e=e||{};f.call(this,e);var t;var n;this.stream=function(e){t=e;n=e;return this._nextChunk()};this._nextChunk=function(){if(this._finished)return;var e=this._config.chunkSize;var t=e?n.substr(0,e):n;n=e?n.substr(e):"";this._finished=!n;return this.parseChunk(t)}}function p(e){function c(){if(f&&u){b("Delimiter","UndetectableDelimiter","Unable to auto-detect delimiting character; defaulted to '"+Papa.DefaultDelimiter+"'");u=false}if(e.skipEmptyLines){for(var t=0;t=a.length){if(!n["__parsed_extra"])n["__parsed_extra"]=[];n["__parsed_extra"].push(f.data[t][r])}else n[a[r]]=f.data[t][r]}}if(e.header){f.data[t]=n;if(r>a.length)b("FieldMismatch","TooManyFields","Too many fields: expected "+a.length+" fields but parsed "+r,t);else if(r1){a+=Math.abs(h-s);s=h}}f/=l.data.length;if((typeof i==="undefined"||a1.99){i=a;r=u}}e.delimiter=r;return{successful:!!r,bestDelimiter:r}}function g(e){e=e.substr(0,1024*1024);var t=e.split("\r");if(t.length==1)return"\n";var n=0;for(var r=0;r=t.length/2?"\r\n":"\r"}function y(e){var n=t.test(e);return n?parseFloat(e):e}function b(e,t,n,r){f.errors.push({type:e,code:t,message:n,row:r})}var t=/^\s*-?(\d*\.?\d+|\d+\.?\d*)(e[-+]?\d+)?\s*$/i;var n=this;var r=0;var i;var s;var o=false;var u;var a=[];var f={data:[],errors:[],meta:{}};if(x(e.step)){var l=e.step;e.step=function(t){f=t;if(h())c();else{c();if(f.data.length==0)return;r+=t.data.length;if(e.preview&&r>e.preview)s.abort();else l(f,n)}}}this.parse=function(t,n,r){if(!e.newline)e.newline=g(t);u=false;if(!e.delimiter){var a=m(t);if(a.successful)e.delimiter=a.bestDelimiter;else{u=true;e.delimiter=Papa.DefaultDelimiter}f.meta.delimiter=e.delimiter}var l=E(e);if(e.preview&&e.header)l.preview++;i=t;s=new d(l);f=s.parse(i,n,r);c();return o?{meta:{paused:true}}:f||{meta:{paused:false}}};this.paused=function(){return o};this.pause=function(){o=true;s.abort();i=i.substr(s.getCharIndex())};this.resume=function(){o=false;n.streamer.parseChunk(i)};this.abort=function(){s.abort();if(x(e.complete))e.complete(f);i=""}}function d(e){e=e||{};var t=e.delimiter;var n=e.newline;var r=e.comments;var i=e.step;var s=e.preview;var o=e.fastMode;if(typeof t!=="string"||t.length!=1||Papa.BAD_DELIMITERS.indexOf(t)>-1)t=",";if(r===t)throw"Comment character same as delimiter";else if(r===true)r="#";else if(typeof r!=="string"||Papa.BAD_DELIMITERS.indexOf(r)>-1)r=false;if(n!="\n"&&n!="\r"&&n!="\r\n")n="\n";var u=0;var a=false;this.parse=function(e,f,l){function C(e){m.push(e);b=u}function k(t){if(l)return A();if(!t)t=e.substr(u);y.push(t);u=c;C(y);if(v)O();return A()}function L(t){u=t;C(y);y=[];x=e.indexOf(n,u)}function A(e){return{data:m,errors:g,meta:{delimiter:t,linebreak:n,aborted:a,truncated:!!e,cursor:b+(f||0)}}}function O(){i(A());m=[],g=[]}if(typeof e!=="string")throw"Input must be a string";var c=e.length,h=t.length,p=n.length,d=r.length;var v=typeof i==="function";u=0;var m=[],g=[],y=[],b=0;if(!e)return A();if(o||o!==false&&e.indexOf('"')===-1){var w=e.split(n);for(var E=0;E=s){m=m.slice(0,s);return A(true)}}return A()}var S=e.indexOf(t,u);var x=e.indexOf(n,u);for(;;){if(e[u]=='"'){var T=u;u++;for(;;){var T=e.indexOf('"',T+1);if(T===-1){if(!l){g.push({type:"Quotes",code:"MissingQuotes",message:"Quoted field unterminated",row:m.length,index:u})}return k()}if(T===c-1){var N=e.substring(u,T).replace(/""/g,'"');return k(N)}if(e[T+1]=='"'){T++;continue}if(e[T+1]==t){y.push(e.substring(u,T).replace(/""/g,'"'));u=T+1+h;S=e.indexOf(t,u);x=e.indexOf(n,u);break}if(e.substr(T+1,p)===n){y.push(e.substring(u,T).replace(/""/g,'"'));L(T+1+p);S=e.indexOf(t,u);if(v){O();if(a)return A()}if(s&&m.length>=s)return A(true);break}}continue}if(r&&y.length===0&&e.substr(u,d)===r){if(x==-1)return A();u=x+p;x=e.indexOf(n,u);S=e.indexOf(t,u);continue}if(S!==-1&&(S=s)return A(true);continue}break}return k()};this.abort=function(){a=true};this.getCharIndex=function(){return u}}function v(){var e=document.getElementsByTagName("script");return e.length?e[e.length-1].src:""}function m(){if(!Papa.WORKERS_SUPPORTED)return false;if(!n&&Papa.SCRIPT_PATH===null)throw new Error("Script path cannot be determined automatically when Papa Parse is loaded asynchronously. "+"You need to set Papa.SCRIPT_PATH manually.");var t=new e.Worker(Papa.SCRIPT_PATH||r);t.onmessage=g;t.id=s++;i[t.id]=t;return t}function g(e){var t=e.data;var n=i[t.workerId];var r=false;if(t.error)n.userError(t.error,t.file);else if(t.results&&t.results.data){var s=function(){r=true;y(t.workerId,{data:[],errors:[],meta:{aborted:true}})};var o={abort:s,pause:b,resume:b};if(x(n.userStep)){for(var u=0;u
3 |
4 |
5 |
6 |
7 |
8 | JsDoc Reference - hxl.classes.TagPattern
9 |
10 |
174 |
175 |
176 |
177 |
178 |
179 |
181 |
182 |
183 |
184 |
185 |
186 |
188 |
189 |
Classes
190 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 | Class hxl.classes.TagPattern
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
Defined in: hxl.js.
243 |
244 |
245 |
246 |
247 |
248 |
249 | Class Summary
250 |
251 |
252 | | Constructor Attributes |
253 | Constructor Name and Description |
254 |
255 |
256 |
257 |
258 | | |
259 |
260 |
263 | A compiled pattern for matching HXL columns.
264 | |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 | Method Summary
279 |
280 |
281 | | Method Attributes |
282 | Method Name and Description |
283 |
284 |
285 |
286 |
287 |
288 | | |
289 |
290 |
292 | Test if a column matches this pattern.
293 | |
294 |
295 |
296 |
297 | | |
298 |
299 |
301 | Test if a tag pattern matches any columns in a list.
302 | |
303 |
304 |
305 |
306 | | <static> |
307 |
308 | hxl.classes.TagPattern. parse(pattern, useException)
309 |
310 | Parse a string into a tag pattern.
311 | |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 | Class Detail
328 |
329 |
330 |
331 | hxl.classes.TagPattern(tag, includeAttributes, excludeAttributes, isAbsolute)
332 |
333 |
334 |
335 | A compiled pattern for matching HXL columns.
336 |
337 |
You should not normally call this constructor directly. All
338 | functions that use a pattern compile it as needed, so you can stick
339 | with strings. If you want to precompile a pattern, use the static
340 | #parse method.
341 |
342 |
The other useful method in this class is #match, with
343 | tests the pattern against a hxl.classes.Column.
344 |
345 |
A pattern specification looks like a normal HXL hashtag and
346 | attributes, except that it can contain "-" attributes as well as
347 | "+" attributes. For example, the following pattern matches any
348 | column with the tag "#org", the attribute "+funder", and *not* the
349 | attribute "+impl" (any other attributes are ignored):
350 |
351 |
352 | #org+funder-impl
353 |
354 |
355 |
More examples:
356 |
357 |
#adm1 will match the following: #adm1, #adm1+code, #adm1+fr,
358 | #adm1+name, etc.
359 |
360 |
#adm1-code will match #adm1, #adm1+fr, and #adm1+name,
361 | but *not* #adm1+code (because the +code attribute is explicitly
362 | forbidden).
363 |
364 |
#adm1+name-fr will match #adm1+name or #adm1+name+en, but
365 | not #adm1+name+fr
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 | - Parameters:
375 |
376 | -
377 | {string} tag
378 |
379 |
380 | - The basic tag to use in the pattern, with the
381 | leading '#'
382 |
383 | -
384 | {array} includeAttributes
385 |
386 |
387 | - A (possibly-empty) list of
388 | attribute names that must be present, without the leading '+'
389 |
390 | -
391 | {array} excludeAttributes
392 |
393 |
394 | - A (possibly-empty) list of
395 | attribute names that must *not* be present, without the leading '+'
396 |
397 | -
398 | isAbsolute
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 | - See:
413 |
414 | - hxl.classes.Column
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 | Method Detail
429 |
430 |
431 |
432 |
433 |
434 | {boolean}
435 | match(column)
436 |
437 |
438 |
439 | Test if a column matches this pattern.
440 |
441 |
442 | data.columns.forEach(function(col) {
443 | if (pattern.match(col)) {
444 | console.log("Found a match: " + col.displayTag);
445 | }
446 | });
447 |
448 |
449 | This method is used heavily in the filter classes.
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 | - Parameters:
459 |
460 | -
461 | {hxl.classes.Column} column
462 |
463 |
464 | - The column to test.
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 | - Returns:
474 |
475 | - {boolean} true on match, false otherwise.
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 | matchList(columns)
489 |
490 |
491 |
492 | Test if a tag pattern matches any columns in a list.
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 | - Parameters:
502 |
503 | -
504 | columns
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
<static>
522 |
523 |
524 | hxl.classes.TagPattern.parse(pattern, useException)
525 |
526 |
527 |
528 | Parse a string into a tag pattern.
529 |
530 |
531 | var pattern = hxl.classes.TagPattern.parse('#org+funder-impl');
532 |
533 |
534 | It is safe to pass an already-compiled
hxl.classes.TagPattern
535 | to this method; it will simple be returned as-is.
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 | - Parameters:
545 |
546 | -
547 | {string} pattern
548 |
549 |
550 | - a tag-pattern string, like "#org+funder-impl"
551 |
552 | -
553 | useException
554 |
555 |
556 | - (optional) throw an exception on failure.
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 | - Returns:
566 |
567 | - a hxl.classes.TagPattern, or null if parsing fails (and useException is false).
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 | Documentation generated by
JsDoc Toolkit 2.4.0 on Sat Jun 30 2018 17:05:53 GMT-0400 (EDT)
589 |
590 |
591 |
592 |
--------------------------------------------------------------------------------