【问题标题】:Highcharts Plot Reciprocal Values For Column HeightHighcharts 绘制列高的倒数
【发布时间】:2016-11-18 06:22:19
【问题描述】:

我正在尝试绘制一个分类多轴柱状图的排名。排名第一的应该是最高的列,最低的排名应该是最短的。

基本上我希望条形的高度是倒数。

非常接近:

var player_name_array = ["Aaron Rodgers", "Andrew Luck", "Drew Brees", "Russell Wilson", "Peyton Manning", "Ryan Tannehill", "Tony Romo", "Matt Ryan", "Cam Newton", "Ben Roethlisberger", "Eli Manning", "Philip Rivers", "Colin Kaepernick", "Teddy Bridgewater", "Marcus Mariota", "Matthew Stafford", "Robert Griffin III", "Joe Flacco", "Jay Cutler", "Sam Bradford"];

var series_array = [{"name":"espn_ranking","data":[38,33,63,64,67,95,75,85,96,76,999,999,999,999,999,999,999,999,999,999]}];

rankings_chart = new Highcharts.Chart({
        chart: {
            renderTo:'rankings_chart',
            type: 'column'
        },
        title: {
            text: 'Draft Rankings'
        },
        subtitle: {
            text: 'Source: The Internet'
        },
        xAxis: {
            categories: player_name_array,
            crosshair: true
        },
        yAxis: {
            type: 'logarithmic',
            //reversed: true,
            title: {
                text: 'Draft Rankings'
            }
        },
        tooltip: {
            headerFormat: '<span style="font-size:14px"><b>{point.key}</b></span><table>',
            pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +
                '<td style="padding:0"><b>{point.y}</b></td></tr>',
            footerFormat: '</table>',
            shared: true,
            useHTML: true
        },
        plotOptions: {
            series: {
                stacking:'normal',
            },
            column: {
                pointPadding: 0.2,
                borderWidth: 0
            }
        },
        rangeSelector: {
          selected: 1
        },
        series: series_array
  });
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="rankings_chart" ></div>

问题是列从顶部下降,排名为 1 的列仍然是最小的列。

有什么方法可以为每列的高度添加一个函数吗?

【问题讨论】:

  • 嗨,布莱恩!你能为你的图表提供jsfillde或jsbin吗?
  • 当然@SagarR!查看更新。
  • 如果您能够添加一些绘图来显示您想要实现的目标,那就太好了。例如,您想获得类似于此图表的内容吗? jsfiddle.net/8yohn998
  • 给你@SagarR 查看代码sn-p。
  • 这是我构建的应用程序的演示。 youtube.com/watch?v=vqtlBKLxedI 我所说的功能是在视频的前 30 秒。现在我今年将它移植到 html 上。

标签: javascript highcharts yaxis


【解决方案1】:

这是一个有趣且有趣的谜题!

我认为 nagyben 的答案非常好,我的代码基于他们将分数反转得出相对排名的方法。

这是我基于该概念创建的一个工作小提琴,以及一些增强功能,我在下面分享了这些功能:https://jsfiddle.net/brightmatrix/j4ug40qm/

  • 我添加了一个排序功能,以降序排列数据,无论数据在原始两个数组中如何排列。为了做到这一点,我首先将两个数组组合成一个 Javascript 对象。
  • 我将格式从柱形(垂直)图表更改为条形(水平)图表。这将使玩家名称对您的用户更具可读性。
  • 我更新了工具提示,以在用户将光标悬停在特定栏上时显示玩家的排名。
  • 我删除了此类图表中不需要的某些图表元素,例如图例、网格线和轴标签(由于您只是进行排名,因此每个条的真实值与用户)。

这是我内置的排序代码:

// combine both arrays into a single object so we can then sort them by rank
var rankArray = [];
$.each(player_name_array, function(index) {
  tempArray = {};
  tempArray['name'] = player_name_array[index];
  tempArray['y'] = 1 / series_array[index];
  rankArray.push(tempArray);
});

// sort the objects by rank (the "y" value) in descending order (due to the inverse)
// see accepted answer by Stobor at:
// http://stackoverflow.com/questions/979256/sorting-an-array-of-javascript-objects
rankArray.sort(function(a, b) {
  return parseFloat(b.y) - parseFloat(a.y);
});

这是更新后的图表选项:

rankings_chart = new Highcharts.Chart({
  chart: {
    renderTo:'rankings_chart',
    type: 'bar'  // chose a bar vs. column chart so the player names are easier to read
  },
  title: { text: 'Draft Rankings' },
  subtitle: { text: 'Source: The Internet' },
  legend: { enabled: false },  // there is no legend needed for this chart
  xAxis: {
    type: 'category',
    tickmarkPlacement: 'on'  // place the lines directly on the player's name
  },
  yAxis: {
    // we're measuring by rank, so there's no need for labels, gridlines, or a title
    labels: { enabled: false },
    title: { enabled: false },
    gridLineWidth: 0
  },
  tooltip: {
    pointFormatter: function() {
        // show the rank of the player, based on their sort order
      return 'ranked #' + parseInt(this.x+1);
    }
  },
  plotOptions: {
    bar: {
      groupPadding: 0.1,
      pointPadding: 0.2,
      borderWidth: 0
    }
  },
  series : [{
    name : 'Draft Data',
    data : rankArray  // our array will look like this: [{name: 'NAME', y: 0}, ...]
  }]
});

结果如下:

希望这对您的图表转换有所帮助。

【讨论】:

  • 非常好的解决方案! +1
【解决方案2】:

将您的数据设置为玩家排名的倒数:

var rankings = [38,33,63,64,67,95,75,85,96,76,999,999,999,999,999,999,999,999,999,999]
var inv_rankings = [];
for (i = 0; i < rankings.length; i++) {
    inv_rankings[i] = 1 / rankings[i]
}

将您的 Highcharts 数据设置为您的逆排名:

series: {
    name: "espn_ranking",
    data: inv_rankings
}

对数据标签和工具提示使用格式化程序以返回倒数的倒数(即原始值):

plotOptions: {
    series: {
        dataLabels: {
            enabled: true,
            formatter: function() {
                return 1 / this.y;
            }
        }
    },
    tooltip: {
        pointFormatter: function() {
            return 1 / this.y;
        }
    }
}

Working fiddle

【讨论】:

    【解决方案3】:

    由于您似乎已经为您的数据设置了 999 的上限,我建议您简单地绘制 1000-x。

    一种方法是让 highcharts 在系列的函数中进行数学运算:

    series : [{
            name : 'Draft Data',
            data : (function () {
                // generate an array of random data
                var data = [];
    
                for (var x = 0;x <= series_array.length; x += 1) {
                    data.push([
                        1000-series_array[x];
                    ]);
                }
                return data;
            }())
        }]
    

    JSFiddle:http://jsfiddle.net/hmjnz/4/

    在这种情况下,我会隐藏 yaxis 标签,而是将注释放在具有排名的列上。

    另外,我会讨论柱形图是否足以表示此类数据。

    【讨论】:

    • 1000-x的问题是排名第一的玩家看起来和100几乎一样,数值相差很大。
    • 虽然确实如此,但您的数据也存在很大问题。如果我要实现这一点,我根本不会显示 999 个播放器,因为那里没有信息,它只会扼杀你的分辨率。我的建议是将他们从图表中删除,剪辑到较低的数字并在单独的列表中显示未排名(我假设)的玩家。
    猜你喜欢
    • 2021-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 2018-06-21
    相关资源
    最近更新 更多