FlexChart入門

はじめに

FlexChartをKnockoutJSアプリケーションで使用する手順は以下のとおりです。

  1. KnockoutJS、Wijmo、およびWijmoのKnockoutJSバインディングへの参照を追加します。
  2. データとロジックを提供するビューモデルを追加します。
  3. FlexChartコントロールをページに追加してデータにバインドします。
  4. (オプション)コントロールの外観をカスタマイズするCSSを追加します。
<html> <head> <link rel="stylesheet" type="text/css" href="css/bootstrap.css"/> <link rel="stylesheet" type="text/css" href="css/wijmo.css" /> <link rel="stylesheet" href="styles/app.css" /> <script src="scripts/knockout.js" type="text/javascript"></script> <script src="scripts/wijmo.js" type="text/javascript"></script> <script src="scripts/wijmo.input.js" type="text/javascript"></script> <script src="scripts/wijmo.chart.js" type="text/javascript"></script> <script src="scripts/wijmo.knockout.js" type="text/javascript"></script> <script src="scripts/bindings/appBindings.js"></script> <script src="scripts/app.js"></script> <script src="scripts/viewmodels/appVM.js"></script> </head> <body> <!-- this is the chart --> <div data-bind="wjFlexChart: { itemsSource: data, bindingX: 'country' }"> <div data-bind="wjFlexChartSeries: { name: 'Sales', binding: 'sales' }"></div> <div data-bind="wjFlexChartSeries: { name: 'Expenses', binding: 'expenses' }"></div> <div data-bind="wjFlexChartSeries: { name: 'Downloads', binding: 'downloads' }"></div> </div> </body> </html>
// create and apply application view model function viewModel1() { // generate some random data var countries = 'US,Germany,UK,Japan,Italy,Greece'.split(','), data = []; for (var i = 0; i < countries.length; i++) { data.push({ country: countries[i], downloads: Math.round(Math.random() * 20000), sales: Math.random() * 10000, expenses: Math.random() * 5000 }); } // add data array to scope this.data = data; }; (function () { ko.applyBindings(new viewModel1()); })();
/* set default chart style */ .wj-flexchart { height: 400px; background-color: white; box-shadow: 4px 4px 10px 0px rgba(50, 50, 50, 0.75); padding: 8px; margin-bottom: 12px; }

結果(ライブ):

チャートタイプ

FlexChartコントロールでは、以下の3つのプロパティを使用してチャートタイプをカスタマイズできます。

  1. chartType: すべての系列に使用するデフォルトのチャートタイプを選択します。 これは個々の系列でオーバーライドできます。
  2. stacking: 系列を個別にプロットするか、積み重ねるか、または合計が100%になるように積み重ねるかを指定します。
  3. rotated: X軸が縦、Y軸が横になるようにXとYを入れ替えます。

以下の例で、これらのプロパティを変更したときにどのようになるかを確認できます。

<div data-bind="wjFlexChart: { itemsSource: data, bindingX: 'country', chartType: chartProps.chartType, stacking: chartProps.stacking, rotated: chartProps.rotated}"> <div data-bind="wjFlexChartSeries: { name: 'Sales', binding: 'sales' }"></div> <div data-bind="wjFlexChartSeries: { name: 'Expenses', binding: 'expenses' }"></div> <div data-bind="wjFlexChartSeries: { name: 'Downloads', binding: 'downloads' }"></div> </div> <div data-bind="wjMenu: { value: chartProps.chartType, header: 'チャートタイプ' }"> <span data-bind="wjMenuItem: { value: 'Column' }">Column</span> <span data-bind="wjMenuItem: { value: 'Bar' }">Bar</span> <span data-bind="wjMenuItem: { value: 'Scatter' }">Scatter</span> <span data-bind="wjMenuItem: { value: 'Line' }">Line</span> <span data-bind="wjMenuItem: { value: 'LineSymbols' }">LineSymbols</span> <span data-bind="wjMenuItem: { value: 'Area' }">Area</span> <span data-bind="wjMenuItem: { value: 'Spline' }">Spline</span> <span data-bind="wjMenuItem: { value: 'SplineSymbols' }">SplineSymbols</span> <span data-bind="wjMenuItem: { value: 'SplineArea' }">SplineArea</span> </div> <div data-bind="wjMenu: { value: chartProps.stacking, header: 'Stacking' }"> <span data-bind="wjMenuItem: { value: 'None' }">None</span> <span data-bind="wjMenuItem: { value: 'Stacked' }">Stacked</span> <span data-bind="wjMenuItem: { value: 'Stacked100pc' }">Stacked 100%</span> </div> <div data-bind="wjMenu: { value: chartProps.rotated, header: 'Rotated' }"> <span data-bind="wjMenuItem: { value: false }">False</span> <span data-bind="wjMenuItem: { value: true }">True</span> </div>
// add chart properties to view model this.chartProps = { chartType: ko.observable('Column'), stacking: ko.observable('None'), rotated: ko.observable(false), ............ };

結果(ライブ):

Column 横棒 散布図 Line 折れ線記号 スプライン スプライン記号 スプライン面
なし 積み上げ 100%積み上げ
False True

複合チャート

系列自体のchartTypeプロパティを設定することで、チャート系列ごとに異なるチャートタイプを使用できます。これにより、チャートのデフォルトチャートタイプがオーバーライドされます。

以下の例では、チャートのchartTypeプロパティはColumnに設定されていますが、Downloads系列ではこれをオーバーライドしてLineAndSymbolチャートタイプを使用しています。

<div data-bind="wjFlexChart: { itemsSource: data, bindingX: 'country', chartType: 'Column' }"> <div data-bind="wjFlexChartSeries: { name: 'Sales', binding: 'sales' }"></div> <div data-bind="wjFlexChartSeries: { name: 'Expenses', binding: 'expenses' }"></div> <div data-bind="wjFlexChartSeries: { name: 'Downloads', binding: 'downloads', chartType: 'LineSymbols' }"></div> </div>

結果(ライブ):

凡例とタイトル

チャート凡例の外観をカスタマイズするには、legendプロパティを使用します。チャートにタイトルを追加するには、headerfooter、および軸のtitleプロパティを使用します。

凡例とタイトルのスタイルはCSSを使用して設定できます。以下の[CSS]タブに、凡例とタイトルの外観のカスタマイズに使用されるルールを示します。これらはSVG要素なので、"color"ではなく"fill"などのCSS属性を使用する必要があります。

<div data-bind="wjFlexChart: { itemsSource: data, bindingX: 'country', header: chartProps.header, footer: chartProps.footer }"> <div data-bind="wjFlexChartLegend : { position: chartProps.legendPosition }"></div> <div data-bind="wjFlexChartAxis: { wjProperty: 'axisX', title: chartProps.titleX }"></div> <div data-bind="wjFlexChartAxis: { wjProperty: 'axisY', title: chartProps.titleY }"></div> <div data-bind="wjFlexChartSeries: { name: 'Sales', binding: 'sales' }"></div> <div data-bind="wjFlexChartSeries: { name: 'Expenses', binding: 'expenses' }"></div> <div data-bind="wjFlexChartSeries: { name: 'Downloads', binding: 'downloads' }"></div> </div> <dl class="dl-horizontal"> <dt>Header</dt><dd><input data-bind="value: chartProps.header, valueUpdate: 'input'" class="form-control"/></dd> <dt>Footer</dt><dd><input data-bind="value: chartProps.footer, valueUpdate: 'input'" class="form-control"/></dd> <dt>X軸タイトル</dt><dd><input data-bind="value: chartProps.titleX, valueUpdate: 'input'" class="form-control"/></dd> <dt>Y軸タイトル</dt><dd><input data-bind="value: chartProps.titleY, valueUpdate: 'input'" class="form-control"/></dd> <dt></dt> <dd> <div data-bind="wjMenu: { value: chartProps.legendPosition, header: 'Legend' }"> <span data-bind="wjMenuItem: { value: 'None' }">None</span> <span data-bind="wjMenuItem: { value: 'Left' }">Left</span> <span data-bind="wjMenuItem: { value: 'Top' }">Top</span> <span data-bind="wjMenuItem: { value: 'Right' }">Right</span> <span data-bind="wjMenuItem: { value: 'Bottom' }">Bottom</span> </div> </dd> </dl>
this.chartProps = { chartType: ko.observable('Column'), stacking: ko.observable('None'), legendPosition: ko.observable('Right'), rotated: ko.observable(false), header: ko.observable('Sample Chart'), footer: ko.observable('copyright (c) ComponentOne'), titleX: ko.observable('country'), titleY: ko.observable('amount'), };
.wj-flexchart .wj-title { font-weight: bold; } .wj-flexchart .wj-header .wj-title { font-size: 18pt; fill: #80044d; } .wj-flexchart .wj-footer .wj-title { fill: #80044d; } .wj-flexchart .wj-axis-x .wj-title, .wj-flexchart .wj-axis-y .wj-title { font-style: italic; }

結果(ライブ):

ヘッダ
フッタ
X軸タイトル
Y軸タイトル
なし

ツールチップ

FlexChartにはツールチップのサポートが組み込まれています。デフォルトでは、ユーザーがデータポイントにタッチするかマウスを合わせると、ツールチップが表示されます。

ツールチップの内容はテンプレートを使用して生成されます。テンプレートには以下のパラメーターを含めることができます。

デフォルトでは、ツールチップテンプレートは次のように設定されており<b>{seriesName}</b><br/>{x} {y}、上のチャートでこのデフォルトツールチップがどのように表示されるかを確認できます。この例では、ツールチップテンプレートは次のように設定されており<b>{seriesName}</b> <img src='resources/{x}.png'/><br/>{y}、国名が国旗に置き換えられています。

チャートのツールチップを無効にするには、テンプレートを空の文字列に設定します。

<div data-bind="wjFlexChart: { itemsSource: data, bindingX: 'country', tooltipContent: '<img src="resources/{x}.png"/> <b>{seriesName}</b><br/>{y}' }"> <div data-bind="wjFlexChartSeries: { name: 'Sales', binding: 'sales' }"></div> <div data-bind="wjFlexChartSeries: { name: 'Expenses', binding: 'expenses' }"></div> <div data-bind="wjFlexChartSeries: { name: 'Downloads', binding: 'downloads' }"></div> </div>

結果(ライブ):

系列のスタイルの設定

FlexChartでは、デフォルトパレットに基づいて各系列の色が自動的に選択されます。このパレットは、paletteプロパティを設定することでオーバーライドできます。 また、系列のstyleオブジェクトをSVGスタイル設定属性(fillstrokestrokeThicknessなど)を指定するオブジェクトに設定することによってデフォルト設定をオーバーライドすることもできます。

Series.styleプロパティは、Wijmoのスタイル設定はすべてCSSを通じてなされるという原則の例外です。この例外は、チャートには動的な系列を含むものが多いという事実を反映しています。動的な系列のスタイルを事前に設定することは不可能です。たとえば、株価チャートには、アプリケーションの実行中にユーザーが選択した系列が表示されます。

この例のチャートでは、styleプロパティとsymbolStyleプロパティを使用して各系列のスタイル属性を選択しています。

<div data-bind="wjFlexChart: { itemsSource: data, bindingX: 'country' }"> <div data-bind="wjFlexChartSeries: { name: 'Sales', binding: 'sales', style: {fill:'green', stroke:'darkgreen', 'stroke-width': '1'} }"></div> <div data-bind="wjFlexChartSeries: { name: 'Expenses', binding: 'expenses', style: {fill:'red', stroke:'darkred', 'stroke-width': '1'} }"></div> <div data-bind="wjFlexChartSeries: { name: 'Downloads', binding: 'downloads' , chartType: 'LineSymbols', style: { stroke:'orange', 'stroke-width': '5'}, symbolStyle: {fill:'gold', stroke:'gold' } }"></div> </div>

結果(ライブ):

軸のカスタマイズ

チャートの軸をカスタマイズするには、範囲(最小値と最大値)、ラベル書式、目盛間隔、罫線などの軸プロパティを使用します。

Axisクラスには、各機能をオン/オフできるブール型プロパティがあります(axisLinelabelsmajorTickMarksmajorGrid)。オンにした機能の外観はCSSを使用してスタイル設定できます。

<div data-bind="wjFlexChart: { itemsSource: data, bindingX: 'country' }"> <div data-bind="wjFlexChartAxis: { wjProperty: 'axisX', axisLine: true, majorGrid: true }"></div> <div data-bind="wjFlexChartAxis: { wjProperty: 'axisY', format: 'c0', max: 10000, majorUnit: 2000, axisLine: true, majorGrid: true }"></div> <div data-bind="wjFlexChartSeries: { name: 'Sales', binding: 'sales' }"></div> <div data-bind="wjFlexChartSeries: { name: 'Expenses', binding: 'expenses' }"></div> </div>

結果(ライブ):

テーマ

FlexChartの外観はCSSで定義されます。デフォルトテーマに加えてプロフェッショナルなデザインのテーマが多数用意されており、すべてのWijmoコントロールの外観をカスタマイズして一貫性のある魅力的な見た目を提供できます。

チャートの外観をカスタマイズするには、スタイル設定する要素を調べて、それらの要素に適用するCSSルールを作成します。

たとえば、IEまたはChromeでいずれかのX軸ラベルを右クリックすると、それが"wj-label"クラスを持つ要素であることがわかります。この要素は"wj-axis-x"クラスを持つ要素に含まれており、さらにその要素は"wj-flexchart"クラスを持つ最上位コントロール要素に含まれています。 この例の最初のCSSルールは、この情報を使用してXラベルをカスタマイズします。 このルールのセレクターには、親要素が"wj-flexchart"と"custom-flex-chart"の両方のクラスを持たなければならないという要件が追加されています。 これがなければ、このルールはページ上のすべてのチャートに適用されます。

<div class="custom-flex-chart" data-bind="wjFlexChart: { itemsSource: data, bindingX: 'country' }"> <div data-bind="wjFlexChartSeries: { name: 'Sales', binding: 'sales' }"></div> <div data-bind="wjFlexChartSeries: { name: 'Expenses', binding: 'expenses' }"></div> <div data-bind="wjFlexChartSeries: { name: 'Downloads', binding: 'downloads' }"></div> </div>
/* custom chart theme */ .custom-flex-chart.wj-flexchart .wj-axis-x .wj-label { font-family: Courier New, Courier, monospace; font-weight: bold; } .custom-flex-chart.wj-flexchart .wj-legend .wj-label { font-family: Courier New, Courier, monospace; font-weight: bold; } .custom-flex-chart.wj-flexchart .wj-legend > rect { fill: #f8f8f8; stroke: #c0c0c0; } .custom-flex-chart.wj-flexchart .wj-plot-area > rect { fill: #f8f8f8; stroke: #c0c0c0; }

結果(ライブ):

選択モード

FlexChartでは、系列またはデータポイントをクリックまたはタッチすることで、それらを選択できます。 系列単位またはデータポイント単位で選択できるようにするか、あるいはいずれも選択できないようにするかを指定するには、selectionModeプロパティを使用します(選択はデフォルトではオフになっています)。

selectionModeプロパティをSeriesまたはPointに設定すると、ユーザーがマウスをクリックしたときにSelectionプロパティが更新され、選択されたチャート要素に"wj-state-selected"クラスが適用されます。

Selectionプロパティは現在選択されている系列を返します。現在選択されているデータポイントを取得するには、この例で示すように、Series.collectionView.currentItemプロパティを使用して、選択された系列内の現在選択されている項目を取得します。

<div data-bind="wjFlexChart: { itemsSource: data, bindingX: 'country', tooltipContent: '', chartType: chartProps.chartType, selectionMode: chartProps.selectionMode, selection: chartProps.selection, selectionChanged: selectionChangedEH }"< <div data-bind="wjFlexChartSeries: { name: 'Sales', binding: 'sales' }"<</div< <div data-bind="wjFlexChartSeries: { name: 'Expenses', binding: 'expenses' }"<</div< <div data-bind="wjFlexChartSeries: { name: 'Downloads', binding: 'downloads' }"<</div< </div< <div data-bind="wjMenu: { value: chartProps.selectionMode, header: '選択モード' }"< <span data-bind="wjMenuItem: { value: 'None' }"<None</span< <span data-bind="wjMenuItem: { value: 'Series' }"<Series</span< <span data-bind="wjMenuItem: { value: 'Point' }"<Point</span< </div< <div data-bind="wjMenu: { value: chartProps.chartType, header: 'チャートタイプ' }"< <span data-bind="wjMenuItem: { value: 'Column' }"<Column</span< <span data-bind="wjMenuItem: { value: 'Bar' }"<Bar</span< <span data-bind="wjMenuItem: { value: 'Scatter' }"<Scatter</span< <span data-bind="wjMenuItem: { value: 'Line' }"<Line</span< <span data-bind="wjMenuItem: { value: 'LineSymbols' }"<LineSymbols</span< <span data-bind="wjMenuItem: { value: 'Area' }"<Area</span< <span data-bind="wjMenuItem: { value: 'Spline' }"<Spline</span< <span data-bind="wjMenuItem: { value: 'SplineSymbols' }"<SplineSymbols</span< <span data-bind="wjMenuItem: { value: 'SplineArea' }"<SplineArea</span< </div< <div data-bind="if: chartProps.selectionMode() != 'None' && chartProps.selection()"< <h4< 現在の選択</h4< <p< Series: <b<<span data-bind="text: chartProps.selection().name"<</span<</b<</p< <div data-bind="ifnot: chartProps.selectionMode() != 'Point' || chartProps.selectionPoint() == null"< <dl class="dl-horizontal" data-bind="with: chartProps.selectionPoint"< <dt<Country</dt<<dd data-bind="text: country" <</dd< <dt<Sales</dt<<dd data-bind="text: $parent.format(sales, 'n2')"<</dd< <dt<Expenses</dt<<dd data-bind="text: $parent.format(expenses, 'n2')"<</dd< <dt<Downloads</dt<<dd data-bind="text: $parent.format(downloads, 'n0')"<</dd< </dl< </div< </div<
this.chartProps = { chartType: ko.observable('Column'), stacking: ko.observable('None'), legendPosition: ko.observable('Right'), rotated: ko.observable(false), header: ko.observable('Sample Chart'), footer: ko.observable('copyright (c) ComponentOne'), titleX: ko.observable('country'), titleY: ko.observable('amount'), selectionMode: ko.observable('Series'), selection: ko.observable(null), selectionPoint: ko.observable() }; // update the selectionPoint observable on selection change this.selectionChangedEH = function (data, sender, args) { var curSel = sender.selection; self.chartProps.selectionPoint(curSel && curSel.collectionView.currentItem); }

結果(ライブ):

なし Series Point
Column 横棒 散布図 Line 折れ線記号 スプライン スプライン記号 スプライン面

現在の選択

系列:

Country
Sales
Expenses
Downloads

系列の表示/非表示

Seriesクラスのvisibilityプロパティを使用して、系列をチャートと凡例の両方に表示するか、凡例のみに表示するか、表示しないかを指定できます。

このサンプルは、visibilityプロパティを使用して、以下の2通りの方法で系列の表示/非表示を切り替える方法を示します。

  1. 凡例エントリをクリックする:
    チャートバインディングによってチャートの$1プロパティがtrueに設定されています。そのため、系列の凡例エントリをクリックすると、その系列のvisibilityプロパティが切り替わります。
  2. チェックボックスを使用する:
    このページでは、Knockoutの書き込み可能な計算されたobservableを使用して、入力コントロールを各系列のvisibilityプロパティにバインドして、boolean値をSeriesVisibility値に変換しています。
<div data-bind="wjFlexChart: { itemsSource: data, legendToggle: true }"< <div data-bind="wjFlexChartSeries: { name: 'Sales', binding: 'sales', visibility: visibility1 }"<</div< <div data-bind="wjFlexChartSeries: { name: 'Expenses', binding: 'expenses', visibility: visibility2 }"<</div< <div data-bind="wjFlexChartSeries: { name: 'Downloads', binding: 'downloads', visibility: visibility3 }"<</div< </div< <!-- toggle series with checkboxes --< Sales <input type="checkbox" data-bind="checked: ko.computed(null, visibility1, visibilityToBool)"/<<br /< Expenses <input type="checkbox" data-bind="checked: ko.computed(null, visibility2, visibilityToBool)"/<<br /< Downloads <input type="checkbox" data-bind="checked: ko.computed(null, visibility3, visibilityToBool)"/<<br /<
this.visibility1 = ko.observable(); this.visibility2 = ko.observable(); this.visibility3 = ko.observable(); // SeriesVisibility-to-boolean writable computed observable. 'this' references a source SeriesVisibility observable. this.visibilityToBool = { read: function () { var vis = this(); return vis === wijmo.chart.SeriesVisibility.Visible || vis === wijmo.chart.SeriesVisibility.Plot; }, write: function (value) { this(value ? wijmo.chart.SeriesVisibility.Visible : wijmo.chart.SeriesVisibility.Legend); } }

結果(ライブ):

Sales
Expenses
Downloads

動的チャート

FlexChartはICollectionViewを内部で使用するため、データソースに加えた変更は自動的にチャートに反映されます。

このサンプルでは、タイマーを使用してデータソースに項目を追加し、古い項目を破棄して総件数を200件に維持しています。その結果、新しいデータが到着するにつれてスクロールする動的チャートになります。

<div data-bind="wjFlexChart: { itemsSource: trafficData, chartType: 'Area', stacking: 'Stacked', bindingX: 'time' }"> <div data-bind="wjFlexChartAxis: { wjProperty: 'axisX', format: 'mm:ss' }"></div> <div data-bind="wjFlexChartSeries: { name: 'Trucks', binding: 'trucks' }"></div> <div data-bind="wjFlexChartSeries: { name: 'Ships', binding: 'ships' }"></div> <div data-bind="wjFlexChartSeries: { name: 'Planes', binding: 'planes' }"></div> </div> <dl class="dl-horizontal"> <dt>更新速度</dt> <dd> <div class="btn-group"> <button type="button" class="btn btn-default" data-bind="click: setInterval.bind($data, 200)">Slow</button> <button type="button" class="btn btn-default" data-bind="click: setInterval.bind($data, 100)">Medium</button> <button type="button" class="btn btn-default" data-bind="click: setInterval.bind($data, 50)">Fast</button> <button type="button" class="btn btn-default" data-bind="click: setInterval.bind($data, 0)">Stop</button> </div> </dd> </dl>
var toAddData; this.trafficData = new wijmo.collections.ObservableArray(); this.setInterval = function (interval) { if (toAddData) { clearTimeout(toAddData); toAddData = null; } self.interval = interval; if (interval) { toAddData = setTimeout(addTrafficItem); } }; this.setInterval(500); function addTrafficItem() { // add random data, limit array length ... // keep adding ... }

結果(ライブ):

更新速度