def compute_static_patch(document, models, json=None): """ Computes a patch to update an existing document without diffing the json first, making it suitable for static updates between arbitrary frames. Note that this only supports changed attributes and will break if new models have been added since the plot was first created. """ references = refs(json if json else document.to_json()) requested_updates = [m.ref['id'] for m in models] value_refs = {} events = [] update_types = defaultdict(list) for ref_id, obj in references.items(): if ref_id not in requested_updates: continue if obj['type'] in MODEL_PRIORITY: priority = MODEL_PRIORITY.index(obj['type']) else: priority = float('inf') for key, val in obj['attributes'].items(): event = Document._event_for_attribute_change(references, obj, key, val, value_refs) events.append((priority, event)) update_types[obj['type']].append(key) events = [delete_refs(e, LOCATIONS, IGNORED_MODELS) for _, e in sorted(events, key=lambda x: x[0])] value_refs = {ref_id: delete_refs(val, LOCATIONS, IGNORED_MODELS) for ref_id, val in value_refs.items()} references = [val for val in value_refs.values() if val is not None] return dict(events=events, references=references)
def compute_static_patch(document, models, json=None): """ Computes a patch to update an existing document without diffing the json first, making it suitable for static updates between arbitrary frames. Note that this only supports changed attributes and will break if new models have been added since the plot was first created. """ references = refs(json if json else document.to_json()) requested_updates = [m.ref['id'] for m in models] value_refs = {} events = [] update_types = defaultdict(list) for ref_id, obj in references.items(): if ref_id not in requested_updates: continue if obj['type'] in MODEL_PRIORITY: priority = MODEL_PRIORITY.index(obj['type']) else: priority = float('inf') for key, val in obj['attributes'].items(): event = Document._event_for_attribute_change( references, obj, key, val, value_refs) events.append((priority, event)) update_types[obj['type']].append(key) events = [ delete_refs(e, LOCATIONS, IGNORED_MODELS) for _, e in sorted(events, key=lambda x: x[0]) ] value_refs = {ref_id: val for ref_id, val in value_refs.items()} value_refs = delete_refs(value_refs, LOCATIONS, IGNORED_MODELS) return dict(events=events, references=list(value_refs.values()))
def compute_static_patch(document, models): """ Computes a patch to update an existing document without diffing the json first, making it suitable for static updates between arbitrary frames. Note that this only supports changed attributes and will break if new models have been added since the plot was first created. A static patch consists of two components: 1) The events: Contain references to particular model attributes along with the updated value. 2) The references: Contain a list of all references required to resolve the update events. This function cleans up the events and references that are sent to ensure that only the data that is required is sent. It does so by a) filtering the events and references for the models that have been requested to be updated and b) cleaning up the references to ensure that only the references between objects are sent without duplicating any of the data. """ references = to_references(document) model_ids = [m.ref['id'] for m in models] requested_updates = [] value_refs = {} events = [] update_types = defaultdict(list) for ref_id, obj in references.items(): if ref_id in model_ids: requested_updates += get_ids(obj) else: continue if obj['type'] in MODEL_PRIORITY: priority = MODEL_PRIORITY.index(obj['type']) else: priority = float('inf') for key, val in obj['attributes'].items(): event = Document._event_for_attribute_change( references, obj, key, val, value_refs) events.append((priority, event)) update_types[obj['type']].append(key) events = [ delete_refs(e, IGNORED_MODELS, ignored_attributes=IGNORED_ATTRIBUTES) for _, e in sorted(events, key=lambda x: x[0]) ] events = [ e for e in events if all(i in requested_updates for i in get_ids(e)) if 'new' in e ] value_refs = { ref_id: delete_refs(val, IGNORED_MODELS, IGNORED_ATTRIBUTES) for ref_id, val in value_refs.items() } references = [val for val in value_refs.values() if val not in [None, {}]] return dict(events=events, references=references)