Skip to content

Commit

Permalink
fix: Updated number formatting library. Added fix for locale format i…
Browse files Browse the repository at this point in the history
…ssue. (#17)

Updated number formatting library. Added fix for locale format issue. (#17)

Also:
- [ ] Updated dependencies
- [ ] Fix build and yarn.lock update
- [ ] ignore yarn lock when formatting
  • Loading branch information
andres-rubio-go authored Nov 10, 2023
1 parent 708bbcf commit 2cf6e53
Show file tree
Hide file tree
Showing 12 changed files with 13,177 additions and 629 deletions.
3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/multiple_value.js
node_modules/
node_modules
/yarn.lock
24 changes: 12 additions & 12 deletions multiple_value.js

Large diffs are not rendered by default.

12,308 changes: 12,308 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"jsdom": "^11.11.0",
"lodash": "^4.17.19",
"moment": "^2.24.0",
"numfmt": "^2.5.2",
"prop-types": "^15.8.1",
"react": "^16.9.0",
"react-dom": "^16.9.0",
Expand Down Expand Up @@ -53,7 +54,8 @@
"eslint-plugin-prettier": "^3.1.0",
"eslint-plugin-react": "^7.14.3",
"husky": "^8.0.3",
"jest": "^29.6.4",
"jest": "^29.7.0",
"prettier": "3.0.3",
"style-loader": "^2.0.0",
"typescript": "^4.0.2",
"uglifyjs-webpack-plugin": "^1.2.5",
Expand Down
9 changes: 9 additions & 0 deletions src/constants/locale_formats_tags.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const LOCALE_NUMBER_FORMATS = {
DEFAULT_EN: '1,234.56',
DEFAULT_EU: '1.234,56',
};

export const LOCALE_TAGS = {
EN: 'eu',
DE: 'de',
};
24 changes: 24 additions & 0 deletions src/constants/plot_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export const PLOT_CONFIG = {
font_size_main: {
label: 'Font Size',
type: 'string',
section: 'Style',
default: '',
order: 0,
display_size: 'half',
},
orientation: {
label: 'Orientation',
type: 'string',
section: 'Style',
display: 'select',
values: [
{Auto: 'auto'},
{Vertical: 'vertical'},
{Horizontal: 'horizontal'},
],
default: 'auto',
order: 0,
display_size: 'half',
},
};
196 changes: 196 additions & 0 deletions src/functions/common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
import React from 'react';
import * as d3 from 'd3';
import _ from 'lodash';

export const formatType = valueFormat => {
if (typeof valueFormat != 'string') {
return function (x) {
return x;
};
}
let format = '';
switch (valueFormat.charAt(0)) {
case '$':
format += '$';
break;
case '£':
format += '£';
break;
case '€':
format += '€';
break;
}
if (valueFormat.indexOf(',') > -1) {
format += ',';
}
const splitValueFormat = valueFormat.split('.');
format += '.';
format += splitValueFormat.length > 1 ? splitValueFormat[1].length : 0;

switch (valueFormat.slice(-1)) {
case '%':
format += '%';
break;
case '0':
format += 'f';
break;
}
return d3.format(format);
};

export const handleErrors = (vis, resp, options) => {
function messageFromLimits(min, max, field) {
let message = 'You need ' + min;
if (max) {
message += ' to ' + max;
}
message += ' ' + field;
return message;
}

if (
resp.fields.pivots.length < options.min_pivots ||
resp.fields.pivots.length > options.max_pivots
) {
let message;
vis.addError({
group: 'pivot-req',
title: 'Incompatible Pivot Data',
message: messageFromLimits(
options.min_pivots,
options.max_pivots,
'pivots'
),
});
return false;
} else {
vis.clearErrors('pivot-req');
}

if (
resp.fields.dimensions.length < options.min_dimensions ||
resp.fields.dimensions.length > options.max_dimensions
) {
vis.addError({
group: 'dim-req',
title: 'Incompatible Dimension Data',
message: messageFromLimits(
options.min_dimensions,
options.max_dimensions,
'dimensions'
),
});
return false;
} else {
vis.clearErrors('dim-req');
}

if (
resp.fields.measure_like.length < options.min_measures ||
resp.fields.measure_like.length > options.max_measures
) {
vis.addError({
group: 'mes-req',
title: 'Incompatible Measure Data',
message: messageFromLimits(
options.min_measures,
options.max_measures,
'measures'
),
});
return false;
} else {
vis.clearErrors('mes-req');
}
return true;
};

const drillingCallback = event => {
// eslint-disable-line
const ds = event.currentTarget.dataset;
const keys = Object.keys(ds);
let links = [];
_.forEach(keys, key => {
const [k, i] = key.split('-');
if (!links[i]) {
links[i] = {};
}
links[i][k] = ds[key];
});
LookerCharts.Utils.openDrillMenu({links, event});
};

// Attempt to display in this order: HTML/drill -> rendered -> value
export const displayData = (cell, formattedValue) => {
if (_.isEmpty(cell)) {
return null;
}
let formattedCell;
if (cell.links) {
let dataset = {};
// Adding data to DOM that we will need when drilling into link which we would not
// otherwise have when ag-grid hits our callback fn.
_.forEach(cell.links, (link, i) => {
dataset[`data-label-${i}`] = link.label;
dataset[`data-url-${i}`] = link.url;
dataset[`data-type-${i}`] = link.type;
});
// const val = !_.isUndefined(cell.rendered) ? cell.rendered : cell.value;
formattedCell = (
<a
className="drillable-link"
href="#"
onClick={drillingCallback}
{...dataset}
>
{formattedValue}
</a>
);
} else if (cell.html) {
formattedCell = LookerCharts.Utils.htmlForCell(cell).replace(
'<a ',
'<a className="drillable-link" '
);
} else {
// formattedCell = LookerCharts.Utils.textForCell(cell);
formattedCell = formattedValue;
}

return formattedCell;
};

// Manipulate HEX colors
const addLight = function (color, amount) {
let cc = parseInt(color, 16) + amount;
let c = cc > 255 ? 255 : cc;
c = c.toString(16).length > 1 ? c.toString(16) : `0${c.toString(16)}`;
return c;
};

export const lighten = (color, amount) => {
color = color.indexOf('#') >= 0 ? color.substring(1, color.length) : color;
amount = parseInt((255 * amount) / 100);
return (color = `#${addLight(color.substring(0, 2), amount)}${addLight(
color.substring(2, 4),
amount
)}${addLight(color.substring(4, 6), amount)}`);
};

const subtractLight = function (color, amount) {
let cc = parseInt(color, 16) - amount;
let c = cc < 0 ? 0 : cc;
c = c.toString(16).length > 1 ? c.toString(16) : `0${c.toString(16)}`;
return c;
};

export const darken = (color, amount) => {
color = color.indexOf('#') >= 0 ? color.substring(1, color.length) : color;
amount = parseInt((255 * amount) / 100);
return (color = `#${subtractLight(
color.substring(0, 2),
amount
)}${subtractLight(color.substring(2, 4), amount)}${subtractLight(
color.substring(4, 6),
amount
)}`);
};
24 changes: 24 additions & 0 deletions src/functions/number_date_format.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import numfmt from 'numfmt';
import {
LOCALE_NUMBER_FORMATS,
LOCALE_TAGS,
} from '../constants/locale_formats_tags';

export function formatValue(format, value, localeFormat) {
const formatter = numfmt(format);

return formatter(value, {
locale: getLocaleTagFromNumberFormat(localeFormat),
});
}

function getLocaleTagFromNumberFormat(format) {
switch (format) {
case LOCALE_NUMBER_FORMATS.DEFAULT_EN:
return LOCALE_TAGS.EN;
case LOCALE_NUMBER_FORMATS.DEFAULT_EU:
return LOCALE_TAGS.DE;
default:
return LOCALE_TAGS.EN;
}
}
2 changes: 1 addition & 1 deletion src/multiple_value/ComparisonDataPoint.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { PureComponent, useState } from "react";
import styled from 'styled-components'
// @ts-ignore
import {formatType, lighten} from '../common'
import {formatType, lighten} from '../functions/common'
import SSF from "ssf";

let ComparisonDataPointGroup = styled.div`
Expand Down
35 changes: 6 additions & 29 deletions src/multiple_value/multiple_value_container.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,8 @@ import React from 'react';
import ReactDOM from 'react-dom';
import isEqual from 'lodash/isEqual';
import MultipleValue from './multiple_value';
import SSF from 'ssf';

const baseOptions = {
font_size_main: {
label: 'Font Size',
type: 'string',
section: 'Style',
default: '',
order: 0,
display_size: 'half',
},
orientation: {
label: 'Orientation',
type: 'string',
section: 'Style',
display: 'select',
values: [
{Auto: 'auto'},
{Vertical: 'vertical'},
{Horizontal: 'horizontal'},
],
default: 'auto',
order: 0,
display_size: 'half',
},
};
import {formatValue} from '../functions/number_date_format';
import {PLOT_CONFIG} from '../constants/plot_config';

let currentOptions = {};
let currentConfig = {};
Expand All @@ -39,7 +15,7 @@ const renderBlankVisualization = (element, done) => {
looker.plugins.visualizations.add({
id: 'multiple_value',
label: 'Multiple Value',
options: baseOptions,
options: PLOT_CONFIG,
create: function (element, config) {
this.chart = renderBlankVisualization(element, () => {});
},
Expand Down Expand Up @@ -96,9 +72,10 @@ looker.plugins.visualizations.add({
config[`value_format_${measure.name}`] === '' ||
config[`value_format_${measure.name}`] === undefined
? LookerCharts.Utils.textForCell(firstRow[measure.name])
: SSF.format(
: formatValue(
config[`value_format_${measure.name}`],
firstRow[measure.name].value
firstRow[measure.name].value,
queryResponse.number_format
),
html: firstRow[measure.name].html,
};
Expand Down
10 changes: 10 additions & 0 deletions src/tests/multiple_value_container.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {LOCALE_NUMBER_FORMATS} from '../constants/locale_formats_tags';
import {formatValue} from '../functions/number_date_format';

describe('formatValue', () => {
test('should format value with appropiate format and locale settings', () => {
expect(
formatValue('0.0,k', 22789, LOCALE_NUMBER_FORMATS.DEFAULT_EU)
).toEqual('22,8k');
});
});
Loading

0 comments on commit 2cf6e53

Please sign in to comment.