web-dev-qa-db-ja.com

Googleチャートの縦軸を整数で

縦軸を整数で表示するようにGoogle縦棒グラフを構成しようとしていますが、1などの小さい数値を表示している場合は、0.25、0.50なども表示されます。

これを変更する方法はありますか?ドキュメントを確認しましたが、関連があると思われるものを見つけることができません。

ありがとう

15
tatty27

簡単な答え:はい、しかしそれは複雑です。

数値を整数としてdisplayしたい場合は、簡単です:

function drawVisualization() {
  // Create and populate the data table.
  var data = google.visualization.arrayToDataTable([
    ['x', 'Cats', 'Blanket 1', 'Blanket 2'],
    ['A',   1,       1,           0.5],
    ['B',   2,       0.5,         1],
    ['C',   4,       1,           0.5],
    ['D',   8,       0.5,         1],
    ['E',   7,       1,           0.5],
    ['F',   7,       0.5,         1],
    ['G',   8,       1,           0.5],
    ['H',   4,       0.5,         1],
    ['I',   2,       1,           0.5],
    ['J',   3.5,     0.5,         1],
    ['K',   3,       1,           0.5],
    ['L',   3.5,     0.5,         1],
    ['M',   1,       1,           0.5],
    ['N',   1,       0.5,         1]
  ]);

  // Create and draw the visualization.
  new google.visualization.LineChart(document.getElementById('visualization')).
      draw(data, {curveType: "function",
                  width: 500, height: 400,
                  vAxis: {maxValue: 10, format: '0'}}
          );
}

google playground に移動すると、軸のラベルが0、2.5、5、7.5、10であることがわかります。「0」という形式をvAxisに追加すると、整数のみが表示されます。したがって、私のラベルは0、3、5、8、10になります。しかし、8は5と10の中間として表示されるため、これは理想的ではありません。数値は実際には7.5であり、丸められているためです。

軸のスケール/ラベルを変更する機能は制限されています。そして、あなたが求めていることを行うには、特別なJavaScriptを使用して適切なスケールとグリッドラインの数を作成し、ファンキーな数に分解しないようにします。

基本的に、最大値と最小値、およびグリッド線の数によって、整数だけが得られるように簡単に除算できるようにする必要があります。そのためには、ファンキーな新しいロジックを作成する必要があります。以下は、適切な最小/最大軸値を取得できるようにするサンプルコードです。

// Take the Max/Min of all data values in all graphs
var totalMax = 345;
var totalMin = -123;

// Figure out the largest number (positive or negative)
var biggestNumber = Math.max(Math.abs(totalMax),Math.abs(totalMin));

// Round to an exponent of 10 appropriate for the biggest number
var roundingExp = Math.floor(Math.log(biggestNumber) / Math.LN10);
var roundingDec = Math.pow(10,roundingExp);

// Round your max and min to the nearest exponent of 10
var newMax = Math.ceil(totalMax/roundingDec)*roundingDec;
var newMin = Math.floor(totalMin/roundingDec)*roundingDec;

// Determine the range of your values
var range = newMax - newMin;

// Define the number of gridlines (default 5)
var gridlines = 5;

// Determine an appropriate gap between gridlines
var interval = range / (gridlines - 1);

// Round that interval up to the exponent of 10
var newInterval = Math.ceil(interval/roundingDec)*roundingDec;

// Re-round your max and min to the new interval
var finalMax = Math.ceil(totalMax/newInterval)*newInterval;
var finalMin = Math.floor(totalMin/newInterval)*newInterval;

ここにはいくつかの問題があります(残念ながら)。 1つ目は、グリッド線の数を使用して最小値/最大値を決定していることです。ニースの整数を使用するために必要なグリッド線の数を把握する必要があります。これを行う最も簡単な方法は、次のようになると思います(疑似コードのみ)。

// Take the Max/Min of all data values in all graphs
var totalMax = 3;
var totalMin = -1;

// Figure out the largest number (positive or negative)
var biggestNumber = Math.max(Math.abs(totalMax),Math.abs(totalMin));

// Round to an exponent of 10 appropriate for the biggest number
var roundingExp = Math.floor(Math.log(biggestNumber) / Math.LN10);
var roundingDec = Math.pow(10,roundingExp);

// Round your max and min to the nearest exponent of 10
var newMax = Math.ceil(totalMax/roundingDec)*roundingDec;
var newMin = Math.floor(totalMin/roundingDec)*roundingDec;

// Determine the range of your values
var range = newMax - newMin;

// Calculate the best factor for number of gridlines (2-5 gridlines)
// If the range of numbers divided by 2 or 5 is a whole number, use it
for (var i = 2; i <= 5; ++i) {
    if (Math.round(range/i) = range/i) {
        var gridlines = i
    }
}

次に、gridlinesオプション(vAxis.gridlines)を上記の変数に設定し、maxをnewMaxに、minをnewMinに設定します。整数の軸ラベルが表示されます。

注:数値が本当に小さい場合、上記の関数は機能しない可能性があります。関数もテストされていないので、実際の時間にいくつかの例と照合して、正しく機能しない場合はお知らせください。

25
jmac

Jmacの答えを拡張するだけです。グラフの最大値がわかっている場合、maxvalueを使用すると、解決策が簡単になり、グラフに常に同じ高さを使用できるようになります。

コンテンツが非常に動的である場合は、彼のソリューションが唯一のようです。

7
Mathijs Segers

同じ問題に取り組んだ後、私は非常に簡単な解決策を見つけました。チャートを右クリックし、「高度な編集」を選択して、

1)グラフの垂直線の量を「自動」(または手動でデータ列の数に等しい)に設定します-その後、グーグルは非整数のブレークポイントを計算する必要はありません。私のためにトリックをしました。

2)または、[ラベルをテキストとして扱う]を選択します。これにより、ラベルがそのまま残ります。

1
The D

私はJavaでプログラミングして、動的データに基づいてhtmlファイルを生成し、クラスを再利用しています。BarCharthtml生成のデータ部分とオプション部分の両方にArrayList()を使用しています。

私のデータは、TreeMultisetとして初期化されるGuava Multisetで取得されます。

Multiset<String> items = TreeMultiset.create();

options = new ArrayList<String>();

アイテムの順序が正しいことを確認する必要があるため、アイテムリストのコピーを作成します。

Multiset<String> occurrences = Multisets.copyHighestCountFirst(items);

動的にする必要があるオプションごとに、文字列を追加します。たとえば、キーはグラフのタイトルです。

options.add("\n      title : '"+key+"'");

私が最初に行うことは、ソートされたマルチセットで最も多くのオカレンスを取得することです。

int max = occurrences.count(Iterables.get(occurrences,  0));

次に、いくつかのティックをhAxisに追加します。私は約12のデータセットを持っています。最大数が100未満の場合は見栄えがいいですが、数が数百または数千の場合は、値に基づいて「mod」関数をフィルタリングする必要があります。

もう1つの問題は、最大値を超える行を少なくとも1つは欲しかったことです。私もそれを調整する必要があります。

だから私のオプション文字列配列に文字列を追加します:

options.add("\n         hAxis : { title : 'Count', ticks: <<"+      
          IntStream.range(0, max+5)
                   .filter(x -> x % 4 == 0)
                   .boxed()
                   .collect(Collectors.toList())
         +">> }");      

IntStreamは、値の間にあるすべての数値を生成します。 max + 5は、最も長いバーの右側に最後のグリッド線を1つ許可します。これは、間隔のサイズよりも大きくなります。フィルターは、4で変更できる数値のみを表示します。間隔は後で調整します。 .boxed()は、整数が印刷用に誤って解釈されるのを防ぎます。 .collectは、それらをString配列にラップするだけです。

次に、options.toString()を使用してストロングを印刷できますが、印刷の場合は、オプションリストの配列の括弧を削除する必要がありますが、目盛りは削除しません。例えば[と]。上を見れば、それが「<<」と「>>」を使用した理由です。

  String optionstr = stripBrackets(options.toString())
                          .replaceAll("<<", "[")
                          .replaceAll(">>", "]");

私がこのソリューションを投稿しているのは、実際の軸のラベル付けを大幅に制御できるためです。次に行う間隔を動的にすることを除いて、これはすべてのデータセットに対して非常にうまく機能します。

これが、印刷された最終的なHTMLです。括弧で囲まれたティックパラメータではありません。

<html>
  <head>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script type="text/javascript">
      google.charts.load('current', {'packages':['corechart']});
      google.charts.setOnLoadCallback(drawVisualization);

      function drawVisualization() {
        var data = google.visualization.arrayToDataTable([
          [ 'Signals', 'Count', { role: 'style' }], 
          [ 'Agreements' , 6, 'blue' ], 
          [ 'ProductsMarkets' , 3, 'blue' ], 
          [ 'DebtEquity' , 1, 'blue' ], 
          [ 'Executive' , 1, 'blue' ], 
          [ 'Securities' , 1, 'blue' ]]);

    var options = {
         title : 'Signals', 
         vAxis : { title : 'Signals' }, 
         hAxis : { title : 'Count', ticks: [0, 4, 8] }, 
         bars: 'horizontal', 
         bar : { groupWidth : "95%" }, 
         legend : { position : "none" }
    };

    var chart = new google.visualization.BarChart(document.getElementById('signals'));
    chart.draw(data, options);
    }
    </script>
  </head>
  <body>
    <div id="signals" style="width: 900px; height: 500px;"></div>
  </body>
</html>
0