highcharts 如何更改高图中条形图的宽度?

bkhjykvo  于 2023-06-23  发布在  Highcharts
关注(0)|答案(5)|浏览(176)

对于像this one这样的条形图,可以改变条形图的宽度来表示另一个数据属性,比如水果的重量。水果越重,酒吧越厚。
你玩的脚本here。我对其他JavaScript绘图库持开放态度,只要它们是免费的,它们就可以做到这一点。

$(function () {
    var chart;
    $(document).ready(function() {
        chart = new Highcharts.Chart({
            chart: {
                renderTo: 'container',
                type: 'column'
            },
            title: {
                text: 'Column chart with negative values'
            },
            xAxis: {
                categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
            },
            tooltip: {
                formatter: function() {
                    return ''+
                        this.series.name +': '+ this.y +'';
                }
            },
            credits: {
                enabled: false
            },
            series: [{
                name: 'John',
                data: [5, 3, 4, 7, 2]
                // I would like something like this (3.5, 6 etc is the width) :
                // data: [[5, 3.4], [3, 6], [4, 3.4], [7, 2], [2, 5]]
            }, {
                name: 'Jane',
                data: [2, -2, -3, 2, 1]
            }, {
                name: 'Joe',
                data: [3, 4, 4, -2, 5]
            }]
        });
    });

});​
bzzcjhmw

bzzcjhmw1#

Fusioncharts可能是最好的选择,如果你有一个许可证,它做更优化的Marimekko图表...
我做了一些工作,试图在highcharts中获得Marimekko图表解决方案。它并不完美,但近似于在Fusion Charts页面上找到的第一个Marimekko图表示例。
http://www.fusioncharts.com/resources/chart-tutorials/understanding-the-marimekko-chart/
关键是使用dateTime轴,因为该模式为您在X轴上分配点和线的方式提供了更大的灵活性,从而使您能够在此轴上构建可变大小的“条”。我使用0-1000秒的空间和图表之外的数字Map到这个规模,以近似的百分比值,以步伐您的垂直线。这里(http://jsfiddle.net/miken/598d9/2/)是一个创建可变宽度柱形图的jsfiddle示例。

$(function () {

    var chart;
        Highcharts.setOptions({
            colors: [ '#75FFFF', '#55CCDD', '#60DD60' ]
        });
        $(document).ready(function() {
            var CATEGORY = {  // number out of 1000
            0: '',    
            475: 'Desktops',
            763: 'Laptops',
            1000: 'Tablets'  
        };
        var BucketSize = {  
            0: 475,
            475: 475,
            763: 288,
            1000: 237   
        };
        chart = new Highcharts.Chart({
            chart: {
                renderTo: 'container',
                type: 'area'
            },
            title: {
                text: 'Contribution to Overall Sales by Brand & Category (in US$)<br>(2011-12)'
            },
            xAxis: {
                min: 0,
                max: 1000,
                title: {
                    text: '<b>CATEGORY</b>'
                },
                tickInterval: 1,
                minTickInterval: 1,
                dateTimeLabelFormats: {
                    month: '%b'
                },
                labels: {
                    rotation: -60,
                    align: 'right',
                    formatter: function() {
                        if (CATEGORY[this.value] !== undefined) {
                            return '<b>' + CATEGORY[this.value] + ' (' + 
                                this.value/10 + '%)</b>';
                        }
                    }
                }
            },
            yAxis: {
                max: 100,
                gridLineWidth: 0,
                title: {
                    text: '<b>% Share</b>'
                },
                labels: {
                    formatter: function() {
                        return this.value +'%'
                    }
                }
            },
            tooltip: {
                shared: true,
                useHTML: true,
                formatter: function () {
                    var result = 'CATEGORY: <b>' +
                        CATEGORY[this.x] + ' (' + Highcharts.numberFormat(BucketSize[this.x]/10,1) + '% sized bucket)</b><br>';
                    $.each(this.points, function(i, datum) {
                        if (datum.point.y !== 0) {
                            result += '<span style="color:' +
                                datum.series.color + '"><b>' +
                                datum.series.name + '</b></span>: ' +
                                    '<b>$' + datum.point.y + 'K</b> (' +
                                Highcharts.numberFormat(
                                    datum.point.percentage,2) +
                                '%)<br/>';
                        }
                    });
                return (result);
                }
            },
            plotOptions: {
                area: {
                    stacking: 'percent',
                    lineColor: 'black',
                    lineWidth: 1,
                    marker: {
                        enabled: false
                    },
                    step: true
                }
            },
            legend: {
                layout: 'vertical',
                align: 'right',
                verticalAlign: 'top',
                x: 0,
                y: 100,
                borderWidth: 1,
                title: {
                text : 'Brand:'
                }
            },
            series: [ {
                name: 'HP',
                data: [
                    [0,298],
                    [475,109],
                    [763,153],
                    [1000,153]          
                ]
            }, {
               name: 'Dell',
                data: [
                    [0,245],
                    [475,198],
                    [763,120],
                    [1000,120]
               ]
            }, {
                name: 'Sony',
                data: [
                    [0,335],
                    [475,225],
                    [763,164],
                    [1000,164]          
               ]
            }]
        },
        function(chart){    
            // Render bottom line.
            chart.renderer.path(['M', chart.plotLeft, chart.plotHeight + 66, 'L', chart.plotLeft+chart.plotWidth, chart.plotHeight + 66])
            .attr({
                'stroke-width': 3,
                stroke: 'black',
                zIndex:50
            })
            .add();
            for (var category_idx in CATEGORY) {
                chart.renderer.path(['M', (Math.round((category_idx / 1000) * chart.plotWidth)) + chart.plotLeft, 66, 'V', chart.plotTop + chart.plotHeight])
                .attr({
                    'stroke-width': 1,
                    stroke: 'black',
                    zIndex:4
                })
                .add();
            }
        });
    });
});

它添加了一个额外的数组,允许您将类别名称Map到第二个tic值,以给予您可能需要的更“类别”的视图。我还在底部添加了代码,用于在图表的不同列和底线之间添加垂直分隔线。它可能需要一些调整你周围标签的大小等。我在这里用像素硬编码作为数学的一部分,但这应该是可行的。
使用'percent'类型的重音符号可以让y轴从原始数据中计算出百分比总数,而如前所述,您需要自己计算x轴。我更依赖于一个工具提示函数来提供标签等,而不是图表本身的标签。
这项工作的另一个重大改进是找到一种方法来使工具提示悬停区域和标签集中并居中,并包含栏本身,而不是现在每个栏的右边框。如果有人想补充这一点,请随意在这里。

v2g6jxz6

v2g6jxz62#

如果我没弄错的话,你想让每一根线都有不同的宽度。我也有同样的问题,并努力找到一个图书馆提供这个选项很多。我得出的结论是-没有。

无论如何,我玩了一下highcharts,有了创造性,想出了这个:

您提到您希望数据看起来像这样:data: [[5, 3.4], [3, 6], [4, 3.4]],第一个值是高度,第二个值是宽度。
让我们用highcharts的柱状图来做。

第一步:

要更好地区分条形图,请将每个条形图作为一个新系列输入。由于我是动态生成数据的,所以我必须动态分配新的系列:

const objects: any = [];
const extra = this.data.length - 1;
this.data.map((range) => {
  const obj = {
    type: 'column',
    showInLegend: false,
    data: [range[1]],
    animation: true,
    borderColor: 'black',
    borderWidth: 1,
    color: 'blue'
  };
  for (let i = 0; i < extra; i++) {
    obj.data.push(null);
  }
  objects.push(obj);
});
this.chartOptions.series = objects;

这样,您的不同系列将看起来像这样:

series: [{
  type: 'column',
  data: [5, 3.4]
}, {
  type: 'column',
  data: [3, 6]
}, {
  type: 'column',
  data: [4, 3.4]
}]

第二步:

将其指定为高图的绘图选项:

plotOptions: {
  column: {
    pointPadding: 0,
      borderWidth: 0,
      groupPadding: 0,
      shadow: false
  }
}

第三步:

现在让我们来创造性地-为所有条形图具有相同的起点,我们需要将每个条形图移动到图形的开始:

setColumnsToZero() {
  this.data.map((item, index) => {
    document.querySelector('.highcharts-series-' + index).children[0].setAttribute('x', '0');
  });
}

第四步:

getDistribution() {
  let total = 0;

  // Array including all of the bar's data: [[5, 3.4], [3, 6], [4, 3.4]]
  this.data.map(item => {
    total = total + item[0];
  });

  // MARK: Get xAxis' total width
  const totalWidth = document.querySelector('.highcharts-axis-line').getBoundingClientRect().width;

  let pos = 0;
  this.data.map((item, index) => {
    const start = item[0];
    const width = (start * totalWidth) / total;
    document.querySelector('.highcharts-series-' + index).children[0].setAttribute('width', width.toString());
    document.querySelector('.highcharts-series-' + index).children[0].setAttribute('x', pos.toString());
    pos = pos + width;
    this.getPointsPosition(index, totalWidth, total);
  });
}

第四步:

让我们来看看xAxis的点。在第一个函数中,修改已经存在的点,将最后一个点移动到轴的末端并隐藏其他点。在第二个函数中,我们克隆最后一个点,修改它使其具有总共6个或3个xAxis点,并将每个点移动到正确的位置

getPointsPosition(index, totalWidth, total) {
  const col = document.querySelector('.highcharts-series-' + index).children[0];
  const point = (document.querySelector('.highcharts-xaxis-labels').children[index] as HTMLElement);
  const difference = col.getBoundingClientRect().right - point.getBoundingClientRect().right;
  const half = point.getBoundingClientRect().width / 2;
  if (index === this.data.length - 1) {
    this.cloneNode(point, difference, totalWidth, total);
  } else {
    point.style.display = 'none';
  }
  point.style.transform = 'translateX(' + (+difference + +half) + 'px)';

  point.innerHTML = total.toString();
}

cloneNode(ref: HTMLElement, difference, totalWidth, total) {
  const width = document.documentElement.getBoundingClientRect().width;

  const q = total / (width > 1000 && ? 6 : 3);
  const w = totalWidth / (width > 1000 ? 6 : 3);
  let val = total;
  let valW = 0;
  for (let i = 0; i < (width > 1000 ? 6 : 3); i++) {
    val = val - q;
    valW = valW + w;
    const clone = (ref.cloneNode(true) as HTMLElement);

    document.querySelector('.highcharts-xaxis-labels').appendChild(clone);

    const half = clone.getBoundingClientRect().width / 2;

    clone.style.transform = 'translateX(' + (-valW + difference + half) + 'px)';
    const inner = Math.round(val * 100) / 100;
    clone.innerHTML = inner.toString();
  }
}

最后,我们得到了一个类似于下面的图(不是这个例子中的数据,而是[[20, 0.005], [30, 0.013333333333333334], [20, 0.01], [30, 0.005555555555555555], [20, 0.006666666666666666]],第一个值是宽度,第二个值是高度):

可能会有一些修改,以100%适合您的情况。我不得不调整xAxis的点,一个特定的起点和终点-我省去了这一部分。

aydmsdu9

aydmsdu93#

HighChart中设置列宽的setpointWidth:

var options = {
  chart: {
    // Your chart configuration options
  },
  plotOptions: {
    column: {
      pointWidth: 20, // Set the desired width for columns
    
    }
  },
};
irtuqstp

irtuqstp4#

pointWidth是设置条形图宽度所需的值。尝试

plotOptions: {
            series: {
                pointWidth: 15
            }
        }

这个显示条的宽度为15px。玩here。只是对现有代码进行了编辑。

yhuiod9q

yhuiod9q5#

我使用一组面积图来模拟可变宽度柱形图/条形图。比方说,每个列/条由矩形区域表示。
查看我的小提琴演示(http://jsfiddle.net/calfzhou/TUt2U/)。

$(function () {
    var rawData = [
        { name: 'A', x: 5.2, y: 5.6 },
        { name: 'B', x: 3.9, y: 10.1 },
        { name: 'C', x: 11.5, y: 1.2 },
        { name: 'D', x: 2.4, y: 17.8 },
        { name: 'E', x: 8.1, y: 8.4 }
    ];

    function makeSeries(listOfData) {
        var sumX = 0.0;
        for (var i = 0; i < listOfData.length; i++) {
            sumX += listOfData[i].x;
        }
        var gap = sumX / rawData.length * 0.2;
        var allSeries = []
        var x = 0.0;
        for (var i = 0; i < listOfData.length; i++) {
            var data = listOfData[i];
            allSeries[i] = {
                name: data.name,
                data: [
                    [x, 0], [x, data.y],
                    {
                        x: x + data.x / 2.0,
                        y: data.y,
                        dataLabels: { enabled: true, format: data.x + ' x {y}' }
                    },
                    [x + data.x, data.y], [x + data.x, 0]
                ],
                w: data.x,
                h: data.y
            };
            x += data.x + gap;
        }
        return allSeries;
    }

    $('#container').highcharts({
        chart: { type: 'area' },
        xAxis: {
            tickLength: 0,
            labels: { enabled: false}
        },
        yAxis: {
            title: { enabled: false}
        },
        plotOptions: {
            area: {
                marker: {
                    enabled: false,
                    states: {
                        hover: { enabled: false }
                    }
                }
            }
        },
        tooltip: {
            followPointer: true,
            useHTML: true,
            headerFormat: '<span style="color: {series.color}">{series.name}</span>: ',
            pointFormat: '<span>{series.options.w} x {series.options.h}</span>'
        },
        series: makeSeries(rawData)
    });
});

相关问题