ponshu-room-lite/lib/models/sakenowa/sakenowa_models.dart

195 lines
4.9 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// さけのわAPI データモデル
// API Documentation: https://muro.sakenowa.com/sakenowa-data/api/
/// 銘柄データ
class SakenowaBrand {
final int id;
final String name;
final int breweryId;
const SakenowaBrand({
required this.id,
required this.name,
required this.breweryId,
});
factory SakenowaBrand.fromJson(Map<String, dynamic> json) {
return SakenowaBrand(
id: json['id'] as int,
name: json['name'] as String,
breweryId: json['breweryId'] as int,
);
}
}
/// 蔵元データ
class SakenowaBrewery {
final int id;
final String name;
final int areaId;
const SakenowaBrewery({
required this.id,
required this.name,
required this.areaId,
});
factory SakenowaBrewery.fromJson(Map<String, dynamic> json) {
return SakenowaBrewery(
id: json['id'] as int,
name: json['name'] as String,
areaId: json['areaId'] as int,
);
}
}
/// 地域データ
class SakenowaArea {
final int id;
final String name;
const SakenowaArea({
required this.id,
required this.name,
});
factory SakenowaArea.fromJson(Map<String, dynamic> json) {
return SakenowaArea(
id: json['id'] as int,
name: json['name'] as String,
);
}
}
/// 6軸フレーバーチャート
/// f1: 華やか, f2: 芳醇, f3: 重厚, f4: 穏やか, f5: 軽快, f6: ドライ
class SakenowaFlavorChart {
final int brandId;
final double f1; // 華やか
final double f2; // 芳醇
final double f3; // 重厚
final double f4; // 穏やか
final double f5; // 軽快
final double f6; // ドライ
const SakenowaFlavorChart({
required this.brandId,
required this.f1,
required this.f2,
required this.f3,
required this.f4,
required this.f5,
required this.f6,
});
factory SakenowaFlavorChart.fromJson(Map<String, dynamic> json) {
return SakenowaFlavorChart(
brandId: json['brandId'] as int,
f1: (json['f1'] as num).toDouble(),
f2: (json['f2'] as num).toDouble(),
f3: (json['f3'] as num).toDouble(),
f4: (json['f4'] as num).toDouble(),
f5: (json['f5'] as num).toDouble(),
f6: (json['f6'] as num).toDouble(),
);
}
/// 軸名のラベル
static const axisLabels = {
'f1': '華やか',
'f2': '芳醇',
'f3': '重厚',
'f4': '穏やか',
'f5': '軽快',
'f6': 'ドライ',
};
/// レーダーチャート用のリストに変換
List<double> toList() => [f1, f2, f3, f4, f5, f6];
/// 五味チャート形式に変換(互換性維持)
/// 既存の五味チャートaroma, sweetness, acidity, bitterness, bodyに対応
Map<String, double> toFiveAxisTaste() {
return {
'aroma': f1, // 華やか → 香り
'sweetness': (f2 + f4) / 2, // 芳醇・穏やか → 甘み
'acidity': f5, // 軽快 → 酸味
'bitterness': f6, // ドライ → キレ
'body': f3, // 重厚 → コク
};
}
/// 五味チャート形式1-5スケールに変換
/// Gemini AI解析結果との互換性維持
Map<String, int> toFiveAxisTasteInt() {
final fiveAxis = toFiveAxisTaste();
return fiveAxis.map((k, v) => MapEntry(k, (v * 5).round().clamp(1, 5)));
}
/// レーダーチャート表示用6軸、ラベル付き
List<MapEntry<String, double>> toRadarData() {
return [
MapEntry(axisLabels['f1']!, f1),
MapEntry(axisLabels['f2']!, f2),
MapEntry(axisLabels['f3']!, f3),
MapEntry(axisLabels['f4']!, f4),
MapEntry(axisLabels['f5']!, f5),
MapEntry(axisLabels['f6']!, f6),
];
}
/// 英語ラベルでのレーダーチャート用
List<MapEntry<String, double>> toRadarDataEn() {
return [
MapEntry('Elegant', f1), // 華やか
MapEntry('Rich', f2), // 芳醇
MapEntry('Full', f3), // 重厚
MapEntry('Mild', f4), // 穏やか
MapEntry('Light', f5), // 軽快
MapEntry('Dry', f6), // ドライ
];
}
}
/// ランキングエントリ
class SakenowaRanking {
final int rank;
final int brandId;
final int? areaId;
final double score;
const SakenowaRanking({
required this.rank,
required this.brandId,
this.areaId,
required this.score,
});
factory SakenowaRanking.fromJson(Map<String, dynamic> json) {
return SakenowaRanking(
rank: json['rank'] as int,
brandId: json['brandId'] as int,
areaId: json['areaId'] as int?,
score: (json['score'] as num).toDouble(),
);
}
}
/// フレーバータグ
class SakenowaFlavorTag {
final int id;
final String tag;
const SakenowaFlavorTag({
required this.id,
required this.tag,
});
factory SakenowaFlavorTag.fromJson(Map<String, dynamic> json) {
return SakenowaFlavorTag(
id: json['id'] as int,
tag: json['tag'] as String,
);
}
}