Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tag cloud for tags linked to a given tag #21

Closed
GoogleCodeExporter opened this issue Mar 26, 2015 · 10 comments
Closed

Tag cloud for tags linked to a given tag #21

GoogleCodeExporter opened this issue Mar 26, 2015 · 10 comments

Comments

@GoogleCodeExporter
Copy link

I'd like to display a tag cloud on a tag page with tags which have been
used with this tag. Hum, ok not really clear and you need an example:

post1.tags = 'foo bar'
post2.tags = 'bar baz'
post3.tags = 'foo ter'
post4.tags = 'bar ter'

Now, the foo tag page will contain a tag cloud with bar and ter tags. The
bar one with foo, baz and ter, and so one...

Let me know if it's easily feasible, maybe I can help.

Original issue reported on code.google.com by lar...@gmail.com on 26 Apr 2007 at 1:27

@GoogleCodeExporter
Copy link
Author

hi larlet,

i guess what you are looking for is this:

snippets = TaggedItem.objects.get_by_model(Snippet, tags)

related_tags = Tag.objects.filter(items__object_id__in=[s.id for s in
snippets]).distinct()

Original comment by jefferso...@googlemail.com on 1 May 2007 at 12:19

  • Added labels: ****
  • Removed labels: ****

@GoogleCodeExporter
Copy link
Author

Thanks a lot for your help, here is my final view:

def view_tag(request, tags):
    tag_list = [Tag.objects.get(name=tag) for tag in tags.split(',')]
    post_list = TaggedItem.objects.get_by_model(Post, tag_list)
    if len(post_list) > 1:
        ctype = ContentType.objects.get_for_model(Post)
        related_tags = Tag.objects.filter(items__object_id__in=[s.id for s in
post_list]).filter(items__content_type__pk=ctype.id).exclude(items__tag__in=tag_
list).distinct()
    else:
        related_tags = []

I need to specify the content type and to exclude current tags but it works, 
you can
close the "issue".

Original comment by lar...@gmail.com on 1 May 2007 at 8:55

  • Added labels: ****
  • Removed labels: ****

@GoogleCodeExporter
Copy link
Author

"I need to specify the content type and to exclude current tags but it works, 
you can
close the issue."

i´ve just put it in the usage_for_model function:

class TagManager(models.Manager):
    def usage_for_model(self, Model, tags=None, counts=False):
        """
        Create a queryset matching all tags associated with instances
        of the given Model.

        If ``counts`` is True, a ``count`` attribute will be added to
        each tag, indicating how many times it has been used against
        the Model in question.
        """
        ctype = ContentType.objects.get_for_model(Model)
        if tags:
            objs = TaggedItem.objects.get_by_model(Model, tags)
            qs = self.filter(items__content_type__pk=ctype.id, 
                             items__object_id__in=[s.id for s in objs]).distinct()
        else:
            qs = self.filter(items__content_type__pk=ctype.id).distinct()

        if counts is True:
            and_so_on

next step is to make the cloud_for_model work with it.

i´ve not done this yet, but i want to show you my cloud_for_model function 
what it
looks like so far:

    def cloud_for_model(self, Model, steps=4):
        tag_list = list(self.usage_for_model(Model, counts=True))
        tags_dict = [(tag.count, tag.id, tag,) for tag in tag_list]
        tags_dict.sort()
        tags_dict.reverse()
        tags = [tag[2] for tag in tags_dict[:100]]
        if len(tags) > 0:
            new_thresholds, results = [], []
            temp = [tag.count for tag in tags]
            max_weight = float(max(temp))
            min_weight = float(min(temp))
            new_delta = (max_weight - min_weight)/float(steps)
            for i in range(steps + 1):
                new_thresholds.append((100 * math.log((min_weight + i * new_delta) +
2), i))
            for tag in tags:
                font_set = False
                for threshold in new_thresholds[1:int(steps)+1]:
                    if (100 * math.log(tag.count + 2)) <= threshold[0] and not font_set:
                        tag.font_size = threshold[1]
                        font_set = True   
        pre_tags = [(tag.name, tag) for tag in tags]
        pre_tags.sort()
        fin_tags = [tag[1] for tag in pre_tags]
        return fin_tags

as a python beginner i guess this looks ugly, but it works...

this is for my index page, it shows a tag_cloud limited to 100 results, where 
first
the tags are sorted/reversed by count so the tag_cloud will be generated for 
the 100
 tags with most count. afterwards its sorted by name.

in the end, both things should be done with something like this..

index-page:
tag_cloud = Tag.objects.cloud_for_model(Snippet, offset=100, steps=4)

tag-detail:
tag_cloud = Tag.objects.cloud_for_model(Snippet, tags, steps=4)





Original comment by jefferso...@googlemail.com on 1 May 2007 at 9:41

  • Added labels: ****
  • Removed labels: ****

@GoogleCodeExporter
Copy link
Author

"in the end, both things should be done with something like this.."

here we go..


class TagManager(models.Manager):

    def usage_for_model(self, Model, tags=None, counts=False):
        """
        Create a queryset matching all tags associated with instances
        of the given Model.

        If ``counts`` is True, a ``count`` attribute will be added to
        each tag, indicating how many times it has been used against
        the Model in question.
        """
        ctype = ContentType.objects.get_for_model(Model)
        if tags:
            objs = TaggedItem.objects.get_by_model(Model, tags)
            qs = self.filter(items__content_type__pk=ctype.id, 
                             items__object_id__in=[s.id for s in objs]) \
                            .exclude(items__tag__in=tags).distinct()
        else:
            qs = self.filter(items__content_type__pk=ctype.id).distinct()

        if counts is True:
            qs = qs.extra(
                select={
                    'count': 'SELECT COUNT(*) FROM tagged_item ' \
                             ' WHERE tagged_item.tag_id = tag.id ' \
                             ' AND tagged_item.content_type_id = %s ', \
                },
                params=[ctype.id],
            )
            return qs

    def cloud_for_model(self, Model, tags=None, steps=4, offset=100):
        if tags:
            tag_list = list(self.usage_for_model(Model, tags, counts=True))
        else:
            tag_list = list(self.usage_for_model(Model, counts=True))
        tags_dict = [(tag.count, tag.id, tag,) for tag in tag_list]
        tags_dict.sort()
        tags_dict.reverse()
        tags = [tag[2] for tag in tags_dict[:offset]]
        if len(tags) > 0:
            new_thresholds, results = [], []
            temp = [tag.count for tag in tags]
            max_weight = float(max(temp))
            min_weight = float(min(temp))
            new_delta = (max_weight - min_weight)/float(steps)
            for i in range(steps + 1):
                new_thresholds.append((100 * math.log((min_weight + i * new_delta) +
2), i))
            for tag in tags:
                font_set = False
                for threshold in new_thresholds[1:int(steps)+1]:
                    if (100 * math.log(tag.count + 2)) <= threshold[0] and not font_set:
                        tag.font_size = threshold[1]
                        font_set = True   
        pre_tags = [(tag.name, tag) for tag in tags]
        pre_tags.sort()
        fin_tags = [tag[1] for tag in pre_tags]
        return fin_tags

usage..

Tagcloud as usual by model:
tag_cloud = Tag.objects.cloud_for_model(Model, steps=4, offset=50)

Tagcloud by model and tags:
tag_cloud = Tag.objects.cloud_for_model(Model, tags, steps=2, offset=5)




Original comment by jefferso...@googlemail.com on 1 May 2007 at 10:59

  • Added labels: ****
  • Removed labels: ****

@GoogleCodeExporter
Copy link
Author

Oh, thanks! That's great, can't wait for a new revision ;-)

--
david(`bgk on irc)

Original comment by lar...@gmail.com on 1 May 2007 at 6:16

  • Added labels: ****
  • Removed labels: ****

@GoogleCodeExporter
Copy link
Author

Bumping this up to next on the hitlist :)

Original comment by jonathan.buchanan on 11 May 2007 at 2:16

  • Changed state: Started
  • Added labels: Type-Enhancement
  • Removed labels: Type-Defect

@GoogleCodeExporter
Copy link
Author

hi jonathan, 

great that you have some time and it´s going on. i really love to see the 
tagging-app
in django.contrib. (guess i´m not alone, this is the django-project hosted on 
google
that has got the most attention of all, has been blogged most often and 
tagging-apps
are quite often asked for in django-users group... i dont want to push you, just
motivate a little :]).


one thing that i´m missing with my approach is, that i would expect the 
tagcloud for
a given tag to show the relevancy for each tag in the tagcloud with the given 
tag.

right now the tag with the most tagged items at all will be the biggest one.

imagine those nice plus-signs beside each tag like on blogmarks, it is 
confusing when
i combine the actual tag with the biggest tag in the cloud and its not having 
the
most items.

hope you got what i mean and i hope you can get your head around it because i 
couldn´t.





Original comment by jefferso...@googlemail.com on 11 May 2007 at 8:34

  • Added labels: ****
  • Removed labels: ****

@GoogleCodeExporter
Copy link
Author

Thanks Jonathan, I second Jefferson in his contrib suggestion :)

Jefferson, that's exactly what I want to do (+ sign ala blogmarks) and I hope 
it will
be quickly possible.

Original comment by lar...@gmail.com on 16 May 2007 at 7:59

  • Added labels: ****
  • Removed labels: ****

@GoogleCodeExporter
Copy link
Author

Added related_for_model method in revision 49. You can use this together with 
the
separated out calculate_cloud method to create a tag cloud for related tags for 
a
particular model. 

Original comment by jonathan.buchanan on 16 May 2007 at 3:22

  • Added labels: ****
  • Removed labels: ****

@GoogleCodeExporter
Copy link
Author

Original comment by jonathan.buchanan on 16 May 2007 at 4:31

  • Changed state: Fixed
  • Added labels: ****
  • Removed labels: ****

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant