/// <summary> /// Builds the table response data object recursively. /// </summary> /// <param name="model"></param> /// <param name="formatter"></param> /// <param name="varIdx"></param> /// <param name="row"></param> /// <param name="response"></param> /// <param name="key"></param> private void Build(PXModel model, DataFormatter formatter, int varIdx, ref int row, TableResponse response, List <string> key) { foreach (var value in model.Meta.Stub[varIdx].Values) { if (varIdx + 1 < model.Meta.Stub.Count) { // Continue building Build(model, formatter, varIdx + 1, ref row, response, new List <string>(key) { value.Code }); } else { // No more variables. Output key and data var data = new TableResponseData { Key = new List <string>(key) { value.Code } }; for (int col = 0; col < model.Data.MatrixColumnCount; col++) { data.Values.Add(formatter.ReadElement(row, col)); } response.Data.Add(data); row++; } } }
private void WriteDataLine(System.IO.StreamWriter wr, PCAxis.Paxiom.PXModel model, System.Globalization.CultureInfo ci, int precision, int row) { string value; string n = String.Empty; string dataNote = String.Empty; PCAxis.Paxiom.PXData data = model.Data; for (int c = 0; (c <= (data.MatrixColumnCount - 1)); c++) { wr.Write("<td>"); value = _fmt.ReadElement(row, c, ref n, ref dataNote); wr.Write(value); wr.WriteLine("</td>"); } }
private void ExtractValueAndStatus(PXModel model, out double?[] value, out Dictionary <int, string> status) { int matrixSize = model.Data.MatrixColumnCount * model.Data.MatrixRowCount; value = new double?[matrixSize]; var buffer = new double[model.Data.MatrixColumnCount]; var dataSymbolMap = BuildDataSymbolMap(model.Meta); var formatter = new DataFormatter(model); string note = string.Empty; string dataNote = string.Empty; status = new Dictionary <int, string>(); int n = 0; var numberFormatInfo = new System.Globalization.NumberFormatInfo(); for (int i = 0; i < model.Data.MatrixRowCount; i++) { model.Data.ReadLine(i, buffer); for (int j = 0; j < model.Data.MatrixColumnCount; j++) { string symbol = null; if (dataSymbolMap.TryGetValue(buffer[j], out symbol)) { value[n] = null; status.Add(n, symbol); } else { value[n] = Convert.ToDouble(formatter.ReadElement(i, j, ref note, ref dataNote, ref numberFormatInfo), numberFormatInfo); if (!string.IsNullOrEmpty(dataNote)) { status.Add(n, dataNote); } } n++; } } }
private string GenerateJsonData(PXModel model) { meta = model.Meta; BuildDataSymbolMap(); var jsonResult = new JsonStat.Model.JsonStat(); var dataset = new JsonStat.Model.JsonStatDatasetBase(model.Data.MatrixSize); var formatter = new DataFormatter(model); dataset.source = meta.Source; if (model.Meta.ContentVariable != null && model.Meta.ContentVariable.Values.Count > 0) { var lastUpdatedContentsVariable = model.Meta.ContentVariable.Values.OrderByDescending(x => x.ContentInfo.LastUpdated).FirstOrDefault(); dataset.updated = lastUpdatedContentsVariable.ContentInfo.LastUpdated.PxDateStringToDateTime().ToString(); } else { dataset.updated = model.Meta.CreationDate.PxDateStringToDateTime().ToString(); } dataset.dimension = new Dictionary <string, object>(); //Extension, PX if (meta.InfoFile != null || meta.TableID != null || meta.Decimals != -1) { dataset.extension = new Dictionary <string, object>(); var px = new JsonStat.Model.JsonStatPx(); px.infofile = meta.InfoFile; px.tableid = meta.TableID; //If not Showdecimal has value use Decimal var decimals = meta.ShowDecimals < 0 ? meta.Decimals : meta.ShowDecimals; px.decimals = decimals; dataset.extension.Add(PX, px); } if (DatasetTitle != null) { dataset.label = DatasetTitle; } else { dataset.label = meta.Title; } var roles = new Model.JsonStatDimension(); var id = new string[meta.Variables.Count]; var size = new int[meta.Variables.Count]; var variableIndex = 0; #region Variables foreach (var variable in meta.Variables) { var variableName = variable.Code; var category = new Dictionary <string, object>(); var index = new Dictionary <string, int>(); var label = new Dictionary <string, string>(); var variableEntry = new Dictionary <string, object>(); var unit = new Dictionary <string, object>(); var link = new Dictionary <string, object>(); if (variable.IsContentVariable) { // The reason roles are an array, is that it's possible to have several time-variables (in theory) roles.Add(METRIC, variableName); } else if (variable.IsTime) { roles.Add(TIME, variableName); } // Adding regional variables to the geo-field. if (variable.Map != null || geoVariableMap.ContainsKey(variableName)) { roles.Add(GEO, variableName); } id[variableIndex] = variableName; size[variableIndex] = variable.Values.Count; variableIndex++; var variableValueIndex = 0; foreach (var value in variable.Values) { index.Add(value.Code, variableValueIndex); label.Add(value.Code, value.Value); if (variable.IsContentVariable) { var unitContent = new Dictionary <string, object>(); unitContent.Add(BASE, value.ContentInfo.Units); //If not Showdecimal has value use Decimal var currentDecimal = meta.ShowDecimals < 0 ? meta.Decimals : meta.ShowDecimals; var decimals = (value.HasPrecision()) ? value.Precision : currentDecimal; unitContent.Add(DECIMALS, decimals); unit.Add(value.Code, unitContent); } variableValueIndex++; } category.Add(INDEX, index); category.Add(LABEL, label); if (variable.IsContentVariable) { category.Add(UNIT, unit); } variableEntry.Add(LABEL, variable.Name); variableEntry.Add(CATEGORY, category); var extensions = GetAllSerializedMetaIdsForVariable(variable); if (extensions.Count > 0) { link.Add(DESCRIBEDBY, new List <object> { extensions }); variableEntry.Add(LINK, link); } dataset.dimension.Add(variableName, variableEntry); } #endregion dataset.dimension.Add(ID, id); dataset.dimension.Add(SIZE, size); dataset.dimension.Add(ROLE, roles); // All data is in a single array in JSON-stat. #region Data var haveObsStatus = false; var observationStatus = new Dictionary <string, string>(); var bufferIndex = 0; var buffer = new double[model.Data.MatrixColumnCount]; string note = string.Empty; string dataNote = string.Empty; var numberFormatInfo = new System.Globalization.NumberFormatInfo(); for (int i = 0; i < model.Data.MatrixRowCount; i++) { model.Data.ReadLine(i, buffer); for (int j = 0; j < model.Data.MatrixColumnCount; j++) { string symbol = null; if (dataSymbolMap.TryGetValue(buffer[j], out symbol)) { observationStatus.Add(bufferIndex.ToString(), symbol); haveObsStatus = true; dataset.value[bufferIndex] = null; } else { dataset.value[bufferIndex] = Convert.ToDouble(formatter.ReadElement(i, j, ref note, ref dataNote, ref numberFormatInfo), numberFormatInfo); if (!string.IsNullOrEmpty(dataNote)) { observationStatus.Add(bufferIndex.ToString(), dataNote); haveObsStatus = true; } } bufferIndex++; } } if (!haveObsStatus) { jsonResult.dataset = dataset; } else { var datasetEx = new Model.JsonStatDatasetExtended(model.Data.MatrixSize); // Copy values from the baseobject to the extended object. And add observation status. datasetEx.dimension = dataset.dimension; datasetEx.label = dataset.label; datasetEx.source = dataset.source; datasetEx.updated = dataset.updated; datasetEx.value = dataset.value; datasetEx.status = observationStatus; jsonResult.dataset = datasetEx; } #endregion // override converter to stop adding ".0" after interger values. string result = JsonConvert.SerializeObject(jsonResult, new DecimalJsonConverter()); return(result); }
/// <summary> /// Creates a DataTable from a PXModel instance. /// </summary> /// <param name="px"></param> /// <param name="addExtraInfoColumns">Include columns with info about codes and texts (default is false)</param> /// <param name="storeDataAsFormattedString">Whether to store data as a formatted string according to the rules in the model - if not the value is converted back to Double (default is false)</param> /// <returns></returns> //public static DataTable AsDataTable(this PXModel px, bool showValues = true, bool showCodes = false, bool addExtraInfoColumns = false) //TODO: 4.0: Implement defaults when migrating to 4.0 public static DataTable AsDataTable(this PXModel px, bool addExtraInfoColumns, bool storeDataAsFormattedString) { if (!px.IsComplete) { throw new PxExtendExceptions.ModelNotReadyException("PXModel must be complete before converting it."); } if (px.Meta.GetPreferredLanguage() == null) { px.Meta.SetPreferredLanguage(px.Meta.Language); } List <Variable> variables = px.Meta.Variables; DataTable table = new DataTable(); table.Columns.AddRange( ( from v in variables select new DataColumn(v.Name) ).ToArray() ); table.Columns.Add( new DataColumn("DATA") ); if (addExtraInfoColumns) { table.Columns.AddRange( new DataColumn[] { new DataColumn("CODES"), new DataColumn("TEXT") } ); } int rows = 1; foreach (Variable variable in variables) { rows *= variable.Values.Count; } for (int i = 0; i < rows; i++) { table.Rows.Add(table.NewRow()); } int repeat = 1; for (int c = variables.Count - 1; c >= 0; c--) { Value[] data = px.expandVariable(variables[c], rows, repeat); for (int r = 0; r < rows; r++) { table.Rows[r][c] = data[r].Text ?? data[r].Value; if (addExtraInfoColumns) { table.Rows[r][variables.Count + 1] = variables[c].Name + "|" + (data[r].Code ?? data[r].Text) + (c < variables.Count - 1 ? "||" : "") + table.Rows[r][variables.Count + 1]; table.Rows[r][variables.Count + 2] = data[r].Text + (c < variables.Count - 1 ? ", " : "") + table.Rows[r][variables.Count + 2]; } } repeat *= variables[c].Values.Count; } DataFormatter df = new DataFormatter(px); NumberFormatInfo format = new NumberFormatInfo() { NumberGroupSeparator = df.ThousandSeparator, NumberDecimalSeparator = df.DecimalSeparator }; int counter = 0; for (int r = 0; r < px.Data.MatrixRowCount; r++) { for (int c = 0; c < px.Data.MatrixColumnCount; c++) { if (storeDataAsFormattedString) { table.Rows[counter++][variables.Count] = df.ReadElement(r, c); } else { double d; bool parseSuccess = Double.TryParse( df.ReadElement(r, c), NumberStyles.Number, format, out d ); if (parseSuccess) { table.Rows[counter++][variables.Count] = d; } else { table.Rows[counter++][variables.Count] = df.ReadElement(r, c); } } } } return(table); }
public static GenericDataType createGenericData(PXModel model) { DataSetType ds = new DataSetType(); ds.KeyFamilyRef = model.Meta.Matrix.CleanID(); DataIndexer di = new DataIndexer(model.Meta); // Get all table level notes (this includes notes for variables) List <AnnotationType> dsAnnotations = new List <AnnotationType>(); if (model.Meta.Notes != null) { dsAnnotations.AddRange(model.Meta.Notes.ToSDMXAnnotation()); } foreach (Variable var in model.Meta.Stub) { if (var.Notes != null) { dsAnnotations.AddRange(var.Notes.ToSDMXAnnotation()); } } foreach (Variable var in model.Meta.Heading) { if (var.Notes != null) { dsAnnotations.AddRange(var.Notes.ToSDMXAnnotation()); } } if (dsAnnotations.Count > 0) { ds.Annotations = dsAnnotations.ToArray(); } if (model.Meta.ContentVariable == null) { List <org.sdmx.ValueType> dsAtts = new List <org.sdmx.ValueType>(); if (model.Meta.ContentInfo != null) { // Unit of measure { org.sdmx.ValueType att = new org.sdmx.ValueType(); att.concept = "UNIT_MEASURE"; att.value = model.Meta.ContentInfo.Units; dsAtts.Add(att); } // Decimals { org.sdmx.ValueType att = new org.sdmx.ValueType(); att.concept = "DECIMALS"; att.value = model.Meta.Decimals.ToString(); dsAtts.Add(att); } // Stock/flow/average indicator if (model.Meta.ContentInfo.StockFa != null) { org.sdmx.ValueType att = new org.sdmx.ValueType(); att.concept = "SFA_INDICATOR"; att.value = model.Meta.ContentInfo.StockFa; dsAtts.Add(att); } // Seasonal adjustement if (model.Meta.ContentInfo.SeasAdj != null) { org.sdmx.ValueType att = new org.sdmx.ValueType(); att.concept = "SEAS_ADJ"; att.value = model.Meta.ContentInfo.SeasAdj; dsAtts.Add(att); } // Daily adjustment if (model.Meta.ContentInfo.DayAdj != null) { org.sdmx.ValueType att = new org.sdmx.ValueType(); att.concept = "DAY_ADJ"; att.value = model.Meta.ContentInfo.DayAdj; dsAtts.Add(att); } // Base period if (model.Meta.ContentInfo.Baseperiod != null) { org.sdmx.ValueType att = new org.sdmx.ValueType(); att.concept = "BASE_PER"; att.value = model.Meta.ContentInfo.Baseperiod; dsAtts.Add(att); } // Reference period if (model.Meta.ContentInfo.RefPeriod != null) { org.sdmx.ValueType att = new org.sdmx.ValueType(); att.concept = "REF_PERIOD"; att.value = model.Meta.ContentInfo.RefPeriod; dsAtts.Add(att); } // Current / fixed prices if (model.Meta.ContentInfo.CFPrices != null) { org.sdmx.ValueType att = new org.sdmx.ValueType(); att.concept = "PRICE_BASIS"; att.value = model.Meta.ContentInfo.CFPrices; dsAtts.Add(att); } } ds.Attributes = dsAtts.ToArray(); } ds.Items = new Object[model.Data.MatrixRowCount]; for (int i = 0; i < model.Data.MatrixRowCount; i++) { SeriesType series = new SeriesType(); series.SeriesKey = new org.sdmx.ValueType[model.Meta.Stub.Count + 1]; org.sdmx.ValueType key = new org.sdmx.ValueType(); key.concept = "FREQ"; switch (model.Meta.Heading[0].TimeScale) { case TimeScaleType.Annual: key.value = "A"; break; case TimeScaleType.Halfyear: key.value = "B"; break; case TimeScaleType.Monthly: key.value = "M"; break; case TimeScaleType.Quartely: key.value = "Q"; break; case TimeScaleType.Weekly: key.value = "W"; break; default: //TODO break; } series.SeriesKey[0] = key; di.SetContext(i, 0); // Create annotations based on value notes (not variable notes) List <AnnotationType> serAnnotations = new List <AnnotationType>(); for (int j = 0; j < model.Meta.Stub.Count; j++) { key = new org.sdmx.ValueType(); key.concept = model.Meta.Stub[j].Name.CleanID(); key.value = model.Meta.Stub[j].Values[di.StubIndecies[j]].Code.CleanID(); series.SeriesKey[j + 1] = key; if (model.Meta.Stub[j].Values[di.StubIndecies[j]].Notes != null) { serAnnotations.AddRange(model.Meta.Stub[j].Values[di.StubIndecies[j]].Notes.ToSDMXAnnotation()); } } if (serAnnotations.Count > 0) { series.Annotations = serAnnotations.ToArray(); } series.Obs = new ObsType[model.Data.MatrixColumnCount]; //Added code for reading the cellnotes DataFormatter formatter = new DataFormatter(model); for (int j = 0; j < model.Data.MatrixColumnCount; j++) { string notes = null; ObsType obs = new ObsType(); // Set observation time obs.Time = model.Meta.Heading[0].Values[j].ToSDMXTime(); Boolean missing = PXConstant.ProtectedNullValues.Contains(model.Data.ReadElement(i, j)) || PXConstant.ProtectedValues.Contains(model.Data.ReadElement(i, j)); //Create observation status attribute org.sdmx.ValueType status = new org.sdmx.ValueType(); status.concept = "OBS_STATUS"; obs.Attributes = new org.sdmx.ValueType[1]; obs.Attributes[0] = status; // Set observation value and status code if (!missing) { obs.ObsValue = new ObsValueType(); obs.ObsValue.value = model.Data.ReadElement(i, j); obs.ObsValue.valueSpecified = true; status.value = "A"; } else { status.value = "M"; } // Cell notes formatter.ReadElement(i, j, ref notes); if (notes != null && notes.Length != 0) { AnnotationType annotation = new AnnotationType(); List <TextType> annotationText = new List <TextType>(); TextType text = new TextType(); text.lang = "en"; text.Value = notes; annotationText.Add(text); annotation.AnnotationText = annotationText.ToArray(); obs.Annotations = new AnnotationType[1]; obs.Annotations[0] = annotation; } series.Obs[j] = obs; } if (model.Meta.ContentVariable != null) { List <org.sdmx.ValueType> serAtts = new List <org.sdmx.ValueType>(); if (model.Meta.ContentInfo != null) { // Unit of measure { org.sdmx.ValueType att = new org.sdmx.ValueType(); att.concept = "UNIT_MEASURE"; int cIndex = model.Meta.Stub.GetIndexByCode(model.Meta.ContentVariable.Code); att.value = model.Meta.ContentVariable.Values[di.StubIndecies[cIndex]].ContentInfo.Units; serAtts.Add(att); } // Stock/flow/average indicator if (model.Meta.ContentInfo.StockFa != null) { org.sdmx.ValueType att = new org.sdmx.ValueType(); att.concept = "SFA_INDICATOR"; int cIndex = model.Meta.Stub.GetIndexByCode(model.Meta.ContentVariable.Code); att.value = model.Meta.ContentVariable.Values[di.StubIndecies[cIndex]].ContentInfo.StockFa; serAtts.Add(att); } // Seasonal adjustement if (model.Meta.ContentInfo.SeasAdj != null) { org.sdmx.ValueType att = new org.sdmx.ValueType(); att.concept = "SEAS_ADJ"; int cIndex = model.Meta.Stub.GetIndexByCode(model.Meta.ContentVariable.Code); att.value = model.Meta.ContentVariable.Values[di.StubIndecies[cIndex]].ContentInfo.SeasAdj; serAtts.Add(att); } // Daily adjustment if (model.Meta.ContentInfo.DayAdj != null) { org.sdmx.ValueType att = new org.sdmx.ValueType(); att.concept = "DAY_ADJ"; int cIndex = model.Meta.Stub.GetIndexByCode(model.Meta.ContentVariable.Code); att.value = model.Meta.ContentVariable.Values[di.StubIndecies[cIndex]].ContentInfo.DayAdj; serAtts.Add(att); } // Base period if (model.Meta.ContentInfo.Baseperiod != null) { org.sdmx.ValueType att = new org.sdmx.ValueType(); att.concept = "BASE_PER"; int cIndex = model.Meta.Stub.GetIndexByCode(model.Meta.ContentVariable.Code); att.value = model.Meta.ContentVariable.Values[di.StubIndecies[cIndex]].ContentInfo.Baseperiod; serAtts.Add(att); } // Reference period if (model.Meta.ContentInfo.RefPeriod != null) { org.sdmx.ValueType att = new org.sdmx.ValueType(); att.concept = "REF_PERIOD"; int cIndex = model.Meta.Stub.GetIndexByCode(model.Meta.ContentVariable.Code); att.value = model.Meta.ContentVariable.Values[di.StubIndecies[cIndex]].ContentInfo.RefPeriod; serAtts.Add(att); } // Current / fixed prices if (model.Meta.ContentInfo.CFPrices != null) { org.sdmx.ValueType att = new org.sdmx.ValueType(); att.concept = "PRICE_BASIS"; int cIndex = model.Meta.Stub.GetIndexByCode(model.Meta.ContentVariable.Code); att.value = model.Meta.ContentVariable.Values[di.StubIndecies[cIndex]].ContentInfo.CFPrices; serAtts.Add(att); } } series.Attributes = serAtts.ToArray(); } ds.Items[i] = series; } GenericDataType message = new GenericDataType(); message.DataSet = ds; message.Header = createHeader(model, true); return(message); }