public void TestConstruction()
 {
     SparklineStats point = new SparklineStats(new List<string>());
     Assert.IsNotNull(point.ComparatorValues);
 }
        public List<SparklineRoot> BuildRoots(string parentAreaCode, int areaTypeId,
            int profileId, int groupId, IList<string> dataTypes, int sexId)
        {
            var groupIds = profileReader.GetProfile(profileId).GroupIds;

            IList<IArea> childAreas = areasReader
                .GetChildAreas(parentAreaCode, areaTypeId).Cast<IArea>().ToList();
            childAreas = IgnoredAreasFilterFactory.New(profileId).RemoveAreasIgnoredEverywhere(childAreas).ToList();

            ComparatorMap comparatorMap = new ComparatorMapBuilder(new ParentArea(parentAreaCode, areaTypeId)).ComparatorMap;
            var parentArea = AreaFactory.NewArea(areasReader,parentAreaCode);
            parentCoreDataSetProvider = new CoreDataSetProviderFactory().New(parentArea);
            var nationalArea = AreaFactory.NewArea(areasReader, AreaCodes.England);
            nationalCoreDataSetProvider = new CoreDataSetProviderFactory().New(nationalArea);

            // Get grouping for time info
            IList<int> indicatorIds = groupDataReader.GetIndicatorIdsByGroupIdAndAreaTypeId(groupId, areaTypeId);

            DoubleOverlappingCIsComparer comparer = new DoubleOverlappingCIsComparer();
            IndicatorMetadataRepository repository = IndicatorMetadataRepository.Instance;

            List<SparklineRoot> roots = new List<SparklineRoot>();

            foreach (var indicatorId in indicatorIds)
            {
                var grouping = GetGrouping(groupIds, indicatorId, areaTypeId, sexId);

                IndicatorMetadata metadata = repository.GetIndicatorMetadata(grouping);

                IList<TimePeriod> timePeriods = grouping.GetTimePeriodIterator(metadata.YearType).TimePeriods;

                SparklineRoot root = new SparklineRoot();
                roots.Add(root);

                List<ValueWithCIsData> allData = new List<ValueWithCIsData>();

                foreach (IArea area in childAreas)
                {
                    SparklineArea sparklineArea = new SparklineArea();
                    int startingAllDataCount = allData.Count;

                    foreach (TimePeriod timePeriod in timePeriods)
                    {
                        SparklineTimePoint timePoint = new SparklineTimePoint();
                        sparklineArea.TimePoints.Add(timePoint);

                        foreach (string dataType in dataTypes)
                        {
                            var data = GetData(area, dataType, grouping, timePeriod, allData);
                            timePoint.Data.Add(dataType, data);
                        }

                        // Are different? (comparatorId=10 “Within area 80/20 by deprivation”)
                        if (timePoint.Data.Count > 0)
                        {
                            ValueWithCIsData p1 = timePoint.Data[dataTypes[0]];
                            ValueWithCIsData p2 = timePoint.Data[dataTypes[1]];

                            Significance sig = comparer.Compare(p1, p2, metadata);
                            timePoint.AreDifferent = sig == Significance.Better || sig == Significance.Worse;
                        }
                    }

                    // Do not include areas with no data
                    if (allData.Count > startingAllDataCount)
                    {
                        root.AreaData.Add(area.Code, sparklineArea);
                    }
                }

                // Add statsPercentiles
                if (allData.Count > 0)
                {
                    IndicatorStatsPercentiles statsPercentiles = new IndicatorStatsPercentiles
                    {
                        Min = (from d in allData select d.LowerCI).Min<double>(),
                        Max = (from d in allData select d.UpperCI).Max<double>()
                    };

                    var builder = new TimePeriodTextListBuilder(metadata);
                    builder.AddRange(timePeriods);
                    IList<string> xLabels = builder.GetTimePeriodStrings();

                    SparklineStats sparklineStats = new SparklineStats(xLabels);
                    sparklineStats.IndicatorId = grouping.IndicatorId;
                    sparklineStats.Limits = new MinMaxRounder(statsPercentiles.Min, statsPercentiles.Max).Limits;
                    root.Stats = sparklineStats;

                    // Format
                    NumericFormatter formatter = NumericFormatterFactory.NewWithLimits(metadata, statsPercentiles);
                    new ValueWithCIsDataProcessor(formatter).FormatAndTruncateList(allData);

                    // Add comparator data
                    foreach (var comparator in comparatorMap.Comparators)
                    {
                        List<string> values = GetFormattedComparatorValues(timePeriods, metadata, grouping, formatter,
                            comparator.ComparatorId);
                        sparklineStats.ComparatorValues.Add(comparator.ComparatorId, values);
                    }
                }
            }

            return roots;
        }