Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 
Not applicable

Get fields name of an IGenericObject

Hello,
I'm new to Qlik Sense sdk and I'm trying to retrieve the data of an IGenericObject,
I've encountered with a few issues:

1. How do I know the height and width of the IGenericObject data?

I found this code but not all the object are HyperCube (what type of object is myObject in the code below)

var first10RowsPage = new NxPage { Top = 0, Left = 0, Width = myObject.HyperCube.Size.cx, Height = myObject.HyperCube.Size.cy };


2. When I get the result I can't seem to find the column names and I only get the matrix with the data.

3. Not all object types has the method: GetData(...), e.g :filterpane

4. Is there a way to retrieve all the data without paging?


Here is my code for a table type object:

IGenericObject child = sheet.GetChild(objId);

System.Data.DataTable dt = null;


var cellsPage = new NxPage { Top = 0, Height = 100, Left = 0, Width = 100 };

Table tbl = (Table)child;

IEnumerable<NxDataPage> data= tbl.GetData(new[] { cellsPage });

foreach (NxDataPage page in data)

{

  IEnumerable<NxCellRows> rows = page.Matrix;

  if (dt==null)

  {

      dt = new System.Data.DataTable();

  Rect rect = page.Area;

  int colCount = rect.Width;

  for (int i = 0; i < colCount; i++)

  {

dt.Columns.Add("col_" + i);

  }

  }

  foreach (NxCellRows row in rows)

  {

  DataRow dr = dt.NewRow();

  int j = 0;

  foreach (NxCell cell in row)

  {

  String value = "";

  double num = cell.Num;

  if (Double.IsNaN(num))

      value = cell.Text;

  else

      value = num + "";

  dr = value;

  j++;

  }

  dt.Rows.Add(dr);

  }

}

     

Thanks in advance,

6 Replies
Not applicable
Author

Hi,

1. IGenericObject is a base class, you must use abstract structure to data as different objects for example :
var myHypercube =  genericObject.Get<HyperCube>("hypercube")

myHypercube.Size...

2. You must access the hypercube properties, the DimensionInfo array and MeasureInfo array.

3. Filterpane is an array of ListObjects (IListBox), you will need to retrieve its children.
Example:

if (filterpane.Items.Any())

{

  return "[" + chart.Items.Select(item => (IListbox)chart.GetChild(item.Info.Id)).Aggregate("", (current, child) => current + String.Join(", ", child.Properties.ListObjectDef.Def.FieldDefs)) + "]";

}

4. If you have a small amount data you can set the InitialDataFetch size to the size of the field. NOTE this can have performance impacts.

Best regards

Lars-Göran Book

Not applicable
Author

Hi Lars,

Thank you for your response,

I'm still left with the question how do I retrieve the data from all types of object,

since not all object are hypercubes.

I need to support the following types:

barchart,combochart,filterpane,scatterplot,pivot-table,table,kpi,piechart,linechart,treemap,map,gauge,text-image

I've tried to get the hypercube of the objects but it doesn't work,


IGenericObject iGenObj = (IGenericObject)iapp.GetGenericObject(objId);

var myHypercube =  iGenObj .Get<HyperCube>("hypercube")??

I also tried to get the hypercube of a table:

String type = iGenObj.Info.Type;

Table tbl = (Table)iGenObj;

var myHypercube =  tbl.Get<HyperCube>("hypercube")??

what did you mean by : you must use abstract structure to data as different objects

can you give me example of a structure that has the method Get<HyperCube>("hypercube")

All I managed do so far is to get the pages of the object, go through them and get the matrix of each page,

for example, if the object is table type

Table tbl = (Table)iGenObj;

IEnumerable<NxDataPage> pages = tbl.DataPages;

for (int i = 0; i < pages.Count() ; i++) {

          var page = pages.ElementAt(i);

          IEnumerable<NxCellRows> rows=page.Matrix;

}

But as I've mentioned before I don't know which field belongs to which column,

Am I missing something?

Thanks again,
Moran

pamaxeed
Partner - Creator III
Partner - Creator III

Hi Moran,

have you got a solution?

I am stuck in the same problem.

How we can retrieve dynamically the size of a Hypercube?

I tried several approaches but without any success.

var genericObject = app.GetGenericObject(objId);

  

var first10RowsPage = new NxPage { Top = 0, Left = 0, Width = 2, Height = 10 };

IEnumerable<NxDataPage> data = genericObject.GetHyperCubeData("/qHyperCubeDef", new[] { first10RowsPage });

I read that on hypercube level there is the property size which can help me to get the width and height dynamically.

Can someone of you give me an example how to access this property?

Thanks and regards,

Patric

Øystein_Kolsrud
Employee
Employee

I think there is some confusion regarding a couple of concepts here. GenericObject is the base class of all visualization objects (like bar charts), but a generic object can not be a hypercube directly. Instead, a GenericObject has a properties definitions that may contain definitions of hypercubes. The data for the hypercube is extract from the layout of the object. I have created a project on branch that illustrates how to work with hypercubes through the SDK:

http://branch.qlik.com/#!/project/5818518b9fa7b8156fa73588

There is a class in the SDK called HyperCubePager that you can use to access the size information you are looking for. The class is primarily intended to make it easy to access hypercube data from generic objects, but you can also get information about the table size there. If you know there is exactly one hypercube in your object, then you can do something like this:

var thePager = theObject.GetAllHyperCubePagers().Single();

var columns = thePager.NumberOfColumns;

var rows = thePager.NumberOfRows;

You might also want to have a look at this the following page, and its sub pages discussing generic objects and paging:

Retrieving data ‒ Qlik Sense

Best regards, Øystein Kolsrud

Øystein_Kolsrud
Employee
Employee

As a side note, the classes representing client visualizations contain a set of properties that are basically short cuts to those elements of the layout of the object. If you for instance want to access the title of a bar chart, then you can do like this:

IBarchart theBarChart;

var title = theBarChart.Title;

This will be equivalent to getting the layout of the bar chart and then accessing the Title property of the layout. Like this:

IBarchart theBarChart;

IBarchartLayout theLayout = theBarChart.GetLayout().As<BarchartLayout>();

var title = theLayout.Title;

The call to "As<BarchartLayout>()" in row two above is used to reinterpret the GenericObjectLayout returned by the GetLayout call as an instance of BarchartLayout. This utilizes the "AbstractStructure" concept to do reinterpretation of data returned from the engine (which is originally untyped json). More information about the "AbstractStructure" concept can be found here:

http://help.qlik.com/en-US/sense-developer/3.1/Subsystems/NetSDKAPI/Content/HowTos/Net-Sdk-How-To-Ab...

Not applicable
Author

Hi Patric,

I was able to come up with a solution, I'm going to demonstrate it on a table object:

IGenericObject iGenObj = (IGenericObject)iapp.GetGenericObject(objId);

Table tbl = (Table)iGenObj;

HyperCubePager hcp = tbl.HyperCubePager;

int numOfColumns = hcp.NumberOfColumns;

int numOfRows = hcp.NumberOfRows;

  IEnumerable<IEnumerable<NxDataPage>> allDataPagesNext = hcp.IteratePages(new[] { new NxPage { Top = 0, Height = 1000, Left = 0, Width = numOfColumns } }, Pager.Next);

foreach (IEnumerable<NxDataPage> pages in allDataPagesNext){

..........................

}

I set Height (number of rows in a page) to be 1000 and not numOfRows since I want to manage the pages size,

The function IteratePages iterates all the pages according to the size you give it

This link really helped me:
https://help.qlik.com/en-US/sense-developer/2.2/Subsystems/NetSDKAPI/Content/HowTos/Net-Sdk-How-To-P...

Hope I helped you,

Moran