Line
图表。
- 但是我正在使用的图表使用示例数据,在我的情况下是JSON数据。
- 我还使用
resize-observer-polyfill
库使图表具有响应性。 - 现在我正在努力将其与JSON数据实现,以便使用动态数据呈现它。
我所做的
const svgRef = useRef();
const wrapperRef = useRef();
const dimensions = useResizeObserver(wrapperRef); // for responsive
// will be called initially and on every data change
useEffect(() => {
const svg = select(svgRef.current);
const { width, height } =
dimensions || wrapperRef.current.getBoundingClientRect();
// scales + line generator
const xScale = scaleLinear()
.domain([0, data.length - 1]) // here I need to pass the data
.range([0, width]);
const yScale = scaleLinear()
.domain([0, max(data)])
.range([height, 0]);
const lineGenerator = line()
.x((d, index) => xScale(index))
.y((d) => yScale(d))
.curve(curveCardinal);
// render the line
svg
.selectAll('.myLine')
.data([data])
.join('path')
.attr('class', 'myLine')
.attr('stroke', 'black')
.attr('fill', 'none')
.attr('d', lineGenerator);
svg
.selectAll('.myDot')
.data(data)
.join('circle')
.attr('class', 'myDot')
.attr('stroke', 'black')
.attr('r', (value, index) => 4)
.attr('fill', (value, index) => 'red')
.attr('cx', (value, index) => xScale(index))
.attr('cy', yScale);
// axes
const xAxis = axisBottom(xScale);
svg
.select('.x-axis')
.attr('transform', `translate(0, ${height})`)
.call(xAxis);
const yAxis = axisLeft(yScale);
svg.select('.y-axis').call(yAxis);
}, [data, dimensions]);
<React.Fragment>
<div ref={wrapperRef} style={{ marginBottom: '2rem' }}>
<svg ref={svgRef}>
<g className="x-axis" />
<g className="y-axis" />
</svg>
</div>
</React.Fragment>
我无法传递数据,以下是我的数据
[
{ anno: 2014, consumo: 300, color: "#ff99e6" },
{ anno: 2015, consumo: 290, color: "blue" },
{ anno: 2016, consumo: 295, color: "green" },
{ anno: 2017, consumo: 287, color: "yellow" },
{ anno: 2018, consumo: 282, color: "red" },
{ anno: 2019, consumo: 195, color: "white" }
]
我的数据中每个数据都有颜色,我想在生成的每个点中显示它。
同样地,我尝试制作柱状图,效果很好
当我们调整窗口大小时,我对标签进行了一些动态渲染,标签会自动调整。
我还注释了我正在进行操作的行。
编辑/更新
我一直在遵循@MGO的答案,它对我有很大帮助,但我仍然面临着对齐标签和填充颜色到点的问题。
实际上,由于文字大小的原因,它很明显会重叠,但为了克服这一点,在条形图中我使用了以下代码
const tickWidth = 40;
const width = xScaleLabels.range()[1];
const tickN = Math.floor(width / tickWidth);
const keepEveryNth = Math.ceil(xScaleLabels.domain().length / tickN);
const xScaleLabelDomain = xScaleLabels
.domain()
.filter((_, i) => i % keepEveryNth === 0);
xScaleLabels.domain(xScaleLabelDomain);
当设备尺寸较小时,它将过滤一些标签并且不会显示这些标签。同时我使用以下代码来添加颜色。
.attr("fill", ({ color }) => color)
但它没有显示任何颜色,而是默认显示黑色。
我有一些数据要显示为标签,例如
2021年7月9日11:18:28
,但我只想显示时间,所以我在我的条形图代码中所做的如下。const xScaleLabels = scaleBand()
.domain(
data.map(
({ sensorValueAddedTime }) => sensorValueAddedTime.split(' ')[2] // this I am using to show only time
)
)
.range([0, dimensions.width])
.padding(padding);
我试图使用折线图实现相同的功能,简单来说,我不希望将其更改为任何时间和全部时间。
这是第二个数据,所以基本上我得到的答案只适用于第一个数据,而不是第二个数据,如果数据以任何这些格式出现,我希望它是动态的,我想要显示sensorValueAddedTime
在x轴上,sensorValue
在y轴上。
我已经添加了我的条形图完整工作代码,我希望使用相同的方法制作折线图。
[
{
sensorValue: 32,
sensorValueAddedTime: "July.9.2021 10:56:22",
color_code: null,
condition: null,
__typename: "sensorData"
},
{
sensorValue: 32,
sensorValueAddedTime: "July.9.2021 10:56:23",
color_code: null,
condition: null,
__typename: "sensorData"
},
{
sensorValue: 35,
sensorValueAddedTime: "July.9.2021 11:17:51",
color_code: null,
condition: null,
__typename: "sensorData"
},
{
sensorValue: 35,
sensorValueAddedTime: "July.9.2021 11:17:52",
color_code: null,
condition: null,
__typename: "sensorData"
},
{
sensorValue: 36,
sensorValueAddedTime: "July.9.2021 11:18:08",
color_code: null,
condition: null,
__typename: "sensorData"
},
{
sensorValue: 36,
sensorValueAddedTime: "July.9.2021 11:18:09",
color_code: null,
condition: null,
__typename: "sensorData"
},
{
sensorValue: 38,
sensorValueAddedTime: "July.9.2021 11:18:27",
condition: null,
color_code: null,
__typename: "sensorData"
},
{
sensorValue: 38,
sensorValueAddedTime: "July.9.2021 11:18:28",
condition: null,
color_code: null,
__typename: "sensorData"
}
]