public HealthProfilesKeyMessageDataBuilder(IArea area, CoreDataSetProvider coreDataSetProvider,
            CoreDataSetProvider benchmarkDataProvider, IndicatorMetadataCollection indicatorMetadataCollection,
            HealthProfilesGroupRootSelector groupRootSelector)
        {
            _area = area;
            keyMessageData.Area = area;
            this.coreDataSetProvider = coreDataSetProvider;
            this.benchmarkDataProvider = benchmarkDataProvider;
            this.groupRootSelector = groupRootSelector;
            this.indicatorMetadataCollection = indicatorMetadataCollection;

            _indicatorComparerFactory = new IndicatorComparerFactory {PholioReader = pholioReader};
        }
        public HealthProfilesSupportingInformation Build()
        {
            var supportingInformation = new HealthProfilesSupportingInformation
            {
                HealthProfilesData = data,
                HealthProfilesContent = content
            };

            // Init areas
            Area area = areasReader.GetAreaFromCode(areaCode);
            coreDataSetProvider = new CoreDataSetProviderFactory().New(area);
            Area benchmarkArea = areasReader.GetAreaFromCode(benchmarkAreaCode);
            benchmarkDataProvider = new CoreDataSetProviderFactory().New(benchmarkArea);

            // Init data
            var areaTypeId = HealthProfilesAreaTypeHelper.GetCompositeAreaTypeId(area);
            InitSupportingGroupData(areaTypeId);
            InitMainGroupData(areaTypeId);

            // Page 1
            AssignPopulation();
            content.AreaType = AreaTypeLabel.GetLabelFromAreaCode(areaCode);
            AssignKeyMessages(area);

            // Page 2 top
            AssignDeprivationQuintilesPopulation();
            AssignLsoaQuintiles();

            // Page 2 bottom
            AssignLifeExpectancy();
            AssignLifeExpectancyByDeciles();

            // Page 3 top
            AssignEarlyDeathFromAllCauses();
            AssignEarlyDeathCvd();
            AssignEarlyDeathCancer();

            // Page 3 bottom
            AssignHealthInequalitiesEthnicity();

            return supportingInformation;
        }
        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;
        }