Skip to content

Commit

Permalink
add list2charts files and add table chart formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
Alejandro-Gonzalez committed Sep 18, 2020
1 parent 3bb5a4a commit fd77d3e
Show file tree
Hide file tree
Showing 20 changed files with 3,007 additions and 1,533 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.js
Expand Up @@ -14,6 +14,7 @@ module.exports = {
},

rules: {
'strict': ['error', 'global'],
'operator-linebreak': 0,
'no-continue': 0,
'no-plusplus': 0,
Expand Down Expand Up @@ -106,4 +107,4 @@ module.exports = {
}],
'nonblock-statement-body-position': ['error', 'below', { overrides: { else: 'any' } }]
}
};
};
47 changes: 47 additions & 0 deletions lib/base-chart.js
@@ -0,0 +1,47 @@
'use strict';

const { processPipeline } = require('./pipeline');

class LineChart {

This comment has been minimized.

Copy link
@gastonpereyra

gastonpereyra Oct 6, 2020

🤔 Viendo como se requiere después, llamaría esta clase BaseChart


constructor(dataHandlingProps, options = {}) {
this._dataHandlingProps = dataHandlingProps;
this._options = options;
}

setData(data) {
this._data = data;
}

parse() {
return {
data: this.tryToSort(this._parseData()),
options: this._parseOptions()
};
}

_parseData() {
const { pipeline } = this._dataHandlingProps;

return pipeline ? processPipeline(this._data, pipeline) : this._data;
}

_parseOptions() {
return this._options;
}

tryToSort(data) {
if(!this._dataHandlingProps.sortData || typeof this._dataHandlingProps.sortData !== 'function')
return data;

const [headers, ...realData] = data;

return [
headers,
...realData.sort(([key1], [key2]) => this._dataHandlingProps.sortData(key1, key2))
];
}

}

module.exports = LineChart;
21 changes: 0 additions & 21 deletions lib/format-data-to-google-chart-error.js

This file was deleted.

11 changes: 0 additions & 11 deletions lib/format-data-to-google-chart.js

This file was deleted.

38 changes: 38 additions & 0 deletions lib/helpers.js
@@ -0,0 +1,38 @@
'use strict';

const identity = x => x;

const getTitle = ({ source, title, titleMapper }) => {
return (titleMapper || identity)(title || source);

This comment has been minimized.

Copy link
@gastonpereyra

gastonpereyra Oct 6, 2020

🤔 Si bien entendí que pasa, creo que no queda tan legible.

Se me ocurre que se podría ser mas explicito aunque esto agregue más lineas. Y sea quien sea quien tenga que mantener el package, la tiene un poco mas fácil.

Pienso que podría ser algo asi:

const getTitle = ({ source, title, titleMapper }) => {

   const mapper = titleMapper || identity;
   const value = title || source;

   return mapper(value);
};

Que les Parece ?

This comment has been minimized.

Copy link
@gastonpereyra

gastonpereyra Oct 6, 2020

Incluso viendo mas abajo, se podria hacer una función getMappers ya que sucede algo similar en el getValue, esto de si no esta el mapper usar identity

};

/**
* Maps an array of source definitions to an array of strings representing the titles.
* A source definition is an object with the following properties:
* - title {string}
* - source {string}
* - mapper {callable}. Receives a string and must return another
*
* @param {array<object>} sources The source definitions
* @return {array<string>} The titles.
*/
const getTitles = sources => sources.map(getTitle);

const getValue = (row, { source, valueMapper }) => (valueMapper || identity)(row[source], row);

/**
* Maps a row and an array of source definitions to an array of values.
* A source definition is an object with the following properties:
* - source {string}
* - valueMapper {callable}. Receives a string and must return another
*
* @param {object} row The row with all the data
* @param {array<object>} sources The source definitions
* @return {array<any>} The values.
*/
const getValues = (row, sources) => sources.map(source => getValue(row, source));

module.exports = {
getTitles,
getValues
};
10 changes: 6 additions & 4 deletions lib/index.js
@@ -1,9 +1,11 @@
'use strict';

const FormatDataToGoogleChart = require('./format-data-to-google-chart');
const FormatDataToGoogleChartError = require('./format-data-to-google-chart-error');
const PieChart = require('./pie-chart');
const LineChart = require('./line-chart');
const TableChart = require('./table-chart');

module.exports = {
FormatDataToGoogleChart,
FormatDataToGoogleChartError
PieChart,
LineChart,
TableChart
};
31 changes: 31 additions & 0 deletions lib/line-chart.js
@@ -0,0 +1,31 @@
'use strict';

const BaseChart = require('./base-chart');
const { getTitles, getValues } = require('./helpers');

class LineChart extends BaseChart {

_parseData() {

const data = super._parseData();

return [
getTitles([
this._dataHandlingProps.label,
...this._dataHandlingProps.values
]),
// Data
...data.map(row => this._parseRow(row))
];
}

_parseRow(row) {
return getValues(row, [
this._dataHandlingProps.label,
...this._dataHandlingProps.values
]);
}

}

module.exports = LineChart;
31 changes: 31 additions & 0 deletions lib/pie-chart.js
@@ -0,0 +1,31 @@
'use strict';

const BaseChart = require('./base-chart');
const { getTitles, getValues } = require('./helpers');

class PieChart extends BaseChart {

_parseData() {

const data = super._parseData();

return [
getTitles([
this._dataHandlingProps.label,
this._dataHandlingProps.value
]),
// Data
...data.map(row => this._parseRow(row))
];
}

_parseRow(row) {
return getValues(row, [
this._dataHandlingProps.label,
this._dataHandlingProps.value
]);
}

}

module.exports = PieChart;
49 changes: 49 additions & 0 deletions lib/pipeline.js
@@ -0,0 +1,49 @@
'use strict';

const aggregate = (rows, {
aggregate: aggregationField,
target = aggregationField,
aggregationOperation = 'count',
groupTitleTarget,
groupSelector
}) => {

const indexedAggregation = rows.reduce((aggregated, row) => {

const groupName = groupSelector(row);

if(!aggregated[groupName]) {
aggregated[groupName] = {
[groupTitleTarget]: groupName,
[target]: 0
};
}

if(aggregationOperation === 'sum')
aggregated[groupName][target] += row[aggregationField];
else // Default is 'count'
aggregated[groupName][target]++;

return aggregated;
}, {});

return Object.values(indexedAggregation);
};

const processPipelineStep = (rows, step) => {
if(step.map)
return rows.map(row => step.map(row));

if(step.aggregate)
return aggregate(rows, step);

return rows;
};

const processPipeline = (rows, pipeline) => pipeline.reduce((processedRows, step) => {
return processPipelineStep(processedRows, step);
}, rows);

module.exports = {
processPipeline
};
24 changes: 24 additions & 0 deletions lib/table-chart.js
@@ -0,0 +1,24 @@
'use strict';

const BaseChart = require('./base-chart');
const { getTitles, getValues } = require('./helpers');

class TableChart extends BaseChart {

_parseData() {
const data = super._parseData();

const titles = getTitles(this._dataHandlingProps.values);

return [
titles.map(label => ({ label })),
...data.map(row => this._parseRow(row))
];
}

_parseRow(row) {
return getValues(row, this._dataHandlingProps.values);
}
}

module.exports = TableChart;

0 comments on commit fd77d3e

Please sign in to comment.