如何动态调整 Vega 图表的大小以适应 css 网格
How to dynamically resize a vega chart in react to fit in a css grid
我最初的问题:
我正在使用 react-vega
并在 css 网格中放置一些织女星图表。我想随着浏览器 window 变窄(理想情况下为 min-width
)动态调整图表的大小,目前如果我缩小宽度,图表就会开始重叠,这看起来很糟糕。我找到了一些对 containerSize()
的引用,但没有找到任何关于如何实现它的好例子。 vega 执行此操作的最佳选择是什么?
[发布到 vega slack 频道]
在 "Kanit Wongsuphasawat" 和 "Rob Wollen" 来回反复之后,现在似乎没有一个很好的方法将其合并到 vega 或 vega-react 中,我已经尝试了以下方法但是还是有问题。
我的做法:
我尝试使用 react-measure
npm package 并在下面构建了一个反应组件:
import Measure from 'react-measure';
import React, { Component } from 'react';
import NetworkUpDownChart from './vega-network-updown-chart';
import Vega from 'react-vega';
export default class ItemToMeasure extends Component {
state = {
dimensions: {
width: -1,
height: -1,
},
}
data = {
table: [
{"x": 0, "y": 28, "c":0}, {"x": 0, "y": -55, "c":1}
...
]
};
spec = {
"$schema": "https://vega.github.io/schema/vega/v4.json",
"width": 900,
"height": 200,
"padding": 5,
"autosize": {
"type": "pad",
"resize": true,
},
"data": [
{
"name": "table",
// data will be passed in via props
"transform": [
{
"type": "stack",
"groupby": ["x"],
"sort": {"field": "c"},
"field": "y"
}
]
}
],
"scales": [
{
"name": "x",
"type": "point",
"range": "width",
"domain": {"data": "table", "field": "x"}
},
{
"name": "y",
"type": "linear",
"range": "height",
"nice": true, "zero": true,
"domain": {"data": "table", "field": "y1"}
},
{
"name": "color",
"type": "ordinal",
"range": "category",
"domain": {"data": "table", "field": "c"}
}
],
"axes": [
{"orient": "bottom", "scale": "x", "zindex": 1},
{"orient": "left", "scale": "y", "zindex": 1}
],
"marks": [
{
"type": "group",
"from": {
"facet": {
"name": "series",
"data": "table",
"groupby": "c"
}
},
"marks": [
{
"type": "area",
"from": {"data": "series"},
"encode": {
"enter": {
"interpolate": {"value": "monotone"},
"x": {"scale": "x", "field": "x"},
"y": {"scale": "y", "field": "y0"},
"y2": {"scale": "y", "field": "y1"},
"fill": {"scale": "color", "field": "c"}
},
"update": {
"fillOpacity": {"value": 1}
},
"hover": {
"fillOpacity": {"value": 0.5}
}
}
}
]
}
]
}
render() {
const { width, height } = this.state.dimensions
// const className = classNames(width < 400 && 'small-width-modifier')
return (
<Measure
bounds
onResize={contentRect => {
this.setState({ dimensions: contentRect.bounds })
}}
>
{({ measureRef }) => (
<div ref={measureRef}>
{width < 250 && (
<Vega width={width} spec={this.spec} data={this.data}/>,
<NetworkUpDownChart width={width} data={this.data}> . </NetworkUpDownChart>)}
<pre>{measureRef}</pre>
</div>
)}
</Measure>
)
}
}
当我使用该组件时 "dynamically resizes the graph" 只是当浏览器 window 调整大小时。相反,它只是不断地从 0 -> 250 增长(这是我在组件逻辑中记下的最大值)然后重置。如果我删除那里的条件逻辑,它就会永远增长。
理想情况下,我想修复此问题,以便在我调整浏览器大小时它不会持续增长并且会缩小,但我将不胜感激对此问题的任何帮助或替代解决方案。
谢谢
所以我设法解决了这个问题。
当我使用以下样式将上述组件封装在 css 网格中时:
.parent-container{
display: grid;
grid-template-areas:
'. el1 . el2 .';
grid-template-columns: 10% 30% 20% 30% 10%;
grid-auto-rows: 200px;
}
我需要在组件中添加额外的 div,因为 className 未应用于 <Measure>
块,请参阅下面的更新 return。请注意,我现在可以删除 Vega 图表大小的额外绑定逻辑:
return (
<div className="el2">
<Measure
bounds
onResize={contentRect => {
this.setState({ dimensions: contentRect.bounds })
}}
>
{({ measureRef }) => (
<div ref={measureRef}>
<NetworkUpDownChart width={width} data={this.data}></NetworkUpDownChart>
</div>
)}
</Measure>
</div>
)
}
我最初的问题:
我正在使用 react-vega
并在 css 网格中放置一些织女星图表。我想随着浏览器 window 变窄(理想情况下为 min-width
)动态调整图表的大小,目前如果我缩小宽度,图表就会开始重叠,这看起来很糟糕。我找到了一些对 containerSize()
的引用,但没有找到任何关于如何实现它的好例子。 vega 执行此操作的最佳选择是什么?
[发布到 vega slack 频道]
在 "Kanit Wongsuphasawat" 和 "Rob Wollen" 来回反复之后,现在似乎没有一个很好的方法将其合并到 vega 或 vega-react 中,我已经尝试了以下方法但是还是有问题。
我的做法:
我尝试使用 react-measure
npm package 并在下面构建了一个反应组件:
import Measure from 'react-measure';
import React, { Component } from 'react';
import NetworkUpDownChart from './vega-network-updown-chart';
import Vega from 'react-vega';
export default class ItemToMeasure extends Component {
state = {
dimensions: {
width: -1,
height: -1,
},
}
data = {
table: [
{"x": 0, "y": 28, "c":0}, {"x": 0, "y": -55, "c":1}
...
]
};
spec = {
"$schema": "https://vega.github.io/schema/vega/v4.json",
"width": 900,
"height": 200,
"padding": 5,
"autosize": {
"type": "pad",
"resize": true,
},
"data": [
{
"name": "table",
// data will be passed in via props
"transform": [
{
"type": "stack",
"groupby": ["x"],
"sort": {"field": "c"},
"field": "y"
}
]
}
],
"scales": [
{
"name": "x",
"type": "point",
"range": "width",
"domain": {"data": "table", "field": "x"}
},
{
"name": "y",
"type": "linear",
"range": "height",
"nice": true, "zero": true,
"domain": {"data": "table", "field": "y1"}
},
{
"name": "color",
"type": "ordinal",
"range": "category",
"domain": {"data": "table", "field": "c"}
}
],
"axes": [
{"orient": "bottom", "scale": "x", "zindex": 1},
{"orient": "left", "scale": "y", "zindex": 1}
],
"marks": [
{
"type": "group",
"from": {
"facet": {
"name": "series",
"data": "table",
"groupby": "c"
}
},
"marks": [
{
"type": "area",
"from": {"data": "series"},
"encode": {
"enter": {
"interpolate": {"value": "monotone"},
"x": {"scale": "x", "field": "x"},
"y": {"scale": "y", "field": "y0"},
"y2": {"scale": "y", "field": "y1"},
"fill": {"scale": "color", "field": "c"}
},
"update": {
"fillOpacity": {"value": 1}
},
"hover": {
"fillOpacity": {"value": 0.5}
}
}
}
]
}
]
}
render() {
const { width, height } = this.state.dimensions
// const className = classNames(width < 400 && 'small-width-modifier')
return (
<Measure
bounds
onResize={contentRect => {
this.setState({ dimensions: contentRect.bounds })
}}
>
{({ measureRef }) => (
<div ref={measureRef}>
{width < 250 && (
<Vega width={width} spec={this.spec} data={this.data}/>,
<NetworkUpDownChart width={width} data={this.data}> . </NetworkUpDownChart>)}
<pre>{measureRef}</pre>
</div>
)}
</Measure>
)
}
}
当我使用该组件时 "dynamically resizes the graph" 只是当浏览器 window 调整大小时。相反,它只是不断地从 0 -> 250 增长(这是我在组件逻辑中记下的最大值)然后重置。如果我删除那里的条件逻辑,它就会永远增长。
理想情况下,我想修复此问题,以便在我调整浏览器大小时它不会持续增长并且会缩小,但我将不胜感激对此问题的任何帮助或替代解决方案。
谢谢
所以我设法解决了这个问题。
当我使用以下样式将上述组件封装在 css 网格中时:
.parent-container{
display: grid;
grid-template-areas:
'. el1 . el2 .';
grid-template-columns: 10% 30% 20% 30% 10%;
grid-auto-rows: 200px;
}
我需要在组件中添加额外的 div,因为 className 未应用于 <Measure>
块,请参阅下面的更新 return。请注意,我现在可以删除 Vega 图表大小的额外绑定逻辑:
return (
<div className="el2">
<Measure
bounds
onResize={contentRect => {
this.setState({ dimensions: contentRect.bounds })
}}
>
{({ measureRef }) => (
<div ref={measureRef}>
<NetworkUpDownChart width={width} data={this.data}></NetworkUpDownChart>
</div>
)}
</Measure>
</div>
)
}