// Create chart. public void CreateChart() { // Create chart. _chart = new LightningChartUltimate(); // Set chart control into the parent container. _chart.Parent = this; _chart.Dock = DockStyle.Fill; // Disable rendering before updating chart properties to improve performance // and to prevent unnecessary chart redrawing while changing multiple properties. _chart.BeginUpdate(); // Set a LegendBox into a chart with vertical layout. _chart.ViewXY.LegendBoxes[0].Layout = LegendBoxLayout.Vertical; // Configure X- and Y-axis. var axisX = _chart.ViewXY.XAxes[0]; var axisY = _chart.ViewXY.YAxes[0]; axisX.Title.Text = "X-Axis Position"; axisX.SetRange(MinX, MaxX); axisY.Title.Text = "Y-Axis Position"; axisY.SetRange(MinY, MaxY); // 1. Create a Heat Map instance as IntensityGridSeries. _heatMap = new IntensityGridSeries(_chart.ViewXY, axisX, axisY); // Set Heat Map's contents and properties. _heatMap.LegendBoxUnits = "°C"; _heatMap.Title.Text = "Heat Map"; _heatMap.MouseInteraction = false; _heatMap.PixelRendering = false; _heatMap.SetRangesXY(MinX, MaxX, MinY, MaxY); _heatMap.SetSize(_columns, _rows); // Create a ValueRangePalette to present Heat Map's data. if (_heatMap.ValueRangePalette != null) { _heatMap.ValueRangePalette.Dispose(); } _heatMap.ValueRangePalette = CreatePalette(_heatMap); // Add Heat Map to chart. _chart.ViewXY.IntensityGridSeries.Add(_heatMap); // Auto-scale X- and Y-axes. _chart.ViewXY.ZoomToFit(); #region Hidden polishing // Customize chart. CustomizeChart(_chart); #endregion // Call EndUpdate to enable rendering again. _chart.EndUpdate(); }
/// <summary> /// 输入数据 /// </summary> /// <param name="yValuesData"></param> /// <param name="channelIndex">频道索引</param> /// <param name="rowCount"></param> public void SetData(double[][][] yValuesData, int channelIndex, int rowCount) { if (_chart == null) { return; } _chart.BeginUpdate(); for (int row = 0; row < rowCount; row++) { double[] yValues = yValuesData[row][channelIndex]; //Only accept resolution count of data points Array.Resize(ref yValues, m_iSizeResolution); //move the old time slots one step earlier for (int iTimeSlot = 1; iTimeSlot < m_iSizeTimeSlots; iTimeSlot++) { m_aFastData[iTimeSlot - 1] = m_aFastData[iTimeSlot]; //change the reference } m_aFastData[m_iSizeTimeSlots - 1] = yValues; } _grid.InvalidateValuesDataOnly(); double dCurrentTimeMin = m_dCurrentTime - m_dTimeRangeLengthSec; double dTotalTimeShift = m_dStepTime * (double)rowCount; if (m_bIsHorizontalScrolling) { _chart.ViewXY.XAxes[0].SetRange(dCurrentTimeMin + dTotalTimeShift, dCurrentTimeMin + dTotalTimeShift + m_dTimeRangeLengthSec); } else { _chart.ViewXY.YAxes[0].SetRange(dCurrentTimeMin + dTotalTimeShift, dCurrentTimeMin + dTotalTimeShift + m_dTimeRangeLengthSec); } _grid.SetRangesXY(_chart.ViewXY.XAxes[0].Minimum, _chart.ViewXY.XAxes[0].Maximum, _chart.ViewXY.YAxes[0].Minimum, _chart.ViewXY.YAxes[0].Maximum); m_dCurrentTime += dTotalTimeShift; _chart.EndUpdate(); }
public void SetGraphs(LightningChartUltimate throughputGraph, LightningChartUltimate tfGraph, LightningChartUltimate timeGraph, LightningChartUltimate freqGraph) { int i, j; double fstart = _dataFileNode.fstart; double df = _dataFileNode.fs / _dataFileNode.Nfft / 2; float[] maxfreq = _dbClientService.getMaxFrf(_dataFileNode.Id); flen = maxfreq.Length; _throughputGraph = throughputGraph; _tfGraph = tfGraph; _timeGraph = timeGraph; _freqGraph = freqGraph; { _throughputGraph.BeginUpdate(); _throughputGraph.Title.Visible = false; _throughputGraph.ViewXY.LegendBoxes[0].Position = LegendBoxPositionXY.TopRight; _throughputGraph.ViewXY.LegendBoxes[0].Layout = LegendBoxLayout.Vertical; AxisX axisX = _throughputGraph.ViewXY.XAxes[0]; axisX.Title.Text = "时间(s)"; AxisY axisY0 = _throughputGraph.ViewXY.YAxes[0]; axisY0.Title.Text = "声压(Pa)"; AxisY axisY1 = new AxisY(_throughputGraph.ViewXY); axisY1.Title.Text = "总声压级(dBA)"; _throughputGraph.ViewXY.YAxes.Add(axisY1); _maxrmsSeries = new SampleDataSeries(_throughputGraph.ViewXY, axisX, axisY1); _maxrmsSeries.Title.Text = "最大总声压级"; _maxrmsSeries.LineStyle.Color = Colors.Red; _maxrmsSeries.SampleFormat = SampleFormat.SingleFloat; _maxrmsSeries.FirstSampleTimeStamp = _dataFileNode.Nfft / _dataFileNode.fs / 2; _maxrmsSeries.SamplingFrequency = _dataFileNode.fs / _dataFileNode.FrameDN; _throughputGraph.ViewXY.SampleDataSeries.Add(_maxrmsSeries); _rmsSeries = new SampleDataSeries(_throughputGraph.ViewXY, axisX, axisY1); _rmsSeries.Title.Text = "总声压级"; _rmsSeries.LineStyle.Color = Colors.Blue; _rmsSeries.SampleFormat = SampleFormat.SingleFloat; _rmsSeries.FirstSampleTimeStamp = _maxrmsSeries.FirstSampleTimeStamp; _rmsSeries.SamplingFrequency = _maxrmsSeries.SamplingFrequency; _throughputGraph.ViewXY.SampleDataSeries.Add(_rmsSeries); _throughputgraph_verticalCursor = new LineSeriesCursor(_throughputGraph.ViewXY, axisX); _throughputgraph_verticalCursor.Style = CursorStyle.VerticalNoTracking; _throughputgraph_verticalCursor.LineStyle.Color = Colors.White; _throughputgraph_verticalCursor.LineStyle.Pattern = LinePattern.Dot; _throughputgraph_verticalCursor.LineStyle.Width = 3; _throughputgraph_verticalCursor.ValueAtXAxis = 10; _throughputgraph_verticalCursor.MouseHighlight = MouseOverHighlight.None; _throughputGraph.ViewXY.LineSeriesCursors.Add(_throughputgraph_verticalCursor); _throughputSeries = new SampleDataSeries(_throughputGraph.ViewXY, axisX, axisY0); _throughputSeries.Title.Text = "时域"; _throughputSeries.LineStyle.Color = Colors.Orange; _throughputSeries.SampleFormat = SampleFormat.SingleFloat; _throughputSeries.FirstSampleTimeStamp = 0; _throughputSeries.SamplingFrequency = _dataFileNode.fs; _throughputGraph.ViewXY.SampleDataSeries.Add(_throughputSeries); float[] _maxrmsData = new float[_dataFileNode.NFrame]; _rmsData[0].CopyTo(_maxrmsData, 0); for (i = 1; i < _dataFileNode.NFrame; i++) { for (j = 0; j < _dataFileNode.ChannelNum; j++) { if (_rmsData[j][i] > _maxrmsData[i]) { _maxrmsData[i] = _rmsData[j][i]; } } } _maxrmsSeries.SamplesSingle = _maxrmsData; _throughputGraph.EndUpdate(); } { _tfGraph.BeginUpdate(); _tfGraph.Title.Visible = false; //_tfGraph.ViewXY.LegendBoxes[0].Visible = false; _tfGraph.ViewXY.LegendBoxes[0].Position = LegendBoxPositionXY.TopRight; _tfGraph.ViewXY.LegendBoxes[0].ShowCheckboxes = false; AxisX axisX = _tfGraph.ViewXY.XAxes[0]; axisX.Title.Text = "时间(s)"; AxisY axisY = _tfGraph.ViewXY.YAxes[0]; axisY.Title.Text = "频率(Hz)"; _tfSeries = new IntensityGridSeries(_throughputGraph.ViewXY, axisX, axisY); _tfSeries.PixelRendering = true; _tfSeries.ContourLineType = ContourLineTypeXY.None; _tfSeries.ValueRangePalette = CreatePalette(_tfSeries, 20, 100); _tfSeries.SetRangesXY(_dataFileNode.Nfft / _dataFileNode.fs / 2, _dataFileNode.Nfft / _dataFileNode.fs / 2 + (_dataFileNode.NFrame - 1) * _dataFileNode.FrameDN / _dataFileNode.fs, fstart, fstart + (flen - 1) * df); _tfSeries.MouseInteraction = false; _tfSeries.LegendBoxUnits = null; _tfSeries.LegendBoxValuesFormat = "0"; //_tfSeries.Title.Visible = false; _tfSeries.Title.Text = "声压级(dBA)"; _tfGraph.ViewXY.IntensityGridSeries.Add(_tfSeries); _tfgraph_verticalCursor = new LineSeriesCursor(_tfGraph.ViewXY, axisX); _tfgraph_verticalCursor.Style = CursorStyle.VerticalNoTracking; _tfgraph_verticalCursor.LineStyle.Color = Colors.White; _tfgraph_verticalCursor.LineStyle.Pattern = LinePattern.Dot; _tfgraph_verticalCursor.LineStyle.Width = 3; _tfgraph_verticalCursor.ValueAtXAxis = _throughputgraph_verticalCursor.ValueAtXAxis; _tfgraph_verticalCursor.MouseHighlight = MouseOverHighlight.None; _tfGraph.ViewXY.LineSeriesCursors.Add(_tfgraph_verticalCursor); _tfgraph_horizontalCursor = new ConstantLine(_tfGraph.ViewXY, axisX, axisY); _tfgraph_horizontalCursor.LineStyle.Color = Colors.White; _tfgraph_horizontalCursor.LineStyle.Width = 3; _tfgraph_horizontalCursor.LineStyle.Pattern = LinePattern.Dot; _tfgraph_horizontalCursor.Value = 2000; _tfgraph_horizontalCursor.ShowInLegendBox = false; _tfgraph_horizontalCursor.MouseHighlight = MouseOverHighlight.None; _tfGraph.ViewXY.ConstantLines.Add(_tfgraph_horizontalCursor); spectrumCalculator = new SpectrumCalculator(); double[] _aweight = Weight.GetWeightData(FreqWeightType.AWeight, fstart, df, flen); _aweightdb = new double[_aweight.Length]; for (i = 0; i < flen; i++) { _aweightdb[i] = 20 * Math.Log10(_aweight[i] * Math.Sqrt(2) / _dataFileNode.Nfft) + 93.9794;//93.9794为2e-5Pa参考 } fstarti = (int)(fstart / df); ////Configure legend _tfGraph.ViewXY.LegendBoxes[0].IntensityScales.ScaleSizeDim1 = 400; _tfGraph.ViewXY.LegendBoxes[0].Layout = LegendBoxLayout.Horizontal; //_tfGraph.ViewXY.LegendBoxes[0].Offset = new PointIntXY(-15, -70); _tfGraph.ViewXY.LegendBoxes[0].ResetLocation(); _tfGraph.EndUpdate(); } { _timeGraph.BeginUpdate(); _timeGraph.Title.Visible = false; _timeGraph.ViewXY.LegendBoxes[0].Position = LegendBoxPositionXY.TopRight; _timeGraph.ViewXY.LegendBoxes[0].Visible = false; AxisX axisX = _timeGraph.ViewXY.XAxes[0]; axisX.Title.Text = "时间(s)"; AxisY axisY = _timeGraph.ViewXY.YAxes[0]; axisY.Title.Text = "声压(Pa)"; _timegraph_verticalCursor = new LineSeriesCursor(_timeGraph.ViewXY, axisX); _timegraph_verticalCursor.Style = CursorStyle.VerticalNoTracking; _timegraph_verticalCursor.LineStyle.Color = Colors.White; _timegraph_verticalCursor.LineStyle.Pattern = LinePattern.Dot; _timegraph_verticalCursor.LineStyle.Width = 3; _timegraph_verticalCursor.ValueAtXAxis = _dataFileNode.Nfft / _dataFileNode.fs / 2; _timegraph_verticalCursor.MouseHighlight = MouseOverHighlight.None; _timeGraph.ViewXY.LineSeriesCursors.Add(_timegraph_verticalCursor); _timeSeries = new SampleDataSeries(_timeGraph.ViewXY, axisX, axisY); _timeSeries.Title.Text = "时域"; _timeSeries.LineStyle.Color = Colors.Orange; _timeSeries.SampleFormat = SampleFormat.SingleFloat; _timeSeries.FirstSampleTimeStamp = 0; _timeSeries.SamplingFrequency = _dataFileNode.fs; _timeGraph.ViewXY.SampleDataSeries.Add(_timeSeries); _timeGraph.ViewXY.ZoomToFit(); _timeGraph.EndUpdate(); } { _freqGraph.BeginUpdate(); _freqGraph.Title.Visible = false; _freqGraph.ViewXY.LegendBoxes[0].Position = LegendBoxPositionXY.TopRight; _freqGraph.ViewXY.LegendBoxes[0].Layout = LegendBoxLayout.Vertical; AxisX axisX = _freqGraph.ViewXY.XAxes[0]; axisX.Title.Text = "频率(Hz)"; AxisY axisY = _freqGraph.ViewXY.YAxes[0]; axisY.Title.Text = "声压级(dBA)"; _freqgraph_verticalCursor = new LineSeriesCursor(_freqGraph.ViewXY, axisX); _freqgraph_verticalCursor.Style = CursorStyle.VerticalNoTracking; _freqgraph_verticalCursor.LineStyle.Color = Colors.White; _freqgraph_verticalCursor.LineStyle.Pattern = LinePattern.Dot; _freqgraph_verticalCursor.LineStyle.Width = 3; _freqgraph_verticalCursor.ValueAtXAxis = _tfgraph_horizontalCursor.Value; _freqgraph_verticalCursor.MouseHighlight = MouseOverHighlight.None; _freqGraph.ViewXY.LineSeriesCursors.Add(_freqgraph_verticalCursor); _maxfreqSeries = new SampleDataSeries(_freqGraph.ViewXY, axisX, axisY); _maxfreqSeries.Title.Text = "最大值"; _maxfreqSeries.LineStyle.Color = Colors.Red; _maxfreqSeries.SampleFormat = SampleFormat.SingleFloat; _maxfreqSeries.FirstSampleTimeStamp = fstart; _maxfreqSeries.SamplingFrequency = 1 / df; _freqGraph.ViewXY.SampleDataSeries.Add(_maxfreqSeries); _maxfreqSeries.SamplesSingle = maxfreq; _freqSeries = new SampleDataSeries(_freqGraph.ViewXY, axisX, axisY); _freqSeries.Title.Text = "频谱"; _freqSeries.LineStyle.Color = Colors.Orange; _freqSeries.SampleFormat = SampleFormat.DoubleFloat; _freqSeries.FirstSampleTimeStamp = fstart; _freqSeries.SamplingFrequency = 1 / df; _freqGraph.ViewXY.SampleDataSeries.Add(_freqSeries); _freqGraph.ViewXY.ZoomToFit(); _freqGraph.EndUpdate(); } _ShowTimer.Interval = _dataFileNode.FrameDN / _dataFileNode.fs * 1000 / 2; _ShowTimer.Elapsed += _ShowTimer_Elapsed; _tfgraph_verticalCursor.PositionChanged += verticalCursor_PositionChanged; _tfgraph_horizontalCursor.ValueChanged += horizontalCursor_ValueChanged; UpdateChannel(); }
/// <summary> /// 构造 /// </summary> /// <param name="parentControl">父控件</param> /// <param name="verticalScrolling">是否可以垂直滚动</param> /// <param name="resolution">分辨率</param> /// <param name="timeStepMs"></param> /// <param name="timeRangeLengthSec"></param> /// <param name="freqMin">最小频率</param> /// <param name="freqMax">最大频率</param> /// <param name="title">频谱仪标题(未使用)</param> /// <param name="toneColor"></param> public SpectrogramViewXYIntensity(Panel parentControl, bool verticalScrolling, int resolution, double timeStepMs, double timeRangeLengthSec, double freqMin, double freqMax, string title, Color toneColor) { _parentControl = parentControl; double dDefaultYMax = 7000000; double dAxisTimeScaleMin = timeStepMs / 1000.0 - timeRangeLengthSec; double dAxisTimeScaleMax = 0; m_dStepTime = timeStepMs / 1000.0; m_dTimeRangeLengthSec = timeRangeLengthSec; //Create chart LightningChartUltimate chart = new LightningChartUltimate(); _chart = chart; _chart.VerticalAlignment = VerticalAlignment.Top; _chart.HorizontalAlignment = HorizontalAlignment.Left; m_bIsHorizontalScrolling = !verticalScrolling; chart.BeginUpdate(); parentControl.Children.Add(chart); _chart.ChartBackground.Color = ChartTools.CalcGradient(toneColor, Colors.Black, 65); _chart.ChartBackground.GradientDirection = 0; _chart.ChartBackground.GradientFill = GradientFill.Cylindrical; chart.ChartName = "Spectrogram chart"; chart.ViewXY.XAxes = ViewXY.CreateDefaultXAxes(); chart.ViewXY.YAxes = ViewXY.CreateDefaultYAxes(); chart.Title.Visible = false; chart.Title.Font = new WpfFont("Segoe UI", 13, true, false); chart.Title.Offset.SetValues(0, 20); chart.ViewXY.ZoomPanOptions.RightMouseButtonAction = MouseButtonAction.None; chart.ViewXY.ZoomPanOptions.LeftMouseButtonAction = MouseButtonAction.None; chart.ViewXY.ZoomPanOptions.MouseWheelZooming = MouseWheelZooming.Off; //Disable automatic axis layouts chart.ViewXY.AxisLayout.AutoAdjustMargins = false; chart.ViewXY.AxisLayout.XAxisAutoPlacement = XAxisAutoPlacement.Off; chart.ViewXY.AxisLayout.YAxisAutoPlacement = YAxisAutoPlacement.Off; chart.ViewXY.AxisLayout.XAxisTitleAutoPlacement = false; chart.ViewXY.AxisLayout.YAxisTitleAutoPlacement = false; chart.ViewXY.Margins = new Thickness(60, 10, 15, 50); if (m_bIsHorizontalScrolling) { chart.ViewXY.XAxes[0].ValueType = AxisValueType.Time; chart.ViewXY.XAxes[0].Title.Text = "Time"; chart.ViewXY.XAxes[0].SetRange(dAxisTimeScaleMin, dAxisTimeScaleMax); chart.ViewXY.YAxes[0].ValueType = AxisValueType.Number; chart.ViewXY.YAxes[0].Title.Text = "Frequency(Hz)"; chart.ViewXY.YAxes[0].SetRange(freqMin, freqMax); } else { chart.ViewXY.XAxes[0].ValueType = AxisValueType.Number; chart.ViewXY.XAxes[0].Title.Text = "Frequency(Hz)"; chart.ViewXY.XAxes[0].SetRange(freqMin, freqMax); chart.ViewXY.YAxes[0].ValueType = AxisValueType.Time; chart.ViewXY.YAxes[0].Title.Text = "Time"; chart.ViewXY.YAxes[0].SetRange(dAxisTimeScaleMin, dAxisTimeScaleMax); } m_dCurrentTime = dAxisTimeScaleMax; Color color = Colors.White; chart.ViewXY.XAxes[0].MinorDivTickStyle.Visible = false; chart.ViewXY.XAxes[0].LabelsColor = Color.FromArgb(200, color.R, color.G, color.B); chart.ViewXY.XAxes[0].MajorDivTickStyle.Color = Colors.Orange; chart.ViewXY.XAxes[0].Title.Shadow.Style = TextShadowStyle.Off; chart.ViewXY.XAxes[0].LabelsNumberFormat = "0"; chart.ViewXY.YAxes[0].MinorDivTickStyle.Visible = false; chart.ViewXY.YAxes[0].LabelsColor = Color.FromArgb(200, color.R, color.G, color.B); chart.ViewXY.YAxes[0].MajorDivTickStyle.Color = Colors.Orange; chart.ViewXY.YAxes[0].Title.Shadow.Style = TextShadowStyle.Off; chart.ViewXY.YAxes[0].LabelsNumberFormat = "0"; //Setup legend box chart.ViewXY.LegendBoxes = ViewXY.CreateDefaultLegendBoxes(); chart.ViewXY.LegendBoxes[0].SeriesTitleColor = toneColor; chart.ViewXY.LegendBoxes[0].ValueLabelColor = Colors.White; chart.ViewXY.LegendBoxes[0].IntensityScales.ScaleBorderColor = Colors.White; chart.ViewXY.LegendBoxes[0].Position = LegendBoxPositionXY.RightCenter; chart.ViewXY.LegendBoxes[0].Layout = LegendBoxLayout.Vertical; chart.ViewXY.LegendBoxes[0].Offset.SetValues(-20, 0); chart.ViewXY.LegendBoxes[0].Fill.Style = RectFillStyle.None; chart.ViewXY.LegendBoxes[0].Shadow.Visible = false; chart.ViewXY.LegendBoxes[0].BorderWidth = 0; chart.ViewXY.LegendBoxes[0].IntensityScales.ScaleSizeDim1 = 100; chart.ViewXY.LegendBoxes[0].IntensityScales.ScaleSizeDim2 = 15; chart.ViewXY.LegendBoxes[0].ShowCheckboxes = false; chart.ViewXY.LegendBoxes[0].UnitsColor = Colors.Transparent; chart.Name = "Spectrogram"; //Create grid _grid = new IntensityGridSeries(chart.ViewXY, chart.ViewXY.XAxes[0], chart.ViewXY.YAxes[0]); chart.ViewXY.IntensityGridSeries.Add(_grid); m_iSizeTimeSlots = (int)Math.Round(timeRangeLengthSec / (timeStepMs / 1000.0)); m_iSizeResolution = resolution; m_aFastData = new double[m_iSizeTimeSlots][]; for (int iTimeSlot = 0; iTimeSlot < m_iSizeTimeSlots; iTimeSlot++) { m_aFastData[iTimeSlot] = new double[m_iSizeResolution]; } if (m_bIsHorizontalScrolling) { _grid.SetValuesData(m_aFastData, IntensityGridValuesDataOrder.ColumnsRows); } else { _grid.SetValuesData(m_aFastData, IntensityGridValuesDataOrder.RowsColumns); } _grid.Data = null; _grid.SetRangesXY(chart.ViewXY.XAxes[0].Minimum, chart.ViewXY.XAxes[0].Maximum, chart.ViewXY.YAxes[0].Minimum, chart.ViewXY.YAxes[0].Maximum); _grid.ContourLineType = ContourLineTypeXY.None; _grid.WireframeType = SurfaceWireframeType.None; _grid.PixelRendering = true; _grid.MouseInteraction = false; _grid.ValueRangePalette = CreatePalette(_grid, dDefaultYMax); _grid.Title.Text = "P(f)"; chart.EndUpdate(); }