Page 1 of 2

dynamic property class for mutilple series

Posted: Thu Feb 09, 2023 10:31 am
by 15695007
Hello:
I want to show the multiple line with user select different property.
Now I has the data like
Snipaste_2023-02-09_18-26-47.png
Snipaste_2023-02-09_18-26-47.png (2.92 KiB) Viewed 4698 times
I can't define the data Model with Class, because the property is dynamic.

How do i need to use the class, to show chart with multiple Line.

the code is which i want to realize, but it did't work.

Code: Select all

// http receive
string response = "[{\"name\":\"aa\",\"age\":10,\"height\":170},{\"name\":\"bb\",\"age\":11,\"height\":175},{\"name\":\"cc\",\"age\":12,\"height\":180}]";

using Newtonsoft.Json;
// the response has unknowed property, so i need use object to deserialize

JArray jArray = JsonConvert.DeserializeObject<JArray>(response);
// jArray element actual class type is JObject

// when i use Add( list as IList),it not work.



void showChart(string selXLabel, List<string> selYLineLabelList)
{

    foreach (string item in selYLineLabelList)
    {
    	Line line = new Line();
        line.YValues.DataMember = item;
        line.LabelMember = selXLabel;
        List<object> list = jArray.ToObject<List<object>>();
        line.Add(list as IList);
        this.tChart1.Series.Add(line);
    }
}
...
List<string> selList = ["Age","Height"].toList()....;
showChart("Name",selList );

The data Property is unknowed,
I have use HashTable ,but it doesn't work too. The code like

Code: Select all

List<Hashtable> list = jArray.ToObject<List<Hashtable>>();
line.Add(list as IList);


Re: dynamic property class for mutilple series

Posted: Tue Feb 14, 2023 9:27 am
by Christopher
Hello,

based on this example:
https://www.steema.com/support/viewtopi ... =4&t=17814

It should be easy to use LINQ to create new List<Student> and assign them to multiple series. I'll get an example together for you this morning.

Re: dynamic property class for mutilple series

Posted: Tue Feb 14, 2023 9:58 am
by 15695007
Hello:
The problem I faced is the Class is unknown, so I want to use the class with Dictionary , but it does't work.

Re: dynamic property class for mutilple series

Posted: Tue Feb 14, 2023 10:10 am
by Christopher
Hello,

you can use a class if you know the structure of the Json file—using Microsoft's System.Text.Json, the following works fine:

Code: Select all

        string response = "[{\"name\":\"aa\",\"age\":10,\"height\":170},{\"name\":\"bb\",\"age\":11,\"height\":175},{\"name\":\"cc\",\"age\":12,\"height\":180}]";

        private void InitializeChart()
        {

            var data = System.Text.Json.JsonSerializer.Deserialize<List<Student>>(response);

            var age = new Line(tChart1.Chart);

            age.YValues.DataMember = "age";
            age.LabelMember = "name";

            age.Add(data as IList);

            var height = new Line(tChart1.Chart);

            height.YValues.DataMember = "height";
            height.LabelMember = "name";

            height.Add(data as IList);
        }

        public struct Student
        {
            public string name { get; set; }
            public int age { get; set; }
            public int height { get; set; }
        }

Re: dynamic property class for mutilple series

Posted: Tue Feb 14, 2023 10:40 am
by 15695007
Hello:

The key problem I don't know the structure of the Json file,so i want to use the Dictionary.

Re: dynamic property class for mutilple series

Posted: Tue Feb 14, 2023 11:12 am
by Christopher
Hello,
The key problem I don't know the structure of the Json file,so i want to use the Dictionary.
If you don't know the structure of the Json file, how do you know what to plot in TeeChart?

Re: dynamic property class for mutilple series

Posted: Tue Feb 14, 2023 1:23 pm
by 15695007
Hello:
I need to show chart with the specificed column. before post the http request, i will appoint the column name,then i will receive the data with the specificed column.


eg. request data is
["name","age"],
response data is
[{name:"Lily",age:10},{name:"Jack",age:11}...]

eg.
request data is
["subject","score"],
response data is
[{subject:"english",score:90},{subject:"mathematics",score:99}...]

I just know the response data has the specificed key.
I want to use the code like:

Code: Select all

 height.YValues.DataMember = requestData[1]; // score
 height.LabelMember = requestData[0]; // subject

Re: dynamic property class for mutilple series

Posted: Tue Feb 14, 2023 2:00 pm
by Christopher
Hello,

Okay, in which case you can use code like:

Code: Select all

        string response = "[{\"name\":\"aa\",\"age\":10,\"height\":170},{\"name\":\"bb\",\"age\":11,\"height\":175},{\"name\":\"cc\",\"age\":12,\"height\":180}]";

        private void InitializeChart()
        {

            var data = JsonSerializer.Deserialize<JsonElement>(response).EnumerateArray();
            var age_data = data.SelectMany(x => x.EnumerateObject()).Where(x => x.Name == "age").Select(x => x.Value.GetInt32()).ToArray();
            var height_data = data.SelectMany(x => x.EnumerateObject()).Where(x => x.Name == "height").Select(x => x.Value.GetInt32()).ToArray();

            var age = new Line(tChart1.Chart);
            age.Title = "age";
            age.Add(age_data);

            var height = new Line(tChart1.Chart);
            height.Title = "height";
            height.Add(height_data);
        }
Alternatively you can reconstruct the Student:

Code: Select all

        string response = "[{\"name\":\"aa\",\"age\":10,\"height\":170},{\"name\":\"bb\",\"age\":11,\"height\":175},{\"name\":\"cc\",\"age\":12,\"height\":180}]";

        private void InitializeChart()
        {

            var data = JsonSerializer.Deserialize<JsonElement>(response).EnumerateArray();
            var age_data = data.SelectMany(x => x.EnumerateObject()).Where(x => x.Name == "age").Select(x => x.Value.GetInt32()).ToArray();
            var height_data = data.SelectMany(x => x.EnumerateObject()).Where(x => x.Name == "height").Select(x => x.Value.GetInt32()).ToArray();

            var age = new Line(tChart1.Chart);
            age.YValues.DataMember = "age";
            age.Add(age_data.Select(x => new Student() { age = x }).ToList() as IList);

            var height = new Line(tChart1.Chart);
            height.YValues.DataMember = "height";
            height.Add(height_data.Select(x => new Student() { height = x }).ToList() as IList);
        }

Re: dynamic property class for mutilple series

Posted: Wed Feb 15, 2023 2:44 am
by 15695007
Hello:
The student class is not suitable.Then how do i add xValues to the line,when i use age.Add(xValues,yValues), I receive NullRefrenceException.
I guess the xValues is must number array, but I need use string data to XValues,like name,subject,category..

Code: Select all

var height_data = data.SelectMany(x => x.EnumerateObject()).Where(x => x.Name == "height").Select(x => x.Value.GetInt32()).ToArray();

            var age = new Line(tChart1.Chart);
            age.Title = "age";
            age.Add(age_data);

Re: dynamic property class for mutilple series

Posted: Wed Feb 15, 2023 10:14 am
by Christopher
Hello,
The student class is not suitable.
Then you can create a more suitable one.
I guess the xValues is must number array, but I need use string data to XValues,like name,subject,category..
Yes, TeeChart Series take XValues and YValues, which are numbers, and Labels, which are strings.

Maybe you can make something of code like this:

Code: Select all

        class Request
        {
            public string? Name { get; set; }
            public int Value { get; set; }

            public static Request Empty { get; set; } = new Request { Name = null, Value = -1 };
        }

        private void InitializeChart()
        {

            List<Request> GetData(string request)
            {
                var response = "[{\"name\":\"aa\",\"age\":10,\"height\":170},{\"name\":\"bb\",\"age\":11,\"height\":175},{\"name\":\"cc\",\"age\":12,\"height\":180}]";
                var data = JsonSerializer.Deserialize<JsonElement>(response).EnumerateArray();
                var req = JsonSerializer.Deserialize<JsonElement>(request).EnumerateArray();

                var data_nv = data.SelectMany(x => x.EnumerateObject()).Where(x => x.Name == req.First().GetString() || x.Name == req.Last().GetString()).Select(x => x.Value);

                return Enumerable.Zip(data_nv, data_nv.Skip(1), (x, y) =>
                {
                    if (x.ValueKind == JsonValueKind.String)
                    {
                        return new Request { Name = x.GetString(), Value = y.GetInt32() };
                    }
                    else
                    {
                        return Request.Empty;
                    }
                }).Where(x => x != Request.Empty).ToList();
            }

            var age = new Line(tChart1.Chart);
            age.YValues.DataMember = "Value";
            age.LabelMember = "Name";
            age.Title = "Age";
            age.LinePen.Width = 3;
            age.Add(GetData("[\"name\",\"age\"]") as IList);

            var height = new Line(tChart1.Chart);
            height.YValues.DataMember = "Value";
            height.LabelMember = "Name";
            height.Title = "Height";
            height.Add(GetData("[\"name\",\"height\"]") as IList);

            height.VertAxis = VerticalAxis.Right;

        }
Screenshot from 2023-02-15 11-12-22.png
Screenshot from 2023-02-15 11-12-22.png (39.51 KiB) Viewed 4551 times

Re: dynamic property class for mutilple series

Posted: Wed Feb 15, 2023 11:17 am
by 15695007
Hello:
The newest reply may be suitable with me,but next trouble is my data is not int,may be it's double,or float or long. I attempt to convert with object , I think TeeChart will use actual type,but it's not work.

Re: dynamic property class for mutilple series

Posted: Wed Feb 15, 2023 11:25 am
by Christopher
Hello,
The newest reply may be suitable with me,but next trouble is my data is not int,may be it's double,or float or long. I attempt to convert with object , I think TeeChart will use actual type,but it's not work.
This is not really a TeeChart issue now, as TeeChart will correctly render the data you give it as long as it is either a number type or a string. Your issue now is to convert your data into one of these two formats, which should be easy to do using the JsonValueKind enum as I did in the example I gave you.

Please also be aware that we offer consultancy services by which we can write your TeeChart application for you—for more details please write to sales@steema.com.

Re: dynamic property class for mutilple series

Posted: Wed Feb 15, 2023 12:25 pm
by 15695007
Hello:
Maybe you misunderstood.
the code like:

Code: Select all

            string response = "[{\"name\":\"aa\",\"age\":10,\"height\":170.1},{\"name\":\"bb\",\"age\":11,\"height\":175.3},{\"name\":\"cc\",\"age\":12,\"height\":173.5}]";
            JArray jArray = JsonConvert.DeserializeObject<JArray>(response);
            var data = jArray.Select(ele => {
                var jdata = (JObject)ele;

                return jdata.GetValue("age").ToObject<int>();
            }).ToArray();


            var ageData = jArray.Select(ele => {
                var jdata = (JObject)ele;
                return jdata.GetValue("height").ToObject<object>();
            }).ToArray();

            // System.Double
            MessageBox.Show(ageData[0].GetType().ToString());

            Line line = new Line(this.tChart1.Chart);

            line.Add(data,ageData);
Snipaste_2023-02-15_20-22-39.png
Snipaste_2023-02-15_20-22-39.png (16.92 KiB) Viewed 4541 times
when i change the object to double, it's ok. But maybe it's int.
so i want to use object , and i actually get index 0 data type is System.Double , why TeeChart can't use it.

Re: dynamic property class for mutilple series

Posted: Wed Feb 15, 2023 12:31 pm
by Christopher
Hello,
Maybe you misunderstood.
I can see again that I did understand your problem. Your problem is with Newtonsoft Json.NET. All the examples I used were using Microsoft's System.Text.Json namespace, which again is not strictly a TeeChart issue.

Again I will say that it will be perfectly possible to check for the type and convert it correctly using System.Text.Json, as I mentioned in my last message. If you need help in using either Json.NET or System.Text.Json within your TeeChart app, can I again please suggest you consider the use of our consulting services.

Re: dynamic property class for mutilple series

Posted: Wed Feb 15, 2023 12:59 pm
by 15695007
Hello:
Okay, i'm Beginners with C#. I can find the decimal type, maybe is useful. I hava use System.Text.Json in my project ,but the Decimal is well in Newtonsoft.Json too.
So can i use it to convert the int or double,or long to Decimal on YValue?
Thank you Your Help.