React チャート ナビゲーション
Ignite UI for React チャートを使用すると、マウス、キーボード、およびタッチを介してインタラクティブなパンやズームが可能になります。
React チャート ナビゲーションの例
次の例は、使用可能なすべてのパンやズームのオプションを示しています。ボタンを使用して例を操作したり、ドロップダウンまたはチェックボックスを使用して目的のオプションを選択したりできます。
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';
// data chart's modules:
import { IgrDataChart } from "@infragistics/igniteui-react-charts";
import { IgrDataChartCoreModule } from "@infragistics/igniteui-react-charts";
import { IgrDataChartCategoryModule } from "@infragistics/igniteui-react-charts";
import { IgrDataChartInteractivityModule } from "@infragistics/igniteui-react-charts";
// financial series modules:
import { IgrDataChartFinancialModule } from "@infragistics/igniteui-react-charts";
// data chart's elements:
import { IgrNumericYAxis } from "@infragistics/igniteui-react-charts";
import { IgrCategoryXAxis } from "@infragistics/igniteui-react-charts";
import { IgrFinancialPriceSeries } from "@infragistics/igniteui-react-charts";
import { SampleFinancialData } from './SampleFinancialData';
IgrDataChartCoreModule.register();
IgrDataChartCategoryModule.register();
IgrDataChartFinancialModule.register();
IgrDataChartInteractivityModule.register();
export default class DataChartNavigation extends React.Component<any, any> {
public chart: IgrDataChart;
constructor(props: any) {
super(props);
this.state = {
data: SampleFinancialData.create(),
defaultInteraction: "DragPan",
dragModifier: "Alt",
isZoomEnabled: true,
panModifier: "Control" };
this.onChartRef = this.onChartRef.bind(this);
this.onDefaultInteractionChange = this.onDefaultInteractionChange.bind(this);
this.onPanModifierChange = this.onPanModifierChange.bind(this);
this.onDragModifierChange = this.onDragModifierChange.bind(this);
this.onZoomEnabledChange = this.onZoomEnabledChange.bind(this);
this.onPanDownClick = this.onPanDownClick.bind(this);
this.onPanLeftClick = this.onPanLeftClick.bind(this);
this.onPanRightClick = this.onPanRightClick.bind(this);
this.onPanUpClick = this.onPanUpClick.bind(this);
this.onZoomInClick = this.onZoomInClick.bind(this);
this.onZoomOutClick = this.onZoomOutClick.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample">
<div className="options horizontal">
<div className="options vertical" style={{width: "100px"}}>
<button onClick={this.onPanUpClick}>Pan Up</button>
<button onClick={this.onPanDownClick}>Pan Down</button>
</div>
<div className="options vertical" style={{width: "100px"}}>
<button onClick={this.onPanLeftClick}>Pan Left</button>
<button onClick={this.onPanRightClick}>Pan Right</button>
</div>
<div className="options vertical" style={{width: "100px"}}>
<button onClick={this.onZoomInClick}>Zoom In</button>
<button onClick={this.onZoomOutClick}>Zoom Out</button>
</div>
<div className="options vertical" style={{ width: "120px", alignSelf: "center" }}>
<label className="options-label" style={{ margin: "5px" }}>Pan Modifier:</label>
<label className="options-label" style={{ margin: "5px" }}>Zoom Modifier:</label>
</div>
<div className="options vertical" style={{ width: "100px" }}>
<select value={this.state.panModifier} style={{ margin: "5px"}} onChange={this.onPanModifierChange}>
<option>Alt</option>
<option>Control</option>
<option>Shift</option>
<option>Windows</option>
<option>Apple</option>
<option>None</option>
</select>
<select value={this.state.dragModifier} style={{ margin: "5px"}} onChange={this.onDragModifierChange}>
<option>Alt</option>
<option>Control</option>
<option>Shift</option>
<option>Windows</option>
<option>Apple</option>
<option>None</option>
</select>
</div>
<div className="options vertical" style={{ width: "150px", alignSelf: "center" }}>
<label className="options-label" style={{ margin: "5px"}}>Interaction:</label>
<label className="options-label" style={{ margin: "5px"}}>Zooming:</label>
</div>
<div className="options vertical" style={{ width: "100px" }}>
<select value={this.state.defaultInteraction} style={{ margin: "5px"}} onChange={this.onDefaultInteractionChange}>
<option>DragZoom</option>
<option>DragPan</option>
<option>None</option>
</select>
<input type="checkbox" checked={this.state.isZoomEnabled} onChange={this.onZoomEnabledChange} />
</div>
</div>
<div className="container vertical">
<IgrDataChart
ref={this.onChartRef}
width="100%"
height="100%"
subtitle="Stock Prices Series in Candlestick Display Type"
subtitleTopMargin={10}
isHorizontalZoomEnabled={this.state.isZoomEnabled}
isVerticalZoomEnabled={this.state.isZoomEnabled}
panModifier={this.state.panModifier}
dragModifier={this.state.dragModifier}
defaultInteraction={this.state.defaultInteraction}
dataSource={this.state.data}>
<IgrCategoryXAxis
name="xAxis"
label="Label"/>
<IgrNumericYAxis
name="yAxis"
title="Amount (in USD)"
titleRightMargin={10}
labelRightMargin={10}
labelHorizontalAlignment="Left"
labelLocation="OutsideRight"/>
<IgrFinancialPriceSeries
name="series1"
xAxisName="xAxis"
yAxisName="yAxis"
displayType="Candlestick"
openMemberPath="Open"
closeMemberPath="Close"
highMemberPath="High"
lowMemberPath="Low"
volumeMemberPath="Volume"
showDefaultTooltip={true}
isTransitionInEnabled={true}
title="Price"/>
</IgrDataChart>
</div>
</div>
);
}
public onChartRef(chart: IgrDataChart) {
if (!chart) { return; }
this.chart = chart;
this.chart.actualWindowScaleHorizontal = 0.60;
this.chart.actualWindowScaleVertical = 0.60;
this.chart.actualWindowPositionVertical = 0.20;
this.chart.actualWindowPositionHorizontal = 0.20;
}
public onDefaultInteractionChange = (e: any) => {
this.setState({ defaultInteraction: e.target.value });
}
public onPanModifierChange = (e: any) => {
this.setState({ panModifier: e.target.value });
}
public onDragModifierChange = (e: any) => {
this.setState({ dragModifier: e.target.value });
}
public onZoomEnabledChange = (e: any) => {
this.setState({ isZoomEnabled: e.target.checked });
}
public onPanUpClick = (e: any) => {
this.chart.actualWindowPositionVertical -= 0.05;
}
public onPanDownClick = (e: any) => {
this.chart.actualWindowPositionVertical += 0.05;
}
public onPanLeftClick = (e: any) => {
this.chart.actualWindowPositionHorizontal -= 0.05;
}
public onPanRightClick = (e: any) => {
this.chart.actualWindowPositionHorizontal += 0.05;
}
public onZoomOutClick = (e: any) => {
if (this.chart.actualWindowPositionHorizontal > 0.025) {
this.chart.actualWindowPositionHorizontal -= 0.025;
}
if (this.chart.actualWindowPositionVertical > 0.025) {
this.chart.actualWindowPositionVertical -= 0.025;
}
if (this.chart.actualWindowScaleHorizontal < 1.0) {
this.chart.actualWindowScaleHorizontal += 0.05;
}
if (this.chart.actualWindowScaleVertical < 1.0) {
this.chart.actualWindowScaleVertical += 0.05;
}
}
public onZoomInClick = (e: any) => {
if (this.chart.actualWindowPositionHorizontal < 1.0) {
this.chart.actualWindowPositionHorizontal += 0.025;
}
if (this.chart.actualWindowPositionVertical < 1.0) {
this.chart.actualWindowPositionVertical += 0.025;
}
if (this.chart.actualWindowScaleHorizontal > 0.05) {
this.chart.actualWindowScaleHorizontal -= 0.05;
}
if (this.chart.actualWindowScaleVertical > 0.05) {
this.chart.actualWindowScaleVertical -= 0.05;
}
}
}
// rendering above class to the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<DataChartNavigation/>);
tsx
このサンプルが気に入りましたか? 完全な Ignite UI for Reactツールキットにアクセスして、すばやく独自のアプリの作成を開始します。無料でダウンロードできます。
このサンプルが気に入りましたか?完全な React ツールキットにアクセスして、すばやく独自のアプリの作成を開始します。無料でダウンロードできます。
ユーザー インタラクションによるチャート ナビゲーション
ズームがデフォルトでオンになっているかどうかは、使用しているチャートによって異なります。IgrCategoryChart
を使用している場合、デフォルトでオンになっていますが、IgrDataChart
ではオフです。+UI でナビゲーションを有効または無効にするには、ズームを無効にする方向に応じて、チャートの isHorizontalZoomEnabled
プロパティおよび/または isVerticalZoomEnabled
プロパティを設定する必要があります。
またマウスやタッチでズームまたはパンニングできます。チャートの defaultInteraction
プロパティは、マウスクリック イベントやタッチ イベントで何が起こるかを決定します。このプロパティはデフォルトで DragZoom
に設定されており、ズームを有効に設定すると、クリックしてドラッグした際にプロット領域の上に四角形のプレビューが配置され、グラフのズーム領域になります。この defaultInteraction
プロパティは、パンニングを許可する場合は DragPan
、これらの操作を禁止する場合は None
に設定することもできます。
タッチ、マウスとキーボードによるチャート ナビゲーション
React データ チャートのナビゲーションは、タッチ、マウスまたはキーボードのいずれかを使用して発生します。以下の操作は、デフォルトで以下のタッチ、マウスまたはキーボード操作を使用して呼び出すことができます。
- パン: キーボードの矢印キーを使用するか、Shift キーを押したまま、マウスでクリックしてドラッグするか、タッチで指を押して移動します。
- ズームイン: キーボードの PageUp キーを使用するか、マウスホイールを上に回転させるか、ピンチしてタッチでズームインします。
- ズームアウト: キーボードの PageDown キーを使用するか、マウスホイールを下に回転させるか、ピンチしてタッチでズームアウトします。
- チャート プロット領域に合わせる: キーボードのホームキーを使用します。これに対するマウスまたはタッチ操作はありません。
- 領域ズーム:
defaultInteraction
プロパティをデフォルトのDragZoom
に設定して、プロット領域内でマウスをクリックしてドラッグします。
ズーム操作とパン操作は、それぞれ dragModifier
プロパティと panModifier
プロパティを設定し、修飾キーを使用して有効にすることもできます。これらのプロパティは以下の修飾キーに設定することができ、押すと対応する操作が実行されます。
修飾値 | 対応するキー |
---|---|
Shift |
Shift |
Control |
Ctrl |
Windows |
Win |
Apple |
Apple |
None |
なし |
スクロールバーを使用したチャート ナビゲーション
チャートは、verticalViewScrollbarMode
プロパティと horizontalViewScrollbarMode
プロパティを有効にすることでスクロールできます。
これらは、次のオプションに構成できます:
Persistent
- チャートがズームインされている限り、スクロールバーは常に表示されたままになり、完全にズームアウトされるとフェードアウトします。Fading
- スクロールバーは使用後に消え、マウスがその位置に近づくと再び表示されます。FadeToLine
- ズームを使用していないときは、スクロールバーが細い線に縮小されます。None
- 既定値で、スクロールバーは表示されません。
次の例は、スクロールバーを有効にする方法を示しています。
//begin async data
export class MultipleStocks extends Array<Array<StockItem>> {
public static async fetch(): Promise<MultipleStocks> {
const dataSources: any[] = [
//await this.getAmazonStock(),
await this.getGoogleStock(),
await this.getAmazonStock(),
//await this.getTeslaStock()
];
return new Promise<MultipleStocks>((resolve, reject) => {
resolve(dataSources);
});
}
/** gets Amazon stock OHLC prices from a .JSON file */
public static async getAmazonStock(): Promise<StockItem[]> {
let url = "https://static.infragistics.com/xplatform/data/stocks/stockAmazon.json";
let response = await fetch(url);
let jsonData = await response.json();
let stockData = this.convertData(jsonData);
// setting data intent for Series Title, e.g. FinancialChart usage
(stockData as any).__dataIntents = {
close: ["SeriesTitle/Amazon"]
};
// console.log("fetchAmazonStock: ", stockData.length);
return new Promise<StockItem[]>((resolve, reject) => {
resolve(stockData);
});
}
/** gets Tesla stock OHLC prices from a .JSON file */
public static async getTeslaStock(): Promise<StockItem[]> {
let url = "https://static.infragistics.com/xplatform/data/stocks/stockTesla.json";
let response = await fetch(url);
let jsonData = await response.json();
let stockData = this.convertData(jsonData);
// setting data intent for Series Title, e.g. FinancialChart usage
(stockData as any).__dataIntents = {
close: ["SeriesTitle/Tesla"]
};
return new Promise<StockItem[]>((resolve, reject) => {
resolve(stockData);
});
}
/** gets Microsoft stock OHLC prices from a .JSON file */
public static async getMicrosoftStock(): Promise<StockItem[]> {
let url = "https://static.infragistics.com/xplatform/data/stocks/stockMicrosoft.json";
let response = await fetch(url);
let jsonData = await response.json();
let stockData = this.convertData(jsonData);
// setting data intent for Series Title, e.g. FinancialChart usage
(stockData as any).__dataIntents = {
close: ["SeriesTitle/Microsoft"]
};
return new Promise<StockItem[]>((resolve, reject) => {
resolve(stockData);
});
}
/** gets Google stock OHLC prices from a .JSON file */
public static async getGoogleStock(): Promise<StockItem[]> {
let url = "https://static.infragistics.com/xplatform/data/stocks/stockGoogle.json";
let response = await fetch(url);
let jsonData = await response.json();
let stockData = this.convertData(jsonData);
// setting data intent for Series Title, e.g. FinancialChart usage
(stockData as any).__dataIntents = {
close: ["SeriesTitle/Google"]
};
return new Promise<StockItem[]>((resolve, reject) => {
resolve(stockData);
});
}
public static convertData(jsonData: any[]): StockItem[] {
let stockItems: StockItem[] = [];
for (let json of jsonData) {
let parts = json.date.split("-"); // "2020-01-01"
let item = new StockItem();
item.date = new Date(parts[0], parts[1], parts[2],13,0,0);
item.open = json.open;
item.high = json.high;
item.low = json.low;
item.close = json.close;
item.volume = json.volume;
stockItems.push(item);
}
return stockItems;
}
}
export class StockItem {
public open?: number;
public close?: number;
public high?: number;
public low?: number;
public volume?: number;
public date?: Date;
}
//end async data
tsimport React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrFinancialChartModule, IgrDataChartInteractivityModule, IgrLegendModule } from "@infragistics/igniteui-react-charts";
import { IgrFinancialChart } from "@infragistics/igniteui-react-charts";
import { MultipleStocks } from './MultipleStocks';
const mods: any[] = [
IgrFinancialChartModule,
IgrDataChartInteractivityModule,
IgrLegendModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private chart: IgrFinancialChart
private chartRef(r: IgrFinancialChart) {
this.chart = r;
this.setState({});
}
constructor(props: any) {
super(props);
this.chartRef = this.chartRef.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample">
<div className="container fill">
<IgrFinancialChart
ref={this.chartRef}
isToolbarVisible="false"
isVerticalZoomEnabled="true"
isHorizontalZoomEnabled="true"
dataSource={this.multipleStocks}
verticalViewScrollbarMode="Fading"
horizontalViewScrollbarMode="Persistent"
zoomSliderType="None"
windowRect="0, 0, 0.5, 1">
</IgrFinancialChart>
</div>
</div>
);
}
private _multipleStocks: MultipleStocks = null;
private _isFetching: boolean = false;
public get multipleStocks(): MultipleStocks {
if (this._multipleStocks == null && !this._isFetching)
{
this._isFetching = true;
( async () => { this._multipleStocks = await (await MultipleStocks.fetch()); this.setState({}); })();
}
return this._multipleStocks;
}
}
// 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
コードによるチャート ナビゲーション
チャートのコード ナビゲーションは、IgrDataChart コントロールにのみ使用できます。
React データ チャートは、チャートでズームまたはパン操作が行われるたびに更新されるいくつかのナビゲーション プロパティを提供します。各プロパティは、チャートでズームやパンニングするためにコードで設定できます。以下は、これらのプロパティの一覧です。
windowPositionHorizontal
: コンテンツ ビュー長方形の X 部分を表す数値は、チャートで表示されます。windowPositionVertical
: 数値は、チャートに表示されるコンテンツビュー四角形のの Y 部分を表します。windowRect
: 長方形を表すRect
オブジェクトは、現在ビューにあるチャート部分を表します。例えば、windowRect
の "0, 0, 1, 1" はチャート全体になります。windowScaleHorizontal
: チャートで表示されるコンテンツ ビュー長方形の幅部分を表す数値。windowScaleVertical
: チャートで表示されるコンテンツ ビュー長方形の高さ部分を表す数値。
その他のリソース
関連するチャート機能の詳細については、以下のトピックを参照してください。
API リファレンス
以下は、上記のセクションで説明した API メンバーのリストです。