React 축 레이아웃
모든 Ignite UI for React 차트에는 위치와 같은 많은 축 레이아웃 옵션을 구성하는 옵션과 시리즈 간에 축을 공유하거나 동일한 차트에 여러 축을 두는 기능이 포함되어 있습니다. 이러한 기능은 아래에 제공된 예에서 설명합니다.
다음 예제는 IgrCategoryChart 및 IgrFinancialChart 컨트롤에 적용될 수 있습니다.
축 위치 예
모든 축에 대해 차트 플롯 영역과 관련하여 축 위치를 지정할 수 있습니다. React 차트의 xAxisLabelLocation
속성을 사용하면 x축 선과 레이블을 플롯 영역 위나 아래에 배치할 수 있습니다. 마찬가지로 yAxisLabelLocation
속성을 사용하여 y축을 플롯 영역의 왼쪽이나 오른쪽에 배치할 수 있습니다.
다음 예에서는 2009년 이후 생산된 재생 가능 전기량을 선형 차트로 표시합니다. 차트 플롯 영역 내부 또는 외부의 왼쪽 또는 오른쪽에 레이블이 배치될 때 축이 어떻게 보이는지 시각화할 수 있도록 yAxisLabelLocation
구성할 수 있는 드롭다운이 있습니다.
export class CountryRenewableElectricityItem {
public constructor(init: Partial<CountryRenewableElectricityItem>) {
Object.assign(this, init);
}
public year: string;
public europe: number;
public china: number;
public america: number;
}
export class CountryRenewableElectricity extends Array<CountryRenewableElectricityItem> {
public constructor(items: Array<CountryRenewableElectricityItem> | number = -1) {
if (Array.isArray(items)) {
super(...items);
} else {
const newItems = [
new CountryRenewableElectricityItem({ year: `2009`, europe: 34, china: 21, america: 19 }),
new CountryRenewableElectricityItem({ year: `2010`, europe: 43, china: 26, america: 24 }),
new CountryRenewableElectricityItem({ year: `2011`, europe: 66, china: 29, america: 28 }),
new CountryRenewableElectricityItem({ year: `2012`, europe: 69, china: 32, america: 26 }),
new CountryRenewableElectricityItem({ year: `2013`, europe: 58, china: 47, america: 38 }),
new CountryRenewableElectricityItem({ year: `2014`, europe: 40, china: 46, america: 31 }),
new CountryRenewableElectricityItem({ year: `2015`, europe: 78, china: 50, america: 19 }),
new CountryRenewableElectricityItem({ year: `2016`, europe: 13, china: 90, america: 52 }),
new CountryRenewableElectricityItem({ year: `2017`, europe: 78, china: 132, america: 50 }),
new CountryRenewableElectricityItem({ year: `2018`, europe: 40, china: 134, america: 34 }),
new CountryRenewableElectricityItem({ year: `2018`, europe: 40, china: 134, america: 34 }),
new CountryRenewableElectricityItem({ year: `2019`, europe: 80, china: 96, america: 38 }),
];
super(...newItems.slice(0));
}
}
}
tsimport React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrPropertyEditorPanelModule } from "@infragistics/igniteui-react-layouts";
import { IgrLegendModule, IgrCategoryChartModule } from "@infragistics/igniteui-react-charts";
import { IgrLegend, IgrCategoryChart } from "@infragistics/igniteui-react-charts";
import { IgrPropertyEditorPanel, IgrPropertyEditorPropertyDescription } from "@infragistics/igniteui-react-layouts";
import { ComponentRenderer, PropertyEditorPanelDescriptionModule, LegendDescriptionModule, CategoryChartDescriptionModule } from "@infragistics/igniteui-react-core";
import { CountryRenewableElectricityItem, CountryRenewableElectricity } from './CountryRenewableElectricity';
import 'igniteui-webcomponents/themes/light/bootstrap.css';
const mods: any[] = [
IgrPropertyEditorPanelModule,
IgrLegendModule,
IgrCategoryChartModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private legend: IgrLegend
private legendRef(r: IgrLegend) {
this.legend = r;
this.setState({});
}
private propertyEditorPanel1: IgrPropertyEditorPanel
private propertyEditorPanel1Ref(r: IgrPropertyEditorPanel) {
this.propertyEditorPanel1 = r;
this.setState({});
}
private yAxisLabelLocation: IgrPropertyEditorPropertyDescription
private chart: IgrCategoryChart
private chartRef(r: IgrCategoryChart) {
this.chart = r;
this.setState({});
}
constructor(props: any) {
super(props);
this.legendRef = this.legendRef.bind(this);
this.propertyEditorPanel1Ref = this.propertyEditorPanel1Ref.bind(this);
this.chartRef = this.chartRef.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample">
<div className="options vertical">
<IgrPropertyEditorPanel
componentRenderer={this.renderer}
target={this.chart}
descriptionType="CategoryChart"
isHorizontal="true"
isWrappingEnabled="false"
ref={this.propertyEditorPanel1Ref}>
<IgrPropertyEditorPropertyDescription
propertyPath="YAxisLabelLocation"
name="YAxisLabelLocation"
label="Y Axis - Label Location"
primitiveValue="OutsideRight">
</IgrPropertyEditorPropertyDescription>
</IgrPropertyEditorPanel>
</div>
<div className="legend-title">
Renewable Electricity Generated
</div>
<div className="legend">
<IgrLegend
ref={this.legendRef}
orientation="Horizontal">
</IgrLegend>
</div>
<div className="container fill">
<IgrCategoryChart
ref={this.chartRef}
computedPlotAreaMarginMode="Series"
dataSource={this.countryRenewableElectricity}
includedProperties={["year", "europe", "china", "america"]}
legend={this.legend}
chartType="Line"
yAxisTitle="Labels Location"
isHorizontalZoomEnabled="false"
isVerticalZoomEnabled="false"
xAxisInterval="1"
yAxisLabelLocation="OutsideRight">
</IgrCategoryChart>
</div>
</div>
);
}
private _countryRenewableElectricity: CountryRenewableElectricity = null;
public get countryRenewableElectricity(): CountryRenewableElectricity {
if (this._countryRenewableElectricity == null)
{
this._countryRenewableElectricity = new CountryRenewableElectricity();
}
return this._countryRenewableElectricity;
}
private _componentRenderer: ComponentRenderer = null;
public get renderer(): ComponentRenderer {
if (this._componentRenderer == null) {
this._componentRenderer = new ComponentRenderer();
var context = this._componentRenderer.context;
PropertyEditorPanelDescriptionModule.register(context);
LegendDescriptionModule.register(context);
CategoryChartDescriptionModule.register(context);
}
return this._componentRenderer;
}
}
// rendering above component in the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Sample/>);
tsx/* shared styles are loaded from: */
/* https://static.infragistics.com/xplatform/css/samples */
css
축 고급 시나리오
더욱 고급 축 레이아웃 시나리오의 경우 React 데이터 차트 사용하여 축을 공유하고, 동일한 플롯 영역에 여러 y축 및/또는 x축을 추가하거나, 심지어 특정 값에서 축을 교차할 수 있습니다. 다음 예제는 IgrDataChart
의 이러한 기능을 사용하는 방법을 보여줍니다.
축 공유 예
React IgrDataChart
의 동일한 플롯 영역에서 여러 축을 공유하고 추가할 수 있습니다. IgrTimeXAxis
공유하고 여러 IgrNumericYAxis
추가하여 값 범위가 넓은(예: 주가 및 주식 거래량) 여러 데이터 소스를 플롯하는 것이 일반적인 시나리오입니다.
다음 예에서는 주식형 차트와 기둥 차트가 표시된 주식 가격 및 거래량 차트를 보여줍니다. 이 경우 왼쪽의 Y축은 기둥 차트에서 사용되고 오른쪽의 Y축은 주식형 차트에서 사용되며 X축은 두 축이 공유됩니다.
export class SharedAxisFinancialData {
public static create(items?: number): any[] {
// initial values
let v = 10000;
let o = 500;
let h = Math.round(o + (Math.random() * 5));
let l = Math.round(o - (Math.random() * 5));
let c = Math.round(l + (Math.random() * (h - l)));
if (items === undefined) {
items = 400;
}
const today = new Date();
const end = new Date(today.getFullYear(), today.getMonth(), today.getDay());
let time = this.addDays(end, -items);
const data: any[] = [];
for (let i = 0; i < items; i++) {
const date = time.toDateString();
const label = this.getShortDate(time, false);
// adding new data item
data.push({"Time": time, "Date": date, "Label": label, "Close": c, "Open": o, "High": h, "Low": l, "Volume": v});
// generating new values
const mod = Math.random() - 0.49;
o = Math.round(o + (mod * 20));
o = Math.max(o, 500);
o = Math.min(o, 675);
v = Math.round(v + (mod * 500));
h = Math.round(o + (Math.random() * 5));
l = Math.round(o - (Math.random() * 5));
c = Math.round(l + (Math.random() * (h - l)));
time = this.addDays(time, 1);
}
return data;
}
public static addDays(dt: Date, days: number): Date {
return new Date(dt.getTime() + days * 24 * 60 * 60 * 1000);
}
public static getShortDate(dt: Date, showYear: boolean): string {
const months = [
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
];
const ind = dt.getMonth();
const day = dt.getDay() + 1;
let label = months[ind] + " " + day;
if (showYear) {
label += " " + dt.getFullYear();
}
return label;
}
}
tsimport React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { SharedAxisFinancialData } from './SharedAxisFinancialData';
// axis' modules:
import { IgrNumericYAxis } from "@infragistics/igniteui-react-charts";
import { IgrCategoryXAxis } from "@infragistics/igniteui-react-charts";
// series' modules:
import { IgrFinancialPriceSeries } from "@infragistics/igniteui-react-charts";
import { IgrColumnSeries } from "@infragistics/igniteui-react-charts";
// data chart's modules:
import { IgrDataChart } from "@infragistics/igniteui-react-charts";
import { IgrDataChartCoreModule } from "@infragistics/igniteui-react-charts";
import { IgrDataChartInteractivityModule } from "@infragistics/igniteui-react-charts";
import { IgrNumberAbbreviatorModule } from "@infragistics/igniteui-react-charts";
IgrNumberAbbreviatorModule.register();
IgrDataChartCoreModule.register();
IgrDataChartInteractivityModule.register();
export default class DataChartAxisSharing extends React.Component<any, any> {
public data: any[];
public chart: IgrDataChart;
constructor(props: any) {
super(props);
this.data = SharedAxisFinancialData.create();
}
public render(): JSX.Element {
return (
<div className="container sample">
<div className="container">
<IgrDataChart
width="100%"
height="100%"
subtitle="Stock Prices and Trade Volume"
subtitleTopMargin="10"
dataSource={this.data}
isHorizontalZoomEnabled={true}
isVerticalZoomEnabled={true} >
<IgrCategoryXAxis name="xAxisShared" label="Label" gap="0.75"/>
<IgrNumericYAxis name="yAxisRight" labelLocation="OutsideRight"
minimumValue={400} title="Stock Price ($)"
maximumValue={700}
/>
<IgrNumericYAxis name="yAxisLeft" labelLocation="OutsideLeft"
minimumValue={5000} title="Trade Volume"
maximumValue={45000}
majorStrokeThickness={0}
abbreviateLargeNumbers={true}/>
<IgrColumnSeries
name="series2"
xAxisName="xAxisShared"
yAxisName="yAxisLeft"
valueMemberPath="Volume"
showDefaultTooltip="true"
title="Trade Volume" />
<IgrFinancialPriceSeries
name="series1"
xAxisName="xAxisShared"
yAxisName="yAxisRight"
displayType="Candlestick"
highMemberPath="High"
lowMemberPath="Low"
closeMemberPath="Close"
openMemberPath="Open"
volumeMemberPath="Volume"
showDefaultTooltip="true"
title="Stock Price" />
</IgrDataChart>
</div>
</div>
);
}
}
// rendering above class to the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<DataChartAxisSharing/>);
tsx
축 교차 예
React IgrDataChart
플롯 영역 외부에 축을 배치하는 것 외에도 플롯 영역 내부에 축을 배치하고 특정 값에서 교차하도록 하는 옵션도 제공합니다. 예를 들어, x축과 y축 모두에 crossingAxis
및 crossingValue
속성을 설정하여 삼각 차트를 만들어 축 선과 축 레이블을 (0, 0) 원점에서 교차하도록 렌더링할 수 있습니다.
다음 예에서는 X축과 Y축이 (0, 0) 원점에서 서로 교차하는 분산 스플라인 차트로 표현되는 Sin 및 Cos 파동을 보여줍니다.
export class SampleFinancialData {
public static create(items?: number): any[] {
// initial values
let v = 10000;
let o = 500;
let h = Math.round(o + (Math.random() * 5));
let l = Math.round(o - (Math.random() * 5));
let c = Math.round(l + (Math.random() * (h - l)));
if (items === undefined) {
items = 200;
}
const today = new Date();
const end = new Date(today.getFullYear(), 11, 1);
let time = this.addDays(end, -items);
const data: any[] = [];
for (let i = 0; i < items; i++) {
const date = time.toDateString();
const label = this.getShortDate(time, false);
// adding new data item
data.push({"Time": time, "Date": date, "Label": label, "Close": c, "Open": o, "High": h, "Low": l, "Volume": v});
// generating new values
const mod = Math.random() - 0.45;
o = Math.round(o + (mod * 5 * 2));
v = Math.round(v + (mod * 5 * 100));
h = Math.round(o + (Math.random() * 5));
l = Math.round(o - (Math.random() * 5));
c = Math.round(l + (Math.random() * (h - l)));
time = this.addDays(time, 1);
}
return data;
}
public static addDays(dt: Date, days: number): Date {
return new Date(dt.getTime() + days * 24 * 60 * 60 * 1000);
}
public static getShortDate(dt: Date, showYear: boolean): string {
const months = [
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
];
const ind = dt.getMonth();
const day = dt.getDay() + 1;
let label = months[ind] + " " + day;
if (showYear) {
label += " " + dt.getFullYear();
}
return label;
}
}
tsimport React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrDataChartCoreModule, IgrDataChartInteractivityModule, IgrDataChartScatterCoreModule, IgrDataChartScatterModule,
IgrDataChart, IgrNumericXAxis, IgrNumericYAxis, IgrScatterSplineSeries } from "@infragistics/igniteui-react-charts";
IgrDataChartCoreModule.register();
IgrDataChartScatterCoreModule.register();
IgrDataChartScatterModule.register();
IgrDataChartInteractivityModule.register();
export default class DataChartAxisSharing extends React.Component<any, any> {
public data: any[] = [];
public chart: IgrDataChart;
constructor(props: any) {
super(props);
this.onXAxisCrossValueChange = this.onXAxisCrossValueChange.bind(this);
this.onYAxisCrossValueChange = this.onYAxisCrossValueChange.bind(this);
this.state = {
xAxisCrossValue: 0,
yAxisCrossValue: 0
}
this.initData();
}
public render(): JSX.Element {
return (
<div className="container sample">
<div className="options horizontal">
<label className="option-label">X-Axis Crossing Value: </label>
<label className="options-value">{this.state.xAxisCrossValue}</label>
<input className="options-slider" type="range" min={-360} max={360} step={10} value={this.state.xAxisCrossValue}
onChange={this.onXAxisCrossValueChange}/>
<label className="option-label">Y-Axis Crossing Value: </label>
<label className="options-value">{this.state.yAxisCrossValue}</label>
<input className="options-slider" type="range" min={-1.25} max={1.25} step={0.125} value={this.state.yAxisCrossValue}
onChange={this.onYAxisCrossValueChange}/>
</div>
<div className="container">
<IgrDataChart
width="100%"
height="100%"
dataSource={this.data}
isHorizontalZoomEnabled={true}
isVerticalZoomEnabled={true}
plotAreaMarginBottom={60}
plotAreaMarginTop={60}
plotAreaMarginLeft={30}
plotAreaMarginRight={30}>
<IgrNumericXAxis name="xAxis" interval={40} minimumValue={-360} maximumValue={360} labelLocation="InsideBottom"
labelTopMargin={10} crossingAxisName="yAxis" crossingValue={this.state.yAxisCrossValue} strokeThickness={1} stroke="Black" />
<IgrNumericYAxis name="yAxis" minimumValue={-1.25} maximumValue={1.25} interval={0.25} labelLocation="InsideLeft"
labelRightMargin={10} crossingAxisName="xAxis" crossingValue={this.state.xAxisCrossValue} strokeThickness={1} stroke="Black" />
<IgrScatterSplineSeries name="series1" xAxisName="xAxis" yAxisName="yAxis" markerType="Circle" xMemberPath="X" yMemberPath="sinValue" />
<IgrScatterSplineSeries name="series2" xAxisName="xAxis" yAxisName="yAxis" markerType="Circle" xMemberPath="X" yMemberPath="cosValue" />
</IgrDataChart>
</div>
</div>
);
}
public initData() {
for (let i = -360; i <= 360; i += 10) {
const radians = (i * Math.PI) / 180;
const sin = Math.sin(radians);
const cos = Math.cos(radians);
this.data.push({ X: i, sinValue: sin, cosValue: cos });
}
}
public onXAxisCrossValueChange(e: any){
this.setState({ xAxisCrossValue: e.target.value});
}
public onYAxisCrossValueChange(e: any){
this.setState({ yAxisCrossValue: e.target.value});
}
}
// rendering above class to the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<DataChartAxisSharing/>);
tsx
추가 리소스
다음 항목에서 관련 차트 기능에 대한 자세한 내용을 확인할 수 있습니다.
API 참조
다음은 위 섹션에서 언급된 API 멤버 목록입니다. 위 섹션의 d:
IgrDataChart |
IgrCategoryChart |
---|---|
Axes ➔ IgrNumericYAxis ➔ crossingAxis |
없음 |
Axes ➔ IgrNumericYAxis ➔ crossingValue |
없음 |
Axes ➔ IgrNumericXAxis ➔ isInverted |
xAxisInverted |
Axes ➔ IgrNumericYAxis ➔ isInverted |
yAxisInverted |
Axes ➔ IgrNumericYAxis ➔ LabelLocation |
yAxisLabelLocation |
Axes ➔ IgrNumericXAxis ➔ LabelLocation |
xAxisLabelLocation |
Axes ➔ IgrNumericYAxis ➔ LabelHorizontalAlignment |
yAxisLabelHorizontalAlignment |
Axes ➔ IgrNumericXAxis ➔ LabelVerticalAlignment |
xAxisLabelVerticalAlignment |
Axes ➔ IgrNumericYAxis ➔ LabelVisibility |
yAxisLabelVisibility |
Axes ➔ IgrNumericXAxis ➔ LabelVisibility |
xAxisLabelVisibility |