Telerik Forums
Reporting Forum
1 answer
72 views
The sticky post at the top is dated 2008, can we get an up to date limitations?
Steve
Telerik team
 answered on 08 Dec 2011
0 answers
68 views
Hi,
    Am having one collecetion in tat one of the property is a XML Value. What i want to know how to bind that collection and my requirement is to bind that XML Values in a single row with multiple columns against each row.
Can anyone provide a sample code..



Thanks and Regards,
Karthikeyan G
Karthi Keyan
Top achievements
Rank 1
 asked on 08 Dec 2011
1 answer
98 views
I need to create a report that contains a bracket but I'm struggling to figure out how to design it.  Its it possible to layout the bracket as I want it to print and then as the report processes the records it fills in the participant fields based on a matching IIF condition?  Basically I don't want the details section to repeat for each participant.  Instead I need each participant to go through the IIF condition'ed text boxes to fill it out.  Or any other suggestions are welcome.
Massimiliano Bassili
Top achievements
Rank 1
 answered on 07 Dec 2011
5 answers
258 views
Hi Telerik team,

The new feature, print preview, released with Q3 2011, is not rendering page number as expected. The Global object, PageCount, is not work. this worked well in Q2 2011.

You have any idea how to solve this?

Thanks
Giuliano Caetano
Graeme Garrett
Top achievements
Rank 1
 answered on 07 Dec 2011
3 answers
288 views
Hi,

I am currently evaluating Telerik reporting.  We will be generating reports that are both used in an MVC webapp and emailed to people as part of overnight batch processes.

I want to conditionally display a message in the report if no results have been found. I have looked at this thread but this doesn't suit my needs. Are there any other ways of doing this? eg by counting the number of records in the report and displaying a message if the count == 0?

many thanks,
Jordan.
Steve
Telerik team
 answered on 07 Dec 2011
1 answer
110 views
Hi,

I have a silverlight project, I can generate the report but since I have many columns to display in the report I need to rotate the layout of the textbox in the detail section. I know about the table in reporting but I would like to know if it is possible using textboxes.

Thanks in advance,
Steve
Telerik team
 answered on 07 Dec 2011
2 answers
341 views
Here's my scenario. I'm currently working on incorporating a dynamic print feature for a  Silverlight application and I'm using Telerik Reporting 2011 Q1 to do it.

The "pages" of the application which the user is to be able to print consist of charts, custom controls and datagrids. The way I send this to the report generator is by exporting the charts and usercontrols as byte arrays and the datagrids as csv and then store this data (including a GUID for the client) serverside. The GUID is sent as parameter to the report generator which fetches the data and re-creates the images and generates the table.

Now I'm doing this dynamically to be able to use the same report for all the pages and also because the datagrids are themselves dynamic and can consist of anything between 3-40 columns (selectable by the user).

One of the issue I've encountered is when I try to get a row grouping created for one of the tables and keep getting "Object reference not set to an instance of an object". The table works just fine if I stick to ColumnGroups and a detail RowGroup.

Here's the NeedDataSource code for the report

private void PrintReportNeedDataSource(object sender, EventArgs e)
{
    if(((IList) ReportParameters["GUID"].Value).Count == 0)
        return;
 
    var guidAsString = ((IList) ReportParameters["GUID"].Value)[0].ToString();
    var reportData = new ReportServices().FetchReportDataForGUID(guidAsString);
             
    var report = (Telerik.Reporting.Processing.Report) sender;
    report.DataSource = reportData;
 
    var availableWidth = report.PageSettings.PaperSize.Width - (report.PageSettings.Margins.Left + report.PageSettings.Margins.Right);
 
    // panel1 (used when only one type of chart is to be displayed)
    var panel1 = new Panel
                        {
                            Location = new PointU(
                                new Unit(0, UnitType.Cm),
                                new Unit(0, UnitType.Cm)),
                            Size = new SizeU(
                                availableWidth,
                                new Unit(35, UnitType.Mm)),
                            Dock = DockStyle.Top,
                            KeepTogether = true
                        };
 
    // panel2 (used with panel1 when multiple chart types are to be displayed on top of each other
    var panel2 = new Panel
                        {
                            Location = new PointU(
                                new Unit(0, UnitType.Cm),
                                new Unit(0, UnitType.Cm)),
                            Size = new SizeU(
                                availableWidth,
                                new Unit(40, UnitType.Mm)),
                            Dock = DockStyle.Top,
                            KeepTogether = true
                        };
    panel2.Style.Padding.Top = new Unit(10, UnitType.Mm);
 
    // Report title
    titleField.Value = reportData.ReportTitle;
 
    #region Create charts
    switch (reportData.ReportType)
    {
        case Enumerators.PrintReportType.Consumption:
        case Enumerators.PrintReportType.ComparedConsumption:
        case Enumerators.PrintReportType.Prognose:
            foreach (var chartData in reportData.Charts)
            {
                var chartImage = Image.FromStream(new MemoryStream(chartData.Data));
                var perCentageToChange = panel1.Width / Unit.FromPixels(chartImage.Width, UnitType.Mm);
                         
                var pBox = new PictureBox
                                {
                                    Name = string.Format("CD{0}", reportData.Charts.IndexOf(chartData)),
                                    Location = new PointU(new Unit(0), new Unit(0)),
                                    Sizing = ImageSizeMode.ScaleProportional,
                                    Width = availableWidth,
                                    Height = Unit.FromPixels(chartImage.Height, UnitType.Mm) * perCentageToChange,
                                    Value = chartImage,
                                    Dock = DockStyle.Top
                                };
                panel1.Items.AddRange(new ReportItemBase[] {pBox});
            }
            if (panel1.Items.Count != 0)
                detail.Items.AddRange(new ReportItemBase[] { panel1 });
            break;
        case Enumerators.PrintReportType.StackedConsumption:
            foreach (var chartData in reportData.MiscPictures)
            {
                // Calculate how wide a single image can be to fill the width of the page
                var totalWidthInPx = reportData.MiscPictures.Sum(pic => pic.Width);
                var totalWidthInMm = Unit.FromPixels(totalWidthInPx, UnitType.Mm);
 
                var perCentageToChange = availableWidth.Value / totalWidthInMm.Value;
                var widthPerImage = totalWidthInPx / reportData.MiscPictures.Count * perCentageToChange;
                         
                var chartImage = Image.FromStream(new MemoryStream(chartData.Data));
 
                var pBox = new PictureBox
                                {
                                    Name = string.Format("GCD{0}", reportData.MiscPictures.IndexOf(chartData)),
                                    Width = Unit.FromPixels(widthPerImage, UnitType.Mm),
                                    Value = chartImage,
                                    Sizing = ImageSizeMode.ScaleProportional,
                                    Dock = DockStyle.Left,
                                    Location = new PointU(new Unit(0), new Unit(0))
                                };
                pBox.Style.Padding.Bottom = Unit.Mm(5);
                panel1.Items.AddRange(new ReportItemBase[] { pBox });
            }
            if (panel1.Items.Count != 0)
                detail.Items.AddRange(new ReportItemBase[] { panel1 });
 
            foreach (var chartData in reportData.Charts)
            {
                var chartImage = Image.FromStream(new MemoryStream(chartData.Data));
 
                var chartWidth = Unit.FromPixels(chartImage.Width, UnitType.Mm);
                var perCentageChange = availableWidth / chartWidth;
 
                var pBox = new PictureBox
                {
                    Name = string.Format("CD{0}", reportData.Charts.IndexOf(chartData)),
                    Location = new PointU(new Unit(0), new Unit(0)),
                    Sizing = ImageSizeMode.ScaleProportional,
                    Width = availableWidth,
                    Height = Unit.FromPixels(chartImage.Height, UnitType.Mm)*perCentageChange,
                    Value = chartImage,
                    Dock = DockStyle.Top
                };
                panel2.Items.AddRange(new ReportItemBase[] { pBox });
            }
            if(panel2.Items.Count != 0)
                detail.Items.AddRange(new ReportItemBase[] { panel2 });
 
            // Stacked chart doesn't have any table data and can return
            return;
        default:
            throw new ArgumentOutOfRangeException();
    }
    #endregion
 
    #region Create padding between charts and table
    var paddingPanel = new Panel
                            {
                                Size = new SizeU(
                                    availableWidth,
                                    Unit.Cm(1.5)),
                                Dock = DockStyle.Top
                            };
    detail.Items.AddRange(new ReportItemBase[] { paddingPanel });
    #endregion
 
    #region Create table data
    using (var parser = new GenericParserAdapter(new StringReader(reportData.TableDataCsv)))
    {
        parser.FirstRowHasHeader = true;
        reportData.DataTable = parser.GetDataTable();
    }
 
    // Creating and configuring the ObjectDataSource component:
    var objectDataSource = new ObjectDataSource
                                {
                                    Name = "TableDataSource",
                                    DataSource = reportData.DataTable
                                };
             
    //var tableDataAsCollectionOfDynamics = reportData.DataTable.ToDynamic();
 
    report.DataSource = objectDataSource;
             
    var dataTable = new Table
                        {
                            Name = "DataTable",
                            DataSource = objectDataSource,
                            Location = new PointU(new Unit(0), new Unit(0)),
                            Size = new SizeU(
                                availableWidth,
                                new Unit(40, UnitType.Mm)),
                            Dock = DockStyle.Fill,
                            ColumnHeadersPrintOnEveryPage = true
                        };
    detail.Items.Add(dataTable);
                        
    //create two HtmlTextBox items (one for header and one for data) which would be added to the items collection of the table
    TextBox textBoxHeader;
    TextBox textBoxContent;
 
    var i = 0;
    dataTable.ColumnHeadersPrintOnEveryPage = true;
 
    dataTable.Body.Rows.Add(new TableBodyRow(new Unit(0.1, UnitType.Cm)));
             
    // Create Padding- and DetailGroup (RowGrops)
    var paddingGroup = new TableGroup { Name = "PaddingGroup" };
    var detailGroup = new TableGroup { Name = "DetailGroup" };
    detailGroup.Groupings.Add(new Grouping(""));
 
    #region If the reporttype is prognosis, create grouping by PrognoseType
    switch (reportData.ReportType)
    {
        case Enumerators.PrintReportType.Consumption:
        case Enumerators.PrintReportType.StackedConsumption:
        case Enumerators.PrintReportType.ComparedConsumption:
            dataTable.RowGroups.Add(detailGroup);
            break;
        case Enumerators.PrintReportType.Prognose:
            // Add an additional row to the body (padding)
            dataTable.Body.Rows.Add(new TableBodyRow(new Unit(0.1, UnitType.Cm)));
 
            var prognoseTypeHeader = new TextBox
                                        {
                                            Value = "Prognos",
                                            Name = "PrognosHeader",
                                            Size = new SizeU(
                                                Unit.Cm(0.1),
                                                Unit.Cm(0.1)),
                                            Multiline = true,
                                            TextWrap = true,
                                            CanGrow = false,
                                            CanShrink = true
                                        };
            dataTable.Corner.SetCellContent(0, 0, prognoseTypeHeader);
                     
            var prognoseTypeContent = new TextBox
                            {
                                Name = "PrognosContent",
                                Multiline = false,
                                CanGrow = false,
                                CanShrink = true,
                                Size = new SizeU(
                                    Unit.Cm(1.1),
                                    Unit.Mm(0))
                            };
 
            prognoseTypeContent.Style.Padding.Top = Unit.Mm(0);
            prognoseTypeContent.Style.Padding.Bottom = Unit.Mm(0);
 
            prognoseTypeContent.Style.Color = Color.DimGray;
            prognoseTypeContent.Style.VerticalAlign = VerticalAlign.Middle;
 
            prognoseTypeContent.Style.Font.Size = Unit.Point(GetFontSize(reportData.DataTable.Columns.Count));
 
            prognoseTypeContent.Style.BorderColor.Default = Color.AliceBlue;
            prognoseTypeContent.Style.BorderStyle.Default = BorderType.Solid;
            prognoseTypeContent.Style.BorderWidth.Default = Unit.Point(0.5);
            prognoseTypeContent.Value = "=Fields.Prognostyp";
 
            // Add the header and content to the table
            dataTable.Items.AddRange(
                new ReportItemBase[]
                {
                    prognoseTypeHeader,
                    prognoseTypeContent
                });
 
            // Create RowGroup to group by PrognoseType
            var rowGroupingGroup = new TableGroup { Name = "PrognoseGrouping" };
            rowGroupingGroup.Groupings.Add(new Grouping("=Fields.Prognostyp"));
            rowGroupingGroup.Sortings.Add(new Sorting("=Fields.Prognostyp", SortDirection.Asc));
                     
            rowGroupingGroup.ChildGroups.Add(detailGroup);
            rowGroupingGroup.ChildGroups.Add(paddingGroup);
                     
            rowGroupingGroup.ReportItem = prognoseTypeContent;
 
            dataTable.RowGroups.Add(rowGroupingGroup);
            break;
        default:
            throw new ArgumentOutOfRangeException();
    }
    #endregion
 
    foreach (DataColumn dc in reportData.DataTable.Columns)
    {
        // The prognosetype column is already handled
        if (reportData.ReportType == Enumerators.PrintReportType.Prognose && dc.ColumnName == "Prognostyp")
            continue;
 
        // Encode the column name to make spacing work with the table
        dc.ColumnName = TelerikUtil.EncodeIdentifier(dc.ColumnName);
 
        // Create the colgroup
        var tableColumnGroup = new TableGroup { Name = string.Format("ColGroup{0}", reportData.DataTable.Columns.IndexOf(dc)) };
        dataTable.ColumnGroups.Add(tableColumnGroup);
        dataTable.Body.Columns.Add(
            new TableBodyColumn(i == 0
                ? Unit.Cm(0.5)
                : Unit.Cm(1)));
 
        #region Create header for the column
        textBoxHeader = new TextBox
                            {
                                Name = string.Format("Header{0}", dc.ColumnName),
                                Value = TelerikUtil.DecodeIdentifier(dc.ColumnName),
                                Size = new SizeU(
                                    Unit.Cm(0.1),
                                    Unit.Cm(0.1)),
                                Multiline = true,
                                TextWrap = true,
                                CanGrow = false,
                                CanShrink = true
                            };
                 
        textBoxHeader.Style.VerticalAlign = VerticalAlign.Middle;
        textBoxHeader.Style.TextAlign = HorizontalAlign.Center;
        textBoxHeader.Style.Font.Size = Unit.Point(GetFontSize(reportData.DataTable.Columns.Count));
        textBoxHeader.Style.Font.Bold = true;
        textBoxHeader.Style.BackgroundColor = Color.FromName("ControlLight");
        textBoxHeader.Style.BorderColor.Default = Color.AliceBlue;
        textBoxHeader.Style.BorderStyle.Default = BorderType.Solid;
        textBoxHeader.Style.BorderWidth.Default = Unit.Point(0.5);
 
        // Bind the headern as ReportItem for the colGroup
        tableColumnGroup.ReportItem = textBoxHeader;
        #endregion
 
        #region  Create content for the column
        textBoxContent = new TextBox
                            {
                                Name = string.Format("Content{0}", dc.ColumnName),
                                Multiline = false,
                                CanGrow = false,
                                CanShrink = true,
                                Size = new SizeU(
                                    Unit.Cm(1.1),
                                    Unit.Mm(0))
                            };
 
        textBoxContent.Style.Padding.Top = Unit.Mm(0);
        textBoxContent.Style.Padding.Bottom = Unit.Mm(0);
        textBoxContent.Style.Color = Color.DimGray;
        textBoxContent.Style.VerticalAlign = VerticalAlign.Middle;
        textBoxContent.Style.Font.Size = Unit.Point(GetFontSize(reportData.DataTable.Columns.Count));
        textBoxContent.Style.BorderColor.Default = Color.AliceBlue;
        textBoxContent.Style.BorderStyle.Default = BorderType.Solid;
        textBoxContent.Style.BorderWidth.Default = Unit.Point(0.5);
 
        #region Content value binding & formatting
        if (textBoxHeader.Value.Contains("Procent") || textBoxHeader.Value.Contains("%"))
        {
            var ltZeroFormat = new FormattingRule();
            var gtZeroFormat = new FormattingRule();
 
            ltZeroFormat.Filters.AddRange(
                new[]
                    {
                        new Filter(
                            string.Format("=CDbl(Substr(Fields.{0}, 0, Len(Fields.{0})-1))",dc.ColumnName),
                            FilterOperator.LessThan,
                            "0")
                    });
            ltZeroFormat.Style.Color = Color.Green;
            gtZeroFormat.Filters.AddRange(
                new[]
                    {
                        new Filter(
                            string.Format("=CDbl(Substr(Fields.{0}, 0, Len(Fields.{0})-1))",dc.ColumnName),
                            FilterOperator.GreaterThan,
                            "0")
                    });
            gtZeroFormat.Style.Color = Color.Red;
            textBoxContent.ConditionalFormatting.AddRange(
                new[]
                    {
                        ltZeroFormat,
                        gtZeroFormat
                    });
            textBoxContent.Value = string.Format("=(CDbl(Substr(Fields.{0}, 0, Len(Fields.{0})-1))/100)", dc.ColumnName);
            textBoxContent.Format = "{0:P2}";
        }
        else if (
            !textBoxHeader.Value.Contains("Tidpunkt") &&
            !textBoxHeader.Value.Contains("Kvartal"))
            textBoxContent.Value = string.Format("=CDbl(Fields.{0})", dc.ColumnName);
        else
            textBoxContent.Value = string.Format("=Fields.{0}", dc.ColumnName);
        #endregion
        #endregion
                 
        if(reportData.ReportType == Enumerators.PrintReportType.Prognose)
        {
            var dummyPadding = new TextBox
                                        {
                                            Name = string.Format("Padding{0}", dc.ColumnName),
                                            Size = new SizeU(
                                                Unit.Cm(1),
                                                Unit.Mm(3))
                                        };
            dataTable.Body.SetCellContent(0, i, dummyPadding);
            dataTable.Body.SetCellContent(1, i++, textBoxContent);
 
            // Add the dummy padding item to the table
            dataTable.Items.Add(dummyPadding);
        }
        else
        {
            dataTable.Body.SetCellContent(0, i++, textBoxContent);
        }
 
        // Add header and content to the table
        dataTable.Items.AddRange(
            new ReportItemBase[]
                {
                    textBoxHeader,
                    textBoxContent
                });
    }
    #endregion
}

I do know there's some unnecessary size parameters in the code since the table is docked, I do on the other hand have a hard time getting the row-heights to act as I want to and do appreciate some pointers on this issue as well.

The the current version which I posted here I'm using a DataTable as source for the table. I've also tried converting the datatable into a collection of dynamic (IEnumerable<dynamic>, dynamic = ExpandoObject) without success.

An example on the CSV-string that is used as source:

"\"Prognostyp\",\"Kvartal\",\"Utfall\",\"Prognos\",\"Kvartalssumma\",\"Referens\",\"Procent\"\r\n\"Budget\",\"Q1\",\"203 442\",\"0\",\"203 442\",\"227 045\",\"-10,40 %\"\r\n\"Budget\",\"Q2\",\"85 173\",\"31 463\",\"116 636\",\"117 133\",\"-0,42 %\"\r\n\"Budget\",\"Q3\",\"0\",\"107 558\",\"107 558\",\"107 558\",\"0,00 %\"\r\n\"Budget\",\"Q4\",\"0\",\"200 592\",\"200 592\",\"200 592\",\"0,00 %\"\r\n\"P1\",\"Q1\",\"203 442\",\"0\",\"203 442\",\"227 045\",\"-10,40 %\"\r\n\"P1\",\"Q2\",\"85 173\",\"28 317\",\"113 490\",\"105 420\",\"7,66 %\"\r\n\"P1\",\"Q3\",\"0\",\"107 558\",\"107 558\",\"107 558\",\"0,00 %\"\r\n\"P1\",\"Q4\",\"0\",\"200 592\",\"200 592\",\"200 592\",\"0,00 %\"\r\n"

Now I've tried creating the expected table through the designer and binding this to a mock ObjectDataSource which returns a datatable consisting of the same type of data and read throught the generated code in InitializeComponent, but I'm unable to get the same thing working dynamically.

I've attached screenshots of the table created through the designer and also screenshots from the client and generated reports (the ones that work).

Here's the code that I've used as DataSource while designing the table

[DataObjectMethod(DataObjectMethodType.Select)]
public DataTable PrognoseTableData()
{
    DataTable dt;
    using (var parser = new GenericParserAdapter(new StringReader("\"Prognostyp\",\"Kvartal\",\"Utfall\",\"Prognos\",\"Kvartalssumma\",\"Referens\",\"Procent\"\n\"Budget\",\"Q1\",\"203 442\",\"0\",\"203 442\",\"227 045\",\"-10,40 %\"\n\"Budget\",\"Q2\",\"85 173\",\"31 463\",\"116 636\",\"117 133\",\"-0,42 %\"\n\"Budget\",\"Q3\",\"0\",\"107 558\",\"107 558\",\"107 558\",\"0,00 %\"\n\"Budget\",\"Q4\",\"0\",\"200 592\",\"200 592\",\"200 592\",\"0,00 %\"")))
    {
        parser.FirstRowHasHeader = true;
        dt = parser.GetDataTable();
    }
    return dt;
}

Hopefully someone can help me out with these issues (both to get the table working and to get the row heights shrunk)

Best regards,
Tobias
Tobias Rodewi
Top achievements
Rank 1
 answered on 07 Dec 2011
3 answers
565 views
I have created a Telerik report with parameters. Now i want to handle these parameters using custom UI. IS there any way I can get list of all the parameters in the report and their possible values(In case of drop down)?

I don't want to hard code the parameters in my webpage. I want to create page dynamically. That's why i need to have list of parameters and their possible values from the report.

thanks for the help.

Peter
Telerik team
 answered on 07 Dec 2011
2 answers
449 views
Hi,

I'm trying to create an EntityDataSource with the new report wizard, but I get a Popup with "Exception has been thrown by the target of an invocation"(Very usefull exception message by the way) before the wizard ends. I've the last version of telerik report(2011 Q3), and I've no other version of telerik reporting installed.

I've one c# class library project, and one other containing the EntityFramework and the generated POCO objects(+datacontext).

Here are some screenshot which show what I've done. I think I've done nothing special :/.

I need to have a first running report at leat friday(the 2.12.2011), so please help :(

Step1: Creating the report
http://dl.dropbox.com/u/368403/TelerikReport/Step1.png

Step 2: Clicking on Add New Data Source...
http://dl.dropbox.com/u/368403/TelerikReport/Step2.png

Step 3: Choosing Entity Data Source type
http://dl.dropbox.com/u/368403/TelerikReport/Step3.png

Step 4: Choosing my connection string(copied in the app.config file, from the app.config file of my EF project, so I now it works)
http://dl.dropbox.com/u/368403/TelerikReport/Step4.png

Step 5: Choosing my dataContext object(which is in another referenced project)
http://dl.dropbox.com/u/368403/TelerikReport/Step5.png

Step 6: Choosing the object context member(in my case, offers
http://dl.dropbox.com/u/368403/TelerikReport/Step6.png

Step 7: Get the wonderfull error!
http://dl.dropbox.com/u/368403/TelerikReport/Step7.png

After that, the data source has been created, but do not work, I see it in the bottom of the report, but it cannot be used anywhere, and if I go again on the  report wizard and select the data source, I've the same error than on the Step 7.

What is going wrong and what can I do NOW to get it working
Peter
Telerik team
 answered on 07 Dec 2011
2 answers
91 views
Hi, all

I'm new to Telerik reporting with silverlight and l'm using CSLA business object.
My business objects have no public constructor, instead have factory method .
and every query method allow only 1 criteria object,in which includes 1 to dozens fileds to create
linq entity syntax. However,looking into your manual, Telerik reporting's objectDataSource
should have public constructor and a public method for 'DataMember' which has same
number of params. I have already built hundreds of object and can't change into public constructor
and parameter signature as well. I have read many threads related, and not sure there might be
something I didn't catch up.

Though it looks like unacceptable, what I'd like to know is kinds of follwing code snippet
 is available in server side.

// create biz object with factory methods
MyBizObjType myObj = MyBizObjType.NewMyBizObjType();
// create criteria object from parms
var criteria = new MyBizCriteria(parms1,parms2.......);
// call search method
myObj.FetchData(criteria);

// create reporting datasource
Telerik.Reporting.ObjectDataSource objectDataSource1 = new Telerik.Reporting.ObjectDataSource();

 // objectDataSource1.DataMember = "GetCars";
 // objectDataSource1.DataSource = typeof(Cars);

// set datasource such as data binding in winform's day.
objectDataSource1.DataSource = myObj;

You must have been asked hundreads of similar question,and may have a good alternative.
Pls let me know better way if above is unacceptable.
At this time, I think I have no other way to make each new entity object wrapping business
 object who engages in reporting. But the real pain is that the number of object reaches several hundreads.

Thank you in advance.
Kang




Yonggu Kang
Top achievements
Rank 1
Iron
 answered on 07 Dec 2011
Top users last month
Jay
Top achievements
Rank 3
Iron
Iron
Iron
Benjamin
Top achievements
Rank 3
Bronze
Iron
Veteran
Radek
Top achievements
Rank 2
Iron
Iron
Iron
Bohdan
Top achievements
Rank 2
Iron
Iron
Richard
Top achievements
Rank 4
Bronze
Bronze
Iron
Want to show your ninja superpower to fellow developers?
Want to show your ninja superpower to fellow developers?