Giter Site home page Giter Site logo

Comments (9)

JohnLato avatar JohnLato commented on June 11, 2024

I've been thinking about this, and I think it can be implemented without storing the subdiagram path, or indeed changing the QDiagram type at all.

My idea is to just descend the tree, at each branch checking if the requested Name exists in each sub-tree. If so, continue descending, and if not, leave that branch alone. Continue descending until the correct Name annotation is reached (i.e. the correct Act node is at the root of the subtree), apply the modifications, then re-build the spine. I think this can be implemented very simply by writing a general bottom-up traversal of a DUALTree and then a name-specific transformation function.

Since we'd have to descend the tree anyway (in order to rebuild the spine), this is nearly as efficient as following a path. There is a cost of checking alternate paths at branches, but I think that's probably better than having to update the path annotations, especially as this will likely be a relatively rare operation. I'll try to code it over the next couple days.

from diagrams-core.

byorgey avatar byorgey commented on June 11, 2024

Aha, indeed, that sounds like an excellent idea. This also neatly gets around the issue of multiple subdiagrams with the same name --- no need to store a set of paths or whatever, just filter at each node according to whether the given name exists in a subdiagram.

from diagrams-core.

JohnLato avatar JohnLato commented on June 11, 2024

It turns out my idea isn't quite so great, for two reasons. I was mistaken about how named subdiagrams are currently stored. The current structure is basically Concat [LeafU submap, subdiagram]. One problem is that my current scheme would implicitly rely on this structure, which feels a bit off. The more serious problem is that submaps can refer to arbitrary subdiagrams, even subdiagrams that don't appear in the tree at all. So, here are a few possible solutions:

  • place subdiagrams under a named node, e.g. Annot name subdiagram. Maybe there's a smart way to make this a Down annotation, but I don't see it now. A traversal could get to roughly the correct location by following submaps as I originally proposed.
  • store a relative path to a subdiagram in the submap. Traverse the tree until the root of the up annotation is found, then follow the relative path (which would commonly be Up, Desc 2)
  • create a semigroup for paths to names and make this part of the up annotations.

I feel like Option 3 would result in more duplicated information within a diagram and a more fundamental change, but would probably be the cleanest to implement. Option 2 is conceptually straightforward, but implementing it properly would require a small bit of effort to create the proper framework. Another option may be to create a new prim to refer to a named subdiagram, but that feels like a radical change.

I'll continue to experiment on this; I'd appreciate any ideas or comments.

from diagrams-core.

byorgey avatar byorgey commented on June 11, 2024

Ah, hrm, I guess you're right. The details of how this all works are not really loaded into my head right now. Option 3 does indeed sound cleanest. I don't really mind a bit of duplicated information. I can't say I am very keen on Options 1 or 2.

I also don't understand what you mean by creating a new prim to refer to a named subdiagram. Do you mean to replace named subdiagrams by a placeholder prim, and then look it up when it's time to render it? That wouldn't work since multiple different subdiagrams can have the same name (by design!). If you meant something else then you'll have to explain.

from diagrams-core.

JohnLato avatar JohnLato commented on June 11, 2024

That was exactly what I meant by a new prim. That seems tricky to work around without running all the naming stuff in a Q monad.

I'll see if I can get an implementation along the lines of Option 3. I'm a little busy with personal stuff at the moment so it won't happen right away, but it would be nice to have working with the next release.

from diagrams-core.

byorgey avatar byorgey commented on June 11, 2024

OK, no rush. As you have seen I am deep in the midst of implementing some big features (with not too much time to work on it either) so the next release is not imminent.

from diagrams-core.

cchalmers avatar cchalmers commented on June 11, 2024

I'm having a go at this. I didn't actually read this before but I ended up doing option 3. Creating a semigroup for the paths wasn't too bad, and getting there from a name seems to work. The problem now is what to do once you're there.

Should the diagram you're traversing over be the "original" diagram when it was named? In which case we'd have to store the original diagram and well as accumulate any down annotations applied since then. Or should the diagram include all the down annotation applied since it was named? I'm currently doing the latter but I think I'll end up doing both since they both have uses.

Once you've done that and edited the diagram what should happen to the up annotations? If we want them to be included we'd have to store all the left and right (separately) up annotations the diagram has seen since it's been named, and append these either side to the edited diagram.

Right now I'm looking at

data DUALSub d u a l = DUALSub
  { leftUps       :: u
  , downs         :: d
  , rightUps      :: u
  , pathToSub     :: Tape
  , originalDUAL  :: DUALTree d u a l
  }

where data Tape = T [Int] Int contains the path to the sub, along with the number of a annotations it expects to see. And every time a diagram appends with another, this needs to be updated.

Sorry if this doesn't make much sense, I just thought I should get my current thoughts down. Any suggestions would be great. I'll try to mash together what I've done in a PR soon so it makes more sense.

from diagrams-core.

byorgey avatar byorgey commented on June 11, 2024

Re: the "original" diagram vs. getting accumulated down annotations, the Subdiagram type already encapsulates the notion of a diagram paired with some accumulated down annotations, and there are functions for extracting the original diagram or extracting the diagram with applied down annots (rawSub and getSub, respectively). So in some sense the machinery for doing either is already there. However, it does seem strange/problematic to edit the version of a subdiagram with all the down annotations applied. What if you add more down annotations? Where do they go? They can't go at the root of the entire diagram since then they would affect everything else. But if you put them right above the diagram being edited they are in the wrong order with the down annotations from the context. So I think it only makes sense to edit the "original" diagram.

Not sure I understand your question about up annotations, I'll keep thinking about it.

from diagrams-core.

cchalmers avatar cchalmers commented on June 11, 2024

Adding more down annotations to the selected diagram can make sense, but you have to push down all the d annotations in its path. Diagrams either of the target receive the down annotations up to that point. Maybe this code snipped will explain it better (I'm using Data.Seqence for the Concat, iss is the path to the target diagram)

  go d []         = f d . DUALTree u2
  -- Search for the next Concat and get element i from it.
  go d iss@(i:is) = \case
    Down d' t -> go (d `mappend` d') iss t
    Annot a t -> annot a <$> go d iss t
    -- Everything on the left and right of the target receives the d
    -- annotation accumulated so far. The target has its d annotation
    -- pushed further down.
    Concat ts
      | (sL, sR') <- Seq.splitAt i ts
      , t :< sR   <- viewl sR' ->
          go d is t <&> \(DUALTree u' t') -> DUALTree u' $ list $
            if | null sL   -> [t', dw sR]
               | null sR   -> [dw sL, t']
               | otherwise -> [dw sL, t', dw sR]
          where dw = Down d . Concat

Things get a little icky but I'm pretty sure it works out.

Regarding up annotations, maybe an example will help. Says you have two squares next to each other. You traverse over the left one and half it's size. What should the envelope of the new diagram be? If you it "as if the left square was originally half the size" we'd have to store the envelope without the left square so we can add new up annotation without the original left square.

from diagrams-core.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.