React 축 레이아웃
모든 Ignite UI for React 차트에는 위치와 같은 많은 축 레이아웃 옵션을 구성하는 옵션과 시리즈 간에 축을 공유하거나 동일한 차트에 여러 축을 두는 기능이 포함되어 있습니다. 이러한 기능은 아래에 제공된 예에서 설명합니다.
the following examples can be applied to IgrCategoryChart as well as IgrFinancialChart controls.
Axis Locations Example
모든 축에 대해 차트 플롯 영역과 관련하여 축 위치를 지정할 수 있습니다. 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
Like this sample? Get access to our complete Ignite UI for React toolkit and start building your own apps in minutes. Download it for free.
Axis Advanced Scenarios
더욱 고급 축 레이아웃 시나리오의 경우 React 데이터 차트 사용하여 축을 공유하고, 동일한 플롯 영역에 여러 y축 및/또는 x축을 추가하거나, 심지어 특정 값에서 축을 교차할 수 있습니다. 다음 예제는 IgrDataChart
의 이러한 기능을 사용하는 방법을 보여줍니다.
Axis Sharing Example
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
Axis Crossing Example
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
Additional Resources
다음 항목에서 관련 차트 기능에 대한 자세한 내용을 확인할 수 있습니다.
API References
다음은 위 섹션에서 언급된 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 |