part of 'view.dart'; extension on _ServerDetailPageState { void _onTapGpuItem(NvidiaSmiItem item) { final processes = item.memory.processes; final displayCount = processes.length > 5 ? 5 : processes.length; final height = displayCount * 47.0; context.showRoundDialog( title: item.name, child: SizedBox( width: double.maxFinite, height: height, child: ListView.builder( itemCount: processes.length, itemBuilder: (_, idx) => _buildGpuProcessItem(processes[idx]), ), ), actions: Btnx.oks, ); } void _nTapGpuProcessItem(NvidiaSmiMemProcess process) { context.showRoundDialog( title: '${process.pid}', titleMaxLines: 1, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ UIs.height13, Text('Memory: ${process.memory} MiB'), UIs.height13, Text('Process: ${process.name}') ], ), actions: [ TextButton( onPressed: () => context.pop(), child: Text(libL10n.close), ) ], ); } void _onTapCustomItem(MapEntry cmd) { context.showRoundDialog( title: cmd.key, child: SingleChildScrollView( child: Text(cmd.value, style: UIs.text13Grey), ), actions: [ TextButton( onPressed: () => context.pop(), child: Text(libL10n.close), ), ], ); } void _onTapSensorItem(SensorItem si) { context.showRoundDialog( title: si.device, child: SingleChildScrollView( child: SimpleMarkdown( data: si.toMarkdown, styleSheet: MarkdownStyleSheet( tableBorder: TableBorder.all(color: Colors.grey), tableHead: const TextStyle(fontWeight: FontWeight.bold), ), ), ), ); } void _onTapTemperatureItem(String key) { Pfs.copy(key); context.showSnackBar('${libL10n.copy} ${libL10n.success}'); } } enum _NetSortType { device, trans, recv, ; bool get isDevice => this == _NetSortType.device; bool get isIn => this == _NetSortType.recv; bool get isOut => this == _NetSortType.trans; _NetSortType get next { switch (this) { case device: return trans; case _NetSortType.trans: return recv; case recv: return device; } } int Function(String, String) getSortFunc(NetSpeed ns) { switch (this) { case _NetSortType.device: return (b, a) => a.compareTo(b); case _NetSortType.recv: return (b, a) => ns.speedInBytes(ns.deviceIdx(a)).compareTo(ns.speedInBytes(ns.deviceIdx(b))); case _NetSortType.trans: return (b, a) => ns.speedOutBytes(ns.deviceIdx(a)).compareTo(ns.speedOutBytes(ns.deviceIdx(b))); } } } Widget _buildLineChart( List> spots, { String? tooltipPrefix, bool curve = false, int verticalInterval = 20, }) { return LineChart(LineChartData( lineTouchData: LineTouchData( touchTooltipData: LineTouchTooltipData( tooltipPadding: const EdgeInsets.all(5), tooltipBorderRadius: BorderRadius.circular(8), getTooltipItems: (List touchedSpots) { return touchedSpots.map((e) { return LineTooltipItem( '$tooltipPrefix${e.barIndex}: ${e.y.toStringAsFixed(2)}', const TextStyle( fontSize: 12, fontWeight: FontWeight.bold, ), ); }).toList(); }, ), handleBuiltInTouches: true, ), gridData: FlGridData( show: true, drawVerticalLine: false, horizontalInterval: verticalInterval.toDouble(), getDrawingHorizontalLine: (value) { return const FlLine( color: Color.fromARGB(43, 88, 91, 94), strokeWidth: 1, ); }, ), titlesData: FlTitlesData( show: true, rightTitles: const AxisTitles( sideTitles: SideTitles(showTitles: false), ), topTitles: const AxisTitles( sideTitles: SideTitles(showTitles: false), ), bottomTitles: const AxisTitles( sideTitles: SideTitles(showTitles: false), ), leftTitles: AxisTitles( sideTitles: SideTitles( showTitles: true, interval: 20, getTitlesWidget: (val, meta) { if (val % verticalInterval != 0) return UIs.placeholder; if (val == 0) return const Text('0 %', style: UIs.text12Grey); return Text( val.toInt().toString(), style: UIs.text12Grey, ); }, reservedSize: 27, ), ), ), borderData: FlBorderData(show: false), minY: -1, maxY: 101, lineBarsData: spots .map((e) => LineChartBarData( spots: e, isCurved: curve, barWidth: 2, isStrokeCapRound: true, color: UIs.primaryColor, dotData: const FlDotData(show: false), belowBarData: BarAreaData(show: false), )) .toList(), )); }