@model TimelineViewModel @{ ViewData["Title"] = "Timeline"; ViewData["ShellClass"] = "plotline-shell-wide"; var selectedBook = Model.Books.FirstOrDefault(x => x.Book.BookID == Model.SelectedBookID)?.Book; var timelineMetricScenes = Model.Books .SelectMany(book => book.Chapters.SelectMany(chapter => chapter.Scenes.Select(scene => new { sceneId = scene.SceneID, axisLabel = $"{chapter.Chapter.ChapterNumber:g}.{scene.SceneNumber:g}", chapterLabel = $"Chapter {chapter.Chapter.ChapterNumber:g}", sceneNumber = scene.SceneNumber.ToString("g"), sceneTitle = scene.SceneTitle, bookTitle = book.Book.BookTitle, timelineUrl = Url.Action("Index", "Timeline", new { projectId = Model.Project.ProjectID, bookId = book.Book.BookID, selectedSceneId = scene.SceneID }) }))) .ToList(); var timelineMetricShapePayload = new { scenes = timelineMetricScenes, metrics = Model.MetricGraphs.Select(graph => new { metricName = graph.MetricName, points = graph.Points.Select(point => new { sceneId = point.SceneID, value = point.Value }) }) }; }
Workspace context @Model.Project.ProjectName@if (selectedBook is not null) { / @selectedBook.BookTitle }

Story timeline

@Model.Project.ProjectName

@if (Model.SelectedBookID.HasValue) {
} Warnings Story health
@if (!Model.Books.Any()) {

No timeline yet

Add books, chapters and scenes to see them arranged here in narrative order.

} else {
@foreach (var book in Model.Books) { } @if (Model.PlotLanes.Any() && Model.OrderedScenes.Any()) {
Plot line lanes Thread event markers by scene
@foreach (var lane in Model.PlotLanes) {
@lane.PlotLine.PlotLineName
@foreach (var slot in lane.SceneSlots) {
@foreach (var threadEvent in slot.Events) { var markerClass = threadEvent.EventTypeName is "Resolved" or "Payoff" ? "resolved" : threadEvent.EventTypeName is "Contradicted" ? "contradicted" : ""; @threadEvent.MarkerText }
}
}
} else {
Add visible plot lines and thread events to see narrative lanes here.
} @if (Model.AssetLanes.Any() && Model.OrderedScenes.Any()) {
Story asset lanes Asset event markers by scene
@foreach (var lane in Model.AssetLanes) {
@lane.Asset.AssetName @lane.Asset.KindName / @lane.Asset.Importance
@foreach (var slot in lane.SceneSlots) {
@foreach (var assetEvent in slot.Events) { @assetEvent.MarkerText }
}
}
} else {
Add story assets and asset events to see asset lanes here.
} @if (Model.CharacterLanes.Any() && Model.OrderedScenes.Any()) {
Character appearances First twelve project characters
@foreach (var lane in Model.CharacterLanes) { }
} else {
Add characters to scenes to see character appearance lanes here.
}

Pacing

Metric shape

@Model.OrderedScenes.Count scene@(Model.OrderedScenes.Count == 1 ? "" : "s")
@if (!Model.MetricGraphs.Any() || !Model.OrderedScenes.Any()) {

Add scenes to begin seeing emotional and pacing shape.

} else {

Compare selected metrics across the same scene timeline. Click a point to focus that scene.

Metric chart could not load. The raw metric rows are still available below.

Show raw metric rows
@foreach (var graph in Model.MetricGraphs) {
@graph.MetricName
@foreach (var point in graph.Points) { @point.Value }
}
}
} @section Scripts { }