15

我正在尝试配置一个谷歌柱形图以显示整数的垂直轴,但是当它显示一个小的数字(如 1)时,它也会显示 0.25、0.50 等。

有没有办法改变这个?我浏览了文档,找不到任何似乎相关的内容。

谢谢

4

4 回答 4

27

简单的答案:是的,但它很复杂。

如果您只想将数字显示为整数,那么很容易:

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'}}
          );
}

如果你去谷歌游乐场,你会注意到轴标签是 0、2.5、5、7.5、10。通过向 vAxis 添加格式:'0',它将只显示整数,所以我的标签变为 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;

这里有几个问题(不幸的是)。首先是我使用网格线的数量来确定最小/最大值——你想弄清楚你应该有多少网格线来使用漂亮的整数。我认为最简单的方法如下(仅限伪代码):

// 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
    }
}

然后将网格线选项 (vAxis.gridlines) 设置为上述变量,将 max 设置为 newMax,将 min 设置为 newMin。那应该给你整数轴标签。

注意:如果您的数字非常小,则上述功能可能不起作用。该功能也未经过测试,因此请根据您自己的时间检查一些示例,如果它不能正常工作,请告诉我。

于 2013-01-23T04:13:35.583 回答
7

只是为了扩展jmac的答案。如果您知道图表的最大值,解决方案很简单,只要maxvalue确保您始终为图表使用相同的高度。

如果您的内容非常动态,那么他的解决方案似乎是唯一的。

于 2013-08-23T10:05:41.867 回答
1

在遇到同样的问题后,我得出了非常简单的解决方案。右键单击您的图表,选择“高级编辑”,然后:

1)将图表的垂直线数量设置为“自动”(或手动等于数据列的数量) - 随后谷歌不必计算非整数断点。为我做了诀窍。

2)或选择“将标签视为文本”,这将使它们保持不变。

于 2016-08-17T10:05:19.223 回答
0

我正在用 Java 编程以根据动态数据生成 html 文件并重用该类。我将 ArrayList() 用于 BarChart html 生成的数据和选项部分。

我的数据来自一个 Guava Multiset,它被初始化为 TreeMultiset。

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

options = new ArrayList<String>();

我需要确保我的物品井然有序,所以我制作了物品清单的副本。

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

对于我需要动态的每个选项,我将添加一个字符串。例如 key 是我的图表的标题。

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

我要做的第一件事是在已排序的 Multiset 中获得最多的出现次数。

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

然后我想向 hAxis 添加一些刻度。我有大约十几个数据集。当最大数字低于 100 时,它看起来不错,但是当数字为数百或数千时,我需要根据该值过滤“mod”函数。

另一个烦恼是我希望至少有一条线超出最大值。我也需要调整一下。

所以将字符串添加到我的选项字符串数组中:

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

IntStream 生成值之间的所有数字。max+5 允许在最长条右侧的最后一条网格线,也就是比间隔的大小大一。过滤器只显示可以修改 4 的数字,我稍后会调整的间隔。.boxed() 防止整数被错误地解释为打印。.collect 只是将它们包装成一个字符串数组。

然后我可以只使用 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>
于 2018-05-06T22:33:51.560 回答