데이터 애플리케이션 개발을 위한 현대 WPF UI 컨트롤
소개
지금까지 제 콘텐츠를 따라오셨다면, Windows Presentation Foundation(WPF)을 사용한 프로그래밍 관련 아티클들을 이미 접해 보셨을 것입니다. 각 아티클에서는 WPF 프레임워크, 코드 비하인드(code-behind), 그리고 UI에 대해 간단한 설명을 제공해 왔습니다. 이번 글에서는 이론적인 부분에 조금 더 집중하여, LightningChart .NET의 최신 WPF UI 컨트롤을 사용하는 방법에 대한 기존 지식을 명확히 하고 확장해 보고자 합니다.
LightningChart .NET은 WPF에서 XY 차트를 구현하기 위한 다양한 2D 및 3D 최신 WPF UI 컨트롤과 도구를 제공합니다. 이를 통해 코드 비하인드에서 차트의 콘텐츠를 직접 사용자 정의, 업데이트 또는 수정할 수 있으며, 완전한 객체를 XAML 컴포넌트로 직접 전달할 수 있습니다.
XY 차트는 X축과 Y축을 가지는 2차원 맵으로 정의할 수 있습니다. LightningChart .NET에서는 데이터 시리즈를 추가하기 위해 차트 유형의 객체가 필요합니다. 이 데이터 시리즈는 숫자 값으로 구성된 배열이며, LightningChart에서 지원하는 형식을 충족해야 합니다.
이 배열은 차트에 직접 전달할 수 없으므로, 반드시 시리즈에 할당해야 합니다. 이 시리즈는 라인(line) 또는 포인트-라인(points-lines), 막대(bar), 영역(area), 폴리곤(polygons) 등 다양한 형태가 될 수 있습니다. 아래에서는 LC .NET 최신 WPF UI 컨트롤이 제공하는 각 시리즈 유형과 그 구현을 위한 간단한 코드 예제를 살펴봅니다.
WPF란 무엇인가요?
Windows Presentation Foundation(WPF)는 Windows 데스크톱 애플리케이션을 개발하기 위한 프레임워크입니다. WPF는 드래그, 사용자 정의, 설정이 가능한 컴포넌트들을 활용하여 2D 및 3D 그래픽을 지원하는 그래픽 인터페이스를 생성할 수 있는 기능을 제공합니다. 이러한 작업은 XAML 언어를 통해 인터랙티브하게 또는 코드로 구성할 수 있습니다. WPF는 애플리케이션을 구축하는 데 사용할 수 있는 다양한 도구와 컴포넌트 패널을 포함한 인터랙티브 프레임워크를 제공합니다.
XAML은 eXtensible Application Markup Language의 약자로, UWP나 Xamarin과 같은 Microsoft 기술에서 주로 사용되는 언어입니다. HTML을 사용해 본 경험이 있다면, 각 컴포넌트가 시각적 속성과 함께 태그로 선언된다는 점에서 XAML이 다소 익숙하게 느껴질 수 있습니다. 이는 HTML 컴포넌트의 스타일 방식과 유사합니다.
XAML에서 ‘확장 가능(extensible)’이라는 의미는, 고유하고 풍부하며 적응 가능한 사용자 인터페이스를 생성하기 위해 사용자 정의 컴포넌트를 정의할 수 있는 능력을 의미합니다. 한편, WPF는 이벤트(events), 속성(properties), 데이터 바인딩(data binding)을 통해 XAML 컴포넌트와 코드 비하인드 간의 직접적인 통신을 허용합니다. 이러한 통신은 필요할 때나 사용자가 컴포넌트를 실행할 때 프로세스를 수행하도록 합니다.
이벤트 (Events)
이벤트는 발생 시 특정 동작을 실행하는 메커니즘입니다. 예를 들어, 사용자가 버튼을 클릭하면 OnClick 이벤트가 발생합니다. 이 이벤트가 발생하면, 해당 이벤트 내에 정의된 모든 로직이 실행됩니다.
<Button Content="Click Me" Click="Button_Click"/>
속성 (Properties)
프로퍼티(Properties)는 이름 또는 ID를 사용하여 XAML 컴포넌트를 참조하는 속성입니다. 프로퍼티를 통해 코드 비하인드에서 컴포넌트를 프로그래밍 객체처럼 접근할 수 있으며, 이를 통해 해당 컴포넌트의 콘텐츠를 프로그램적으로 수정할 수 있습니다. 또한 각 컴포넌트가 지원하는 데이터 유형을 고려하여, 해당 프로퍼티를 올바르게 사용하는 것이 중요합니다.
<TextBlock x:Name="myTextBlock" Text="Hello"/>myTextBlock.Text "New Text"데이터 바인딩:
데이터 바인딩(Data Binding)은 WPF의 가장 중요한 기능 중 하나입니다. 이를 통해 코드 내에서 선언된 어떤 객체와도 컴포넌트의 콘텐츠를 직접 연결할 수 있습니다. 데이터 바인딩을 사용하면 동적인 콘텐츠를 가진 인터페이스를 구현할 수 있으며, 애플리케이션의 보안성과 안정성 또한 향상시킬 수 있습니다.
<TextBox Text="{Binding MyProperty}"/>
public string MyProperty { get; set; }
코드 비하인드 (Code-behind)

간단히 말해, 코드 비하인드(code behind)는 사용자 인터페이스와 연결된 프로그래밍 코드입니다. 일부 웹 프로그래밍 언어처럼 코드가 인터페이스에 직접 포함되는 방식과 달리, WPF에서는 코드를 독립적인 파일로 분리할 수 있어 애플리케이션의 가독성과 유지 보수성이 향상됩니다.
앞서 언급했듯이, WPF는 사용자 인터페이스와 그와 연관된 코드를 분리하면서도 양방향 상호작용을 유지합니다. 사용자 인터페이스는 컴포넌트와 그 시각적 속성을 정의하고, 코드 비하인드는 프레임워크에서 지원하는 각종 이벤트를 처리하며, 콘텐츠를 업데이트하거나 사용자가 수행한 동작을 검증합니다.
코드 비하인드는 C# 객체 지향 프로그래밍을 사용하며, 이를 통해 WPF 프레임워크가 제공하는 대부분의 클래스, 라이브러리, 메서드, 함수에 접근할 수 있습니다. 따라서 데이터베이스, 파일, 이미지, HTTP 요청 등에 접근할 수 있으며, 클라이언트 측에서 데이터를 처리하고 결과를 생성하는 것도 가능합니다.
코드 비하인드의 장점:
명료성: 로직을 인터페이스와 분리함으로써 애플리케이션의 흐름을 더 쉽게 이해할 수 있습니다.
사용 편의성: 시각적 디자인에 영향을 주지 않고 비즈니스 로직을 개발할 수 있습니다.
직접 상호작용: 컨트롤과 그 속성에 직접 쉽게 접근할 수 있습니다.
SampleDataBlockSeries
SampleDataBlockSeries는 SampleDataSeries의 향상된 버전으로, 실시간 및 스트리밍 데이터 애플리케이션을 위해 특별히 설계되었습니다. CPU 및 메모리 사용량을 최소화하면서 성능을 극대화하여, 매우 많은 수의 데이터 포인트를 동시에 렌더링할 수 있도록 합니다.
이름에서 알 수 있듯이, 데이터는 개별적으로 관리되는 블록 단위로 구성되며 메모리에서 독립적으로 처리됩니다. 이 방식은 대규모의 연속된 메모리 공간을 요구하지 않으므로, ECG/EKG 및 EEG와 같은 실시간 의료 모니터링 애플리케이션은 물론, 산업 모니터링, 텔레메트리, 파형 진동 분석에도 SampleDataBlockSeries를 이상적으로 활용할 수 있습니다.

구현
ViewXY view = _chart.ViewXY;
//Set real-time monitoring scroll mode
view.XAxes[0].ScrollMode = XAxisScrollMode. Scrolling;
view.XAxes[0].SweepingGap = 0;
view.XAxes[0].ValueType = AxisValueType. Number;
view.XAxes[0].AutoFormatLabels = false;
view.XAxes[0].Labels NumberFormat = "NO";
view.XAxes[0].Title.Text = "Point number";
view.XAxes[0].SetRange(0, 100000);
view.XAxes[0].MajorGrid. Pattern LinePattern. Solid;
view.XAxes[0].Units.Text = "Points";
스트리밍을 위해서는 ViewXY 객체를 생성해야 합니다. 데이터가 왼쪽에서 오른쪽으로 흐르며 표시되므로, 스크롤링(scrolling) 모드를 사용하는 것이 필요합니다.
Band sweepBand Dark = new Band (view, view. XAxes[0], view. YAxes[0])
{
BorderWidth = 0
};
sweepBandDark. Fill. Color Color. FromArgb(255, 0, 0, 0);
sweepBandDark. Fill. GradientColor = Color.FromArgb(0, 0, 0, 0);
sweepBandDark. Fill. GradientFill = GradientFill.Linear;
sweepBandDark. Fill. GradientDirection = 0;
sweepBandDark. Binding = AxisBinding.XAxis;
sweepBandDark.AllowUserInteraction = false;
view.Bands.Add(sweepBandDark);
PointLineSeries
PointLineSeries는 최신 WPF UI 컨트롤의 일부로, 값이나 시간이 일정하지 않은 간격으로 변화하는 데이터를 시각화하도록 특별히 설계되었습니다. 이로 인해 비균일한 증가 값을 가지는 데이터 세트에 이상적입니다. 이 시리즈는 연속적인 선(line), 개별 포인트(scatter), 또는 두 가지를 결합한 포인트-라인(point line) 표현 등 여러 형식으로 데이터를 표시할 수 있는 유연성을 제공합니다.
사용자는 선 스타일, 색상, 포인트 크기 등 다양한 요소를 수정할 수 있어, 특정 분석 요구 사항에 맞는 세밀한 시각적 표현이 가능합니다. 또한 툴팁(tooltips), 레이블(labels), 범례(legends)와 같은 추가 기능을 지원하여 시각화된 데이터의 인터랙티브 요소와 가독성을 향상시킵니다.
PointLineSeries는 과학 연구, 금융 분석, 또는 변수 범위를 정확히 이해하는 것이 중요한 모든 애플리케이션과 같이 유연성과 세부 표현이 중요한 상황에서 매우 적합한 선택입니다.

구현
// Configure x-axis.
AxisX axisX = _chart. ViewXY.XAxes[0];
axisX.SetRange(0, 60);
axisX.ScrollMode = XAxisScrollMode.None;
axisX.ValueType = AxisValueType.Number;
//Chart has one Y axis ready to go. Just set the range
_chart.ViewXY.YAxes[0].SetRange(0, 800);|
ViewXY 유형의 차트를 생성하면, 기본적으로 X-Y 축(인덱스 0)에 접근할 수 있습니다. 이후에는 각 축을 구성하기만 하면 되며, 기본 설정에서는 각 축의 범위(range), 스크롤 모드(scroll mode), 그리고 값 유형(value type)을 지정합니다.
PointLineSeries 클래스는 데이터 세트 배열을 포함하게 되며, 이 배열의 각 요소는 하나의 데이터 포인트에 해당합니다.
//Add point line series
PointLineSeries pointLineSeries = new PointLineSeries (_chart. ViewXY, chart. ViewXY.XAxes[0], chart.ViewXY. YAxes[0])
{
//Make points visible
PointsVisible = true
};
DigitalLineSeries
DigitalLineSeries는 0과 1과 같이 두 개의 Y 값 사이를 번갈아 표시하는 선을 표현하도록 설계된 특수한 유형의 라인 시리즈입니다. 이 시리즈는 고성능에 최적화되어 있으며, 모든 시리즈 유형 중에서 가장 메모리 효율적인 옵션입니다.
이 시리즈는 개별 데이터 포인트 마커를 생략하고 선 자체에만 집중함으로써 설정을 단순화합니다. 외형 조정을 위한 속성도 Color와 Width 두 가지만 제공하여 사용자 정의 옵션을 최소화합니다. 이러한 특성 덕분에 디지털 신호 표현이나 이진 데이터 시각화와 같이 단순성과 성능이 중요한 애플리케이션에 매우 적합한 선택입니다.

구현
DigitalLineSeries는 각 값이 32비트 데이터에 해당하는 단위(unit) 배열을 입력 데이터로 사용합니다. 이 유형의 시리즈는 Linear 축과 DirectX11 엔진에서만 사용할 수 있습니다.
DigitalLineSeries dls = new DigitalLineSeries (_chart.ViewXY, axisX, yAxis);
_chart.ViewXY.DigitalLineSeries.Add(dls);
dls.Color = DefaultColors. Series ForBlackBackgroundWpf[iSeriesCounter++ % DefaultColors.SeriesForBlackBackgroundWpf.Length];
dls. Title.Color = Chart Tools. CalcGradient(dls. Color, Colors. Transparent, 50);
dls. Title.Text = "DigitalLineSeries";
dls. Title.Visible = true;
dls. Title. HorizontalAlign = AlignmentHorizontal.Right;
dls. Title.VerticalAlign = AlignmentVertical.Center;
dls. Title.AutoPlacement = true;
dls. SamplingFrequency = (double)32 / iPointCount; // stretch Value over all range
dls. FirstSampleTimeStamp = 0;
dls.DigitalLow = -5;
dls.DigitalHigh = 5;
dls.Width = 2;
dls.AddBits(new uint[] { 2773350416 }, false);
AreaSeries
AreaSeries는 기준선(baseline)과 플로팅된 값 사이의 영역을 채워 데이터를 시각화하는 차트 유형입니다. 이를 통해 음영 처리된 영역이 생성되며, 특정 범위에 걸친 데이터의 양을 직관적으로 표현할 수 있어 시간에 따른 추세와 변화를 쉽게 파악할 수 있습니다.
차트에 AreaSeries를 추가하려면, AreaSeries 객체를 AreaSeries 목록에 추가하기만 하면 됩니다. 채워지는 영역의 기준선은 BaseValue 속성을 사용해 정의할 수 있으며, 이를 통해 영역이 시작되는 위치를 설정할 수 있습니다.
영역 차트의 외형은 Fill 속성을 사용해 원하는 채우기 스타일로 사용자 정의할 수 있고, LineStyle 및 PointStyle 속성을 통해 선과 포인트의 외형을 조정할 수 있습니다. 또한 HighLowSeries에서와 유사하게 초과(exceed) 및 감소(decrease) 한계값을 사용할 수 있어, 데이터의 임계값을 정의하는 데 도움이 됩니다.

구현
AreaSeries series = new AreaSeries (_chart. ViewXY, _chart. ViewXY.XAxes[0], chart. ViewXY.YAxes[0]);
series.Fill.Color = GradientColors[i];
series.Fill.GradientFill = GradientFill.Solid;
series.Fill. GradientDirection = 90;
series.LineStyle. Color = SolidColors[4];
series. LineStyle.Width = 2f;
series. Highlight = Highlight. None;
series.AllowUserInteraction = false;
series. Title.Text = "Series " + (i + 1).ToString();
BarSeries
BarSeries는 수평 또는 수직 막대를 통해 데이터를 시각화할 수 있도록 하여, 서로 다른 값들을 즉시 비교하기 쉽게 해줍니다. BarSeries에 대한 값을 저장하려면 values 배열 속성을 사용할 수 있습니다.
시리즈에 새로운 값을 추가하려면 AddValue 메서드를 사용합니다. 특정 인덱스에 있는 기존 값을 업데이트해야 하는 경우에는 SetValue 메서드를 사용하여 해당 값을 수정할 수 있습니다.
막대의 외형을 사용자 정의하려면 차트의 chart.ViewXY 설정 내에 있는 BarViewOptions 속성을 조정하면 됩니다. 이를 통해 다양한 표시 요소를 제어할 수 있으며, 막대 차트의 전체적인 표현을 더욱 향상시킬 수 있습니다.

구현
int seriesLength = specularColors.Length;
for (int i = 0; i < seriesLength; i++)
{
BarSeries 3D barSeries = new BarSeries 3D(_chart.View3D, Axis3DBinding. Primary, Axis3DBinding. Primary, Axis3DBinding.Primary)
{
Shape shapes[i],
BarWidth = 2 ((i % 2) + 1)
};
barSeries. BarDepth = barSeries.BarWidth;
barSeries. Material. DiffuseColor = diffuseColors[i];
barSeries. Material. SpecularColor = specularColors[i];
barSeries. Material. SpecularPower = 20;
barSeries.BaseLevel = 0;
barSeries.Title.Text = "Bar series " + (i + 1).ToString();
_chart.View3D.BarSeries 3D.Add(barSeries);
}
BarSeries3D와 BarSeries는 하나 이상의 막대(bar)를 포함할 수 있습니다. 시각적 속성은 시리즈 전체에 적용되지만, 값(values)은 각 개별 막대에 적용될 수 있습니다. Bar 시리즈의 데이터는 x, y, z 축 값과 텍스트 필드를 포함하는 BarSeriesValue3D 구조체 형태로 추가할 수 있습니다.
BarSeriesValue3D[] values = new BarSeriesValue3D[addSeriesLength];
for (int i = 0; i < addSeriesLength; i++)
{
values[i] = new BarSeriesValue3D(i + 1, 10f + 1f Math. Sin(_x + series Index 10.0i 100.0), 20, "");
}
_x += 0.025f;
IntensityMeshSeries (Heatmap)
IntensityMeshSeries 유형의 차트는 한 가지 중요한 차이점을 제외하면 IntensityGridSeries와 유사합니다. 이 시리즈에서는 노드(nodes)를 X-Y 공간에 자유롭게 배치할 수 있어, 직사각형이 아닌 비정형 배열도 구현할 수 있습니다.
WireframeType 속성을 사용하면 와이어프레임 선의 표시 여부를 제어할 수 있으며, 개별 노드를 표시하고 싶다면 ShowNodes를 true로 설정하면 됩니다. 이러한 유연성 덕분에 IntensityMeshSeries는 불규칙한 레이아웃이 필요한 다양한 데이터 시각화 시나리오에 적합합니다.

구현
//Create intensity mesh series
intensityMesh = new IntensityMeshSeries (chart. ViewXY, chart. ViewXY.XAxes[0], chart.ViewXY.YAxes[0])
{
ContourLineType = ContourLineTypeXY.None,
Optimization IntensitySeriesOptimization. DynamicData,
ShowNodes = checkBox ShowNodes. IsChecked.Value
};
StockSeries
주식 차트(stock chart)는 시간에 따른 주가 변동을 그래픽으로 표현한 것입니다. 이를 통해 투자자와 트레이더는 가격 추세, 패턴, 시장 움직임에 대한 시각적 인사이트를 얻을 수 있으며, 매수 또는 매도 결정을 보다 합리적으로 내릴 수 있습니다.
주식 차트는 다음과 같은 다양한 목적을 가집니다:
추세 분석: 상승 또는 하락 추세를 식별하여 합리적인 트레이딩 결정을 내리는 데 활용됩니다.
패턴 인식: 헤드앤숄더(head and shoulders), 더블 탑(double tops)과 같은 특정 차트 패턴을 인식하여 향후 가격 움직임을 예측하는 데 도움을 줍니다.
의사결정: 과거 가격 흐름과 시장 행동을 기반으로 매수 또는 매도 결정을 내릴 수 있는 시각적 맥락을 제공합니다.
StockSeries는 캔들스틱(candlestick) 또는 스톡 바(stock bar) 형식을 사용하여 주식 시장 데이터를 시각화할 수 있는 방법을 제공합니다. StockSeries 리스트 속성을 사용하면 하나의 차트에 여러 개의 StockSeries 객체를 추가할 수 있어, 동일한 뷰 내에서 서로 다른 주식 데이터를 비교할 수 있습니다.
표시 스타일을 선택하려면 Style 속성을 사용합니다. 사용 가능한 옵션에는 Bars, CandleStick, OptimizedCandleStick가 있으며, 데이터 표현 요구 사항에 가장 적합한 형식을 선택할 수 있습니다.

구현
데이터 배열을 생성하고 배열의 각 항목을 설정합니다. 각 항목에는 다음과 같은 필드가 포함됩니다:
Date: DateTime 값(연, 월, 일)
Open: 해당 날짜의 시가(Open) 값
Close: 해당 날짜의 종가(Close) 값
Low: 해당 날짜 동안의 최저가
High: 해당 날짜 동안의 최고가
Transaction: 총 거래 금액
Volume: 거래된 주식 수
데이터는 Date 값 기준으로 항상 오름차순(가장 오래된 날짜가 먼저)으로 유지해야 합니다.
// Create data array
StockSeriesData[] data = new StockSeriesData[] {
new StockSeriesData(2010, 09, 01, 24.35, 24.76, 24.81, 23.82, 269210, 6610451.55),
new StockSeriesData(2010, 09, 02, 24.85, 24.66, 24.85, 24.53, 216395, 5356858.225),
new StockSeriesData(2010, 09, 03, 24.80, 24.84, 25.07, 24.60, 164583, 4084950.06),
new StockSeriesData(2010, 09, 06, 24.85, 25.01, 25.12, 24.84, 118367, 2950889.31)
};
// Assign the data array to series
chart.ViewXY.StockSeries[0].DataPoints = data;
X 축을 날짜 표시로 설정하기:
chart.ViewXY.XAxes[0].ValueType = AxisValueType.DateTime;
chart.ViewXY.XAxes[0].LabelsAngle = 90;
chart.ViewXY.XAxes[0].LabelsTimeFormat =
System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
chart.ViewXY.XAxes[0].MajorDiv = 24 60 60; // Major div is one day in seconds
chart.ViewXY.XAxes[0].AutoFormatLabels = false;
// Set datetime origin
chart.ViewXY.XAxes[0].DateOriginYear = data[0].Date.Year;
chart.ViewXY.XAxes[0].DateOriginMonth = data[0].Date.Month;
chart.ViewXY.XAxes[0].DateOriginDay = data[0].Date.Day;
3D 차트용 현대 WPF UI 컨트롤
LightningChart .NET은 완전히 사용자 정의 가능한 3D 객체를 생성할 수 있습니다. 예를 들어, 카메라(camera)를 사용하면 다양한 각도에서 3D 차트를 시각화할 수 있습니다. 또한 XAML 컨트롤을 활용하여 3D 뷰를 수정하는 것도 가능합니다.

3D 차트를 사용할 경우, 세 번째 축 또는 차원인 Z축에 접근할 수 있으며, 이를 통해 데이터 세트의 각 포인트에 새로운 값을 추가할 수 있습니다:

PointLineSeries3D

PointLineSeries3D는 3D 공간에서 포인트와 라인을 표현할 수 있도록 합니다. 포인트의 경우 다양한 기본 3D 형태를 사용할 수 있습니다. LineVisible 속성이 true로 설정된 경우, 포인트들은 하나의 라인과 연결됩니다. 또한 포인트는 실제 3D 포인트로 표시할 수도 있고, 2D 형태로 표시할 수도 있습니다.

라인은 음영 처리된 3D 라인으로 렌더링할 수도 있고, 한 픽셀 두께의 헤어라인(hair line)으로 렌더링할 수도 있습니다. 시리즈에 많은 양의 데이터가 포함된 경우, 성능 문제를 방지하기 위해 LineOptimization = Hairline으로 설정하는 것이 권장됩니다.

Adding points:
PointLineSeries3D는 다음과 같은 세 가지 서로 다른 포인트 형식을 지원합니다:
· Points 속성 (SeriesPoint3D 배열)
· PointsCompact 속성 (SeriesPointCompact3D 배열)
· PointsCompactColored 속성 (SeriesPointCompactColored3D 배열)
PointsCompact 및 PointsCompactColored 구조체는 메모리 효율이 매우 뛰어나며, 단순한 포인트 스타일을 사용하는 경우 최대 1억(100 million) 개의 데이터 포인트까지 시각화할 수 있습니다.
Points:
Points 속성을 사용하면 포인트에 대한 모든 고급 색상 지정 옵션을 사용할 수 있습니다. SeriesPoint3D 구조체는 다음과 같은 필드로 구성됩니다:
double X: X축 값
double Y: Y축 값
double Z: Z축 값
Color: 개별 데이터 포인트의 색상. IndividualPointColors 또는 MultiColorLine이 활성화된 경우에만 적용됩니다.
Float sizeFactor: 포인트 크기 계수로, PointStyle.Size에 정의된 크기에 곱해집니다. IndividualPointSizes가 활성화된 경우에만 적용됩니다.
object Tag: 자유롭게 할당할 수 있는 보조 객체로, 예를 들어 추가적인 세부 정보를 연결하는 데 사용할 수 있습니다.
시리즈 포인트는 코드에서 직접 추가해야 합니다. 기존 포인트의 끝에 새로운 포인트를 추가하려면 AddPoints(…) 메서드를 사용합니다.
SeriesPoint3D[] pointsArray = new SeriesPoint3D[3];
pointsArray[0] = new SeriesPoint3D(50, 50, 50);
pointsArray[1] = new SeriesPoint3D(30, 50, 20);
pointsArray[2] = new SeriesPoint3D(80, 50, 80);
chart.View3D.PointLineSeries3D[0].AddPoints(pointsArray);
SurfaceGridSeries3D
SurfaceGridSeries3D는 데이터를 3D 표면(surface) 형태로 시각화할 수 있도록 합니다. SurfaceGridSeries3D에서는 노드(nodes)가 X 차원과 Z 차원 모두에서 동일한 간격으로 배치됩니다.

Calculation

표면 격자 데이터 설정
RangeMinX 및 RangeMaxX 속성을 사용하여 할당된 X축을 기준으로 X 범위의 최소값과 최대값을 설정합니다.
RangeMinZ 및 RangeMaxZ 속성을 사용하여 할당된 Z축을 기준으로 Z 범위의 최소값과 최대값을 설정합니다.
SizeX 및 SizeZ 속성을 설정하여 그리드의 크기를 열(columns)과 행(rows) 기준으로 지정합니다.
모든 노드에 대한 Y 값을 설정합니다:
for (int nodeIndexX = 0; nodeIndexX < columnCount; nodeIndexX++)
{
for (int nodeIndexZ = 0; nodeIndexZ < rowCount; nodeIndexZ++)
{
Y = //some height value.
gridSeries.Data[iNodeX, iNodeZ].Y = Y;
}
}
gridSeries.InvalidateData(); // Notify to refresh when the new values are ready
Surfaces는 SetHeightDataFromBitmap 메서드를 사용하여 비트맵 이미지로부터 생성할 수 있습니다. 이 경우(안티앨리어싱이나 리샘플링을 사용하지 않는다면) 서피스는 비트맵의 크기를 그대로 사용합니다.
비트맵 이미지의 각 픽셀에 대해 빨강(red), 초록(green), 파랑(blue) 값이 합산됩니다. 이 합이 클수록 해당 노드의 높이 데이터 값은 더 커집니다. 검은색이나 어두운 색상은 더 낮은 값을 가지며, 밝은 색상이나 흰색에 가까울수록 더 높은 값을 갖게 됩니다.

Wireframe Mash
WireframeType을 사용하여 와이어프레임 스타일을 선택할 수 있습니다. 사용 가능한 옵션은 다음과 같습니다:
None: 와이어프레임을 표시하지 않습니다.
Wireframe: 단색 와이어프레임을 표시합니다. 색상은 WireframeLineType.Color로 설정합니다.
WireframePalettedByY: 와이어프레임 색상이 SurfacePoint의 Y 필드를 기준으로 ContourPalette를 따릅니다.
WireframePalettedByValue: 와이어프레임 색상이 SurfacePoint의 Value 필드를 기준으로 ContourPalette를 따릅니다.
WireframeSourcePointColored: 와이어프레임 색상이 서피스 노드의 색상을 따릅니다.
Dots: 노드 위치에 단색 점(dots)을 표시합니다.
DotsPalettedByY: 노드 위치에 점을 표시하고, SurfacePoint의 Y 필드를 기준으로 ContourPalette에 따라 색상을 적용합니다.
DotsPalettedByValue: 노드 위치에 점을 표시하고, SurfacePoint의 Value 필드를 기준으로 ContourPalette에 따라 색상을 적용합니다.
DotsSourcePointColored: 노드 위치에 점을 표시하며, 색상은 서피스 노드의 색상을 따릅니다.

결론
LightningChart .NET은 최신 WPF UI 컨트롤과의 매끄러운 통합을 제공하여 높은 호환성과 성능을 보장합니다. 앞서 살펴본 것처럼, WPF는 코드 비하인드에서 사용자 인터페이스 컴포넌트를 직접 조작할 수 있도록 하며, LC .NET은 이러한 기능을 자연스럽게 활용합니다. 차트 컴포넌트는 캡슐화된 객체로 동작하며, XAML 컴포넌트에 추가하는 것만으로 사용자 인터페이스에 표시할 수 있습니다.
차트 컴포넌트는 독립적으로 동작하도록 설계되었으며, 코드를 통해 완전히 구성 및 사용자 정의가 가능해 알고리즘을 통한 동적 제어를 구현할 수 있습니다. 이를 통해 가독성이 뛰어나고 유지 보수가 용이한 지속 가능한 프로젝트를 만들 수 있습니다. 차트를 수정하는 컨트롤이 필요할 때에만 사용자 인터페이스를 조정하면 됩니다.
최신 WPF UI 컨트롤은 WPF의 이벤트 처리 기능과 결합되어 차트의 인터랙티브한 조작을 가능하게 합니다. 예를 들어, 마우스를 이동하거나 우클릭을 하거나 슬라이더를 조정하면 입력 값에 따라 차트 출력이 즉시 업데이트될 수 있습니다.
LightningChart .NET은 이러한 최신 WPF UI 컨트롤과 완전히 통합되어 있으며, 간단한 입력만으로도 상호작용을 구현할 수 있습니다. 또한 인터랙티브 예제 도구를 통해 WPF UI 컴포넌트와 차트를 연결하는 다양한 샘플 프로젝트를 제공합니다. 이 도구를 직접 탐색해 보고, 관심 있는 차트를 실험해 보시길 권장합니다. 감사합니다!