Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Row Functions, String Functions, Percent Functions #280

Open
wants to merge 18 commits into
base: osd
Choose a base branch
from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ npm-debug.log*
package-lock.json
yarn.lock
.project
.idea
*.zip
109 changes: 85 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ This project is a Kibana plugin that provides two visualizations:
- Ability to compute column total using formula
- Support for numeric pretty format using [Numeral.js](http://numeraljs.com/#format) (ex: `0,0.00`)
- Support for date pretty format using [Moment.js](http://momentjs.com/docs/#/displaying/format/) (ex: `YYYY-MM-DD`)
- Support for duration pretty format using Kibana duration format (with same options than Kibana Duration format)
- Support for column alignment (ex: `left`, `right`)
- Support for template rendering using [Handlebars](https://handlebarsjs.com/guide/expressions.html) (ex: `<strong>{{value}}</strong>`)
- Template can reference other columns (ex: `<span style="color: {{col0}}">{{value}}</span>`)
Expand Down Expand Up @@ -57,8 +58,8 @@ This project is a Kibana plugin that provides two visualizations:
- Add a row number column
- Ability to add the visualization to a Canvas workpad (Kibana 7.9+)
- Ability to use dashboard drilldowns (Kibana 7.9+)
- Kibana supported versions: all versions from 5.5 to 8.4
- OpenSearch Dashboards supported versions : all versions from 1.0 to 2.2
- Kibana supported versions: all versions from 5.5 to 8.12
- OpenSearch Dashboards supported versions : all versions from 1.x to 2.x

## Demo

Expand Down Expand Up @@ -267,6 +268,32 @@ Helper | Description
[encodeURIComponent(str)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) | Encodes the provided string as a Uniform Resource Identifier (URI) component. Example: `<a href="my-dashboard?param={{{encodeURIComponent rawValue}}}">{{value}}</a>`


## Row Functions

Function | Description
:----------- | :----------
rowValue(colName: string, actionName: string, fallback, qFilters: any) | filter all rows that match `qFilters`, group all values of `colName`, then calc the to single value based `actionName`. if there are no rows , return `fallback`<br><br> `colName` can be a string or colX where X is the index of the column. <br><br> `actionNmae` can be `first`, `last`, `max`, `min`, `sum`, `avg` <br><br> `qFilters` : a json object in { "key": value } format <br> --- `key` format is the same `colName`. <br> --- if the value is true, then the row `colName` must match `colName` of the current row <br> --- if value is `base.colX` or `base[name]` the row must match the column in the current row <br> --- if value is `row.colX` or `row[name]` the row must match the other column in the row <br> --- otherwise the row must match value
colShare( colName: string, fallback:unknown = 0, qFilters = {} ) | find the percent of the value of `colName` in current row from the sum of all values of `colName` in all the rows that match the `qFllter`. If no rows matched return `fallback`
colChange( colName: string, fallback:unknown = 0, qFilters = {} ) | find the percent of the value of `colName` in current row from the value of `colName` in first row that match the `qFllter`. If no rows matched return `fallback`

## String Functions
Function | Description
:----------- | :----------
findRe( ss: string , pattern : string, group: number or string, fallback: string ) | search the regular expression `pattern` in `ss`. If found return `group` in the match, otherwise return `fallback`. `group` can be number ( for unnamed groups) or string ( for named groups)
function findReGroups( ss: string , reStr : string ) : string[] | search the regular expression `pattern` in `ss`. return array of unnamed groups
function findReNamed( ss: string , reStr : string ) : { [key: string]: string; } | search the regular expression `pattern` in `ss`. return object of named groups
strJoin(s1:string, s2: string) | return joining of `s1` and `s2`
strColor(ss: string, hue? : number, saturation?: number, lightness?:number, hRange?: number, sRange?: number, lRange?: number) : string | return a css color based on a `ss`
strHash(ss: string, algorithm : string = 'sha1') : string | return an hash of `ss` using the `algorithm`


## Percent Functions
Function | Description
:----------- | :----------
percentFrom (num: number, from: number) : number | return how much percent is `num` from `from`
percentOf(num: number, percent: number) : number | return `percent%` of `num`
percentChange(valNew: number, valOld: number) : number | return the percent change `valNew` from `valOld`

## Change Log

Versions and Release Notes are listed in [Releases](https://github.com/fbaligand/kibana-enhanced-table/releases) page
Expand All @@ -280,36 +307,70 @@ Thanks for their great work !

## Development

To run enhanced-table plugin in development mode (that enables hot code reload), follow these instructions:
- execute these commands :
``` bash
git clone https://github.com/opensearch-project/OpenSearch-Dashboards
You can run the enhanced-table plugin in development mode that supports hot code reload.

Follow those steps:

### Clone OpenSearch-Dashboards & kibina-enhanced-table
```bash
git clone https://github.com/opensearch-project/OpenSearch-Dashboards -b 1.0.0
cd OpenSearch-Dashboards
git checkout X.Y.Z # replace 'X.Y.Z' by desired OpenSearch-Dashboards version
cd plugins
git clone https://github.com/fbaligand/kibana-enhanced-table.git enhancedTable
git checkout osd
git clone https://github.com/fbaligand/kibana-enhanced-table.git -b osd plugins/enhancedTable
```
- install the version of Node.js noted in `OpenSearch-Dashboards/.node-version` file
- ensure that node binary directory is in PATH environment variable
- install the latest version of yarn: `npm install -g yarn`
- execute these commands:
``` bash
cd OpenSearch-Dashboards
yarn osd bootstrap
### Update OpenSearch-Dashboards config

Update `OpenSearch-Dashboards/config/opensearch_dashboards.yml` with opensearch hosts and user credentials.

```yaml
opensearch.hosts: [""]
opensearch.username: ""
opensearch.password: ""
```

- - -

If you do not have opensearch server running yet,
you can use the `opensearchproject/opensearch` docker image

```bash
docker run -p 9200:9200 -p 9600:9600 -e "discovery.type=single-node" opensearchproject/opensearch:latest
```
and update config with the following settings:

```yaml
opensearch.hosts: ["https://localhost:9200"]
opensearch.username: "admin" # Default username on the docker image
opensearch.password: "admin" # Default password on the docker image
opensearch.ssl.verificationMode: none
```
### Install Node.js and yarn
install the version of Node.js listed in the .node-version file.
```bash
volta install node@$(<.node-version)
npm install -g yarn
```

### Build with Hot Reload
```bash
cd plugins/enhancedTable
yarn osd bootstrap
yarn install
yarn start
```
- in your browser, call `http://localhost:5601` and enjoy!


To build a distributable archive, execute this command:
``` bash
yarn compile-and-build --opensearch-dashboards-version X.Y.Z # replace 'X.Y.Z' by target OSD version
Now, you can open your browser,

- In your browser, open the generated URL displayed in the console. It is something like: `http://localhost:5601/abc`
- Now, each time you change the code, the plugin will be reloaded with the changes.
- Happy coding :-)

### Build a distributable archive
```bash
yarn build
```
The zip archive is generated into `build` directory.

The result artifact located at `build/enhancedTable-X.Y.Z_osd-A.B.C.zip` where:
- X.Y.Z is the `${npm_package_version}`
- A.B.C is the OpenSearch-Dashboards version

## Donation

Expand Down
11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "enhanced-table",
"version": "1.13.3",
"version": "1.14.0",
"description": "This visualization plugin is like a Data Table, but with enhanced features like computed columns, filter bar and pivot table",
"license": "Apache-2.0",
"homepage": "https://github.com/fbaligand/kibana-enhanced-table",
Expand All @@ -14,9 +14,10 @@
"lint": "../../node_modules/.bin/eslint .",
"start": "cd ../.. && node scripts/opensearch_dashboards --dev",
"debug": "node --nolazy --inspect ../../scripts/opensearch_dashboards --dev",
"build": "../../node_modules/.bin/plugin-helpers build",
"compile-and-build": "node ../../scripts/plugin_helpers.js build",
"compile": "rm -rf ./target && node ../../scripts/build_opensearch_dashboards_platform_plugins.js --scan-dir ."
"build": "yarn plugin-helpers build",
"compile": "rm -rf ./target && node ../../scripts/build_opensearch_dashboards_platform_plugins.js --scan-dir .",
"plugin-helpers": "node ../../scripts/plugin_helpers",
"postbuild": "old=(build/*.zip) && new=\"$(echo $old | cut -f 1 -d '-')-${npm_package_version}_osd-$(echo $old | cut -f 2 -d '-')\" && echo renaming build artifact to $new && mv $old $new"
},
"dependencies": {
"angular": "^1.8.0",
Expand All @@ -26,4 +27,4 @@
},
"devDependencies": {
}
}
}
19 changes: 16 additions & 3 deletions public/enhanced-table-vis-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import { formulaFunctions } from './utils/formula_functions';
import { Parser } from 'expr-eval';
import handlebars from 'handlebars/dist/handlebars';

import * as parser_rows from "./parser/rows";
import * as parser_percents from "./parser/percents";
import * as parser_strings from "./parser/strings";

// EnhancedTableVis AngularJS controller
function EnhancedTableVisController ($scope, config) {

Expand Down Expand Up @@ -174,8 +178,10 @@ function EnhancedTableVisController ($scope, config) {
realFormula = realFormula.replace(/(col|formattedCol)\s*\(/g, '$1(row, ');
realFormula = realFormula.replace(/(sumSplitCols)\s*\(/g, '$1(row');

// add 'table' & 'row' param for functions that require whole table
realFormula = realFormula.replace(/(total|cell|formattedCell)\s*\(/g, '$1(table, row, ');
const functionsWithTableRow = ['total', 'cell', 'formattedCell', 'rowValue', 'colShare', 'colChange' ];
for ( const functionName of functionsWithTableRow ) {
realFormula = realFormula.replace( new RegExp(`(${functionName})\\s*\\(`, 'g'), '$1(table, row, ');
}

// replace 'total' variable by 'totalHits'
realFormula = realFormula.replace(/([^\w]|^)total([^(\w]|$)/g, '$1totalHits$2');
Expand Down Expand Up @@ -326,6 +332,13 @@ function EnhancedTableVisController ($scope, config) {
return count;
};

// add from parser directory
(parser_rows ).addParser(parser,EnhancedTableError);
(parser_percents).addParser(parser);
(parser_strings ).addParser(parser);



// parse formula and return final formula object
try {
return {
Expand Down Expand Up @@ -1230,4 +1243,4 @@ function EnhancedTableVisController ($scope, config) {

}

export { EnhancedTableVisController };
export { EnhancedTableVisController };
17 changes: 17 additions & 0 deletions public/parser/percents.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export let parser: any;

function percentFrom (num: number,from: number) : number{
return from > 0 ? num * 100 / from : 0;
}
function percentOf(num: number,percent: number) : number {
return num*percent / 100;
}
function percentChange(valNew: number,valOld: number) : number{
return percentFrom(valNew - valOld, valOld)
}

export function addParser(parser) {
parser.functions.percentFrom = percentFrom;
parser.functions.percentOf = percentOf;
parser.functions.percentChange = percentChange;
}
Loading