Let's say I have 10 companies that have signed up to my service, and then dropped off. I want to figure out how many of these companies are hitting milestones of usage in my system, so I want a bar chart that shows the data. For instance, I have 2 boolean fields on the companies, "Added Card Details" and "Logged in 3 times".
How do I create a bar chart which shows 2 bars, the % of companies which have that value set to "true", as the example below?
I'm pulling the data from BigQuery, but here's an example table of data to create the graph from:
Name
Added Card Details
Logged in 3 times
Com1
true
true
Com2
true
true
Com3
false
true
Com4
false
true
Com5
false
false
Com6
false
false
Com7
false
false
Com8
false
false
Com9
false
false
Com10
false
false
Should produce a graph which looks like:
Here's a sheet with example data and an example graph:
https://docs.google.com/spreadsheets/d/12jt1ZlhJ-5Hc8XtQsyXVVnLC1F6GOZz9euZkN2y1jNw/edit?usp=sharing
Here's my attempt at creating the graph. Not sure where to go from here when Dimension has to be declared and only allows one option.
https://datastudio.google.com/reporting/f9a2db1c-2c32-41b6-8e47-1848e2577417
One approach is to use a CONCAT field as the dimension and 2 calculated fields in each of the metrics:
Description
Details
Chart:
Column Chart
Dimension 1:Formula:
Actions"Actions"
Metric 1:Formula:Type:
Added Card DetailsCOUNT(IF(Added Card Details = "TRUE", Added Card Details, NULL)) / COUNT(Name)Number > Percent
Metric 2:Formula:Type:
Logged in 3 timesCOUNT(IF(Logged in 3 times = "TRUE", Logged in 3 times, NULL)) / COUNT(Name)Number > Percent
Publicly editable Google Data Studio report (embedded Google Sheets data source) and an image elaborate:
Related
I need help creating a sparkline chart for an example data as below:
name
timestamps
test
action
try 1
2022-11-16 22:39:35.653819+00:00
TRUE
TRUE
try 2
2022-11-16 22:39:33.171203+00:00
TRUE
TRUE
try 1
2022-11-16 22:39:30.699472+00:00
FALSE
TRUE
try 4
2022-11-16 22:39:27.711734+00:00
TRUE
FALSE
Let's say I am only trying to create a sparkline chart for try 1 against the timestamps.
What I want the chart to show is:
If test and action is TRUE and TRUE then for that timestamp Try 1 value is 2
If test and action is TRUE and FALSE then for that timestamp Try 1 value is 1
If test and action is FALSE and FALSE then for that timestamp Try 1 value is 0
I don't want to 'code' this into the google sheet as the data uploaded will be refreshed automatically and all my code will be gone when the data is refreshed.
Is there anyway I can code this into the sparkline chart itself on google data studio?
I tried creating a field in the metric section of the sparkline chart but it gives a system error.
hopefully this should get you started.
fix the timestamp to be studio-compatible
PARSE_DATETIME("%F %H:%M:%E*S",LEFT_TEXT(timestamps,26))
get the value score from test and action
CASE WHEN action='TRUE' THEN 1 ELSE 0 END+CASE WHEN test='TRUE' THEN 1 ELSE 0 END
you can use both these calculated fields as dimension and metric for spark chart.
lastly you can apply a filter to chart to see just the 'try 1' score.
I have an ag-grid table (Enterprise version: 22.1.0) which is grouped using autoGroupColumnDef property. The grouping is dependent on the table's data and the data loads on a button click. I need to update the autoGroupColumnDef property's field name (_this.colName in the below code) after the page is loaded, right before loading the data.
Table's grid options:
_this.gridOptions = {
defaultColDef: {
sortable: true,
resizable: true,
filter: true
},
columnDefs: _this.columnDefs,
rowData: [],
enableRangeSelection: true,
autoGroupColumnDef: {
headerName: "Sector",
field: _this.colName,
cellRendererParams: {
suppressCount: true
},
tooltipValueGetter: function(params) {
return _this.tooltipVal
}
},
suppressAggFuncInHeader: true,
enableBrowserTooltips: true
};
I update the variable _this.colName before setting data to the grid. I have tried the following options and none of them worked for me:
_this.gridOptions.api.refreshClientSideRowModel('group');
_this.gridOptions.api.refreshCells();
_this.gridOptions.autoGroupColumnDef.field = 'Column's Name'
Any help would be appreciated!
There is a good workaround for this. You can set autoGroupColumnDef, then remove and readd all row groupings. It will redraw the group column with the new name.
gridOptions.autoGroupColumnDef.headerName = 'new_name';
// Get current groupings
var colstate = gridOptions.columnApi.getColumnState();
var colstateclear = gridOptions.columnApi.getColumnState();
// Clear groupings
var x = 0, xcount = colstateclear.length;
while ( x < xcount ) {
colstateclear[x].rowGroupIndex = null;
x += 1;
}
gridOptions.columnApi.setColumnState(colstateclear);
// Reset groupings
gridOptions.columnApi.setColumnState(colstate);
I contacted ag-grid support and apparently this is a bug and they have it in their backlog with no ETA available for now. A workaround they provided was to use: https://www.ag-grid.com/javascript-grid-grouping/#showRowGroup.
This is not really a good workaround because the grouped columns are separated and makes the page feel cramped. Also there are some look and feel issues that keep popping up (Eg: empty space added before each column that increases with each grouped column. ie second column has 1 cm added before it, third column has 2 cm added before it and so on. I guess this was added to bring the grouped look in the group column but you wouldn't expect this behavior when the columns are separated.)
ag-grid's backlog ID for the ticket: AG-3359 - Allow the autoGroupColumn to be used in the API calls for columns, at the moment there is no way to dynamically change it after creation. (ie, setColumnDefs …)
Link to track the progress: https://www.ag-grid.com/ag-grid-pipeline/
there is a straight forward method to update the autoGroupColumnDef object and its properties with setAutoGroupColumnDef
this.gridOptions.api.setAutoGroupColumnDef(<ColDef>{
...this.gridOptions.autoGroupColumnDef, // preserve the other settings except the ones you need to change
minWidth: 500
})
if any problems with the spread operator,
do it manually:
this.gridOptions.api.setAutoGroupColumnDef(<ColDef>{
// ...this.gridOptions.autoGroupColumnDef, // preserve the other settings except the ones you need to change
headerName: this.gridOptions.autoGroupColumnDef.headerName,
minWidth: 500
})
and one more thing, add this if you have any visual bugs, like: header row gets resized but bellow rows stays the same as previus state, so the refresh of model is required:
this.gridOptions.api.refreshClientSideRowModel();
this refresh is not ideal solution, because it refreshes everything, so you will loose expanded levels for example, still no clue how to preserve all settings.
https://angulargrid.com/angular-grid/client-side-model/#refreshing-the-client-side-model
and best solution for now is tu use:
this.gridOptions.api.redrawRows();
it keeps the rows expanded if are, checkbox selected if is.
How to set infinite scroll/Pagination in the details grid. I'm using server side model for master and want to use infinite model for details. How to setup details grid detailCellRendererParams with infinite scroll row Data
Define in detailGridOptions infinite row model type & its properties:
detailGridOptions: {
...
rowModelType: 'infinite',
// enable pagination
pagination: true,
// fetch 15 rows per at a time
cacheBlockSize: 15,
// display 10 lines per page
paginationPageSize: 10,
// how many rows to seek ahead when unknown data size.
cacheOverflowSize: 2,
// how many concurrent data requests are allowed.
// default is 2, so server is only ever hit with 2 concurrent requests.
maxConcurrentDatasourceRequests: 2,
// how many rows to initially allow scrolling to in the grid.
infiniteInitialRowCount: 1,
// how many pages to hold in the cache.
maxBlocksInCache: 2
}
The infiniteDatasource presents the way you can retrieve the data for detail part:
getDetailRowData: (params) => {
//Get grid api regarding current row
var detailGrid = gridOptions.api.getDetailGridInfo(params.node.id);
//Simulation of server
var server = new FakeServer(params.data.callRecords);
//Preparation of data
var datasource = new infiniteDatasource(server, params);
detailGrid.api.setDatasource(datasource);
}
Please note that regarding the documantation:
If you are an enterprise user you should consider using the Server-side row model instead of the infinite row model. It offers the same functionality with many more features.
Setting of Server-side row model should be similar to Infinite one.
Working example
When we give service data as null to extjs with pagination,then it is disabling the pagination tool bar.
We have some requirement like we have a filter button on enabling we will show filtered data at first and remaining pages as empty. Total count will be the same.
Example:
If we have 1000 records as total and the page size is 50, then we have total pages size will be 20. If we enable filter then we will get 500 records which are filtered, then, in that case, we will show total records as 1000 (Actual size without filter) and from 11 page onwards we will show empty pages by returning empty records.
Issue:
When we return empty records to Extjs,it is disabling the pagination, we want 'next page' to be disabled but we need ' the previous page' button to be enabled
Is it possible in Extjs?
Do you have any idea why it is disabling the pagination tool bar?
So, this is a FIDDLE
SERVER: I'm using some free service to load data, where i have 10 records(5 per page) but i send total: 15 from server to force toolbar displaying 3 pages. On the server, in query if page === 3 i send empty array. Here's the CODE
CLIENT: In pagination toolbar i define change event listener, where i make sure buttons will be always enabled. Also make input, for page number, enabled + correct, with total page counter.
listeners: {
change: function (cmp, config) {
var store = cmp.up('grid').getStore();
var numb = cmp.getComponent('inputItem');
numb.setDisabled(false);
numb.setValue(store.currentPage);
var text = cmp.getComponent('afterTextItem');
text.setHtml('of ' + (store.totalCount / store.pageSize));
cmp.setChildDisabled('#first', false);
cmp.setChildDisabled('#prev', false);
cmp.setChildDisabled('#next', false);
cmp.setChildDisabled('#last', false);
cmp.setChildDisabled('#refresh', false);
}
}
In Redmine's calendar, I would like to show all Tasks/Issues on which a currently logged in person in the account is a Member, Task Creator, Assignee, Reporter, or Watcher.
Now, from the following two arrays of helper.rb, I have created another array which merges issues_only and tasks_only. Then I wish to call that array in view part.
def issues_only
issues_all = issuesreportedbyme_items
issues_all.push *issueswatched_items
issues_all.push *issuesassignedtome_items
all = issues_all.reject{|v| v.tracker_id == 4}
rest = all.reject {|k| k.status_id == 5 }
rest.inject([]) { |result,h| result << h unless result.include?(h); result }
end
def tasks_only
tasks_all = issuesreportedbyme_items
tasks_all.push *issueswatched_items
tasks_all.push *issuesassignedtome_items
all = tasks_all.reject{|v|v.tracker_id == 5}
rest = all.reject {|k| k.status_id == 5 }
rest.inject([]) { |result,h| result << h unless result.include?(h); result }
end
Now, my question is what to include in view part in order to show the required calendar.
As you can see on this image the Calendar tab has filter options same as all other lists in Redmine. First you click on the filter switch icon (the little triangle on the image) and then you can add your filters to a report, list, gantt chart etc by selecting the filters from the filter selection combo box.
Your main problem will be that this filters don't have any logical operator feature. All the filters you select will be connected with the 'AND' operator so you can't define a list, gantt or report which corresponds to your 'OR' operator.
To get all the activities of all members of a specific project you only have to select the project and then unselect the "is : open" filter on the project calendar and click on "Apply Settings".
PS : This image is taken from our customized Redmine installation which has the Easyredmine plugin but the basics of filters are the same with Redmine.
Edit:
A way achieving your 'OR' requirement would be just selecting the filters which don't belong to your requirements and applying those filters. This way you would exclude those specific criteria that you want to apply the 'OR' statement to.
Don't forget to select the appropriate status filter in your filters. (Status is open/close/any/is not/is)