Ejemplo n.º 1
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            object        ChartObject  = null;
            List <double> listContents = new List <double>();
            List <string> names        = new List <string>();
            string        Title        = null;
            string        SubTitle     = null;

            //Get the Chart object and assign it
            if (!DA.GetData <object>("Chart to modify", ref ChartObject))
            {
                return;
            }
            var ChartElem = HUI_Util.GetUIElement <ChartBase>(ChartObject);


            //set new title and subtitle or get old ones
            if (DA.GetData <string>("Title", ref Title))
            {
                ChartElem.ChartTitleVisibility = System.Windows.Visibility.Visible;
                ChartElem.ChartTitle           = Title;
            }
            if (DA.GetData <string>("SubTitle", ref SubTitle))
            {
                ChartElem.ChartSubTitle = SubTitle;
            }

            chartModel = ChartElem.DataContext as SeriesModel;

            if (chartModel == null)
            {
                chartModel = new SeriesModel();
            }

            bool valuesSupplied = DA.GetDataList <double>("New Chart Values", listContents);

            bool namesSupplied = DA.GetDataList <string>("New Chart Names", names);


            //make sure there are the same number of names and values
            if (valuesSupplied && namesSupplied && (names.Count != listContents.Count))
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Different number of names and values supplied.");
                return;
            }


            //if the data isnt supplied modify it
            if (valuesSupplied)
            {
                //replace the ones already in there
                for (int i = 0; i < chartModel.Chart.Count; i++)
                {
                    if (listContents.Count > i)
                    {
                        chartModel.Chart[i].Number = (float)listContents[i];
                    }
                }
                //add any on the end
                if (listContents.Count > chartModel.Chart.Count)
                {
                    for (int i = chartModel.Chart.Count; i < listContents.Count; i++)
                    {
                        chartModel.Chart.Add(new ChartItem()
                        {
                            Number = (float)listContents[i], Category = "UNSET"
                        });
                    }
                }

                //subtract any off the end
                if (listContents.Count < chartModel.Chart.Count)
                {
                    for (int i = chartModel.Chart.Count - 1; i >= listContents.Count; i--)
                    {
                        chartModel.Chart.RemoveAt(i);
                    }
                }
            }

            //check if the names array is different. We don't want to fire a full update unless we absolutely have to.

            bool hasChanged = false;

            var alreadyNames = chartModel.Chart.Select(item => item.Category).ToArray();

            //if the length of names is different, we know it's changed
            if (alreadyNames.Length != names.Count())
            {
                hasChanged = true;
            }
            else //if the length is the same, check each item
            {
                for (int i = 0; i < alreadyNames.Count(); i++)
                {
                    if (alreadyNames[i] != names[i])
                    {
                        hasChanged = true;
                        break;
                    }
                }
            }



            //if the data is supplied and different than what's in the chart, modify it
            if (namesSupplied && hasChanged)
            {
                //replace the ones already in there
                for (int i = 0; i < chartModel.Chart.Count; i++)
                {
                    if (names.Count > i)
                    {
                        chartModel.Chart[i].Category = names[i];
                    }
                }
                //add any on the end
                if (names.Count > chartModel.Chart.Count)
                {
                    for (int i = chartModel.Chart.Count; i < names.Count; i++)
                    {
                        chartModel.Chart.Add(new ChartItem()
                        {
                            Category = names[i], Number = float.NaN
                        });
                    }
                }

                //subtract any off the end
                if (names.Count < chartModel.Chart.Count)
                {
                    for (int i = chartModel.Chart.Count - 1; i >= names.Count; i--)
                    {
                        chartModel.Chart.RemoveAt(i);
                    }
                }

                //refresh display - the binding works when the values change but not when categories do.
                var Values = chartModel.Chart.ToArray();

                chartModel.Chart.Clear();

                foreach (var item in Values)
                {
                    chartModel.Chart.Add(item);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            var           Collection   = new ObservableCollection <ChartItem>();
            string        Title        = "";
            string        SubTitle     = "";
            List <double> listContents = new List <double>();
            List <string> names        = new List <string>();
            int           chartType    = 0;


            //get GH input data
            DA.GetDataList <double>("Data", listContents);
            DA.GetDataList <string>("Names", names);
            bool hasTitle    = DA.GetData <string>("Title", ref Title);
            bool hasSubTitle = DA.GetData <string>("SubTitle", ref SubTitle);

            DA.GetData <int>("Chart Type", ref chartType);
            ChartBase ChartElem = null;

            switch (chartType)
            {
            case 0:
                var pieElem = new PieChart();
                ChartElem = pieElem;
                break;

            case 1:
                var barElem = new ClusteredBarChart();
                ChartElem = barElem;
                break;

            case 2:
                var columnElem = new ClusteredColumnChart();
                ChartElem = columnElem;
                break;

            case 3:
                var doughnutElem = new DoughnutChart();
                ChartElem = doughnutElem;
                break;

            case 4:
                var gaugeElem = new RadialGaugeChart();
                ChartElem = gaugeElem;

                break;

            default:
                var defaultElem = new PieChart();
                ChartElem = defaultElem;
                break;
            }
            //Create the chart and give it a name

            ChartElem.ChartTitle           = Title;
            ChartElem.ChartTitleVisibility = hasTitle ? Visibility.Visible : Visibility.Collapsed;
            ChartElem.ChartSubTitle        = SubTitle;



            //package the data into a custom chart model and series
            SeriesModel vm = new SeriesModel(names.ToList(), listContents.ToList());

            ChartElem.DataContext = vm;


            ChartSeries series = new ChartSeries();

            series.SeriesTitle   = " ";
            series.DisplayMember = "Category";
            series.ValueMember   = "Number";

            //set up the data binding for the series - this is useful so it can be reset later without redrawing the whole Chart
            Binding seriesBinding = new Binding();

            seriesBinding.Source = vm;
            seriesBinding.Path   = new PropertyPath("Chart");
            BindingOperations.SetBinding(series, ChartSeries.ItemsSourceProperty, seriesBinding);



            // series.ItemsSource = vm.Chart;

            //Pass data to the chart
            ChartElem.Series.Add(series);
            ChartElem.ToolTipFormat = "{}Caption: {0}, Value: '{1}', Series: '{2}', Percentage: {3:P2}";


            ChartElem.MinWidth  = 10;
            ChartElem.MinHeight = 10;

            DA.SetData("Chart", new UIElement_Goo(ChartElem, "Chart Elem", InstanceGuid, DA.Iteration));
        }
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            object        GraphObject  = null;
            List <double> listContents = new List <double>();
            List <string> names        = new List <string>();
            string        Title        = null;
            string        SubTitle     = null;

            //Get the Graph object and assign it
            if (!DA.GetData <object>("Graph to modify", ref GraphObject))
            {
                return;
            }
            var ChartElem = HUI_Util.GetUIElement <ChartBase>(GraphObject);


            //set new title and subtitle or get old ones
            if (!DA.GetData <string>("Title", ref Title))
            {
                Title = ChartElem.ChartTitle;
            }
            if (!DA.GetData <string>("SubTitle", ref SubTitle))
            {
                SubTitle = ChartElem.ChartSubTitle;
            }


            //extract existing data from graph element
            SeriesModel dataExtractor = new SeriesModel();
            ChartSeries series        = ChartElem.Series[0];

            dataExtractor.Chart = series.ItemsSource as ObservableCollection <ChartItem>;

            //if the data isnt supplied get it from old graph
            if (!DA.GetDataList <double>("New Pie Graph Values", listContents))
            {
                for (int i = 0; i < dataExtractor.Chart.Count; i++)
                {
                    listContents.Add(dataExtractor.Chart[i].Number);
                }
            }

            //if the data isnt supplied get it from old graph
            if (!DA.GetDataList <string>("New Pie Graph Names", names))
            {
                for (int i = 0; i < dataExtractor.Chart.Count; i++)
                {
                    names.Add(dataExtractor.Chart[i].Category);
                }
            }



            //make sure there are the same number of names and values
            if (names.Count != listContents.Count)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "different number of names and values supplied");
            }


            //reconstruct graph data
            SeriesModel vm = new SeriesModel(names.ToList(), listContents.ToList());

            //assign new values back to graph
            series.ItemsSource      = vm.Chart;
            ChartElem.ChartTitle    = Title;
            ChartElem.ChartSubTitle = SubTitle;



            //DA.SetData("TEST", new UIElement_Goo(ChartElem, "Chart Elem", InstanceGuid, DA.Iteration));
        }
Ejemplo n.º 4
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            object ChartObject = null;
            GH_Structure <GH_Number> NewValueTree = new GH_Structure <GH_Number>();
            List <string>            names        = new List <string>();
            string        Title        = "";
            string        SubTitle     = "";
            List <string> Clustertitle = new List <string>();

            //Get the Chart object and assign it
            if (!DA.GetData <object>("Chart to modify", ref ChartObject))
            {
                return;
            }
            var ChartElem = HUI_Util.GetUIElement <ChartBase>(ChartObject);


            //set new title and subtitle or get old ones
            if (DA.GetData <string>("Title", ref Title))
            {
                ChartElem.ChartTitleVisibility = System.Windows.Visibility.Visible;
                ChartElem.ChartTitle           = Title;
            }
            if (DA.GetData <string>("SubTitle", ref SubTitle))
            {
                ChartElem.ChartSubTitle = SubTitle;
            }

            bool ClusterTitleSupplied = DA.GetDataList <string>("ClusterTitle", Clustertitle);

            bool valuesSupplied = DA.GetDataTree <GH_Number>("New Chart Values", out NewValueTree);

            bool namesSupplied = DA.GetDataList <string>("New Chart Names", names);


            //   MultiChartModel mcm = ChartElem.DataContext as MultiChartModel;

            //check if the cluster titles have changed to avoid unnecessary full redraws.
            bool clusterTitleChanged = false;

            if (ClusterTitleSupplied)
            {
                var alreadyClusterTitles = ChartElem.Series.Select(s => s.SeriesTitle).ToArray();
                if (Clustertitle.Count() != alreadyClusterTitles.Length)
                {
                    clusterTitleChanged = true;
                }
                else
                {
                    for (int i = 0; i < alreadyClusterTitles.Length; i++)
                    {
                        if (alreadyClusterTitles[i] != Clustertitle[i])
                        {
                            clusterTitleChanged = true;
                            break;
                        }
                    }
                }
            }


            //check if the names array is different. We don't want to fire a full update unless we absolutely have to.
            bool haveNamesChanged = false;
            var  firstModel       = ChartElem.Series[0].DataContext as SeriesModel;
            var  alreadyNames     = firstModel.Chart.Select(item => item.Category).ToArray();

            if (namesSupplied)
            {
                //if the length of names is different, we know it's changed
                if (alreadyNames.Length != names.Count())
                {
                    haveNamesChanged = true;
                }
                else //if the length is the same, check each item
                {
                    for (int i = 0; i < alreadyNames.Count(); i++)
                    {
                        if (alreadyNames[i] != names[i])
                        {
                            haveNamesChanged = true;
                            break;
                        }
                    }
                }
            }
            else
            {
                names = alreadyNames.ToList();
            }

            bool removedCharts = false;

            //Remove extra data
            if (NewValueTree.Branches.Count < ChartElem.Series.Count())
            {
                removedCharts = true;
                for (int k = ChartElem.Series.Count() - 1; k >= NewValueTree.Branches.Count; k--)
                {
                    ChartElem.Series.RemoveAt(k);
                }
            }

            bool addedCharts = false;


            for (int j = 0; j < NewValueTree.Branches.Count; j++)
            {
                List <Double> valueList = NewValueTree.Branches[j].Select(n => n.Value).ToList();

                //modify existing series
                if (ChartElem.Series.Count > j)
                {
                    var ChartSeries = ChartElem.Series[j];
                    var model       = ChartSeries.DataContext as SeriesModel;

                    if (ClusterTitleSupplied)
                    {
                        ChartSeries.SeriesTitle = Clustertitle[j];
                    }


                    //make sure there are the same number of names and values
                    if (valuesSupplied && namesSupplied && (names.Count != valueList.Count))
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Different number of names and values supplied.");
                        return;
                    }

                    //if the data isnt supplied modify it
                    if (valuesSupplied)
                    {
                        //replace the ones already in there
                        for (int i = 0; i < model.Chart.Count; i++)
                        {
                            if (valueList.Count > i)
                            {
                                model.Chart[i].Number = (float)valueList[i];
                            }
                        }
                        //add any on the end
                        if (valueList.Count > model.Chart.Count)
                        {
                            for (int i = model.Chart.Count; i < valueList.Count; i++)
                            {
                                model.Chart.Add(new ChartItem()
                                {
                                    Number = (float)valueList[i], Category = "UNSET"
                                });
                            }
                        }

                        //subtract any off the end
                        if (valueList.Count < model.Chart.Count)
                        {
                            for (int i = model.Chart.Count - 1; i >= valueList.Count; i--)
                            {
                                model.Chart.RemoveAt(i);
                            }
                        }
                    }


                    //if the data is supplied and different than what's in the chart, modify it
                    if (namesSupplied && haveNamesChanged)
                    {
                        //replace the ones already in there
                        for (int i = 0; i < model.Chart.Count; i++)
                        {
                            if (names.Count > i)
                            {
                                model.Chart[i].Category = names[i];
                            }
                        }
                        //add any on the end
                        if (names.Count > model.Chart.Count)
                        {
                            for (int i = model.Chart.Count; i < names.Count; i++)
                            {
                                model.Chart.Add(new ChartItem()
                                {
                                    Category = names[i], Number = float.NaN
                                });
                            }
                        }

                        //subtract any off the end
                        if (names.Count < model.Chart.Count)
                        {
                            for (int i = model.Chart.Count - 1; i >= names.Count; i--)
                            {
                                model.Chart.RemoveAt(i);
                            }
                        }
                    }
                    if (haveNamesChanged || clusterTitleChanged)
                    {
                        //refresh display - the binding works when the values change but not when categories do.
                        var Values = model.Chart.ToArray();

                        model.Chart.Clear();

                        foreach (var item in Values)
                        {
                            model.Chart.Add(item);
                        }
                    }
                }
                else
                {
                    addedCharts = true;
                    //Add new series
                    SeriesModel vm = new SeriesModel(names.ToList(), valueList);



                    ChartSeries series = new ChartSeries();
                    //We have to set the series data context rather than the whole chart
                    series.DataContext = vm;

                    series.SeriesTitle   = Clustertitle[j];
                    series.DisplayMember = "Category";
                    series.ValueMember   = "Number";

                    Binding seriesBinding = new Binding();
                    seriesBinding.Source = vm;
                    seriesBinding.Path   = new PropertyPath("Chart");
                    BindingOperations.SetBinding(series, ChartSeries.ItemsSourceProperty, seriesBinding);

                    ChartElem.Series.Add(series);
                }
            }



            if (addedCharts || removedCharts)
            {
                var oldSeries = ChartElem.Series;
                ChartElem.SeriesSource = null;
                //  ChartElem.Series.Clear();
                ChartElem.SeriesSource = oldSeries;
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            var                      Collection   = new ObservableCollection <ChartItem>();
            string                   Title        = "";
            string                   SubTitle     = "";
            List <string>            Clustertitle = new List <string>();
            GH_Structure <GH_Number> treeValues   = new GH_Structure <GH_Number>();
            //GH_Structure<GH_String> treeNames = new GH_Structure<GH_String>();
            List <string> names     = new List <string>();
            int           chartType = 0;

            //get GH input data
            bool hasTitle = DA.GetData <string>("Title", ref Title);

            DA.GetData <string>("SubTitle", ref SubTitle);
            DA.GetDataList <string>("ClusterTitle", Clustertitle);
            DA.GetDataTree <GH_Number>("Data", out treeValues);
            //DA.GetDataTree<GH_String>("Names", out treeNames);
            DA.GetDataList <string>("Names", names);

            DA.GetData <int>("Chart Type", ref chartType);
            ChartBase ChartElem = null;

            switch (chartType)
            {
            case 0:
                var ColumnCluster = new ClusteredColumnChart();
                ChartElem = ColumnCluster;
                break;

            case 1:
                var BarCluster = new ClusteredBarChart();
                ChartElem = BarCluster;
                break;

            case 2:
                var ColumnStack = new StackedColumnChart();
                ChartElem = ColumnStack;
                break;

            case 3:
                var BarStack = new StackedBarChart();
                ChartElem = BarStack;
                break;

            case 4:
                var pieElem = new PieChart();
                ChartElem = pieElem;

                break;

            default:
                var defaultElem = new ClusteredBarChart();
                ChartElem = defaultElem;
                break;
            }

            //Give the chart its name

            ChartElem.ChartTitle    = Title;
            ChartElem.ChartSubTitle = SubTitle;

            // MultiChartModel mcm = new MultiChartModel();
            // mcm.Series = new ObservableCollection<SeriesModel>();


            for (int i = 0; i < treeValues.Branches.Count; i++)
            {
                //package the data into a custom chart model and series
                List <double> listDouble = treeValues[i].ConvertAll(x => x.Value);
                SeriesModel   vm         = new SeriesModel(names.ToList(), listDouble, Clustertitle[i]);



                ChartSeries series = new ChartSeries();
                //We have to set the series data context rather than the whole chart
                series.DataContext = vm;

                series.SeriesTitle   = Clustertitle[i];
                series.DisplayMember = "Category";
                series.ValueMember   = "Number";

                Binding seriesBinding = new Binding();
                seriesBinding.Source = vm;
                seriesBinding.Path   = new PropertyPath("Chart");
                BindingOperations.SetBinding(series, ChartSeries.ItemsSourceProperty, seriesBinding);

                ChartElem.Series.Add(series);
                //Pass data to the chart
                //  mcm.Series.Add(vm);
            }

            //Binding seriesSetBinding = new Binding();
            //seriesSetBinding.Source = mcm;
            //seriesSetBinding.Path = new PropertyPath("Series");
            //BindingOperations.SetBinding(ChartElem, ChartBase.SeriesSourceProperty, seriesSetBinding);



            ////Send Data to GH output
            DA.SetData("MultiChart", new UIElement_Goo(ChartElem, "Chart Elem", InstanceGuid, DA.Iteration));
            //  DA.SetData("Test","listNames");
        }