Построение пользовательской диаграммы на React Native

#reactjs #react-native #svg #react-native-svg #react-native-svg-charts

#reactjs #react-native #svg #react-native-svg #react-native-svg-диаграммы

Вопрос:

Задача под рукой:

введите описание изображения здесь

На что я пока потратил много времени:

  1. Круговая диаграмма из [https://github.com/JesperLekland/react-native-svg-charts-examples ][2]

Здесь я разделил весь круг на 50 единиц по 1 значению, чтобы получить эффект разделения полосы. Я могу передать цвет в соответствии с изображением, показанным выше. Но как я могу добавить внутренние линии (красные и зеленые) и данные внутри? Будем признательны за любую помощь!

Комментарии:

1. В следующий раз, пожалуйста, попробуйте опубликовать код, который вы пробовали!

Ответ №1:

Итак, подход, который я бы выбрал, заключается в том, чтобы сделать внешнее кольцо PieChart (как вы сделали), но сделать внутренний круг ProgressCircle (https://github.com/JesperLekland/react-native-svg-charts#progresscircle ) поскольку этот компонент, естественно, выглядит как внутренний круг на картинке. Вы можете изменить его backgroundColor реквизит на красный, а его progressColor реквизит на зеленый.

 import {PieChart, ProgressCircle} from 'react-native-svg-charts';
import Svg, {Text as SvgText, ForeignObject} from 'react-native-svg';
import Icon from 'react-native-vector-icons/FontAwesome5';

// ...

class CustomPieChart extends React.PureComponent {
  render() {
    const data = Array.apply(null, Array(50)).map(Number.prototype.valueOf, 1);

    // Change to whatever your fill function looks like...
    const getFill = (index) => {
      if (index > 30) return 'purple';
      if (index > 20) return 'blue';
      if (index > 10) return 'green';
      return 'red';
    };

    const pieData = data.map((value, index) => ({
      value,
      svg: {
        fill: getFill(index),
      },
      key: `pie-${index}`,
    }));

    return (
      <PieChart innerRadius="90%" style={styles.pieChart} data={pieData}>
        <ProgressCircle
          style={styles.progressCircle}
          progress={0.7}
          backgroundColor="red"
          progressColor="green">
          <ForeignObject x={-100} y={-100}>
            <View style={styles.progressCircleContentContainer}>
              <Text style={{...styles.text, color: 'green', marginBottom: 5}}>
                Active
              </Text>
              <View
                style={{
                  ...styles.progressCircleContentView,
                  width: 110,
                }}>
                <Icon name="heartbeat" size={30} color="red" />
                <Text style={styles.text}>72 BPM</Text>
              </View>
              <View style={styles.progressCircleContentView}>
                <Icon name="shoe-prints" size={30} color="red" />
                <Text style={styles.text}>4,565</Text>
                <Icon name="bolt" size={30} color="red" />
                <Text style={styles.text}>45 min</Text>
              </View>
              <View style={styles.progressCircleContentView}>
                <Icon name="fire-alt" size={30} color="red" />
                <Text style={styles.text}>1,856</Text>
                <Icon name="glass-whiskey" size={30} color="red" />
                <Text style={styles.text}>Active</Text>
              </View>
              <View style={{...styles.progressCircleContentView, width: 150}}>
                <Icon name="moon" size={30} color="red" />
                <Text style={styles.text}>6 hr 10 min</Text>
              </View>
            </View>
          </ForeignObject>
        </ProgressCircle>
      </PieChart>
    );
  }
}

const styles = StyleSheet.create({
  pieChart: {
    height: 300,
  },
  progressCircle: {
    height: 250,
    marginTop: 25,
  },
  progressCircleContentContainer: {
    alignItems: 'center',
    width: 200,
    height: 200,
    transform: [],
  },
  progressCircleContentView: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    width: 200,
    marginBottom: 5,
  },
  text: {
    fontSize: 20,
  },
});
  

Чего не делает этот пример:

  • Добавьте тень фона на круг
  • Добавьте значки за пределами внешнего круга

Пользовательские формы были созданы с помощью react-native-svg библиотеки, которая используется react-native-svg-charts внутри компании. Вы можете прочитать его документацию здесь:https://github.com/react-native-community/react-native-svg.


Как это выглядит:

демонстрация

Комментарии:

1. Огромное вам спасибо! Я попробую это сейчас и дам вам знать!

2. По какой-то причине индикатор выполнения и значки не загружаются. Однако ошибок нет — snack.expo.io/HnAtix !VG Пожалуйста, взгляните? Вот мой проект ^

3. Я использовал этот оператор импорта для Ionicons: import Icon from 'react-native-vector-icons/Ionicons' . Но самое главное, вам нужно удалить комментарий, который я оставил в моем примере: // Add further ForeignObject for other text and icons...

4. Также обязательно выберите Android или ios, если вы запускаете его в snack, он не будет корректно отображаться в web. Если вы видите знак вопроса, это потому, что для векторных значков react native требуется некоторая настройка, которую вы не можете выполнить в snack (насколько я знаю). Поэтому вы, вероятно, захотите настроить ее локально и протестировать на устройстве. За инструкциями вы можете обратиться к этому: github.com/oblador/react-native-vector-icons#installation .

5. Вот моя скорректированная вилка для вашей закуски snack.expo.io/@bvdl/chart-draft .