Xkcd-Style नैरेटिव चार्ट बनाएँ


45

अधिक प्रतिष्ठित xkcd स्ट्रिप्स में से एक में, रान्डेल मुनरो ने कथा चार्ट में कई फिल्मों की समयसीमा की कल्पना की:

यहाँ छवि विवरण दर्ज करें (बड़े संस्करण के लिए क्लिक करें)

स्रोत: xkcd नंबर 657

एक फिल्म (या कुछ अन्य कथा) की समयरेखा के विनिर्देश को देखते हुए, आप इस तरह के चार्ट को उत्पन्न करने के लिए हैं। यह एक लोकप्रियता प्रतियोगिता है, इसलिए सबसे (शुद्ध) वोटों के साथ जवाब जीत जाएगा।

न्यूनतम आवश्यकताएं

कल्पना को थोड़ा कसने के लिए, यहां उन सुविधाओं का न्यूनतम सेट है, जिन्हें हर उत्तर को लागू करना चाहिए:

  • इनपुट के रूप में चरित्र नामों की सूची लें, उसके बाद घटनाओं की सूची। प्रत्येक घटना या तो मरने वाले पात्रों की सूची है, या पात्रों के समूहों की एक सूची है (यह दर्शाता है कि वर्तमान में कौन से वर्ण एक साथ हैं)। यहाँ एक उदाहरण है कि जुरासिक पार्क कथा को कैसे एन्कोड किया जा सकता है:

    ["T-Rex", "Raptor", "Raptor", "Raptor", "Malcolm", "Grant", "Sattler", "Gennaro",
     "Hammond", "Kids", "Muldoon", "Arnold", "Nedry", "Dilophosaurus"]
    [
      [[0],[1,2,3],[4],[5,6],[7,8,10,11,12],[9],[13]],
      [[0],[1,2,3],[4,7,5,6,8,9,10,11,12],[13]],
      [[0],[1,2,3],[4,7,5,6,8,9,10],[11,12],[13]],
      [[0],[1,2,3],[4,7,5,6,9],[8,10,11,12],[13]],
      [[0,4,7],[1,2,3],[5,9],[6,8,10,11],[12],[13]],
      [7],
      [[5,9],[0],[4,6,10],[1,2,3],[8,11],[12,13]],
      [12],
      [[0, 5, 9], [1, 2, 3], [4, 6, 10, 8, 11], [13]], 
      [[0], [5, 9], [1, 2], [3, 11], [4, 6, 10, 8], [13]], 
      [11], 
      [[0], [5, 9], [1, 2, 10], [3, 6], [4, 8], [13]], 
      [10], 
      [[0], [1, 2, 9], [5, 6], [3], [4, 8], [13]], 
      [[0], [1], [9, 5, 6], [3], [4, 8], [2], [13]], 
      [[0, 1, 9, 5, 6, 3], [4, 8], [2], [13]], 
      [1, 3], 
      [[0], [9, 5, 6, 3, 4, 8], [2], [13]]
    ]
    

    उदाहरण के लिए, पहली पंक्ति का मतलब है कि चार्ट की शुरुआत में, टी-रेक्स एक अकेला है, तीन रैप्टर एक साथ हैं, मैल्कम अकेला है, ग्रांट और सैटलर एक साथ हैं, आदि दूसरी से अंतिम घटना का मतलब है कि रैप्टर के दो मर जाते हैं। ।

    जब तक आप इनपुट की अपेक्षा करते हैं, तब तक आपके लिए इस तरह की जानकारी निर्दिष्ट की जा सकती है। उदाहरण के लिए, आप किसी भी सुविधाजनक सूची प्रारूप का उपयोग कर सकते हैं। आप घटनाओं में पात्रों को फिर से पूर्ण चरित्र नाम आदि की अपेक्षा कर सकते हैं।

    आप कर सकते हैं (लेकिन ऐसा नहीं है) मान लें कि समूहों की प्रत्येक सूची में प्रत्येक समूह में प्रत्येक जीवित चरित्र शामिल है। हालाँकि, आपको यह नहीं मान लेना चाहिए कि एक घटना के भीतर समूह या वर्ण विशेष रूप से सुविधाजनक क्रम में हैं।

  • स्क्रीन या फ़ाइल (एक वेक्टर या रेखापुंज ग्राफिक के रूप में) के लिए रेंडर एक चार्ट जिसमें प्रत्येक वर्ण के लिए एक पंक्ति है। प्रत्येक पंक्ति को पंक्ति के आरंभ में एक वर्ण नाम के साथ लेबल किया जाना चाहिए।

  • प्रत्येक सामान्य घटना के लिए, क्रम में, चार्ट के कुछ क्रॉस-सेक्शन होना चाहिए जिसमें वर्णों के समूह स्पष्ट रूप से उनकी संबंधित लाइनों की निकटता से मिलते-जुलते हैं।
  • प्रत्येक मौत की घटना के लिए, संबंधित पात्रों की पंक्तियों को एक दृश्यमान बूँद में समाप्त करना होगा।
  • आपको रान्डेल के भूखंडों की किसी भी अन्य विशेषता को पुन: पेश करने की आवश्यकता नहीं है, न ही आपको उनकी ड्राइंग शैली को पुन: पेश करना है। तेज मोड़ों के साथ सीधी रेखाएं, सभी काले रंग में, आगे के लेबल के बिना और प्रतियोगिता में प्रवेश करने के लिए एक शीर्षक बिल्कुल ठीक है। वहाँ भी कुशलता से अंतरिक्ष का उपयोग करने की कोई जरूरत नहीं है - जैसे कि आप संभावित रूप से अन्य वर्णों के साथ मिलने के लिए केवल नीचे की ओर जाने वाली लाइनों द्वारा एल्गोरिथ्म को सरल बना सकते हैं, जब तक कि समय की एक स्पष्ट दिशा है।

मैंने एक संदर्भ समाधान जोड़ा है जो इन न्यूनतम आवश्यकताओं को पूरा करता है।

यह सुंदर बना रही है

हालांकि यह एक लोकप्रियता प्रतियोगिता है, इसलिए इसके शीर्ष पर, आप जो भी चाहते हैं, उसे लागू कर सकते हैं। सबसे महत्वपूर्ण जोड़ एक सभ्य लेआउटिंग एल्गोरिथ्म है जो चार्ट को अधिक सुपाठ्य बनाता है - जैसे कि जो लाइनों का अनुसरण करने में आसान बनाता है और जो आवश्यक लाइन क्रॉसिंग की संख्या को कम करता है। यह इस चुनौती की मुख्य एल्गोरिथम समस्या है! वोट तय करेंगे कि आपका एल्गोरिथ्म चार्ट को ठीक रखने में कितना अच्छा प्रदर्शन करता है।

लेकिन यहाँ कुछ और विचार हैं, उनमें से ज्यादातर रान्डेल के चार्ट के आधार पर हैं:

सजावट:

  • रंगीन रेखाएँ।
  • कथानक का एक शीर्षक।
  • लेबलिंग लाइन समाप्त होती है।
  • स्वचालित रूप से relabelling लाइनें जो एक व्यस्त अनुभाग से गुजरी हैं।
  • हाथ से तैयार शैली (या अन्य! जैसा कि मैंने कहा, रैंडल की शैली को पुन: पेश करने की कोई आवश्यकता नहीं है यदि आपके पास बेहतर विचार है) लाइनों और फोंट के लिए।
  • समय अक्ष के अनुकूलन उन्मुखीकरण।

अतिरिक्त अभिव्यक्ति:

  • नामित घटनाओं / समूहों / मौतों।
  • गायब और फिर से दिखाई देने वाली लाइनें।
  • देर से प्रवेश करने वाले पात्र।
  • हाइलाइट्स जो वर्णों के हस्तांतरणीय (?) गुणों को दर्शाते हैं (उदाहरण के लिए, लोटआर चार्ट में रिंगबियर देखें)।
  • समूहीकरण अक्ष में अतिरिक्त जानकारी को एन्कोड करना (जैसे भौगोलिक सूचना जैसे लोटआर चार्ट में)।
  • समय यात्रा?
  • वैकल्पिक वास्तविकताओं?
  • एक चरित्र दूसरे में बदल रहा है?
  • दो पात्रों का विलय? (एक चरित्र विभाजन?)
  • 3 डी? (यदि आप वास्तव में इतनी दूर जाते हैं, तो कृपया सुनिश्चित करें कि आप वास्तव में अतिरिक्त आयाम का उपयोग कर रहे हैं कि कुछ कल्पना करें!)
  • किसी भी अन्य प्रासंगिक विशेषताएं, जो किसी फिल्म (या पुस्तक आदि) के कथानक की कल्पना करने के लिए उपयोगी हो सकती हैं।

बेशक, इनमें से कई को अतिरिक्त इनपुट की आवश्यकता होगी, और आप आवश्यक के रूप में अपने इनपुट प्रारूप को बढ़ाने के लिए स्वतंत्र हैं, लेकिन कृपया यह दस्तावेज करें कि डेटा कैसे दर्ज किया जा सकता है।

आपके द्वारा कार्यान्वित सुविधाओं को दिखाने के लिए कृपया एक या दो उदाहरण शामिल करें।

आपका समाधान किसी भी मान्य इनपुट से निपटने में सक्षम होना चाहिए, लेकिन यह बिल्कुल ठीक है अगर यह दूसरों की तुलना में कुछ प्रकार के आख्यानों के लिए बेहतर है।

वोटिंग क्राइटेरिया

मुझे कोई भ्रम नहीं है कि मैं लोगों को बता सकता हूं कि उन्हें अपना वोट कैसे खर्च करना चाहिए, लेकिन महत्व के क्रम में यहां कुछ सुझाव दिए गए हैं:

  • डाउनवोट उत्तर जो कमियां, मानक वाले या दूसरों का शोषण करते हैं, या हार्डकोड एक या अधिक परिणाम देते हैं।
  • ऐसे उत्तर न दें जो न्यूनतम आवश्यकताओं को पूरा नहीं करते (कोई फर्क नहीं पड़ता कि बाकी कैसे हो सकता है)।
  • और सबसे पहले, अच्छा लेआउट एल्गोरिदम upvote। इसमें ऐसे उत्तर शामिल हैं, जो ग्राफ़ को सुपाठ्य रखने के लिए लाइनों को पार करते समय ऊर्ध्वाधर स्थान का बहुत अधिक उपयोग नहीं करते हैं, या जो ऊर्ध्वाधर अक्ष में अतिरिक्त जानकारी को एन्कोड करने का प्रबंधन करते हैं। भारी गड़बड़ी किए बिना समूहों की कल्पना करना इस चुनौती का मुख्य केंद्र होना चाहिए, जैसे कि यह एक प्रोग्रामिंग प्रतियोगिता है जिसमें एक दिलचस्प एल्गोरिदम समस्या है।
  • वैकल्पिक सुविधाओं को अपवोट करें जो अभिव्यंजक शक्ति को जोड़ते हैं (यानी केवल शुद्ध सजावट नहीं हैं)।
  • अंत में, अच्छी प्रस्तुति को बढ़ाएं।

7
क्योंकि कोड-गोल्फ में पर्याप्त xkcd नहीं है
पर २६

8
@proudhaskeller PPCG में कभी भी पर्याप्त xkcd नहीं हो सकता है। ;) लेकिन मुझे नहीं लगता कि हमने अभी तक उनके सुपरसाइड किए गए इंफॉर्मेशन ग्राफिक्स / विज़ुअलाइज़ेशन की चुनौतियों का सामना करने की कोशिश की है, इसलिए मुझे उम्मीद है कि मैं इसके साथ कुछ नया ला रहा हूं। और मुझे यकीन है कि कुछ अन्य भी बहुत अलग और दिलचस्प चुनौतियाँ पेश करेंगे।
मार्टिन एंडर

क्या यह ठीक है अगर मेरा समाधान केवल 12 नाराज पुरुषों, द्वंद्वयुद्ध (स्पीलबर्ग, 1971, नियमित मोटर चालक बनाम पागल ट्रक वाले), और विमानों, ट्रेनों और ऑटोमोबाइल को संभालता है? ;-)
लेवल रिवर सेंट

4
मुझे आश्चर्य है कि प्राइमर के लिए इनपुट कैसा दिखेगा ...
जोशुआ

1
@ जपना हाँ, यही विचार था। यदि किसी ईवेंट में आगे की सूची है, तो यह एक सूची समूह है। तो [[x,y,z]]इसका मतलब यह होगा कि सभी पात्र वर्तमान में एक साथ हैं। लेकिन अगर घटना में सूचियाँ नहीं होती हैं, लेकिन केवल पात्र सीधे होते हैं, तो यह मृत्यु भी है, इसलिए उसी स्थिति में [x,y,z]इसका मतलब है कि वे तीन वर्ण मर जाते हैं। एक और प्रारूप का उपयोग करने के लिए स्वतंत्र महसूस करें, एक स्पष्ट संकेत के साथ कि क्या कुछ मृत्यु या समूहन घटना है अगर यह आपकी मदद करता है। उपरोक्त प्रारूप केवल एक सुझाव है। जब तक आपका इनपुट प्रारूप कम से कम अभिव्यंजक है, तब तक आप कुछ और उपयोग कर सकते हैं।
मार्टिन एंडर

जवाबों:


18

Python3 के साथ सुन्न, डरावना और matplotlib

जुरासिक पार्क

संपादित करें :

  • मैंने घटनाओं के बीच समूहों को उसी सापेक्ष स्थिति में रखने की कोशिश की, इसलिए sorted_eventफ़ंक्शन।
  • वर्णों की y स्थिति की गणना करने के लिए नया कार्य ( coords)।
  • प्रत्येक जीवित घटना को अब दो बार प्लॉट किया जाता है, इसलिए पात्र एक साथ बेहतर होते हैं।
  • जोड़ा गया किंवदंती और हटाए गए कुल्हाड़ियों लेबल।
import math
import numpy as np
from scipy.interpolate import interp1d
from matplotlib import cm, pyplot as plt


def sorted_event(prev, event):
    """ Returns a new sorted event, where the order of the groups is
    similar to the order in the previous event. """
    similarity = lambda a, b: len(set(a) & set(b)) - len(set(a) ^ set(b))
    most_similar = lambda g: max(prev, key=lambda pg: similarity(g, pg))
    return sorted(event, key=lambda g: prev.index(most_similar(g)))


def parse_data(chars, events):
    """ Turns the input data into 3 "tables":
    - characters: {character_id: character_name}
    - timelines: {character_id: [y0, y1, y2, ...],
    - deaths: {character_id: (x, y)}
    where x and y are the coordinates of a point in the xkcd like plot.
    """
    characters = dict(enumerate(chars))
    deaths = {}
    timelines = {char: [] for char in characters}

    def coords(character, event):
        for gi, group in enumerate(event):
            if character in group:
                ci = group.index(character)
                return (gi + 0.5 * ci / len(group)) / len(event)
        return None

    t = 0
    previous = events[0]
    for event in events:
        if isinstance(event[0], list):
            previous = event = sorted_event(previous, event)
            for character in [c for c in characters if c not in deaths]:
                timelines[character] += [coords(character, event)] * 2
            t += 2
        else:
            for char in set(event) - set(deaths):
                deaths[char] = (t-1, timelines[char][-1])

    return characters, timelines, deaths


def plot_data(chars, timelines, deaths):
    """ Draws a nice xkcd like movie timeline """

    plt.xkcd()  # because python :)

    fig = plt.figure(figsize=(16,8))
    ax = fig.add_subplot(111)
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
    ax.set_xlim([0, max(map(len, timelines.values()))])

    color_floats = np.linspace(0, 1, len(chars))
    color_of = lambda char_id: cm.Accent(color_floats[char_id])

    for char_id in sorted(chars):
        y = timelines[char_id]
        f = interp1d(np.linspace(0, len(y)-1, len(y)), y, kind=5)
        x = np.linspace(0, len(y)-1, len(y)*10)
        ax.plot(x, f(x), c=color_of(char_id))

    x, y = zip(*(deaths[char_id] for char_id in sorted(deaths)))
    ax.scatter(x, y, c=np.array(list(map(color_of, sorted(deaths)))), 
               zorder=99, s=40)

    ax.legend(list(map(chars.get, sorted(chars))), loc='best', ncol=4)
    fig.savefig('testplot.png')


if __name__ == '__main__':
    chars = [
        "T-Rex","Raptor","Raptor","Raptor","Malcolm","Grant","Sattler",
        "Gennaro","Hammond","Kids","Muldoon","Arnold","Nedry","Dilophosaurus"
    ]
    events = [
        [[0],[1,2,3],[4],[5,6],[7,8,10,11,12],[9],[13]],
        [[0],[1,2,3],[4,7,5,6,8,9,10,11,12],[13]],
        [[0],[1,2,3],[4,7,5,6,8,9,10],[11,12],[13]],
        [[0],[1,2,3],[4,7,5,6,9],[8,10,11,12],[13]],
        [[0,4,7],[1,2,3],[5,9],[6,8,10,11],[12],[13]],
        [7],
        [[5,9],[0],[4,6,10],[1,2,3],[8,11],[12,13]],
        [12],
        [[0,5,9],[1,2,3],[4,6,10,8,11],[13]],
        [[0],[5,9],[1,2],[3,11],[4,6,10,8],[13]],
        [11],
        [[0],[5,9],[1,2,10],[3,6],[4,8],[13]],
        [10],
        [[0],[1,2,9],[5,6],[3],[4,8],[13]],
        [[0],[1],[9,5,6],[3],[4,8],[2],[13]],
        [[0,1,9,5,6,3],[4,8],[2],[13]],
        [1,3],
        [[0],[9,5,6,3,4,8],[2],[13]]
    ]
    plot_data(*parse_data(chars, events))

हह, बहुत अच्छा xkcd देखो:) ... किसी भी मौका आप लाइनों लेबल करने में सक्षम हो जाएगा?
मार्टिन एंडर

लाइनों को लेबल करें, अलग-अलग चौड़ाई की लाइनें (कुछ बिंदुओं के बीच घटती / बढ़ती के साथ) और अंत में ... लाइनों को अधिक क्षैतिज बनाते हैं जब प्रक्षेप करते समय एक शीर्ष के पास होते हैं, एक बीज़ियर वक्र की तरह और यह सबसे अच्छा प्रवेश आईएमओ होगा: )
ऑप्टिमाइज़र

1
धन्यवाद, लेकिन xkcd शैली को matplotlib में शामिल किया गया है, इसलिए यह केवल एक फ़ंक्शन कॉल था :) खैर, मैंने एक किंवदंती बनाई, लेकिन यह लगभग एक तिहाई छवि पर कब्जा कर लिया, इसलिए मैंने इसे टिप्पणी की।
21

मैंने अपना उत्तर संशोधित किया, मुझे लगता है कि यह अब बेहतर लग रहा है।
पग

6

T-SQL

मैं एक प्रविष्टि के रूप में इससे खुश नहीं हूं, लेकिन मुझे लगता है कि यह सवाल कम से कम इसके लिए एक प्रयास है। मैं बाद में अनुमति देते हुए इसे सुधारने की कोशिश करूंगा, लेकिन लेबलिंग हमेशा SQL में एक समस्या होगी। समाधान के लिए SQL 2012+ की आवश्यकता होती है और यह SSMS (SQL सर्वर प्रबंधन स्टूडियो) में चलाया जाता है। आउटपुट स्थानिक परिणाम टैब में है।

-- Variables for the input
DECLARE @actors NVARCHAR(MAX) = '["T-Rex", "Raptor", "Raptor", "Raptor", "Malcolm", "Grant", "Sattler", "Gennaro", "Hammond", "Kids", "Muldoon", "Arnold", "Nedry", "Dilophosaurus"]';
DECLARE @timeline NVARCHAR(MAX) = '
[
   [[1], [2, 3, 4], [5], [6, 7], [8, 9, 11, 12, 13], [10], [14]],
   [[1], [2, 3, 4], [5, 8, 6, 7, 9, 10, 11, 12, 13], [14]],
   [[1], [2, 3, 4], [5, 8, 6, 7, 9, 10, 11], [12, 13], [14]],
   [[1], [2, 3, 4], [5, 8, 6, 7, 10], [9, 11, 12, 13], [14]],
   [[1, 5, 8], [2, 3, 4], [6, 10], [7, 9, 11, 12], [13], [14]],
   [8],
   [[6, 10], [1], [5, 7, 11], [2, 3, 4], [9, 12], [13, 14]],
   [13],
   [[1, 6, 10], [2, 3, 4], [5, 7, 11, 9, 12], [14]],
   [[1], [6, 10], [2, 3], [4, 12], [5, 7, 11, 9], [14]],
   [12],
   [[1], [6, 10], [2, 3, 11], [4, 7], [5, 9], [14]],
   [11],
   [[1], [2, 3, 10], [6, 7], [4], [5, 9], [14]],
   [[1], [2], [10, 6, 7], [4], [5, 9], [3], [14]],
   [[1, 2, 10, 6, 7, 4], [5, 9], [3], [14]],
   [2, 4],
   [[1], [10, 6, 7, 5, 9], [3], [14]]
]
';

-- Populate Actor table
WITH actor(A) AS ( SELECT CAST(REPLACE(STUFF(REPLACE(REPLACE(@actors,', ',','),'","','</a><a>'),1,2,'<a>'),'"]','</a>') AS XML))
SELECT ROW_NUMBER() OVER (ORDER BY(SELECT \)) ActorID, a.n.value('.','varchar(50)') Name
INTO Actor
FROM actor CROSS APPLY A.nodes('/a') as a(n);

-- Populate Timeline Table
WITH Seq(L) AS (
    SELECT CAST(REPLACE(REPLACE(REPLACE(REPLACE(@timeline,'[','<e>'),']','</e>'),'</e>,<e>','</e><e>'),'</e>,','</e>') AS XML)
    ),
    TimeLine(N,Exerpt,Elem) AS (
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) N
        ,z.query('.')
        ,CAST(REPLACE(CAST(z.query('.') AS VARCHAR(MAX)),',','</e><e>') AS XML)
    FROM Seq 
        CROSS APPLY Seq.L.nodes('/e/e') AS Z(Z)
    ),
    Groups(N,G,Exerpt) AS (
    SELECT N, 
        ROW_NUMBER() OVER (PARTITION BY N ORDER BY CAST(SUBSTRING(node.value('.','varchar(50)'),1,ISNULL(NULLIF(CHARINDEX(',',node.value('.','varchar(50)')),0),99)-1) AS INT)), 
        CAST(REPLACE(CAST(node.query('.') AS VARCHAR(MAX)),',','</e><e>') AS XML) C
    FROM TimeLine 
        CROSS APPLY Exerpt.nodes('/e/e') as Z(node)
    WHERE Exerpt.exist('/e/e') = 1
    )
SELECT * 
INTO TimeLine
FROM (
    SELECT N, null G, null P, node.value('.','int') ActorID, 1 D 
    FROM TimeLine CROSS APPLY TimeLine.Elem.nodes('/e') AS E(node)
    WHERE Exerpt.exist('/e/e') = 0
    UNION ALL
    SELECT N, G, DENSE_RANK() OVER (PARTITION BY N, G ORDER BY node.value('.','int')), node.value('.','int') ActorID, 0
    FROM Groups CROSS APPLY Groups.Exerpt.nodes('/e') AS D(node)
    ) z;

-- Sort the entries again
WITH ReOrder AS (
            SELECT *, 
                ROW_NUMBER() OVER (PARTITION BY N,G ORDER BY PG, ActorID) PP, 
                COUNT(P) OVER (PARTITION BY N,G) CP, 
                MAX(G) OVER (PARTITION BY N) MG, 
                MAX(ActorID) OVER (ORDER BY (SELECT\)) MA
            FROM (
                SELECT *,
                    LAG(G,1) OVER (PARTITION BY ActorID ORDER BY N) PG,
                    LEAD(G,1) OVER (PARTITION BY ActorID ORDER BY N) NG
                FROM timeline
                ) rg
    )
SELECT * INTO Reordered
FROM ReOrder;
ALTER TABLE Reordered ADD PPP INT
GO
ALTER TABLE Reordered ADD LPP INT
GO
WITH U AS (SELECT N, P, LPP, LAG(PP,1) OVER (PARTITION BY ActorID ORDER BY N) X FROM Reordered)
UPDATE U SET LPP = X FROM U;
WITH U AS (SELECT N, ActorID, P, PG, LPP, PPP, DENSE_RANK() OVER (PARTITION BY N,G ORDER BY PG, LPP) X FROM Reordered)
UPDATE U SET PPP = X FROM U;
GO

SELECT Name, 
    Geometry::STGeomFromText(
        STUFF(LS,1,2,'LINESTRING (') + ')'
        ,0)
        .STBuffer(.1)
        .STUnion(
        Geometry::STGeomFromText('POINT (' + REVERSE(SUBSTRING(REVERSE(LS),1,CHARINDEX(',',REVERSE(LS))-1)) + ')',0).STBuffer(D*.4)
        )
FROM Actor a
    CROSS APPLY (
        SELECT CONCAT(', '
            ,((N*5)-1.2)
                ,' ',(G)+P
            ,', '
            ,((N*5)+1.2)
                ,' ',(G)+P 
            ) AS [text()]
        FROM (
            SELECT ActorID, N,
                CASE WHEN d = 1 THEN
                    ((MA+.0) / (LAG(MG,1) OVER (PARTITION BY ActorID ORDER BY N)+.0)) * 
                    PG * 1.2
                ELSE 
                    ((MA+.0) / (MG+.0)) * 
                    G * 1.2
                END G,
                CASE WHEN d = 1 THEN
                (LAG(PPP,1) OVER (PARTITION BY ActorID ORDER BY N) -((LAG(CP,1) OVER (PARTITION BY ActorID ORDER BY N)-1)/2)) * .2 
                ELSE
                (PPP-((CP-1)/2)) * .2 
                END P
                ,PG
                ,NG
            FROM Reordered
            ) t
        WHERE a.actorid = t.actorid
        ORDER BY N, G
        FOR XML PATH('')
        ) x(LS)
    CROSS APPLY (SELECT MAX(D) d FROM TimeLine dt WHERE dt.ActorID = a.ActorID) d
GO

DROP TABLE Actor;
DROP TABLE Timeline;
DROP TABLE Reordered;

परिणामी समयरेखा निम्नलिखित की तरह दिखती है यहाँ छवि विवरण दर्ज करें


4

गणितज्ञ, संदर्भ समाधान

संदर्भ के लिए, मैं एक गणितज्ञ लिपि प्रदान करता हूं जो बिल्कुल न्यूनतम आवश्यकताओं को पूरा करती है, अधिक कुछ नहीं, कुछ भी कम नहीं।

यह उम्मीद करता है कि पात्रों को प्रश्न में प्रारूप की सूची chars, और घटनाओं की सूची में होना चाहिए events

n = Length@chars;
m = Max@Map[Length, events, {2}];
deaths = {};
Graphics[
 {
  PointSize@Large,
  (
     linePoints = If[Length@# == 3,
         lastPoint = {#[[1]], #[[2]] + #[[3]]/(m + 2)},
         AppendTo[deaths, Point@lastPoint]; lastPoint
         ] & /@ Position[events, #];
     {
      Line@linePoints,
      Text[chars[[#]], linePoints[[1]] - {.5, 0}]
      }
     ) & /@ Range@n,
  deaths
  }
 ]

एक उदाहरण के रूप में, यहाँ गणितीय पार्क की सूची प्रकार का उपयोग करके जुरासिक पार्क उदाहरण है:

chars = {"T-Rex", "Raptor", "Raptor", "Raptor", "Malcolm", "Grant", 
   "Sattler", "Gennaro", "Hammond", "Kids", "Muldoon", "Arnold", 
   "Nedry", "Dilophosaurus"};
events = {
   {{1}, {2, 3, 4}, {5}, {6, 7}, {8, 9, 11, 12, 13}, {10}, {14}},
   {{1}, {2, 3, 4}, {5, 8, 6, 7, 9, 10, 11, 12, 13}, {14}},
   {{1}, {2, 3, 4}, {5, 8, 6, 7, 9, 10, 11}, {12, 13}, {14}},
   {{1}, {2, 3, 4}, {5, 8, 6, 7, 10}, {9, 11, 12, 13}, {14}},
   {{1, 5, 8}, {2, 3, 4}, {6, 10}, {7, 9, 11, 12}, {13}, {14}},
   {8},
   {{6, 10}, {1}, {5, 7, 11}, {2, 3, 4}, {9, 12}, {13, 14}},
   {13},
   {{1, 6, 10}, {2, 3, 4}, {5, 7, 11, 9, 12}, {14}},
   {{1}, {6, 10}, {2, 3}, {4, 12}, {5, 7, 11, 9}, {14}},
   {12},
   {{1}, {6, 10}, {2, 3, 11}, {4, 7}, {5, 9}, {14}},
   {11},
   {{1}, {2, 3, 10}, {6, 7}, {4}, {5, 9}, {14}},
   {{1}, {2}, {10, 6, 7}, {4}, {5, 9}, {3}, {14}},
   {{1, 2, 10, 6, 7, 4}, {5, 9}, {3}, {14}},
   {2, 4},
   {{1}, {10, 6, 7, 4, 5, 9}, {3}, {14}}
};

हम मिलेंगे:

यहाँ छवि विवरण दर्ज करें

(बड़े संस्करण के लिए क्लिक करें)

यह बहुत बुरा नहीं है, लेकिन ऐसा इसलिए है क्योंकि इनपुट डेटा कम या ज्यादा ऑर्डर किया गया है। यदि हम प्रत्येक घटना में समूहों और पात्रों को फेरबदल करते हैं (समान संरचना को बनाए रखते हुए), तो सामान इस तरह हो सकता है:

यहाँ छवि विवरण दर्ज करें

जो थोड़ा गड़बड़ है।

इसलिए जैसा कि मैंने कहा, यह केवल न्यूनतम आवश्यकताओं को पूरा करता है। यह एक अच्छा लेआउट खोजने की कोशिश नहीं करता है और यह सुंदर नहीं है, लेकिन यह वह जगह है जहाँ आप लोग आते हैं!


मुझे लगा कि आप तीखे कोनों को हटाने के लिए क्वाड्रेटिक या क्यूबिक स्प्लिन का उपयोग करके शायद इसे tt प्रेटिफाई ’कर सकते हैं? (मैं इसे इस तरह से करूंगा कि दिए गए बिंदुओं पर स्पर्शरेखा हमेशा 0 हो)
8

@flawr ज़रूर, या मैं इनमें से कुछ ट्रिक लागू कर सकता था, लेकिन यह इस उत्तर का उद्देश्य नहीं था। ;) मैं वास्तव में पूर्ण न्यूनतम के लिए एक संदर्भ प्रदान करना चाहता था।
मार्टिन एंडर

3
क्षमा करें, यह भी ध्यान नहीं दिया गया कि यह आपका अपना प्रश्न = P
त्रुटी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.