предисловие
В проекте реализовано: создание диаграмм, произвольное перетаскивание, изменение размера диаграммы, стиля (введите ввод и нажмите Enter), двойной щелчок для удаления, полноэкранный режим, настраиваемая визуализация данных на большом экране.
Адрес опыта проекта:Визуализация данных на большом экране
Адрес исходного кода проекта:исходный код
Стек технологий: react + antd + echarts + react-hooks + react-dnd
Предварительный просмотр проекта
выполнить
Создавайте диаграммы, реализуйте перетаскивание, полноэкранный режим, см. предыдущую статью:Создать диаграмму
Схема пакета
Вы можете обратиться к сообществу echarts:echarts
Здесь много больших парней, которые сделали много хороших чартов, блоггеры ленивы, и все они чарты от больших парней.
import ReactEcharts from 'echarts-for-react';
<ReactEcharts
option={option}
theme="Imooc"
style={{ width: `${width}px`, height: `${height}px` }}
ref={chartRef}
/>
пройти черезecharts-for-reactС опцией стиля диаграммы в сообществе мы можем легко инкапсулировать различные стили диаграмм. Блогеру потребовалось менее 20 минут, чтобы сделать вышеуказанные стили.
Измените стиль диаграммы для синхронного обновления представления.
Элемент на некоторое время застревает в обновлении синхронизации представления, сложность здесь заключается в том, чтобы заставить диаграмму повторно отображаться после того, как мы изменим состояние справа.
Я начал думать о том, чтобы использовать ререндер echarts самостоятельно. Позже нашелecharts-for-reactПредоставляет нам доступ к диаграмме и предоставляет API.
Через ref получаем предоставленную библиотекуgetEchartsInstanceметод, на нем есть все методы echarts, а ререндер чарта можно реализовать сбросом setOption.
Идеи реализации:
Когда мы нажимаем клавишу Enter (ввод) в состоянии обновления справа, чтобы вызвать отправку и изменить данные, соответствующие центру обработки данных, наш компонент диаграммы также будет отображаться, запускаяuseEffectПерехватите функцию для завершения синхронного обновления представления.
const chartRef = React.useRef()
React.useEffect(() => {
chartRef.current.getEchartsInstance().setOption(option)
}, [option])
return (
<div
className={ClassNames({ 'active': active })}
onDoubleClick={(e) => deleteChart(id)}
onClick={(e) => selectChart(e, id)}
ref={drag}
style={{ ...style, left, top }}
>
<ReactEcharts
option={option}
theme="Imooc"
style={{ width: `${width}px`, height: `${height}px` }}
ref={chartRef}
/>
</div>
)
Панель стиля диаграммы
Когда мы выбираем диаграмму, получаем параметр диаграммы, анализируем ее и преобразуем в соответствующий тег dom.
Основная проблема здесь в том, что option — это глубокая структура объекта, и нам нужно пройти слой за слоем, чтобы получить свойства объекта.
После долгих размышлений об этом я все еще не могу придумать хорошего решения. В конце концов, мы можем использовать только самый глупый метод, послойный анализ и оценку, и отфильтровывать данные, которые не могут быть отображены на боковой панели.
Такая реализация глупа:
<Menu
className="tab-menu"
theme="dark"
mode="inline"
openKeys={openKeys}
onOpenChange={(v) => onOpenChange(v)}
style={{ width: '100%', height: '100%' }}
>
{
Object.keys(view).map(v => {
if (v === 'data' || v === 'series') {
return null
}
return (
<SubMenu
className="tab-submenu"
key={v}
title={
<span>
<span>{v}</span>
</span>
}
>
{
Object.keys(view[v]).map(item => {
if (item === 'data' || item === 'series') {
return null
}
if (typeof view[v][item] === 'object') {
return (
<SubMenu
className="tab-subitemmenu"
key={item}
title={
<span>
<span>{item}</span>
</span>
}
>
{
Object.keys(view[v][item]).map(subitem => {
return (
<Menu.Item key={subitem} className="tab-submenuitem">
<span style={{ marginRight: '5px' }}>{subitem}</span>
<Input
onPressEnter={(e) => onPressEnter(e, subitem, item, v)}
className="submenuitem-input"
onChange={e => inputOnChange(e, subitem, item, v)}
value={view[v][subitem]}
/>
</Menu.Item>
)
})
}
</SubMenu>
)
}
return (
<Menu.Item key={item} className="tab-menuitem">
<span style={{ marginRight: '5px' }}>{item}</span>
<Input
onPressEnter={(e) => onPressEnter(e, item, v)}
className="menuitem-input"
onChange={e => inputOnChange(e, item, v)}
value={view[v][item]}
/>
</Menu.Item>
)
})
}
</SubMenu>
)
})
}
</Menu>
выбранный стиль
Когда мы нажимаем на диаграмму, добавляем к ней класс: активный, щелкните в другом месте, чтобы удалить стиль.
Идеи:
Здесь я используюclassnamesплагин. Это позволяет нам:
className={ClassNames({ 'active': active })}
где active — логическое значение, если true, добавить активный стиль, если false, удалить активный стиль.
выполнить:
В состояние каждого графика добавляю активный элемент, по умолчанию false, при клике становится true, а остальные false.
Примечание: чтобы остановить пузырение.
case 'activeClass': //给选中的图表添加选中的样式
Object.keys(state).map(item => {
if (item === id) {
state[item].active = true
return item
}
state[item].active = false
return item
})
return { ...state }
...
const selectChart = (e, id) => { //设置选中图表, 并添加被选中的样式
e.stopPropagation()
setSelect(chartsObj[id])
dispatch({ type: "activeClass", id })
}
При нажатии на область, не относящуюся к графику, диспетчер превращает все в false:
const cancelSelect = () => { //取消选中样式
setSelect({})
dispatch({ type: "activeClass" })
}
позже
Что делать дальше:
Самое главное — запустить данные, настроить источник данных, настроить сгенерированный большой экран и сохранить его на сервере.
Во-вторых, настроить стиль графика (в настоящее время эти пакеты в основном скопированы из Интернета, а некоторые подходящие графики будут разработаны позже)