如果你有一个带有 css 的 flex 容器
显示:弹性;
弹性方向:行;
和 4 个孩子
弹性增长:1;
弹性基础:25%;
您希望有一行包含 4 个图表,每个图表大小为父级的 25%。
实际行为取决于它可能是的父级的大小
一行 4 项,占 25%(预期行为)
一行 3 件小号商品,下一行 100% 商品。
4 行,里面有 100% 的项目。
http://jsfiddle.net/xLz8tcrc/1/
铬合金
火狐
在您的演示中,我添加了一个片段来在调整弹性框大小后运行chart.reflow()
。 这是必要的,因为图表只会在 _window_ 调整大小时自动回流。
此外,向图表容器添加overflow: hidden
可确保容器可以小于图表,从而防止它们在缩小时过宽。
这能解决您的问题吗? http://jsfiddle.net/xLz8tcrc/2/
感谢您的回复。
使用 chart.reflow() 看起来更像是一种解决方法,而不是对原始问题的修复。 如果 HighCharts 能够根据父元素的 CSS 规则正确调整大小,将会简单得多。
我只发布了一个示例,在实际用例中,我们希望图表在窗口调整大小或父元素调整大小时调整大小,因此实现可以调用 chart.reflow() 的逻辑并不那么容易。 对于窗口调整大小,它更不那么直接,只需使用窗口调整大小事件。
对于其他组件,我们需要为父组件实现某种可调整大小的接口,因此我们可以在调整大小时调用chart.reflow,这在某些情况下可能有效,但不确定所有情况。
能否请您暂时不要关闭票证,我会尝试实施您的方法,或者也许有人有其他想法。
您所描述的问题与我们在 Highcharts 内部遇到的问题基本相同。 我们目前在调整窗口大小时进行自动重排。 理想情况下,我们也希望对包含元素调整大小进行自动重排,但目前没有有效的方法来监听 DOM 元素大小的变化。
请参阅http://stackoverflow.com/questions/6492683/how-to-detect-divs-dimension-changed进行讨论,之前在本论坛中也讨论过相同的主题。 正如线程中提到的,目前唯一可能的方法似乎是使用setTimeout
或requestAnimationFrame
,这两者都在浪费 CPU。
您是否查看了链接到的 StackOverflow 帖子中提到的 ResizeSensor(https://github.com/marcj/css-element-queries)? 它使用几个额外的 DOM 元素和一个scroll
事件侦听器来检测调整大小。 它仅使用requestAnimationFrame
来限制发送的调整大小事件的数量(每帧最多 1 个)。
还有http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/描述了如何使用object
标签来实现这一点,其中巧合的是当它的大小改变时触发resize
事件。
将来,浏览器中将实现ResizeObserver
,但现在不可行。 在https://github.com/WICG/ResizeObserver/issues/3上列出了几个 polyfill,但它们似乎依赖于MutationObeserver
和轮询或其他浪费的方法。
在我看来,Highcharts 不应该在核心中实现这样的技巧。 窗口调整大小侦听器涵盖了大多数情况,然后我们有chart.reflow
钩子来允许实现者覆盖其他情况,当元素调整大小而不调整窗口大小时。 因此,如果您测试了上述方法之一并且它适用于您的情况,我建议您将其与chart.reflow
一起使用。
+1 我们刚刚遇到这个问题,花了很长时间才意识到问题是 flexbox。
我停止使用 flex 的原因之一......调整大小从来没有按预期工作,显示网格同样糟糕
显示内联块要好得多
我停止使用 flex 的原因之一......调整大小从来没有按预期工作,显示网格同样糟糕
这只是另一种解决方法。
是否有任何更新? 有没有计划修复这个@TorsteinHonsi ?
我开始在 Angular 项目中使用 Highcharts,我也遇到了这个问题。
我不明白的是图表实际上是SVG
。 因此,将其设为 100% 大小应该没有任何问题。 相反,它看起来像宽度和高度被直接设置为 svg。
嗨@GeorgeKnap
你能提供一个带有 Highcharts 和非 Highcharts SVG 的现场演示来展示你的想法吗? 这将如何影响锐化渲染的缩放和像素精度?
@KacperMadej
好吧,svg 是矢量图形。 这意味着将 SVG 宽度和高度设置为 100% 应该不会对渲染产生任何不良影响,如果我错了,请纠正我。
我设法覆盖了内部svg
元素宽度 CSS:
highcharts-chart::ng-deep {
.highcharts-container,
.highcharts-container svg {
width: 100% !important;
height: 100% !important;
}
}
它现在运行得相当好。
感谢您分享解决方案。
缩放 SVG 的问题在于,这可能会导致渲染模糊,因为像素精度可能会丢失。 通用 Highcharts 解决方案的另一个问题是对旧浏览器的支持(它不是阻止程序,我们只需要确保我们有适当的 polyfill)。
我对这个问题进行了深入研究,发现了三个问题:
在确定容器的大小时,Highcharts 使用scrollWidth
,如果实际宽度是亚像素,则会四舍五入。 在原始小提琴中,这导致第一个图表被绘制的像素太宽,并且 flex 布局从 4 列跳到 3 列。 这是通过使用Math.floor
和element.getBoundingClientRect
在上面的提交中修复的。
当缩小页面或容器的宽度时,图表将比分配给它们的 25% 更宽,从而破坏布局。 这在上面的提交中通过将overflow:hidden
到顶级图表容器来修复。
当缩放 flex 容器 _without_ 调整窗口大小时,图表不会缩放。 他们仍然不会,但至少现在他们不会破坏布局。 @GeorgeKnap的解决方案可能适用于某些人,但正如 Kacper 所说,它可能会导致图表模糊,而且还会调整高度,它会不尊重字体大小等。请参阅http://jsfiddle.net/highcharts/xLz8tcrc/219 /以及带有显式chart.reflow
调用的相同设置: http : ResizeObserver
。
我上面的 CSS 覆盖解决方案导致鼠标悬停(工具提示)位置出现重大问题。 为了修复它,我完全删除了 CSS 覆盖并实现了ResizeObserver
。 它观察父元素的大小并直接在图表选项中更改width
和height
属性:
这是 Angular 解决方案,因此使用ElementRef
来访问本机 DOM 元素并使用ChangeDetectorRef
来触发更改检查:
const resizeObserver = new ResizeObserver(debounce((data: Array<ResizeObserverEntry>) => {
if (this.chartOptions) {
const options = { ...this.chartOptions } as Highcharts.Options;
options.chart!.height = data[0].contentRect.height;
options.chart!.width = data[0].contentRect.width;
this.chartOptions = options;
this.cd.markForCheck();
}
}, 200));
resizeObserver.observe(this.elementRef.nativeElement.children[0]);
感谢分享! 这是一个普通的插件响应该chart.reflow
选项,并取消绑定内置window.onresize
处理程序,如果ResizeObserver
支持:
// Generic plugin that adds support for listening to container resize rather than
// window resize. As of 2018 only Chrome supports ResizeObserver.
Highcharts.wrap(Highcharts.Chart.prototype, 'setReflow', function(proceed, reflow) {
var chart = this;
proceed.call(this, reflow);
if (reflow !== false && typeof ResizeObserver === 'function') {
// Unbind window.onresize handler so we don't do double redraws
if (this.unbindReflow) {
this.unbindReflow();
}
var ro = new ResizeObserver(function () {
chart.reflow();
});
ro.observe(this.renderTo);
}
});
你好,
我是使用 highcharts 的新手,在那些附加的屏幕截图中,您可以清楚地看到图表超出了容器的宽度。 我在同一页面中有许多图表,当我单击手风琴时会打开这些图表。 在每次初始加载时,图表宽度都会超过其容器宽度。
这个问题有什么解决办法吗?
下面是关于手风琴的代码。
函数initsectionclicks(容器){
$('.fe-section-accordion-header', container).click(function () {
var parentcontainer = $(this).parent();
var 手风琴容器 = $(parentcontainer).find('.fe-section-accordion-container');
if (accordioncontainer != null)
{
var accordioncontainerOpen = accordioncontainer.is(':visible');
accordioncontainer[accordioncontainerOpen ? 'slideUp' : 'slideDown'](400, "swing", function() {
ToolkitUI.Common.ResizeIFrame();
var highChartsWrapper = $('.fe-section-chart-wrap', accordioncontainer);
if (highChartsWrapper.length) {
$.each(highChartsWrapper,
function(index, obj) {
var hcObj = $(obj).highcharts();
if (hcObj)
hcObj.reflow();
});
}
});
if (!accordioncontainerOpen)
{
$(accordioncontainer).ShowLoadingInsideContainer();
}
$(parentcontainer).find('.fe-expandcollapse').toggleClass("fe-icon-expand", accordioncontainerOpen).toggleClass("fe-icon-collapse", !accordioncontainerOpen);
$('.fe-section-accordion-header', parentcontainer).toggleClass('highlight', !accordioncontainerOpen);
}
$(window).resize();
});
//we have to unbind any click event handlers before attaching a new one, as without unbind we will be attaching the same handler multiple times.
//this is because we are binding the data from the start for each tab when it is clicked, which rebinds the same method again and again.
$('.fe-accordion-expandcollapse-all', container).unbind('click').click(function () {
var isallopen = $(this).hasClass('fe-accordion-collapse');
var counter = 1;
$(this).toggleClass('fe-accordion-expand', isallopen).toggleClass('fe-accordion-collapse', !isallopen);
$('.fe-expandcollapse', container).toggleClass('fe-icon-expand', isallopen).toggleClass('fe-icon-collapse', !isallopen);
$('.fe-section-accordion-header', container).toggleClass('highlight', !isallopen);
$('.fe-section-accordion-container')[isallopen ? 'slideUp' : 'slideDown'](400, "swing", function () {
if (counter == $('.fe-section-accordion-container').length) {
ToolkitUI.Common.ResizeIFrame();
}
counter++;
});
if (!isallopen)
{
$('.fe-section-accordion-container').ShowLoadingInsideContainer();
}
$(window).resize();
});
};
@Nagaraj2106
请为问题添加实时演示,以便我们重新创建问题、调试并测试可能的解决方案和变通方法。 另外,请查看此评论中建议的解决方法: https :
在窗口调整大小时调用 reflow() 或使用插件都没有为我解决问题; 然而,这个来自 SO 的回答确实如此。
我在 bootstrap 4 flex 容器中使用 highcharts。 图表会向上调整(更宽)但不会缩小,除非我将容器设为绝对:
<div id="chart-container">
<div id="chart"></div>
</div>
使用 CSS:
#chart-container {
position: relative;
width: 100%;
height: 280px;
}
#chart {
position: absolute;
width: 100%;
}
我已经用renderTo: 'chart'
将图表附加到 #chart 。
最有用的评论
@KacperMadej
好吧,svg 是矢量图形。 这意味着将 SVG 宽度和高度设置为 100% 应该不会对渲染产生任何不良影响,如果我错了,请纠正我。
我设法覆盖了内部
svg
元素宽度 CSS:它现在运行得相当好。