Giter Club home page Giter Club logo

ggnet's People

Contributors

pablofrommars avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

ggnet's Issues

NullReferenceException if limits.min == limits.max

The following setup (taking from samples) throws a NullReferenceException

            map = Plot.New (data)
                .Geom_Map (o => o.country.Polygons, tooltip: o => (o.country.Capital.Point, o.country.Name), alpha: 0.7, width: 0.2, animation: true)
                .Scale_Longitude (limits: (-15, 30))
                .Scale_Latitude (limits: (30, 70))
                .Scale_Fill_Continuous (o => o.count, Colors.Viridis, name: "count")
                .Theme (theme);

in Set function in class Fill.cs, because Wilkinson.extended returns null if limits.min is equal to limits.max. This seams to be the case if all data supplied to Plot.New have the same value of count.

            var extended = Wilkinson.extended(limits.min, limits.max, m);

            var labels = new (string value, string label)[extended.Length];

And Wilkinson.extended returns null because of this code

            if (dmax - dmin < eps)
            {
                //return(seq(from=dmin, to=dmax, length.out=m))
                return null;
            }

source set has to be order by time, if LocalDateTime is used for x-axis

If LocalDateTime is used for x-axis function Train In DateTimePosition does expect the data to come in ordered already (oldest to youngest). Also in case more than one panel is used the first panel has to start with the oldest data. Otherwise those data will not be shown.

I replaced …

                var current = values[values.Count - 1];
                if (current.Date == key.Date)
                {
                    current = current.Plus(sampling);

                    while(current <= key)
                    {
                        values.Add(current);

                        current = current.Plus(sampling);
                    }
                }
                else
                {
                    values.Add(key);
                }

… with …

                for (var pos = values[0].Minus (sampling); pos >= min; pos = pos.Minus (sampling))
                {
                    values.Add (pos);
                }

                for (var pos = values[values.Count - 1].Plus (sampling); pos <= max; pos = pos.Plus (sampling))
                {
                    values.Add (pos);
                }

feel free to use it.

Chart vertical height, horizontal axis spacing [User help]

Hey Pablo, thanks for creating this project. It's really promising for my use case. I'm creating a pain chart for physical therapy patients. I started from the SPY example and got this far:

image

        data = Plot.New(source, x: o => o.When, y: o => o.Pain)
            .Title("Pain Over Time")
            .Geom_Area(alpha: 0.3)
            .Geom_VLine(x: o => string.IsNullOrWhiteSpace(o.Activity) ? default : o.When,
                    color: "#FF00D9",
                    lineType: LineType.Dashed)
            .YLab("Level")
            .XLab("Date")
            .YLim(min: 0, max: 10)
            .Caption("Source: Patient")
            .Theme(theme);

One key difference for me is I am using LocalDateTime instead of just LocalDate.

My questions are

  1. Can I adjust the horizontal axis label spacing or rotation? The text is so crammed it looks like a solid bar.
  2. Can I adjust the vertical height of the chart to fill the window? Would this be better done with CSS or the chart Height property?

I found a solution to some of my questions by Googling for ggplot, but not all solutions seem to map to ggnet. It's much harder to Google for ggnet, so here I am.

Thanks!

Time series with subminute resolution

Love your library and I'm successfully using it for some charts. Now I ran into a problem.

A line chart with X axis defined as Scale_X_DateTime_Discrete will fault if the data points have X values with subminute resolution (i.e. with a 'seconds' part in the DateTime).

Using the following:

    "Metrics": [
        {
            "Timestamp": "2020-04-30T13:30:00+02:00",
            "Series": "broker",
            "Value": "10"
        },
        {
            "Timestamp": "2020-04-30T15:30:05+02:00",
            "Series": "broker",
            "Value": "40"
        },
        {
            "Timestamp": "2020-05-01T15:50:10+02:00",
            "Series": "broker",
            "Value": "50"
        }
    ],

Will cause output errors like the following in the console:

Error: <line> attribute x1: Expected length, "NaN".
Error: <path> attribute d: Expected number, "M NaN 123.80198019…".

When I set the Seconds part to 0, the chart renders OK.

My code (experimented with limits to no avail):

data = Plot.New(source, x: o => o.Timestamp, y: o => o.Value)
            .Geom_Line(source, width: 2, x: o => o.Timestamp, y: o => o.Value)
            .XLab("Timestamp")
            .YLab("Value")
            //.Scale_X_Discrete_DateTime(limits: limits)
            .Scale_Y_Continuous(limits: (0, maxQueueLength))
            .Scale_Color_Discrete(o => o.Series, Colors.Viridis )
            .Theme(dark:false, legend: Position.Bottom)

Unfortunately, my time series have timespans of once per second over 10 minutes.

GGNet Choropleth State Map

Thank you for the work you have done in GGNet. My co-worker and I are trying to implement a map of the United States divided into states. We’re looking for a way to implement this, but we can’t seem to find out how the GGNet library draws the countries. Is it possible to do this? Please get back to us when convenient for you.

BoxPlots

Are there any plans to implement a BoxPlot to accompany those Violin plots. It would be mighty useful.

text label rotation

I'm having a chart with long labels. So as they are (very) long the text can't be read as the text is overlapping.

It would be great to have an option to rotate the text labels by (at least) a certain degree (e.g. 45° or 90°). I'm not an expert in svg, but it seems this could be done in Panel.razor by adding a transform attribute to the text object. Maybe it would be also possible to add this to the style definitions in Plot.razor.

Thanks

Change Geom in client side Blazor

Hi, I was testing your component but was not able to change the geom type depending on what type of chart the user has selected. When I refresh the page (F5) the the data is shown correctly. This is the code I use for selecting the geom:

    switch (ChartType)
    {
        case 1:
            reportData = Plot.New(reportSource, x: pX, o => o.Value)
                .Geom_Bar(position: PositionAdjustment.Dodge)
                .Scale_X_Discrete(expand: (0.0, 0.1, 0, 0.1), formatter: labeller)
                .Scale_Fill_Discrete(o => o.Id, Colors.Brewer.YlGnBu[4], direction: -1)
                .YLab("y label%")
                .XLab("Parameters")
                .Title("Test report")
                .Theme(dark: false);
            break;
        default:
            reportData = Plot.New(reportSource, x: pX, o => o.Value)
                .Geom_Bar(position: PositionAdjustment.Stack)
                .Scale_X_Discrete(expand: (0.0, 0.1, 0, 0.1), formatter: labeller)
                .Scale_Fill_Discrete(o => o.Id, Colors.Brewer.YlGnBu[4], direction: -1)
                .YLab("y label%")
                .XLab("Parameters")
                .Title("Test report")
                .Theme(dark: false);
            break;
    }

x-Axis LocalDateTime based chart can't be set to "include" values outside the source data

I tried to find a way to create a chart which shows values for the last 2 hours. I guess I should use the expand fields of Scale_X_Discrete_DateTime

            past2hPlot = Plot.New (callers.Values.Where (c => c.StartTimeOffset > minLimit),
                    x: o =>
                    {
                        var dto = o.StartTimeOffset;
                        return LocalDateTime.FromDateTime (dto.AddSeconds (-dto.Second).ToLocalTime ().DateTime);
                    },
                    y: o => 1.0)
                .Geom_Bar (position: PositionAdjustment.Stack, width: 0.5)
                .Scale_X_Discrete_DateTime (expand: (0.0, 0.1, 0, 0.1))
                .Scale_Fill_Discrete (o => o.Lang ?? String.Empty, Colors.Viridis, direction: -1)
                //.Facet_Wrap (selector: o => o.label, freeY: true)
                .XLab ("Anrufer")
                .Theme (dark: false, legend: Position.Bottom);

Nevertheless it looks like the Set function in class DateTimePosition which calls SetRange function is based on doubles instead of some sort of time values.

Also from what I see from code the calculation of minimum and maximum of the limits fields in Scale_X_Discrete_DateTime used in Set function does only work for limits which are present in the source set itself. If a limit is specified which is not included in the source set all data will be shown in the chart ignoring any limits. There should be a less or greater than comparission form my point of view.

System.NullReferenceException while rendering data

While rending data an System.NullReferenceException in Data/Data.cs line 409 is thrown.

for (int g = 0; g < panel.Geoms.Count; g++)

stack trace

GGNet.dll!GGNet.Data<(Helper.Database.Models.DbTask.Types, Helper.Database.Models.TaskHistory.States, string, double?), Helper.Database.Models.DbTask.Types, double>.RunLegend(bool first) Zeile 409 C#
GGNet.dll!GGNet.Data<(Helper.Database.Models.DbTask.Types, Helper.Database.Models.TaskHistory.States, string, double?), Helper.Database.Models.DbTask.Types, double>.Render(bool first) Zeile 446 C#
GGNet.dll!GGNet.Components.Plot<(Helper.Database.Models.DbTask.Types, Helper.Database.Models.TaskHistory.States, string, double?), Helper.Database.Models.DbTask.Types, double>.Render(bool firstRender) Zeile 37 C#
GGNet.dll!GGNet.Components.Plot<(Helper.Database.Models.DbTask.Types, Helper.Database.Models.TaskHistory.States, string, double?), Helper.Database.Models.DbTask.Types, double>.OnInitialized() Zeile 32 C#
[Externer Code]

The exception is thrown because panel == NULL. I guess the cause for this is an empty data source (groupTasks) for the following setup

tasksPlot = Plot.New (groupTasks, x: o => o.typ, y: o => o.data ?? 0)
                .Geom_Bar (position: PositionAdjustment.Dodge, width: 0.5, tooltip: o => Math.Round (o.data ?? 0, 2).ToString ())
                .Scale_X_Discrete (expand: (0.0, 0.1, 0, 0.1), formatter: labeller)
                .Scale_Fill_Discrete (o => o.state, Colors.Viridis, direction: -1)
                .Facet_Wrap (selector: o => o.label, freeY: true)
                .XLab ("kind of task")
                .Theme (dark: false, legend: Position.Bottom);

While obviously it's discussable if an empty data source makes sense, from my point of view it should generate an empty chart and at least should not "crash" on rending, but rather throw an exception on setup (if the prefered option (an empty chart) is not the way to go)

Series "overflow"

Hi!

I'm trying to achieve a specific effect where the areas in an area chart are emphasized with a line. I believe this improves clarity. (See * below for a good example, if you have this book)

To achieve this effect, I added both a Geom_Area and a Geom_Line to the plot. It works!

However, two things occur, as you can see in the bottom chart:

  1. There are artifacts from the legend showing up in the Y axis.
    (When I reduce the number of series, the artifacts disappear)
  2. The legend contains both the lines and the areas.
    (If only the boxes showed, the artifacts probably would disappear)

I tried to discover a way to color a series but without having any labels but it doesn't seem possible at the moment.

data = Plot.New(source, x: o => o.Milliseconds, y: o => o.Value)
    .Geom_Line(source, width: 1, x: o => o.Milliseconds, y: o => o.Value)
    .Geom_Area(alpha: 0.3, x: o => o.Milliseconds, y: o => o.Value)
    .XLab(XLabel)
    .YLab(YLabel)
    .Scale_X_Continuous(formatter: MillisecondsFormatter.Instance)
    .Scale_Y_Continuous(limits: (0, maxValue), format: YLabelFormat)
    .Scale_Fill_Discrete(o => o.Series, Colors.Viridis)
    // Need this to get the lines, but I don't want the additional labels :)
    .Scale_Color_Discrete(o => o.Series, Colors.Viridis)
    .Theme(dark: false, legend: Position.Right);

(Series names redacted)
image

(*) Data Visualization (Kieran Healy) page 88, fig 4.18

it's not possible to use time-based x-axis for sources having entries using different seconds within a minute

The x position and width will not be calulated correctly for charts having more than 1 entry per minute in the their source set. The x position will be NaN (as well as the width) resulting in not showing any information in the chart.

class DateTimePosition returns double.NaN when a value (on x-axis) cannot be found. Which in fact should not happen, but …

        public override double Map(LocalDateTime key)
        {
            var index = values.IndexOf(key);
            if (index < 0)
            {
                return double.NaN;
            }

            return index;
        }

… the function Train will skip to add entries in case the sampling rate is less than one minute.

        public override void Train(LocalDateTime key)
        {
            if (values.Count > 0)

            ...

                var current = values[values.Count - 1];
                if (current.Date == key.Date)
                {
                    current = current.Plus(sampling);

                    while(current <= key)
                    {
                        values.Add(current);

                        current = current.Plus(sampling);
                    }
                }

The way it's currently setup also leads to problems if samples have different minutes, but are in the range of less than 60 seconds. What was the reason to use a "sampling frequency" here? My expectation would be to remove this "sampling" completly, as I want to display data within a period of 1 minute. Anyway if sampling is used here to combine entries (what ever that would mean) the lookup function Map should handle that correctly.

extenstion expand_limits is "missing"

It would be great if expand_limits could be implemented. I want to show a certain range in a chart even if values would not need such a "wide" range. For example expand_limits with a range of 0 to 1, even all values are in a range from 0.3 to 0.7

Guid.ColorBar legend is wrongly formatted

As shown on https://pablofrommars.github.io/examples/choropleth the max value of the Guid.ColorBar legend is not placed at the left position of the color bar. From the example it was not clear if just the very left number is missing (or missing by design), but the placements match the colors. But after drawing such a country map it's clear that the numbers placed above the color are the min and max values used in the chart and no additional number are missing on the left side, but the position of the numbers do not match the respective color of the ColorBar shown below.

The max value (in the example above 80) should be places at the very beginning (left side) of the ColorBar, while the min value should stay were it is currently. All values in between should move accordingly to match their colors show on the map.

Bug: CSS should be generated culture invariant

CSS requires numbers using dots (instead of commas). The code just uses standard number to string conversions (implicitly ToString ()) without setting any culture Information. Therefore the svgs generated do not work, when cultures are used which have numbers using commas instead of dots. E.g. style="width: 578,15" instead of corretly generating "width: 578.15"

I've done all the nessecary work on my local repository, but can't create a pull request on your project. Let me know the way in case I should share the code with your project.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.