chartit / django-chartit

A Django app to plot charts and pivot charts directly from the models. Uses HighCharts and jQuery JavaScript libraries to render the charts on the webpage.
http://django-chartit.mrsenko.com/
Other
492 stars 166 forks source link

Support for datetime objects in xAxis #2

Closed sebasmagri closed 8 years ago

sebasmagri commented 12 years ago

Hi.

I've read that support for datetime objects is going to be a feature of the next release. Right now it's kinda critical for me. What's your advance on it? Should I try to do it?

pgollakota commented 12 years ago

@sebasmagri I really haven't gotten a chance to work on this as att as much as I wanted to. You are welcome to to submit a pull request. That would actually be great!

sebasmagri commented 12 years ago

@pgollakota I haven't looked at this, but I'm willing to do it soon as it would make things a lot easier to me. Any hints about the path I should follow?

pgollakota commented 12 years ago

@sebasmagri I am currently at the PyCon. After the PyCon, I'll create a how-to guide for developers explaining how the whole library works. I was really busy with a bunch of transitions personally and professionally and wasn't able to give as much attention to this library as I wanted to. If you are here in California, we could even meet!

sebasmagri commented 12 years ago

@pgollakota I wish I were there :(. Ok no problem, I'll wait then.

camilonova commented 12 years ago

@pgollakota did you have any work on this, i would like to help adding this support, but first i want to make sure you don't have anything yet.

pgollakota commented 12 years ago

@camilonova I don't have anything yet. Please submit a patch and I'll be glad to review it. Thanks a lot!

rohit-nsit08 commented 12 years ago

hello , I wanted to use django chartit for my charts but cannot use it because of missing support of datetime objects in x axis ...since this seems to be an open issue .. I wanted to know if someone has done some work on it and I'm ready to use it even if it is not production ready

awaiting reply thanx

bastir85 commented 12 years ago

Hey, I added a simple hack to allow lambda functions to postprocess the data obtained from the model. Sebastian

gabro commented 12 years ago

Hi bastir, can you provide an example on how to use your hack?

bastir85 commented 12 years ago

Take a look at my pull request.

gabro commented 12 years ago

Thanks, I did take a look but I'm still pretty rusty with this library. I'm working with a DateField and I'd like to use it on the X axis. How can this be achieved with your hack?

rauch commented 12 years ago

See an example https://gist.github.com/3175635 Sure, it's supposed that you've already patched your django-chartit with bastrir85`s hack.

2012/7/25 Gabro < reply@reply.github.com

Thanks, I did take a look but I'm still pretty rusty with this library. I'm working with a DateField and I'd like to use it on the X axis. How can this be achieved with your hack?


Reply to this email directly or view it on GitHub: https://github.com/pgollakota/django-chartit/issues/2#issuecomment-7246485

All the best Alexander

gabro commented 12 years ago

Thank you very much :)

atodorov commented 11 years ago

+1 on this issue. I tried another approach to workaround but it didn't work. See issue #8.

rossiwa commented 11 years ago

I'm trying the lambda function work around suggested by bastir85, but am getting the following: "APIinputError: month is not one of the keys of the datasource series. Allowed values are: houston_temp, boston_temp". What am I missing?

grvhi commented 11 years ago

@rossiwa I'm getting the same error and also hoping there's a way around this! In my case, we have a datetimefield in the model which we'd like to use on the x-axis....

bastir85 commented 11 years ago

@rossiwa @Erve1879 Can you give a little bit more context? It has been a while since I wrote this code. Did you tried my example?

grvhi commented 11 years ago

@bastir85 - Thanks. I'm just starting out with django_chartit, so I may have missed something. Here's my code:

Models.py:

class TotalRatingCount(models.Model):
    timestamp = models.DateTimeField(default=datetime.now(), null=False,
        blank=False,
        help_text='Datetime of this update.')
    rating_count = models.IntegerField(null=False, blank=False,
        help_text='The amount of ratings.')

Views.py:

def ratingCountGraphs(theRequest):
    """
    Returns a highcharts graph of the saved ratingCounts for the user.
    """
    #Step 1: Create a DataPool with the data we want to retrieve.
    ratingsData=\
        DataPool(
           series=
            [{'options': {
               'source': TotalRatingCount.objects.all()},
              'terms': [
                'timestamp',
                'rating_count']}
             ])

    #Step 2: Create the Chart object
    cht = Chart(
            datasource=ratingsData,
            series_options=
              [{'options':{
                  'type': 'line',
                  'stacking': False},
                'terms':{
                  'timestamp': [
                    'rating_count']
                  }}],
            chart_options=
              {'title': {
                   'text': 'Total Ratings Counts'},
               'xAxis': {
                    'title': {
                       'text': 'Total Ratings'}}})

    #Step 3: Send the chart object to the template.
    return render_to_response('website/rating-counts-graphs.html',
                                {'ratingsChart': cht})

With this code, I get the following error from Django:

datetime.datetime(2013, 5, 23, 7, 30, 2, 165034) is not JSON serializable

I've tried the fix suggested above, but I get the same error as @rossiwa (i.e. 'timestamp is not one of the keys....').

I would love it if you could suggest a fix for this - django_chartit is exactly what I need, but this issue will be a big problem!

Thanks very much

bastir85 commented 11 years ago

Yes, this does not work. This is why I did the pull request in the first place. Did you applied it and looked at the example of rauch https://gist.github.com/rauch/3175635 or my reference code: https://github.com/pgollakota/django-chartit/pull/4

grvhi commented 11 years ago

@bastir85 - I did try it, but my mistake was not realising that your pull request hadn't been merged..... Will use your fork and try again. Thanks!

grvhi commented 11 years ago

@bastir85 - OK, using your fork and with the code below, I get no errors, but I'm doing something wrong somewhere....

@staff_member_required
def ratingCountGraphs(theRequest):
    """
    Returns a highcharts graph of the saved ratingCounts for the user.
    """
    #Step 1: Create a DataPool with the data we want to retrieve.
    ratingsData=\
        DataPool(
           series=
            [{'options': {
               'source': TotalRatingCount.objects.all()},
              'terms': [
                ('timestamp', lambda d: time.mktime(d.timetuple())),
                'rating_count']}
             ])

    #Step 2: Create the Chart object
    cht = Chart(
            datasource=ratingsData,
            series_options=
              [{'options':{
                  'type': 'line',
                  'stacking': False},
                'terms':{
                  'timestamp': [
                    'rating_count']
                  }}],
            chart_options=
              {'title': {
                   'text': 'Total Ratings Counts'},
               'xAxis': {
                    'title': {
                       'text': 'Date/Time'}}},
            x_sortf_mapf_mts=(None, lambda i: datetime.fromtimestamp(i).strftime("%D:%M"), False)))

    #Step 3: Send the chart object to the template.
    return render_to_response('website/rating-counts-graphs.html',
                                {'ratingsChart': cht})

screenshot

bastir85 commented 11 years ago

How many datapoints do you have? Did you checked the JS code? maybe it is just a formating issue. It looks a little bit like overlapping text.

grvhi commented 11 years ago

Thanks for your help @bastir85 - got everything working now.

rossiwa commented 11 years ago

I also did not realize that the datetime fix was only in the fork by bastir85. Once I got the updated code, things started working. Thanks!

rossiwa commented 11 years ago

@erve1879, how did you implement the “step” setting? I can’t seem to get any of the Highcharts options to work from within Chartit.

From: Erve1879 [mailto:notifications@github.com] Sent: Tuesday, May 28, 2013 7:08 AM To: pgollakota/django-chartit Cc: rossiwa Subject: Re: [django-chartit] Support for datetime objects in xAxis (#2)

Yes - I've solved the overlapping text issue by using the Highcharts 'step' setting, but my data points and the line are not appearing for some reason.... Instead I get those small blue rectangles visible on the xaxis above the overlapping text. I get no JS errors and the highcharts js is included, so not sure what the issue is.

— Reply to this email directly or view it on GitHub https://github.com/pgollakota/django-chartit/issues/2#issuecomment-18552614 .Image removed by sender.

grvhi commented 11 years ago

@rossiwa Here's my code:

@staff_member_required
def ratingCountGraphs(theRequest):
    """
    Returns a highcharts graph of the saved ratingCounts for the user.
    """
    #Step 1: Create a DataPool with the data we want to retrieve.
    ratingsData=\
        DataPool(
           series=
            [{'options': {
               'source': TotalRatingCount.objects.all()},
              'terms': [
                ('timestamp', lambda d: time.mktime(d.timetuple())),
                'rating_count']}
             ])

    #Step 2: Create the Chart object
    cht = Chart(
            datasource=ratingsData,
            series_options=
              [{'options':{
                  'type': 'line',
                  'stacking': False},
                'terms':{
                  'timestamp': [
                    'rating_count']
                  }}],
            chart_options=
               {'chart':
                    {
                    'zoomType': 'x'
                    },
                'title':
                    {
                    'text': 'Total Ratings Counts'
                    },
                'xAxis':
                    {
                    'labels':
                        {'step': 5, 'rotation': 90, 'align': 'bottom'},
                    'minRange': 10
                    },
                'credits':
                    {
                    'enabled': False
                    }
               },
            x_sortf_mapf_mts=(None, lambda i: datetime.fromtimestamp(i).strftime("%d %b %k:%M"), False))

    #Step 3: Send the chart object to the template.
    return render_to_response('website/rating-counts-graphs.html',
                                {'ratingsChart': cht})

Hope that helps!

OmenWild commented 11 years ago

Found another way to do this based on this snippet http://djangosnippets.org/snippets/1435/ . Add code like the following near the top of chartit/templatetags/chartit.py:

# From http://djangosnippets.org/snippets/1435/
import datetime
from dateutil import tz

def encode_datetime(obj):
    if isinstance(obj, datetime.datetime):
        return obj.astimezone(tz.tzutc()).strftime('%Y-%m-%dT%H:%M:%SZ')
    elif isinstance(obj, datetime.date):
        return obj.strftime('%Y-%m-%dT00:00:00Z')

    raise TypeError(repr(obj) + " is not JSON serializable")

I'm having issues getting Highcharts to properly deal with the datetime even when I add

                'xAxis': {
                   'type': 'datetime',
                    'dateTimeLabelFormats': {
                        'day': '%b %e'
                    },
                }

to chart_options, but I can't tell if that's an issue with the datetime object getting serialized or if I've mis-configured Highcharts.

EDIT: Never mind. The datatime/JSON part works, it just doesn't get passed to Highcharts in a way it can understand.

kadubarral commented 10 years ago

The solution of @bastir85 doesn't work for PivotTables. Anyone have some idea what I can do?

proprioceptor commented 10 years ago

How to get datetime fields from related models?

My Models are

class TrackerRecord(models.Model):
    doctor = models.ForeignKey(User, related_name='tracker_record')
    creation_time = models.DateTimeField(default=timezone.now)
    ....

class TrackerRecordField(models.Model):
    field_value = models.CharField(max_length=200)
    tracker_record = models.ForeignKey(TrackerRecord, related_name='tracker_record_field',null=True,blank=True)
    ....

I want to plot 'field_value' against the 'creation_time' on a line chart.

My View has

DataPool(
     series=
         [{'options': {
                        'source': TrackerRecordField.objects.all()},
                        'terms': [
                                    ('tracker_record__creation_time', lambda d: time.mktime(d.timetuple())),
                                    'field_value',
                                 ]
                      }
         ]

cht = Chart(
        datasource = weatherdata,
        series_options =
          [{'options':{
              'type': 'line',
              'stacking': False},
            'terms':{
              'tracker_record__creation_time': [
                'field_value',]
              }}],
        chart_options =
          {"title":{"text":"Test"},
                "xAxis":{"title":{"text":"Date"}},
                "yAxis":{"title":{"text":"Trackerfield"}}})

        x_sortf_mapf_mts=(None, lambda i: datetime.fromtimestamp(i).strftime("%D:%M"), False))

but the things are not working as my datetime field is in related models. Does Chartit support to access datetime fields accross models. If yes. then please guide.

atodorov commented 8 years ago

Hello everyone, please check out the last 2 commits on master. I've added 4 examples using DateField and DateTimeField on the x axis from the model we're plotting and also from a related model. All of them seem to work without any extra changes.

Since this issue has been open for so long and it looks like it has been fixed I will close it at the end of the week if I don't get any complaints or examples which aren't working .

atodorov commented 8 years ago

closing due to inactivity and my previous comment.