iccube : How to remove certainn level(s) from hierarchy in a filter widget? - iccube

Using iccube reporting V6,
I'm looking for a way to remove some levels from a hierarchy (visually) on a filter widget.
This is working on "standards" widgets
but when using a Filter widget, i can only set 1 level as member.

Ok, I found a solution. The issue with the Tree filter is that it's using the parentUnique name to build the tree. But this is something we can trick.
For a time hierachy with multiple levels let's build a Tree with the Year and Month (without quarters). For this we can use this MDX
WITH
FUNCTION __currMember() AS [Date].[Date].hierarchy.currentmember
FUNCTION __defMember() AS {[Date].[Date].allmembers}(0).hierarchy.currentmember
FUNCTION __descendant(_c) AS Tail( Filter( Axis(1) as t, isAncestor(t.currentmember, _c )),1 )(0)
FUNCTION __unName(_c) AS IIF( _c is NULL, NULL, _c.uniqueName)
MEMBER ic3Name AS __currMember().name
MEMBER ic3UName AS __currMember().uniquename
MEMBER ic3PName AS __unName( __descendant(__currMember() ))
MEMBER ic3Measure AS 0
MEMBER ic3IsSelected AS false
MEMBER ic3FilterName as [Measures].[ic3Name]
MEMBER ic3Key as __currMember().key
SELECT
{[Measures].[ic3Name],[Measures].[ic3UName],[Measures].[ic3PName],[Measures].[ic3Measure],[Measures].[ic3IsSelected],[Measures].[ic3FilterName],[Measures].[ic3Key]} ON 0,
__defMember() + Hierarchize([Date].[Date].[Year] + [Date].[Date].[Month]) ON 1
FROM [Cube]
It's the descendant() function that is doing the trick. You can change the function if it's not suiting your needs or it's too slow for something checking the levels. Note, the algo is O(N*N) on the axis, it's not great. But I think it should be generic.
With a bit of imagination and MDX you can do a bit whatever you'd like as for building the tree we're using the measures ( ON 0 axis ).

Related

Update dictionary key inside list using map function -Python

I have a dictionary of phone numbers where number is Key and country is value. I want to update the key and add country code based on value country. I tried to use the map function for this:
print('**Exmaple: Update phone book to add Country code using map function** ')
user=[{'952-201-3787':'US'},{'952-201-5984':'US'},{'9871299':'BD'},{'01632 960513':'UK'}]
#A function that takes a dictionary as arg, not list. List is the outer part
def add_Country_Code(aDict):
for k,v in aDict.items():
if(v == 'US'):
aDict[( '1+'+k)]=aDict.pop(k)
if(v == 'UK'):
aDict[( '044+'+k)]=aDict.pop(k)
if (v == 'BD'):
aDict[('001+'+k)] =aDict.pop(k)
return aDict
new_user=list(map(add_Country_Code,user))
print(new_user)
This works partially when I run, output below :
[{'1+952-201-3787': 'US'}, {'1+1+1+952-201-5984': 'US'}, {'001+9871299': 'BD'}, {'044+01632 960513': 'UK'}]
Notice the 2nd US number has 2 additional 1s'. What is causing that?How to fix? Thanks a lot.
Issue
You are mutating a dict while iterating it. Don't do this. The Pythonic convention would be:
Make a new_dict = {}
While iterating the input a_dict, assign new items to new_dict.
Return the new_dict
IOW, create new things, rather than change old things - likely the source of your woes.
Some notes
Use lowercase with underscores when defining variable names (see PEP 8).
Lookup values rather than change the input dict, e.g. a_dict[k] vs. a_dict.pop(k)
Indent the correct number of spaces (see PEP 8)

Filter vertices on several properties - Julia

I am working on julia with the Metagraphs.jl library.
In order to conduct an optimization problem, I would like to get the set/list of edges in the graph that point to a special set of vertices having 2 particular properties in common.
My first guess was to first get the set/list of vertices. But I am facing a first issue which is that the filter_vertices function doesn't seem to accept to apply a filter on more than one property.
Here is below an example of what I would like to do:
g = DiGraph(5)
mg = MetaDiGraph(g, 1.0)
add_vertex!(mg)
add_edge!(mg,1,2)
add_edge!(mg,1,3)
add_edge!(mg,1,4)
add_edge!(mg,2,5)
add_edge!(mg,3,5)
add_edge!(mg,5,6)
add_edge!(mg,4,6)
set_props!(mg,3,Dict(:prop1=>1,:prop2=>2))
set_props!(mg,1,Dict(:prop1=>1,:prop2=>0))
set_props!(mg,2,Dict(:prop1=>1,:prop2=>0))
set_props!(mg,4,Dict(:prop1=>0,:prop2=>2))
set_props!(mg,5,Dict(:prop1=>0,:prop2=>2))
set_props!(mg,6,Dict(:prop1=>0,:prop2=>0))
col=collect(filter_vertices(mg,:prop1,1,:prop2,2))
And I want col to find vertex 3 and no others.
But the filter_vertices would only admit one property at a time and then it makes it more costly to do a loop with 2 filters and then try to compare in order to sort a list with the vertices that have both properties.
Considering the size of my graph I would like to avoid defining this set with multiple and costly loops. Would any one of you have an idea of how to solve this issue in an easy and soft way?
I ended up making this to answer my own question:
fil3=Array{Int64,1}()
fil1=filter_vertices(mg,:prop1,1)
for f in fil1
if get_prop(mg,f,:prop2)==2
push!(fil3,f)
end
end
println(fil3)
But tell me if you get anything more interesting
Thanks for your help!
Please provide a minimal working example in a way we can simply copy and paste, and start right away. Please also indicate where the problem occurs in the code. Below is an example for your scenario:
Pkg.add("MetaGraphs")
using LightGraphs, MetaGraphs
g = DiGraph(5)
mg = MetaDiGraph(g, 1.0)
add_vertex!(mg)
add_edge!(mg,1,2)
add_edge!(mg,1,3)
add_edge!(mg,1,4)
add_edge!(mg,2,5)
add_edge!(mg,3,5)
add_edge!(mg,5,6)
add_edge!(mg,4,6)
set_props!(mg,3,Dict(:prop1=>1,:prop2=>2))
set_props!(mg,1,Dict(:prop1=>1,:prop2=>0))
set_props!(mg,2,Dict(:prop1=>1,:prop2=>0))
set_props!(mg,4,Dict(:prop1=>0,:prop2=>2))
set_props!(mg,5,Dict(:prop1=>0,:prop2=>2))
set_props!(mg,6,Dict(:prop1=>0,:prop2=>0))
function my_vertex_filter(g::AbstractMetaGraph, v::Integer, prop1, prop2)
return has_prop(g, v, :prop1) && get_prop(g, v, :prop1) == prop1 &&
has_prop(g, v, :prop2) && get_prop(g, v, :prop2) == prop2
end
prop1 = 1
prop2 = 2
col = collect(filter_vertices(mg, (g,v)->my_vertex_filter(g,v,prop1,prop2)))
# returns Int[3]
Please check ?filter_vertices --- it gives you a hint on what/how to write to define your custom filter.
EDIT. For filtering the edges, you can have a look at ?filter_edges to see what you need to achieve the edge filtering. Append the below code excerpt to the solution above to get your results:
function my_edge_filter(g, e, prop1, prop2)
v = dst(e) # get the edge's destination vertex
return my_vertex_filter(g, v, prop1, prop2)
end
myedges = collect(filter_edges(mg, (g,e)->my_edge_filter(g,e,prop1,prop2)))
# returns [Edge 1 => 3]
I found this solution:
function filter_function1(g,prop1,prop2)
fil1=filter_vertices(g,:prop1,prop1)
fil2=filter_vertices(g,:prop2,prop2)
filter=intersect(fil1,fil2)
return filter
end
This seems to work and is quite easy to implement.
Just I don't know if the filter_vertices function is taking a lot of computational power.
Otherwise a simple loop like this seems to also work:
function filter_function2(g,prop1,prop2)
filter=Set{Int64}()
fil1=filter_vertices(g,:prop1,prop1)
for f in fil1
if get_prop(g,f,:prop2)==prop2
push!(filter,f)
end
end
return filter
end
I am open to any other answers if you have some more elegant ones.

IcCube - Treemap with Parent/Child dimension

I currently try to build a google treemap chart in IcCube. Do I do this using a Multi Level dimension and defining every Level of drilldown separately (as shown
here and here), everything works fine.
What I would like to do is using a Parent/Child dimension and telling the treemap, just to go down this hierarchy when drilling into the treemap chart.
Is that possible?
Here is the (not working) MDX I used, where [categories] is the Parent/Child dimension:
WITH
MEMBER [category_name] as [categories].[categories].currentmember.name
SELECT
{[category_name],[Measures].[count_clicks]} on 0,
non empty [categories].[categories] on 1
FROM
[Cube]
Treemap is a tricky visualization. You need to define the two first columns as defining the parent/child relation. For example :
'Global', null
'America', 'Global'
'Europe', 'Global'
'Brazil', 'America'
The first column is by construction the Axis(1) name, so the seconds has to be the name of the parent and not the name of the member. Something like :
MEMBER [parent_name] as IIF( [categories].[categories].currentmember is [categories].[categories].[ALL],
NULL,
[categories].[categories].currentmember.parent.name )
That you can use as :
WITH
MEMBER [parent_name] as IIF( [categories].[categories].currentmember is [categories].[categories].[ALL],NULL,[categories].categories].currentmember.parent.name )
SELECT
{[parent_name],[Measures].[count_clicks]} on 0,
non empty [categories].[categories] on 1
FROM
[Cube]
This should work better.
Hope it helps.
After struggling for a while with my own data, I took the IcCube example of the parent/child Dimension (http://www.iccube.com/support/documentation/user_guide/schemas_cubes/dim_parentchild.php). Then I tried your example:
WITH
MEMBER [parent_name] as IIF( [dim (ALL)].[Hierarchy].currentmember
is [dim (ALL)].[Hierarchy].[ALL],'',
[dim (ALL)]. [Hierarchy].currentmember.parent.name )
SELECT
{[parent_name],[Measures].[value]} on 0,
non empty [dim (ALL)].[Hierarchy] on 1
FROM
[Cube]
(The NULL value had to be replaced by '')
The first dimension works, but if I try to drill into the map, the system tells me, that there is no row with id 'World'. Do you have any ideas, how to fix that?
EDIT:
After using real names in the parent/child dimension instead of ids (child: Spain; parent: Europe, value: 3) and replacing [dim (ALL)].[Hierarchy] with [dim (ALL)].[Hierarchy].members() in the code, I got a treemap working so far:
WITH
MEMBER [parent_name] as IIF( [dim (ALL)].[Hierarchy].currentmember
is [dim (ALL)].[Hierarchy],'',
[dim (ALL)].[Hierarchy].currentmember.parent.name )
SELECT
{[parent_name],[Measures].[value]} on 0,
non empty [dim (ALL)].[Hierarchy].members() on 1
FROM
[Cube]
Now after drilling down to the next level, the is an error message 'failed to find row with id "Europe"'. And I added a 3 Level into my data (child: Madrid; parent: Spain, value: 5), but I am unable to go to this level. Clicking on "Spain" doesn't change anything.

Getting the level x value of the currentmember in a parent-child hierarchy in MDX

I have an employee parent-child hierarchy in a dimension called Employees which shows the managerial structure of an organisation. This hierarchy is [Employees].[Managerial].
There is another hierarchy that lists all the employees for an organisation. This is a single level hierarchy and it is [Employess].[All Employees].
I have a query that looks something like this:
With
Member measures.[FullTimeSalary] as measures.[Salary] * measures.[FullTimeFactor]
Select {measures.[FullTimeSalary]} on 0,
Non empty
{
[Employess].[All Employees].[All].Children
}
On 1
From MyCube
Where ([Time].[Month].&[201501])
Now if I expand the parent-child hierarchy (the [Employees].[Managerial] hierarchy) I can see each of the different levels of this structure( [Level 02], [Level 03], [Level 04], ect) and what I need to do now is create a new calculated measure called measures.[SupervisingManager] that brings back the currentmembers value at [Level 03] of the hierarchy.
I've tried
member measures.[SupervisingManager] as [Employees].[Managerial].[Level 03].currentmember.member_name
but that just returns "#Error" and using
member measures.[SupervisingManager] as [Employees].[Managerial].currentmember.member_name
returns that currentmember. I also experimented with
measures.[SupervisingManager] as [Employees].[Managerial].currentmember.parent.member_name
but the issue with this is that the currentmember can be located at any within the hierarchy. The only way I can think of doing this is to do a massive case statement, get the ordinal value of the current member and use the appropriate .parent.parent logic. Is there a neater way to do this?
Maybe something along these lines will help:
WITH
MEMBER measures.[FullTimeSalary] AS
measures.[Salary] * measures.[FullTimeFactor]
MEMBER measures.[SupervisingManager] AS
IIF
(
[Employees].CurrentMember.Parent.Level.Name = 'Level 03'
,[Employees].CurrentMember.Parent.Member_Caption
,'n/a'
)
SELECT
{
measures.[FullTimeSalary]
,measures.[SupervisingManager]
} ON 0
,NON EMPTY
{[Employess].[All Employees].[All].Children} ON 1
FROM MyCube
WHERE
[Time].[Month].&[201501];

Alternative to Recursive Function

I have been working on MLM (multi level marketing) application.
Below is the code snippet (not entire code) of recursive function which I had written in initial phase and was working properly. But now the MLM tree is too deep and recursive function stops. It says maximum nesting level exceeded. I increased nesting function call levels few times but now I dont want to increase it further as I know that's not right solution.
Can anyone suggest a alternative code (may be iterative) to me for this?
<?php
function findallpairs($username, $totalusers= 0)
{
$sql = "select username,package_id from tbl_user where
parent_id = '".$username."' order by username";
$result = mysql_query($sql);
if(mysql_num_rows($result) > 0)
{
while($row = mysql_fetch_array($result))
{
$username = $row["username"];
$totalusers++;
$arrtmp = findallpairs($username, $totalusers);
$totalusers = $arrtmp["totalusers"];
}
}
$arrpoints["totalusers"] = $totalusers;
return $arrpoints;
}
?>
Note : Please remember my original code is too big but I have been pasting just the important aspect of the logic here.
It would be a great help for me if I find the alternative solution to this.
Thanks in advance!
How deep are you going?
The day makes a mutliway tree within your sql database. Trees are recursive structures, and recursive code is what naturally fits.
You may be able use use what i'm calling quasi-memiozation.
This should be easy if you have the children listed in the DB structure. Take a result for all users with no childrin, memioize their value into a hash or tree with the key being the user ID and the value 1. Then just mass iterate over each user (or just the parents of memiozed entries) and if it has values memiozed for all its children, add them together and memoioze that value. Repeat the iteration until you find the root (a user with no parent)
If you don't have a record of children it's likely terribly inefficient.

Resources