jupyter-ijavascript-utils 1.8.3 → 1.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/DOCS.md CHANGED
@@ -28,7 +28,8 @@ See the [#Installation section for requirements and installation](#install)
28
28
 
29
29
  ## What's New
30
30
 
31
- * 1.8 - add in What can I Do tutorial, and object.join methods
31
+ * 1.9 - allow {@link TableGenerator#transpose|transposing results} on TableGenerator.
32
+ * 1.8 - add in What can I Do tutorial, and {@link module:object.join|object.join methods}
32
33
  * 1.7 - revamp of `animation` method for ijs.htmlScript
33
34
  * 1.6 - add SVG support for rendering SVGs and animations with {@link module:svg}.
34
35
  * 1.5 - Add LaTeX / KaTeX support with {@link module:latex} for rendering Math formulas and PlantUML support for Diagrams
package/README.md CHANGED
@@ -6,6 +6,9 @@
6
6
  <img src="https://img.shields.io/badge/License-MIT-green" />
7
7
  </a>
8
8
  <img src="https://img.shields.io/badge/Coverage-98-green" />
9
+ <a href="https://github.com/paulroth3d/jupyter-ijavascript-utils" alt="npm">
10
+ <img src="https://img.shields.io/badge/npm-%5E1.9.1-red" />
11
+ </a>
9
12
  </p>
10
13
 
11
14
  # Overview
@@ -18,6 +21,7 @@ See documentation at: [https://jupyter-ijavascript-utils.onrender.com/](https://
18
21
 
19
22
  # What's New
20
23
 
24
+ * 1.9 - allow transposing results on TableGenerator.
21
25
  * 1.8 - add in What can I Do tutorial, and object.join methods
22
26
  * 1.7 - revamp of `animation` method to htmlScript
23
27
  * 1.6 - add SVG support for rendering SVGs and animations
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jupyter-ijavascript-utils",
3
- "version": "1.8.3",
3
+ "version": "1.9.1",
4
4
  "description": "Utilities for working with iJavaScript - a Jupyter Kernel",
5
5
  "homepage": "https://jupyter-ijavascript-utils.onrender.com/",
6
6
  "license": "MIT",
@@ -17,6 +17,8 @@ const generateRange = (length, defaultValue) => new Array(length).fill(defaultVa
17
17
 
18
18
  const IJSUtils = require('./ijs');
19
19
 
20
+ const ArrayUtils = require('./array');
21
+
20
22
  const { createSort } = require('./array');
21
23
 
22
24
  /**
@@ -62,29 +64,32 @@ const { createSort } = require('./array');
62
64
  * * change the columns and headers
63
65
  * * {@link TableGenerator#columns|columns(field, field, ...)} - specify fields and order
64
66
  * * {@link TableGenerator#columnsToExclude|columnsToExclude(field, ...)} - specify fields not to show
65
- * * {@link TableGenerator#labels|lables(obj} - labels for field headers
67
+ * * {@link TableGenerator#labels|lables(obj)} - labels for field headers
66
68
  * * augment and change the values (non-destructively)
67
- * * {@link TableGenerator#formatter|formatter(obj} - adjust values of specific fields
68
- * * {@link TableGenerator#formatterFn|formatterFn(fn} - row, column aware adjustment
69
- * * {@link TableGenerator#printOptions|printOptions(object} - options for value rendering
69
+ * * {@link TableGenerator#formatter|formatter(obj)} - adjust values of specific fields
70
+ * * {@link TableGenerator#formatterFn|formatterFn(fn)} - row, column aware adjustment
71
+ * * {@link TableGenerator#printOptions|printOptions(object)} - options for value rendering
70
72
  * * {@link TableGenerator#augment|augment(obj)} - add fields to table
71
73
  * * sort and limit the output
72
- * * {@link TableGenerator#filter|filter(fn))} - determine which rows to include or not
73
- * * {@link TableGenerator#limit|limit(number} - limit only specific # of rows
74
- * * {@link TableGenerator#sortFn|sortFn(fn} - Standard Array sort function
75
- * * {@link TableGenerator#sort|sort(field, field, ...} - sorts by fields, or descending with -
74
+ * * {@link TableGenerator#filter|filter(fn)} - determine which rows to include or not
75
+ * * {@link TableGenerator#limit|limit(number)} - limit only specific # of rows
76
+ * * {@link TableGenerator#sortFn|sortFn(fn)} - Standard Array sort function
77
+ * * {@link TableGenerator#sort|sort(field, field, ...)} - sorts by fields, or descending with '-'
78
+ * * transpose the output
79
+ * * {@link TableGenerator#transpose|transpose()} - transposes the output prior to rendering
76
80
  * * style the table
77
- * * {@link TableGenerator#styleTable|styleTable(string} - css style for the table
78
- * * {@link TableGenerator#styleHeader|styleHeader(string} - css styles for the header row
81
+ * * {@link TableGenerator#styleTable|styleTable(string)} - css style for the table
82
+ * * {@link TableGenerator#styleHeader|styleHeader(string)} - css styles for the header row
79
83
  * * {@link TableGenerator#styleRow|styleRow(fn)} - Function to style rows
80
- * * {@link TableGenerator#styleCell|styleCell(fn} - Function to style cells
84
+ * * {@link TableGenerator#styleCell|styleCell(fn)} - Function to style cells
81
85
  * * generate output
82
- * * {@link TableGenerator#generateHTML|generateHTML(} - returns html table with the results
83
- * * {@link TableGenerator#generateMarkdown|generateMarkdown(} - returns markdown with the results
84
- * * {@link TableGenerator#generateCSV|generateCSV(} - generates a CSV with the results
85
- * * {@link TableGenerator#generateArray|generateArray(} - generates an array for further process
86
+ * * {@link TableGenerator#generateHTML|generateHTML()} - returns html table with the results
87
+ * * {@link TableGenerator#generateMarkdown|generateMarkdown()} - returns markdown with the results
88
+ * * {@link TableGenerator#generateCSV|generateCSV()} - generates a CSV with the results
89
+ * * {@link TableGenerator#generateArray|generateArray()} - generates an array of headers and data for further process
90
+ * * {@link TableGenerator#generateArray2|generateArray2()} - generates a single array for further process
86
91
  * * render in jupyter
87
- * * {@link TableGenerator#render|render(} - renders the results in a table within jupyter
92
+ * * {@link TableGenerator#render|render()} - renders the results in a table within jupyter
88
93
  *
89
94
  */
90
95
  class TableGenerator {
@@ -191,6 +196,12 @@ class TableGenerator {
191
196
  */
192
197
  #styleCell = null;
193
198
 
199
+ /**
200
+ * Whether the data should be output transposed
201
+ * @type {Boolean}
202
+ */
203
+ #isTransposed = false;
204
+
194
205
  /**
195
206
  * Function to format a value for a cell
196
207
  *
@@ -237,6 +248,7 @@ class TableGenerator {
237
248
  this.#styleHeader = '';
238
249
  this.#styleRow = null;
239
250
  this.#styleCell = null;
251
+ this.#isTransposed = false;
240
252
  }
241
253
 
242
254
  //-- GETTER SETTERS
@@ -781,6 +793,53 @@ class TableGenerator {
781
793
  return this;
782
794
  }
783
795
 
796
+ /**
797
+ * Transposes (flips along the diagonal) prior to output.
798
+ *
799
+ * This can be very handy for wide, but short, tables.
800
+ *
801
+ * For example, given the data:
802
+ *
803
+ * ```
804
+ * const data = [
805
+ * { name: 'John', color: 'green', age: 23, hair: 'blond', state: 'IL' },
806
+ * { name: 'Jane', color: 'brown', age: 23, hair: 'blonde', state: 'IL' }
807
+ * ];
808
+ * ```
809
+ *
810
+ * Running normally would give
811
+ *
812
+ * ```
813
+ * new utils.TableGenerator(data)
814
+ * .generateMarkdown();
815
+ * ```
816
+ *
817
+ * name|color|age|hair |state
818
+ * -- |-- |-- |-- |--
819
+ * John|green|23 |blond |IL
820
+ * Jane|brown|23 |blonde|IL
821
+ *
822
+ * Running that transposed flips it.
823
+ *
824
+ * ```
825
+ * new utils.TableGenerator(data)
826
+ * .transpose()
827
+ * .generateMarkdown();
828
+ * ```
829
+ *
830
+ * name |John |Jane
831
+ * -- |-- |--
832
+ * color|green|brown
833
+ * age |23 |23
834
+ * hair |blond|blonde
835
+ * state|IL |IL
836
+ * @returns {TableGenerator}
837
+ */
838
+ transpose() {
839
+ this.#isTransposed = true;
840
+ return this;
841
+ }
842
+
784
843
  //-- Table Generation
785
844
 
786
845
  /**
@@ -833,7 +892,7 @@ class TableGenerator {
833
892
  record: row
834
893
  }));
835
894
 
836
- const headers = keys.map(translateHeader);
895
+ let headers = keys.map(translateHeader);
837
896
  let data = cleanCollection.map(translateData);
838
897
 
839
898
  if (this.#limit < 0) {
@@ -842,6 +901,15 @@ class TableGenerator {
842
901
  data = data.slice(0, this.#limit);
843
902
  }
844
903
 
904
+ if (this.#isTransposed) {
905
+ let transposedResults = [headers, ...data];
906
+ transposedResults = ArrayUtils.transpose(transposedResults);
907
+
908
+ // eslint-disable-next-line prefer-destructuring
909
+ headers = transposedResults[0];
910
+ data = transposedResults.slice(1);
911
+ }
912
+
845
913
  return ({ headers, data });
846
914
  }
847
915
 
@@ -995,8 +1063,10 @@ class TableGenerator {
995
1063
  */
996
1064
 
997
1065
  /**
998
- * Generates an array of objects
1066
+ * Generates an a result set to allow for further processing
999
1067
  *
1068
+ * @see {@link TableGenerator#generateArray2|generateArray2()}
1069
+ * @returns {TableArray}
1000
1070
  * @example
1001
1071
  *
1002
1072
  * dataSet = [{reg:'z', source: 'A', temp: 99},
@@ -1019,14 +1089,44 @@ class TableGenerator {
1019
1089
  * ['A', 100],
1020
1090
  * ]
1021
1091
  * }
1022
- *
1023
- * @returns {TableArray}
1024
1092
  */
1025
- generateArray() {
1093
+ generateArray(returnUnifiedArray = false) {
1026
1094
  const results = this.prepare();
1027
1095
  return results;
1028
1096
  }
1029
1097
 
1098
+ /**
1099
+ * Generates an array of objects in a 2d Array
1100
+ *
1101
+ * NOTE: this can be helpful for needing to transpose results
1102
+ *
1103
+ * @returns {any[][]} - 2d array with both headers and data included
1104
+ * @see {@link TableGenerator#generateArray|generateArray()}
1105
+ * @example
1106
+ *
1107
+ * dataSet = [{reg:'z', source: 'A', temp: 99},
1108
+ * {reg: 'z', source: 'B', temp: 98},
1109
+ * {reg: 'z', source:'A', temp: 100}
1110
+ * ];
1111
+ *
1112
+ * //-- only show the temp and source columns
1113
+ * new TableGenerator(dataSet)
1114
+ * .columnsToExclude('reg') // or .columnsToExclude(['reg'])
1115
+ * .generateArray2();
1116
+ *
1117
+ * //--
1118
+ * [
1119
+ * ['source', 'temp'],
1120
+ * ['A', 99],
1121
+ * ['B', 98],
1122
+ * ['A', 100],
1123
+ * ];
1124
+ */
1125
+ generateArray2() {
1126
+ const results = this.prepare();
1127
+ return [...results.headers, ...results.data];
1128
+ }
1129
+
1030
1130
  /**
1031
1131
  * Renders the html table in the cell results.
1032
1132
  *
package/src/array.js CHANGED
@@ -16,8 +16,14 @@ require('./_types/global');
16
16
  * * {@link module:array.SORT_ASCENDING|array.SORT_ASCENDING} - common ascending sorting function for array.sort()
17
17
  * * {@link module:array.SORT_DESCENDING|array.SORT_DESCENDING} - common descending sorting function for array.sort()
18
18
  * * Rearrange Array
19
- * * {@link module:array.reshape|array.reshape}
20
- * * {@link module:array.transpose|array.transpose}
19
+ * * {@link module:array.reshape|array.reshape} - reshapes an array to a size of rows and columns
20
+ * * {@link module:array.transpose|array.transpose} - transposes (flips - the array along the diagonal)
21
+ * * Picking Values
22
+ * * {@link module:array.peekFirst|array.peekFirst} - peeks at the first value in the list
23
+ * * {@link module:array.peekLast|array.peekLast} - peeks at the last value in the list
24
+ * * {@link module:array.pickRows|array.pickRows} - picks a row from a 2d array
25
+ * * {@link module:array.pickColumns|array.pickColumns} - picks a column from a 2d array
26
+ * * {@link module:array.pick|array.pick} - picks either/or rows and columns
21
27
  *
22
28
  * @module array
23
29
  * @exports array
@@ -101,18 +107,144 @@ module.exports.createSort = (...fields) => {
101
107
  });
102
108
  };
103
109
 
110
+ /**
111
+ * Peek in an array and return the first value in the array.
112
+ *
113
+ * Or return the default value (`defaultVal`) - if the array is empty
114
+ *
115
+ * @param {Array} targetArray - array to be peeked within
116
+ * @param {any} defaultVal - the value to return if the array is empty
117
+ * @returns {any}
118
+ */
104
119
  module.exports.peekFirst = function peekFirst(targetArray, defaultVal = null) {
105
120
  return (Array.isArray(targetArray) && targetArray.length > 0)
106
121
  ? targetArray[0]
107
122
  : defaultVal;
108
123
  };
109
124
 
125
+ /**
126
+ * Peek in an array and return the last value in the array.
127
+ *
128
+ * Or return the default value (`defaultVal`) - if the array is empty
129
+ *
130
+ * @param {Array} targetArray - array to be peeked within
131
+ * @param {any} defaultVal - the value to return if the array is empty
132
+ * @returns {any}
133
+ */
110
134
  module.exports.peekLast = function peekLast(targetArray, defaultVal = null) {
111
135
  return (Array.isArray(targetArray) && targetArray.length > 0)
112
136
  ? targetArray[targetArray.length - 1]
113
137
  : defaultVal;
114
138
  };
115
139
 
140
+ /**
141
+ * Picks a row (or multiple rows) from a 2d array.
142
+ *
143
+ * Please also see [Danfo.js](https://danfo.jsdata.org/) for working with DataFrames.
144
+ *
145
+ * @param {Array} array2d - 2d array to pick from [row][column]
146
+ * @param {...Number} rowIndices - Indexes of the row to return, [0...length-1]
147
+ * @returns - Array with only those rows
148
+ * @example
149
+ * data = [
150
+ * ['john', 23, 'purple'],
151
+ * ['jane', 32, 'red'],
152
+ * ['ringo', 27, 'green']
153
+ * ];
154
+ *
155
+ * utils.array.pickRows(data, 0);
156
+ * //-- [['john', 23, 'purple']];
157
+ *
158
+ * utils.array.pickRows(data, 0, 1);
159
+ * //-- [['john', 23, 'purple'], ['jane', 32, 'red']];
160
+ */
161
+ module.exports.pickRows = function pickRows(array2d, ...rowIndices) {
162
+ //-- allow passing an array as the first item
163
+ const cleanRowIndices = rowIndices.length > 0 && Array.isArray(rowIndices[0])
164
+ ? rowIndices[0]
165
+ : rowIndices;
166
+ return cleanRowIndices.map((index) => array2d[index]);
167
+ };
168
+
169
+ /**
170
+ * Picks a column (or multiple columns) from a 2d array
171
+ *
172
+ * Please also see [Danfo.js](https://danfo.jsdata.org/) for working with DataFrames.
173
+ *
174
+ * @param {Array} array2d - 2d array to pick from [row][column]
175
+ * @param {...any} columns - Indexes of the columns to pick the values from: [0...row.length-1]
176
+ * @returns - Array with all rows, and only those columns
177
+ * @example
178
+ * data = [
179
+ * ['john', 23, 'purple'],
180
+ * ['jane', 32, 'red'],
181
+ * ['ringo', 27, 'green']
182
+ * ];
183
+ *
184
+ * utils.array.pickColumns(data, 0);
185
+ * //-- [['john'], ['jane'], ['ringo']];
186
+ *
187
+ * utils.array.pickColumns(data, 0, 2);
188
+ * //-- [['john', 'purple'], ['jane', 'red'], ['ringo', 'green']];
189
+ */
190
+ module.exports.pickColumns = function pickColumns(array2d, ...columns) {
191
+ //-- allow passing an array as the first item
192
+ const cleanColumns = columns.length > 0 && Array.isArray(columns[0])
193
+ ? columns[0]
194
+ : columns;
195
+ return array2d.map((row) => cleanColumns.map((columnIndex) => row[columnIndex]));
196
+ };
197
+
198
+ /**
199
+ * Convenience function for picking specific rows and columns from a 2d array.
200
+ *
201
+ * Please also see [Danfo.js](https://danfo.jsdata.org/) for working with DataFrames.
202
+ *
203
+ * @param {Array} array2d - 2d array to pick from [row][column]
204
+ * @param {Object} options - options on which to pick
205
+ * @param {Number[]} [options.rows = null] - indices of the rows to pick
206
+ * @param {Number[]} [options.columns = null] - indices of the columns to pick.
207
+ * @returns {Array} - 2d array of only the rows and columns chosen.
208
+ * @see {@link module:Array.pickRows} - picking rows
209
+ * @see {@link module:Array.pickColumns} - picking columns
210
+ * @returns - 2dArray of the columns and rows requested
211
+ * @example
212
+ * data = [
213
+ * ['john', 23, 'purple'],
214
+ * ['jane', 32, 'red'],
215
+ * ['ringo', 27, 'green']
216
+ * ];
217
+ *
218
+ * utils.array.pick(data, {rows: [0, 1]});
219
+ * //-- [['john', 23, 'purple'], ['jane', 32, 'red']];
220
+ *
221
+ * utils.array.pick(data, {columns: [0, 2]});
222
+ * //-- [['john', 'purple'], ['jane', 'red'], ['ringo', 'green']];
223
+ *
224
+ * utils.array.pick(data, {rows:[0, 1], columns:[0, 2]});
225
+ * //-- [['john', 'purple'], ['jane', 'red']];
226
+ */
227
+ module.exports.pick = function pick(array2d, options) {
228
+ const cleanOptions = options || {};
229
+
230
+ const {
231
+ rows = null,
232
+ columns = null
233
+ } = cleanOptions;
234
+
235
+ let results = array2d;
236
+
237
+ if (rows) {
238
+ results = ArrayUtils.pickRows(results, rows);
239
+ }
240
+
241
+ if (columns) {
242
+ results = ArrayUtils.pickColumns(results, columns);
243
+ }
244
+
245
+ return results;
246
+ };
247
+
116
248
  /**
117
249
  * Creates an array of a specific size and default value
118
250
  *
package/src/datasets.js CHANGED
@@ -9,6 +9,9 @@ const fetch = require('node-fetch');
9
9
  * The data lives at [https://github.com/vega/vega-datasets](https://github.com/vega/vega-datasets)
10
10
  * and [https://cdn.jsdelivr.net/npm/vega-datasets](https://cdn.jsdelivr.net/npm/vega-datasets)
11
11
  *
12
+ * **For those of you familiar with Pandas, please consider looking at [danfo.js](https://danfo.jsdata.org/)
13
+ * and [DataFrame.js](https://gmousse.gitbooks.io/dataframe-js/content/#dataframe-js)**
14
+ *
12
15
  * * {@link module:datasets.list|list()} - retrieves the list of the datasets available
13
16
  * * {@link module:datasets.fetch|fetch(datasetName)} - returns a promise and fetches the dataset
14
17
  *
package/src/ijs.js CHANGED
@@ -135,7 +135,7 @@ module.exports.await = async function ijsAsync(fn) {
135
135
  context.$$.async();
136
136
 
137
137
  try {
138
- const results = fn(context.$$, context.console);
138
+ const results = await fn(context.$$, context.console);
139
139
  context.$$.sendResult(results);
140
140
  } catch (err) {
141
141
  context.console.error('error occurred');
package/src/latex.js CHANGED
@@ -95,7 +95,7 @@ module.exports.render = function render(body) {
95
95
  * For example, here we can give options on display options, and additional custom macros.
96
96
  *
97
97
  * ```
98
- * utils.katex.render("c = \\pm\\root{a^2 + b^2}\\in\\RR", {
98
+ * utils.latex.katex("c = \\pm\\root{a^2 + b^2}\\in\\RR", {
99
99
  * displayMode: false,
100
100
  * macros: {
101
101
  * "\\RR": "\\mathbb{R}",