예제 #1
0
def group(request, group_id):
    group = get_object_or_404(GroupedMessage, pk=group_id)

    message_list = group.message_set.all()
    
    obj = message_list.order_by('-id')[0]
    if '__sentry__' in obj.data:
        module, args, frames = obj.data['__sentry__']['exc']
        obj.class_name = str(obj.class_name)
        # We fake the exception class due to many issues with imports/builtins/etc
        exc_type = type(obj.class_name, (Exception,), {})
        exc_value = exc_type(obj.message)

        exc_value.args = args
    
        reporter = ImprovedExceptionReporter(obj.request, exc_type, exc_value, frames, obj.data['__sentry__'].get('template'))
        traceback = mark_safe(reporter.get_traceback_html())
    elif group.traceback:
        traceback = mark_safe('<pre>%s</pre>' % (group.traceback,))
    
    unique_urls = message_list.filter(url__isnull=False).values_list('url', 'logger', 'view', 'checksum').annotate(times_seen=Count('url')).values('url', 'times_seen').order_by('-times_seen')
    
    unique_servers = message_list.filter(server_name__isnull=False).values_list('server_name', 'logger', 'view', 'checksum').annotate(times_seen=Count('server_name')).values('server_name', 'times_seen').order_by('-times_seen')

    def iter_data(obj):
        for k, v in obj.data.iteritems():
            if k.startswith('_') or k in ['url']:
                continue
            yield k, v
    
    json_data = iter_data(obj)
    
    # TODO: this should be a template tag
    engine = get_db_engine()
    if SimpleLineChart and not engine.startswith('sqlite'):
        today = datetime.datetime.now()

        chart_qs = message_list\
                          .filter(datetime__gte=today - datetime.timedelta(hours=24))\
                          .extra(select={'hour': 'extract(hour from datetime)'}).values('hour')\
                          .annotate(num=Count('id')).values_list('hour', 'num')

        rows = dict(chart_qs)
        if rows:
            max_y = max(rows.values())
        else:
            max_y = 1

        chart = SimpleLineChart(300, 80, y_range=[0, max_y])
        chart.add_data([max_y]*30)
        chart.add_data([rows.get((today-datetime.timedelta(hours=d)).hour, 0) for d in range(0, 24)][::-1])
        chart.add_data([0]*30)
        chart.fill_solid(chart.BACKGROUND, 'eeeeee')
        chart.add_fill_range('eeeeee', 0, 1)
        chart.add_fill_range('e0ebff', 1, 2)
        chart.set_colours(['eeeeee', '999999', 'eeeeee'])
        chart.set_line_style(1, 1)
        chart_url = chart.get_url()
    
    return render_to_response('sentry/group/details.html', locals())
예제 #2
0
파일: pygchart.py 프로젝트: krihal/pygchart
def plotter(fund):
    
    (dates, values) = dataparser("data/%s" % fund)
    left_axis = [int(min(values)), int(max(values) + 1)]
    
    chart = SimpleLineChart(600, 375, y_range=[min(values), max(values) + 1])
    chart.add_data(values)
    chart.add_data([0] * 2)
    chart.set_colours(['76A4FB'] * 5)
    chart.add_fill_range('76A4FB', 0, 1)
    chart.set_grid(0, 5, 1, 25)
    chart.set_axis_labels(Axis.LEFT, left_axis)
    chart.set_axis_labels(Axis.BOTTOM, dates)

    chart.download("charts/%s.png" % fund)
def makechart(aaseq, regions):
    hdph = dict()
    hdph['d'] = -3.5
    hdph['e'] = -3.5
    hdph['k'] = -3.9
    hdph['r'] = -4.5
    hdph['h'] = -3.2
    hdph['y'] = -1.3
    hdph['w'] = -0.9
    hdph['f'] = 2.8
    hdph['c'] = 2.5
    hdph['m'] = 1.9
    hdph['s'] = -0.8
    hdph['t'] = -0.7
    hdph['n'] = -3.5
    hdph['q'] = -3.5
    hdph['g'] = -0.4
    hdph['a'] = 1.8
    hdph['v'] = 4.2
    hdph['l'] = 3.8
    hdph['i'] = 4.5
    hdph['p'] = -1.6
    hdphseq = []
    for i in range(len(aaseq)):
        hdphseq.append(hdph[aaseq[i]])
    
    regionseq = parseregion(regions)
    
    #print regionseq

    min_y = -5
    max_y = 5
    chart = SimpleLineChart(800, 300, y_range=[min_y, max_y])
    
    #chart.add_data([max_y]*2)
    chart.add_data(hdphseq)   
    chart.add_data(regionseq)
    chart.add_data([min_y]*2)
    chart.set_colours(['76A4FB', 'ADFF2F', '000000'])
    chart.add_fill_range('ADFF2F', 1, 2)
    chart.set_axis_labels(Axis.LEFT, [min_y, '', max_y])
    chart.set_axis_labels(Axis.BOTTOM, aaseq)
    
    chart.download('test.png')
    
    #print hdphseq
    return hdphseq
예제 #4
0
def group_message_list(request, group_id):
    group = get_object_or_404(GroupedMessage, pk=group_id)

    message_list = group.message_set.all().order_by('-datetime')
    
    unique_urls = message_list.filter(url__isnull=False).values_list('url', 'logger', 'view', 'checksum').annotate(times_seen=Count('url')).values('url', 'times_seen').order_by('-times_seen')
    
    unique_servers = message_list.filter(server_name__isnull=False).values_list('server_name', 'logger', 'view', 'checksum').annotate(times_seen=Count('server_name')).values('server_name', 'times_seen').order_by('-times_seen')
    
    engine = get_db_engine()
    if SimpleLineChart and not engine.startswith('sqlite'):
        today = datetime.datetime.now()

        chart_qs = message_list\
                          .filter(datetime__gte=today - datetime.timedelta(hours=24))\
                          .extra(select={'hour': 'extract(hour from datetime)'}).values('hour')\
                          .annotate(num=Count('id')).values_list('hour', 'num')

        rows = dict(chart_qs)
        if rows:
            max_y = max(rows.values())
        else:
            max_y = 1

        chart = SimpleLineChart(300, 80, y_range=[0, max_y])
        chart.add_data([max_y]*30)
        chart.add_data([rows.get((today-datetime.timedelta(hours=d)).hour, 0) for d in range(0, 24)][::-1])
        chart.add_data([0]*30)
        chart.fill_solid(chart.BACKGROUND, 'eeeeee')
        chart.add_fill_range('eeeeee', 0, 1)
        chart.add_fill_range('e0ebff', 1, 2)
        chart.set_colours(['eeeeee', '999999', 'eeeeee'])
        chart.set_line_style(1, 1)
        chart_url = chart.get_url()
    
    page = 'messages'
    
    return render_to_response('sentry/group/message_list.html', locals())
예제 #5
0
def chart_url(group):
    today = datetime.datetime.now()

    chart_qs = group.message_set.all()\
                      .filter(datetime__gte=today - datetime.timedelta(hours=24))\
                      .extra(select={'hour': 'extract(hour from datetime)'}).values('hour')\
                      .annotate(num=Count('id')).values_list('hour', 'num')

    rows = dict(chart_qs)
    if rows:
        max_y = max(rows.values())
    else:
        max_y = 1

    chart = SimpleLineChart(300, 80, y_range=[0, max_y])
    chart.add_data([max_y]*30)
    chart.add_data([rows.get((today-datetime.timedelta(hours=d)).hour, 0) for d in range(0, 24)][::-1])
    chart.add_data([0]*30)
    chart.fill_solid(chart.BACKGROUND, 'eeeeee')
    chart.add_fill_range('eeeeee', 0, 1)
    chart.add_fill_range('e0ebff', 1, 2)
    chart.set_colours(['eeeeee', '999999', 'eeeeee'])
    chart.set_line_style(1, 1)
    return chart.get_url()
예제 #6
0
def fill():

    # Set the vertical range from 0 to 50
    max_y = 50
    chart = SimpleLineChart(200, 125, y_range=[0, max_y])

    # First value is the highest Y value. Two of them are needed to be
    # plottable.
    chart.add_data([max_y] * 2)

    # 3 sets of real data
    chart.add_data([28, 30, 31, 33, 35, 36, 42, 48, 43, 37, 32, 24, 28])
    chart.add_data([16, 18, 18, 21, 23, 23, 29, 36, 31, 25, 20, 12, 17])
    chart.add_data([7, 9, 9, 12, 14, 14, 20, 27, 21, 15, 10, 3, 7])

    # Last value is the lowest in the Y axis.
    chart.add_data([0] * 2)

    # Black lines
    chart.set_colours(['000000'] * 5)

    # Filled colours
    # from the top to the first real data
    chart.add_fill_range('76A4FB', 0, 1)

    # Between the 3 data values
    chart.add_fill_range('224499', 1, 2)
    chart.add_fill_range('FF0000', 2, 3)

    # from the last real data to the
    chart.add_fill_range('80C65A', 3, 4)

    # Some axis data
    chart.set_axis_labels(Axis.LEFT, ['', max_y / 2, max_y])
    chart.set_axis_labels(Axis.BOTTOM, ['Sep', 'Oct', 'Nov', 'Dec'])

    chart.download('line-fill.png')
예제 #7
0
파일: line.py 프로젝트: Ashwini7/La-resumex
def fill():

    # Set the vertical range from 0 to 50
    max_y = 50
    chart = SimpleLineChart(200, 125, y_range=[0, max_y])

    # First value is the highest Y value. Two of them are needed to be
    # plottable.
    chart.add_data([max_y] * 2)

    # 3 sets of real data
    chart.add_data([28, 30, 31, 33, 35, 36, 42, 48, 43, 37, 32, 24, 28])
    chart.add_data([16, 18, 18, 21, 23, 23, 29, 36, 31, 25, 20, 12, 17])
    chart.add_data([7, 9, 9, 12, 14, 14, 20, 27, 21, 15, 10, 3, 7])

    # Last value is the lowest in the Y axis.
    chart.add_data([0] * 2)

    # Black lines
    chart.set_colours(['000000'] * 5)

    # Filled colours
    # from the top to the first real data
    chart.add_fill_range('76A4FB', 0, 1)

    # Between the 3 data values
    chart.add_fill_range('224499', 1, 2)
    chart.add_fill_range('FF0000', 2, 3)

    # from the last real data to the
    chart.add_fill_range('80C65A', 3, 4)

    # Some axis data
    chart.set_axis_labels(Axis.LEFT, ['', max_y / 2, max_y])
    chart.set_axis_labels(Axis.BOTTOM, ['Sep', 'Oct', 'Nov', 'Dec'])

    chart.download('line-fill.png')
예제 #8
0
def group(request, group_id):
    group = GroupedMessage.objects.get(pk=group_id)

    message_list = group.message_set.all()

    obj = message_list[0]
    if "__sentry__" in obj.data:
        module, args, frames = obj.data["__sentry__"]["exc"]
        obj.class_name = str(obj.class_name)
        # We fake the exception class due to many issues with imports/builtins/etc
        exc_type = type(obj.class_name, (Exception,), {})
        exc_value = exc_type(obj.message)

        exc_value.args = args

        fake_request = FakeRequest()
        fake_request.META = obj.data.get("META", {})
        fake_request.GET = obj.data.get("GET", {})
        fake_request.POST = obj.data.get("POST", {})
        fake_request.FILES = obj.data.get("FILES", {})
        fake_request.COOKIES = obj.data.get("COOKIES", {})
        fake_request.url = obj.url
        if obj.url:
            fake_request.path_info = "/" + obj.url.split("/", 3)[-1]
        else:
            fake_request.path_info = ""

        reporter = ImprovedExceptionReporter(
            fake_request, exc_type, exc_value, frames, obj.data["__sentry__"].get("template")
        )
        traceback = mark_safe(reporter.get_traceback_html())
    else:
        traceback = mark_safe("<pre>%s</pre>" % (group.traceback,))

    unique_urls = (
        message_list.filter(url__isnull=False)
        .values_list("url", "logger", "view", "checksum")
        .annotate(times_seen=Count("url"))
        .values("url", "times_seen")
        .order_by("-times_seen")
    )

    unique_servers = (
        message_list.filter(server_name__isnull=False)
        .values_list("server_name", "logger", "view", "checksum")
        .annotate(times_seen=Count("server_name"))
        .values("server_name", "times_seen")
        .order_by("-times_seen")
    )

    today = datetime.datetime.now()

    chart_qs = (
        message_list.filter(datetime__gte=today - datetime.timedelta(hours=24))
        .extra(select={"hour": "extract(hour from datetime)"})
        .values("hour")
        .annotate(num=Count("id"))
        .values_list("hour", "num")
    )

    rows = dict(chart_qs)
    if rows:
        max_y = max(rows.values())
    else:
        max_y = 1

    if SimpleLineChart:
        chart = SimpleLineChart(384, 80, y_range=[0, max_y])
        chart.add_data([max_y] * 30)
        chart.add_data([rows.get((today - datetime.timedelta(hours=d)).hour, 0) for d in range(0, 24)][::-1])
        chart.add_data([0] * 30)
        chart.fill_solid(chart.BACKGROUND, "eeeeee")
        chart.add_fill_range("eeeeee", 0, 1)
        chart.add_fill_range("e0ebff", 1, 2)
        chart.set_colours(["eeeeee", "999999", "eeeeee"])
        chart.set_line_style(1, 1)
        chart_url = chart.get_url()

    return render_to_response("sentry/group.html", locals())
# Build the elevation chart using the Google Charts API
log.info("Creating elevation profile chart")
chart = SimpleLineChart(600, 300, y_range=[min(elvs), max(elvs)])

# API quirk -  you need 3 lines of data to color
# in the plot so we add a line at the minimum value
# twice.
chart.add_data([min(elvs)]*2)
chart.add_data(elvs)
chart.add_data([min(elvs)]*2)

# Black lines
chart.set_colours(['000000'])

# fill in the elevation area with a hex color
chart.add_fill_range('80C65A', 1, 2)

# Set up labels for the minimum elevation, halfway value, and max value
elv_labels = int(round(min(elvs))), int(min(elvs)+((max(elvs)-min(elvs)/2))), \
                 int(round(max(elvs)))

# Assign the labels to an axis
elv_label = chart.set_axis_labels(Axis.LEFT, elv_labels)

# Label the axis
elv_text = chart.set_axis_labels(Axis.LEFT, ["FEET"])
# Place the label at 30% the distance of the line
chart.set_axis_positions(elv_text, [30])

# Calculate distances between track segments
distances = []
예제 #10
0
    def GetHtml(self):
        if self.IsEmpty(): return ""

        # Determine top 10 addresses
        top_addresses = \
            [(count, address) for (address, count) in self.__all_addresses.items()]
        top_addresses.sort(reverse=True)
        top_addresses = [address for (count, address) in top_addresses]

        if len(top_addresses) > 10:
            top_addresses = top_addresses[0:10]

        top_addresses.reverse()

        # Collect lines for each address
        bucket_lines = {}

        for bucket in self.__buckets:
            sum = 0
            for address in top_addresses:
                sum += bucket.get(address, 0)

            sum = float(sum)
            fraction_sum = 0

            for address in top_addresses:
                if sum == 0:
                    fraction = 0
                else:
                    fraction = bucket.get(address, 0) / sum

                fraction_sum += fraction

                # Make sure everything adds up to 1.0
                if address == top_addresses[-1]:
                    fraction_sum = 1.0

                if address not in bucket_lines:
                    bucket_lines[address] = []

                bucket_lines[address].append(
                    round(fraction_sum * ExtendedData.max_value()))

        # Smooth lines
        for address, points in bucket_lines.items():
            smoothed = []
            window = []
            window_sum = 0
            for i in xrange(0, len(points)):
                if i < self.__min_bucket or i > self.__max_bucket:
                    smoothed.append(0)
                else:
                    point = points[i]
                    if len(window) == Distribution._BUCKET_SIZE:
                        window_sum -= window.pop(0)
                    window.append(point)
                    window_sum += point
                    smoothed.append(round(window_sum / len(window)))
            bucket_lines[address] = smoothed

        # Generate chart
        chart = SimpleLineChart(450, 250)
        data_index = 0
        colors = []
        legend = []

        top_addresses.reverse()

        for address in top_addresses:
            data = bucket_lines[address]
            chart.add_data(data)

            color = _FILL_COLORS[data_index % len(_FILL_COLORS)]

            chart.add_fill_range(color, data_index, data_index + 1)
            data_index += 1

            colors.append(color)
            legend.append((color, self.__address_names[address], address))

        # Another set of points to make sure we will to the bottom
        chart.add_data([0, 0])

        chart.set_colours(colors)
        chart.set_axis_labels(Axis.BOTTOM, MONTH_NAMES)

        t = Template(
            file="templates/distribution.tmpl",
            searchList={
                "id": self.id,
                "chart": chart,
                # We don't use the legend feature of the chart API since that would
                # make the URL longer than its limits
                "legend": legend,
                "class": self.__css_class,
            })
        return unicode(t)
예제 #11
0
# Build the elevation chart using the Google Charts API
log.info("Creating elevation profile chart")
chart = SimpleLineChart(600, 300, y_range=[min(elvs), max(elvs)])

# API quirk -  you need 3 lines of data to color
# in the plot so we add a line at the minimum value
# twice.
chart.add_data([min(elvs)] * 2)
chart.add_data(elvs)
chart.add_data([min(elvs)] * 2)

# Black lines
chart.set_colours(['000000'])

# fill in the elevation area with a hex color
chart.add_fill_range('80C65A', 1, 2)

# Set up labels for the minimum elevation, halfway value, and max value
elv_labels = int(round(
    min(elvs))), int(min(elvs) + ((max(elvs) - min(elvs) / 2))), int(
        round(max(elvs)))

# Assign the labels to an axis
elv_label = chart.set_axis_labels(Axis.LEFT, elv_labels)

# Label the axis
elv_text = chart.set_axis_labels(Axis.LEFT, ["FEET"])
# Place the label at 30% the distance of the line
chart.set_axis_positions(elv_text, [30])

# Calculate distances between track segments
예제 #12
0
  def GetHtml(self):
    if self.IsEmpty(): return ""
    
    # Determine top 10 addresses
    top_addresses = \
        [(count, address) for (address, count) in self.__all_addresses.items()]
    top_addresses.sort(reverse=True)
    top_addresses = [address for (count, address) in top_addresses]
    
    if len(top_addresses) > 10:
      top_addresses = top_addresses[0:10]
    
    top_addresses.reverse()

    # Collect lines for each address
    bucket_lines = {}
    
    for bucket in self.__buckets:
      sum = 0
      for address in top_addresses:
        sum += bucket.get(address, 0)
      
      sum = float(sum)
      fraction_sum = 0
      
      for address in top_addresses:
        if sum == 0:
          fraction = 0
        else:
          fraction = bucket.get(address, 0)/sum
      
        fraction_sum += fraction
        
        # Make sure everything adds up to 1.0
        if address == top_addresses[-1]:
          fraction_sum = 1.0
        
        if address not in bucket_lines:
          bucket_lines[address] = []

        bucket_lines[address].append(round(
            fraction_sum * ExtendedData.max_value()))

    # Smooth lines
    for address, points in bucket_lines.items():
      smoothed = []
      window = []
      window_sum = 0
      for i in xrange(0, len(points)):
        if i < self.__min_bucket or i > self.__max_bucket:
          smoothed.append(0)
        else:
          point = points[i]
          if len(window) == Distribution._BUCKET_SIZE:
            window_sum -= window.pop(0)
          window.append(point)
          window_sum += point
          smoothed.append(round(window_sum/len(window)))
      bucket_lines[address] = smoothed
    
    # Generate chart
    chart = SimpleLineChart(450, 250)
    data_index = 0
    colors = []
    legend = []
    
    top_addresses.reverse()
    
    for address in top_addresses:
      data = bucket_lines[address]
      chart.add_data(data)
      
      color = _FILL_COLORS[data_index % len(_FILL_COLORS)]
      
      chart.add_fill_range(
          color,
          data_index,
          data_index + 1)
      data_index += 1

      colors.append(color)
      legend.append((color, self.__address_names[address], address))

    # Another set of points to make sure we will to the bottom
    chart.add_data([0, 0])
    
    chart.set_colours(colors)
    chart.set_axis_labels(Axis.BOTTOM, MONTH_NAMES)

    t = Template(
        file="templates/distribution.tmpl",
        searchList = {
          "id": self.id,
          "chart": chart,
          # We don't use the legend feature of the chart API since that would
          # make the URL longer than its limits
          "legend": legend, 
          "class": self.__css_class,
        })
    return unicode(t)
예제 #13
0
def group(request, group_id):
    group = GroupedMessage.objects.get(pk=group_id)

    message_list = group.message_set.all()
    
    obj = message_list[0]
    if '__sentry__' in obj.data:
        module, args, frames = obj.data['__sentry__']['exc']
        obj.class_name = str(obj.class_name)
        # We fake the exception class due to many issues with imports/builtins/etc
        exc_type = type(obj.class_name, (Exception,), {})
        exc_value = exc_type(obj.message)

        exc_value.args = args
    
        fake_request = FakeRequest()
        fake_request.META = obj.data.get('META', {})
        fake_request.GET = obj.data.get('GET', {})
        fake_request.POST = obj.data.get('POST', {})
        fake_request.FILES = obj.data.get('FILES', {})
        fake_request.COOKIES = obj.data.get('COOKIES', {})
        fake_request.url = obj.url
        if obj.url:
            fake_request.path_info = '/' + obj.url.split('/', 3)[-1]
        else:
            fake_request.path_info = ''

        reporter = ImprovedExceptionReporter(fake_request, exc_type, exc_value, frames, obj.data['__sentry__'].get('template'))
        traceback = mark_safe(reporter.get_traceback_html())
    elif group.traceback:
        traceback = mark_safe('<pre>%s</pre>' % (group.traceback,))
    
    unique_urls = message_list.filter(url__isnull=False).values_list('url', 'logger', 'view', 'checksum').annotate(times_seen=Count('url')).values('url', 'times_seen').order_by('-times_seen')
    
    unique_servers = message_list.filter(server_name__isnull=False).values_list('server_name', 'logger', 'view', 'checksum').annotate(times_seen=Count('server_name')).values('server_name', 'times_seen').order_by('-times_seen')
    
    if SimpleLineChart:
        today = datetime.datetime.now()

        chart_qs = message_list\
                          .filter(datetime__gte=today - datetime.timedelta(hours=24))\
                          .extra(select={'hour': 'extract(hour from datetime)'}).values('hour')\
                          .annotate(num=Count('id')).values_list('hour', 'num')

        rows = dict(chart_qs)
        if rows:
            max_y = max(rows.values())
        else:
            max_y = 1

        chart = SimpleLineChart(300, 80, y_range=[0, max_y])
        chart.add_data([max_y]*30)
        chart.add_data([rows.get((today-datetime.timedelta(hours=d)).hour, 0) for d in range(0, 24)][::-1])
        chart.add_data([0]*30)
        chart.fill_solid(chart.BACKGROUND, 'eeeeee')
        chart.add_fill_range('eeeeee', 0, 1)
        chart.add_fill_range('e0ebff', 1, 2)
        chart.set_colours(['eeeeee', '999999', 'eeeeee'])
        chart.set_line_style(1, 1)
        chart_url = chart.get_url()
    
    return render_to_response('sentry/group.html', locals())
예제 #14
0
파일: chart.py 프로젝트: gmassei/wfrog
    def render(self,data={}, context={}):

        assert self.series is not None, "'chart.series' must be set"

        converter = wfcommon.units.Converter(context["units"])

        # merge builtin defaults, context and renderer config
        config = ChartConfig()
        if context.has_key('chart'):
            config.__dict__.update(context['chart'])
        config.__dict__.update(self.__dict__)

        # create the chart
        chart = SimpleLineChart(config.width, config.height)

        colors = []
        legend_set = False
        legend = []

        chart_min = sys.maxint
        chart_max = -sys.maxint

        # Prepare series config
        ordered_series = []
        for key, serie in self.series.iteritems():
            serie_config = ChartConfig()
            serie_config.__dict__.update(config.__dict__)
            serie_config.__dict__.update(serie)
            ordered_series.append( (serie_config.order, key, serie) )

        ordered_series.sort( cmp=lambda x,y: cmp(x[0],y[0]) )

        ordered_keys = []
        for order, key, serie in ordered_series:
            ordered_keys.append(key)

        # Draws for each serie
        index=0
        for order, key, serie in ordered_series:
            serie_config = ChartConfig()
            serie_config.__dict__.update(config.__dict__)
            serie_config.__dict__.update(serie)
            serie_data = copy.copy(data[key.split('.')[0]]['series'][key.split('.')[1]])
            measure = key.split('.')[0]

            if flat(serie_data):  # Series with all data = None
                continue

            if serie_config.accumulate:
                serie_data = accumulate(serie_data)
            elif serie_config.interpolate:
                serie_data = interpolate(serie_data)

            # Compute min and max value for the serie and the whole chart
            min_data = amin(serie_data)
            chart_min = rmin(chart_min, min_data)
            if serie_data.__contains__(min_data):
                min_index = serie_data.index(min_data)
            else:
                min_index = None
            max_data = max(serie_data)
            chart_max = max(chart_max, max_data)
            if serie_data.__contains__(max_data):
                max_index = serie_data.index(max_data)
            else:
                max_index = None

            (serie_data, min_index, max_index) = compress_to(serie_data, config.nval, min_index, max_index)

            chart.add_data(serie_data)
            colors.append(_valid_color(serie_config.color))

            if serie_config.max and not max_index == None :
                max_config = ChartConfig()
                max_config.__dict__.update(serie_config.__dict__)
                max_config.__dict__.update(serie_config.max)
                str_max_data = str(round(converter.convert(measure, max_data), 1))
                chart.add_marker(index, max_index, 't'+str_max_data, _valid_color(max_config.text), max_config.size)
                chart.add_marker(index, max_index, max_config.style, _valid_color(max_config.color), max_config.thickness)

            if serie_config.min and not min_index == None:
                min_config = ChartConfig()
                min_config.__dict__.update(serie_config.__dict__)
                min_config.__dict__.update(serie_config.min)
                str_min_data = str(round(converter.convert(measure, min_data), 1))
                chart.add_marker(index, min_index, 't'+str_min_data, _valid_color(min_config.text), min_config.size)
                chart.add_marker(index, min_index, min_config.style, _valid_color(min_config.color), min_config.thickness)

            if serie_config.last:
                last_config = ChartConfig()
                last_config.__dict__.update(serie_config.__dict__)
                last_config.__dict__.update(serie_config.last)
                last_index=len(serie_data)-1
                last_data = serie_data[last_index]
                if last_data:
                    str_last_data = str(round(converter.convert(measure, last_data), 1))
                    chart.add_marker(index, last_index, 't'+str(last_data), _valid_color(last_config.text), last_config.size)
                    chart.add_marker(index, last_index, last_config.style, _valid_color(last_config.color), last_config.thickness)

            if serie_config.area:
                fill_config = ChartConfig()
                fill_config.__dict__.update(serie_config.__dict__)
                fill_config.__dict__.update(serie_config.area)
                to = ordered_keys.index(fill_config.to)
                chart.add_fill_range(_valid_color(fill_config.color), index, to)

            if serie_config.dash:
                chart.set_line_style(index, serie_config.thickness, serie_config.dash, serie_config.dash)
            else:
                chart.set_line_style(index, serie_config.thickness)

            if serie_config.legend:
                legend.append(serie_config.legend)
                legend_set = True
            else:
                legend.append('')

            if serie_config.marks:
                mark_config = ChartConfig()
                mark_config.__dict__.update(serie_config.__dict__)
                mark_config.__dict__.update(serie_config.marks)
                mark_data = copy.copy(data[mark_config.serie.split('.')[0]]['series'][mark_config.serie.split('.')[1]])
                mark_data = compress_to(mark_data, config.nval, min_index, max_index)[0]
                for i, m in enumerate(mark_data):
                    if not m:
                        mark_data[i] = " "
                density = max(1.0, 1.0 * mark_config.space * len("".join(mark_data))*mark_config.size  / config.width)

                for i, v in enumerate(mark_data):
                    if (i +1) % round(density) == 0:
                        if serie_data[i] != 0:
                            text = str(mark_data[i])
                        else:
                            text = " "
                        chart.add_marker(index, i, 't'+text, _valid_color(mark_config.color), mark_config.size)

            index = index + 1

        # Compute vertical range

        if config.axes:
            range_min_ref_units = 0
            if not chart_min == sys.maxint and not chart_max == -sys.maxint:
                range_min = chart_min-config.ymargin[0]
                range_max = chart_max+config.ymargin[1]
                range_min_target_units = math.floor(converter.convert(measure, range_min))
                range_max_target_units = math.ceil(converter.convert(measure, range_max))
                range_min_ref_units = converter.convert_back(measure, range_min_target_units)
                range_max_ref_units = converter.convert_back(measure, range_max_target_units)
                self.logger.debug("Y range: "+str(range_min_target_units) +" "+str(range_max_target_units))
                chart.set_axis_range(Axis.LEFT, range_min_target_units, range_max_target_units+1)
                chart.add_data([range_min_ref_units, range_max_ref_units])
                colors.append("00000000")
            else:
                chart.set_axis_range(Axis.LEFT, 0, 100)
            chart.set_axis_style(0, _valid_color(config.text), config.size, 0, Axis.BOTH if config.ticks else Axis.AXIS_LINES)
        else:
            chart.set_axis_labels(Axis.LEFT, [])
            chart.set_axis_style(0, _valid_color(config.text), config.size, 0, Axis.TICK_MARKS, _valid_color(config.bgcolor))

        if config.zero and config.axes and range_min_ref_units < 0 and range_max_ref_units > 0:
            zero_config = ChartConfig()
            zero_config.__dict__.update(config.__dict__)
            zero_config.__dict__.update(config.zero)
            chart.add_data([0]*2)
            colors.append(_valid_color(zero_config.color))
            chart.set_line_style(index, zero_config.thickness)

        chart.set_colours(colors)
        chart.fill_solid(Chart.BACKGROUND, _valid_color(config.bgcolor))

        if legend_set:
            chart.set_legend(legend)
            chart.set_legend_position(config.legend_pos)

        if self.labels:
            labels_data = copy.copy(data[self.labels.split('.')[0]]['series'][self.labels.split('.')[1]])
            labels_data = compress_to(labels_data, config.nval, None, None)[0]
            if config.axes:
                density = 1.0 * len("".join(labels_data))*config.size  / config.width

                if density > LABEL_DENSITY_THRESHOLD:
                    for i, v in enumerate(labels_data):
                        if i % round(density) != 0:
                            labels_data[i] = ' '
                chart.set_axis_labels(Axis.BOTTOM, labels_data)
                chart.set_axis_style(1, _valid_color(config.text), config.size, 0, Axis.BOTH if config.ticks else Axis.AXIS_LINES)
            else:
                chart.set_axis_labels(Axis.BOTTOM, [])
                chart.set_axis_style(1, _valid_color(config.text), config.size, 0, Axis.TICK_MARKS, _valid_color(config.color))

        try:
            return chart.get_url()+"&chma=10,10,10,10" # add a margin
        except:
            self.logger.exception("Could not render chart")
            return "http://chart.apis.google.com/chart?cht=lc&chs="+str(config.width)+"x"+str(config.height)
예제 #15
0
 def _get_chart(self):
     if not self._chart:
         datapoints = self._get_datapoints()
         data = [datapoint['Average'] for datapoint in self._datapoints]
     
         # Set the vertical range from 0 to 100
         max_y = 1
         if data:
             max_y = max(data)*1.1
         
         # max_y cannot be zero
         if max_y == 0:
             max_y = 1
         
         # Make sure percentage doesn't exceed 100%
         if self.args['unit'] == 'Percent':
             max_y = 100
 
         # Chart size of 300x125 pixels and specifying the range for the Y axis
         chart = SimpleLineChart(380, 125, y_range=[0, max_y])
     
         # Add the chart data
         chart.add_data(data)
         chart.add_data([0, 0])
     
         # Set the line colour to blue
         chart.set_colours(['0000FF', '76A4FB'])
         
         # Fill below data line
         chart.add_fill_range('76A4FB', 0, 1)
     
         # Set the horizontal dotted lines
         chart.set_grid(0, 25, 5, 5)
     
         # The Y axis labels contains 0 to 100 skipping every 25, but remove the
         # first number because it's obvious and gets in the way of the first X
         # label.
         step = (max_y*1.0)/4
         if not step:
             step = 1
         #left_axis = range(0, max_y + 1, step)
         left_axis = []
         left_axis.append('')
         left_axis.append(step)
         left_axis.append(step*2)
         left_axis.append(step*3)
         left_axis.append(step*4)
         
         i = 1
         if self.args['unit'] == 'Percent':
             for point in left_axis[1:]:
                 left_axis[i] = '%s%%' % left_axis[i]
                 i = i + 1
         elif self.args['unit'] == 'Bytes':
             for point in left_axis[1:]:
                 left_axis[i] = convert_bytes(int(left_axis[i]))
                 i = i + 1
         elif self.args['unit'] == 'Bytes/Second':
             for point in left_axis[1:]:
                 left_axis[i] = '%s/s' % convert_bytes(int(left_axis[i]))
                 i = i + 1
         elif self.args['unit'] == 'Seconds':
             for point in left_axis[1:]:
                 left_axis[i] = '%ss' % round_float(left_axis[i])
                 i = i + 1
         elif self.args['unit'] == 'Count/Second':
             for point in left_axis[1:]:
                 left_axis[i] = '%s/s' % round_float(left_axis[i])
                 i = i + 1
 
         chart.set_axis_labels(Axis.LEFT, left_axis)
         
         # X axis labels
         bottom_axis = []
         
         # hourly chart
         if self.range['timedelta'] == timedelta(hours=1):
             bottom_axis.append(self.args['start_time'].strftime('%H:%M'))
             bottom_axis.append((self.args['end_time'] - timedelta(minutes=45)).strftime('%H:%M'))
             bottom_axis.append((self.args['end_time'] - timedelta(minutes=30)).strftime('%H:%M'))
             bottom_axis.append((self.args['end_time'] - timedelta(minutes=15)).strftime('%H:%M'))
             bottom_axis.append(self.args['end_time'].strftime('%H:%M'))
         
         # daily chart
         if self.range['timedelta'] == timedelta(days=1):
             bottom_axis.append(self.args['start_time'].strftime('%H:%M'))
             bottom_axis.append((self.args['end_time'] - timedelta(hours=18)).strftime('%H:%M'))
             bottom_axis.append((self.args['end_time'] - timedelta(hours=12)).strftime('%H:%M'))
             bottom_axis.append((self.args['end_time'] - timedelta(hours=6)).strftime('%H:%M'))
             bottom_axis.append(self.args['end_time'].strftime('%H:%M'))
         
         # weekly chart
         if self.range['timedelta'] == timedelta(days=7):
             bottom_axis.append(self.args['start_time'].strftime('%d'))
             bottom_axis.append((self.args['end_time'] - timedelta(days=6)).strftime('%d'))
             bottom_axis.append((self.args['end_time'] - timedelta(days=5)).strftime('%d'))
             bottom_axis.append((self.args['end_time'] - timedelta(days=4)).strftime('%d'))
             bottom_axis.append((self.args['end_time'] - timedelta(days=3)).strftime('%d'))
             bottom_axis.append((self.args['end_time'] - timedelta(days=2)).strftime('%d'))
             bottom_axis.append((self.args['end_time'] - timedelta(days=1)).strftime('%d'))
             bottom_axis.append(self.args['end_time'].strftime('%d'))
             
         # monthly chart
         if self.range['timedelta'] == timedelta(days=30):
             bottom_axis.append(self.args['start_time'].strftime('%d'))
             bottom_axis.append((self.args['end_time'] - timedelta(days=25)).strftime('%d'))
             bottom_axis.append((self.args['end_time'] - timedelta(days=20)).strftime('%d'))
             bottom_axis.append((self.args['end_time'] - timedelta(days=15)).strftime('%d'))
             bottom_axis.append((self.args['end_time'] - timedelta(days=10)).strftime('%d'))
             bottom_axis.append((self.args['end_time'] - timedelta(days=5)).strftime('%d'))
             bottom_axis.append(self.args['end_time'].strftime('%d'))
  
         chart.set_axis_labels(Axis.BOTTOM, bottom_axis)
     
         self._chart = chart
     return self._chart
예제 #16
0
def index(request):
    logger_names = SortedDict((l, l) for l in GroupedMessage.objects.values_list("logger", flat=True).distinct())
    server_names = SortedDict((l, l) for l in Message.objects.values_list("server_name", flat=True).distinct())
    level_names = SortedDict((str(k), v) for k, v in LOG_LEVELS)

    logger = request.GET.get("logger")
    server_name = request.GET.get("server_name") or ""
    level = request.GET.get("level") or ""

    try:
        page = int(request.GET.get("p", 1))
    except (TypeError, ValueError):
        page = 1

    realtime = page == 1

    if logger not in logger_names:
        logger = ""

    if server_name not in server_names:
        server_name = ""

    if level not in level_names:
        level = ""

    # this only works in postgres
    message_list = (
        GroupedMessage.objects.filter(status=0)
        .extra(
            select={"score": "times_seen / (pow((floor(extract(epoch from now() - last_seen) / 3600) + 2), 1.25) + 1)"}
        )
        .order_by("-score", "-last_seen")
    )

    today = datetime.datetime.now()

    chart_qs = (
        Message.objects.filter(datetime__gte=today - datetime.timedelta(hours=24))
        .extra(select={"hour": "extract(hour from datetime)"})
        .values("hour")
        .annotate(num=Count("id"))
        .values_list("hour", "num")
    )

    if logger:
        message_list = message_list.filter(logger=logger)
        chart_qs = chart_qs.filter(logger=logger)

    if level:
        message_list = message_list.filter(level=level)
        chart_qs = chart_qs.filter(level=level)

    if server_name:
        message_list = message_list.filter(message_set__server_name=server_name).distinct()
        chart_qs = chart_qs.filter(server_name=server_name)

    rows = dict(chart_qs)
    if rows:
        max_y = max(rows.values())
    else:
        max_y = 1

    if SimpleLineChart:
        chart = SimpleLineChart(384, 80, y_range=[0, max_y])
        chart.add_data([max_y] * 30)
        chart.add_data([rows.get((today - datetime.timedelta(hours=d)).hour, 0) for d in range(0, 24)][::-1])
        chart.add_data([0] * 30)
        chart.fill_solid(chart.BACKGROUND, "eeeeee")
        chart.add_fill_range("eeeeee", 0, 1)
        chart.add_fill_range("e0ebff", 1, 2)
        chart.set_colours(["eeeeee", "999999", "eeeeee"])
        chart.set_line_style(1, 1)
        chart_url = chart.get_url()

    return render_to_response("sentry/index.html", locals())
예제 #17
0
    def _get_chart(self):
        if not self._chart:
            datapoints = self._get_datapoints()
            data = [datapoint['Average'] for datapoint in self._datapoints]

            # Set the vertical range from 0 to 100
            max_y = 1
            if data:
                max_y = max(data) * 1.1

            # max_y cannot be zero
            if max_y == 0:
                max_y = 1

            # Make sure percentage doesn't exceed 100%
            if self.args['unit'] == 'Percent':
                max_y = 100

            # Chart size of 300x125 pixels and specifying the range for the Y axis
            chart = SimpleLineChart(380, 125, y_range=[0, max_y])

            # Add the chart data
            chart.add_data(data)
            chart.add_data([0, 0])

            # Set the line colour to blue
            chart.set_colours(['0000FF', '76A4FB'])

            # Fill below data line
            chart.add_fill_range('76A4FB', 0, 1)

            # Set the horizontal dotted lines
            chart.set_grid(0, 25, 5, 5)

            # The Y axis labels contains 0 to 100 skipping every 25, but remove the
            # first number because it's obvious and gets in the way of the first X
            # label.
            step = (max_y * 1.0) / 4
            if not step:
                step = 1
            #left_axis = range(0, max_y + 1, step)
            left_axis = []
            left_axis.append('')
            left_axis.append(step)
            left_axis.append(step * 2)
            left_axis.append(step * 3)
            left_axis.append(step * 4)

            i = 1
            if self.args['unit'] == 'Percent':
                for point in left_axis[1:]:
                    left_axis[i] = '%s%%' % left_axis[i]
                    i = i + 1
            elif self.args['unit'] == 'Bytes':
                for point in left_axis[1:]:
                    left_axis[i] = convert_bytes(int(left_axis[i]))
                    i = i + 1
            elif self.args['unit'] == 'Bytes/Second':
                for point in left_axis[1:]:
                    left_axis[i] = '%s/s' % convert_bytes(int(left_axis[i]))
                    i = i + 1
            elif self.args['unit'] == 'Seconds':
                for point in left_axis[1:]:
                    left_axis[i] = '%ss' % round_float(left_axis[i])
                    i = i + 1
            elif self.args['unit'] == 'Count/Second':
                for point in left_axis[1:]:
                    left_axis[i] = '%s/s' % round_float(left_axis[i])
                    i = i + 1

            chart.set_axis_labels(Axis.LEFT, left_axis)

            # X axis labels
            bottom_axis = []

            # hourly chart
            if self.range['timedelta'] == timedelta(hours=1):
                bottom_axis.append(self.args['start_time'].strftime('%H:%M'))
                bottom_axis.append((self.args['end_time'] -
                                    timedelta(minutes=45)).strftime('%H:%M'))
                bottom_axis.append((self.args['end_time'] -
                                    timedelta(minutes=30)).strftime('%H:%M'))
                bottom_axis.append((self.args['end_time'] -
                                    timedelta(minutes=15)).strftime('%H:%M'))
                bottom_axis.append(self.args['end_time'].strftime('%H:%M'))

            # daily chart
            if self.range['timedelta'] == timedelta(days=1):
                bottom_axis.append(self.args['start_time'].strftime('%H:%M'))
                bottom_axis.append((self.args['end_time'] -
                                    timedelta(hours=18)).strftime('%H:%M'))
                bottom_axis.append((self.args['end_time'] -
                                    timedelta(hours=12)).strftime('%H:%M'))
                bottom_axis.append((self.args['end_time'] -
                                    timedelta(hours=6)).strftime('%H:%M'))
                bottom_axis.append(self.args['end_time'].strftime('%H:%M'))

            # weekly chart
            if self.range['timedelta'] == timedelta(days=7):
                bottom_axis.append(self.args['start_time'].strftime('%d'))
                bottom_axis.append(
                    (self.args['end_time'] - timedelta(days=6)).strftime('%d'))
                bottom_axis.append(
                    (self.args['end_time'] - timedelta(days=5)).strftime('%d'))
                bottom_axis.append(
                    (self.args['end_time'] - timedelta(days=4)).strftime('%d'))
                bottom_axis.append(
                    (self.args['end_time'] - timedelta(days=3)).strftime('%d'))
                bottom_axis.append(
                    (self.args['end_time'] - timedelta(days=2)).strftime('%d'))
                bottom_axis.append(
                    (self.args['end_time'] - timedelta(days=1)).strftime('%d'))
                bottom_axis.append(self.args['end_time'].strftime('%d'))

            # monthly chart
            if self.range['timedelta'] == timedelta(days=30):
                bottom_axis.append(self.args['start_time'].strftime('%d'))
                bottom_axis.append((self.args['end_time'] -
                                    timedelta(days=25)).strftime('%d'))
                bottom_axis.append((self.args['end_time'] -
                                    timedelta(days=20)).strftime('%d'))
                bottom_axis.append((self.args['end_time'] -
                                    timedelta(days=15)).strftime('%d'))
                bottom_axis.append((self.args['end_time'] -
                                    timedelta(days=10)).strftime('%d'))
                bottom_axis.append(
                    (self.args['end_time'] - timedelta(days=5)).strftime('%d'))
                bottom_axis.append(self.args['end_time'].strftime('%d'))

            chart.set_axis_labels(Axis.BOTTOM, bottom_axis)

            self._chart = chart
        return self._chart
예제 #18
0
파일: chart.py 프로젝트: zedoude/wfrog
    def render(self, data={}, context={}):

        assert self.series is not None, "'chart.series' must be set"

        converter = wfcommon.units.Converter(context["units"])

        # merge builtin defaults, context and renderer config
        config = ChartConfig()
        if context.has_key('chart'):
            config.__dict__.update(context['chart'])
        config.__dict__.update(self.__dict__)

        # create the chart
        chart = SimpleLineChart(config.width, config.height)

        colors = []
        legend_set = False
        legend = []

        chart_min = sys.maxint
        chart_max = -sys.maxint

        # Prepare series config
        ordered_series = []
        for key, serie in self.series.iteritems():
            serie_config = ChartConfig()
            serie_config.__dict__.update(config.__dict__)
            serie_config.__dict__.update(serie)
            ordered_series.append((serie_config.order, key, serie))

        ordered_series.sort(cmp=lambda x, y: cmp(x[0], y[0]))

        ordered_keys = []
        for order, key, serie in ordered_series:
            ordered_keys.append(key)

        # Draws for each serie
        index = 0
        for order, key, serie in ordered_series:
            serie_config = ChartConfig()
            serie_config.__dict__.update(config.__dict__)
            serie_config.__dict__.update(serie)
            serie_data = copy.copy(
                data[key.split('.')[0]]['series'][key.split('.')[1]])
            measure = key.split('.')[0]

            if flat(serie_data):  # Series with all data = None
                continue

            if serie_config.accumulate:
                serie_data = accumulate(serie_data)
            elif serie_config.interpolate:
                serie_data = interpolate(serie_data)

            # Compute min and max value for the serie and the whole chart
            min_data = amin(serie_data)
            chart_min = rmin(chart_min, min_data)
            if serie_data.__contains__(min_data):
                min_index = serie_data.index(min_data)
            else:
                min_index = None
            max_data = max(serie_data)
            chart_max = max(chart_max, max_data)
            if serie_data.__contains__(max_data):
                max_index = serie_data.index(max_data)
            else:
                max_index = None

            (serie_data, min_index,
             max_index) = compress_to(serie_data, config.nval, min_index,
                                      max_index)

            chart.add_data(serie_data)
            colors.append(_valid_color(serie_config.color))

            if serie_config.max and not max_index == None:
                max_config = ChartConfig()
                max_config.__dict__.update(serie_config.__dict__)
                max_config.__dict__.update(serie_config.max)
                str_max_data = str(
                    round(converter.convert(measure, max_data), 1))
                chart.add_marker(index, max_index, 't' + str_max_data,
                                 _valid_color(max_config.text),
                                 max_config.size)
                chart.add_marker(index, max_index, max_config.style,
                                 _valid_color(max_config.color),
                                 max_config.thickness)

            if serie_config.min and not min_index == None:
                min_config = ChartConfig()
                min_config.__dict__.update(serie_config.__dict__)
                min_config.__dict__.update(serie_config.min)
                str_min_data = str(
                    round(converter.convert(measure, min_data), 1))
                chart.add_marker(index, min_index, 't' + str_min_data,
                                 _valid_color(min_config.text),
                                 min_config.size)
                chart.add_marker(index, min_index, min_config.style,
                                 _valid_color(min_config.color),
                                 min_config.thickness)

            if serie_config.last:
                last_config = ChartConfig()
                last_config.__dict__.update(serie_config.__dict__)
                last_config.__dict__.update(serie_config.last)
                last_index = len(serie_data) - 1
                last_data = serie_data[last_index]
                if last_data:
                    str_last_data = str(
                        round(converter.convert(measure, last_data), 1))
                    chart.add_marker(index, last_index, 't' + str(last_data),
                                     _valid_color(last_config.text),
                                     last_config.size)
                    chart.add_marker(index, last_index, last_config.style,
                                     _valid_color(last_config.color),
                                     last_config.thickness)

            if serie_config.area:
                fill_config = ChartConfig()
                fill_config.__dict__.update(serie_config.__dict__)
                fill_config.__dict__.update(serie_config.area)
                to = ordered_keys.index(fill_config.to)
                chart.add_fill_range(_valid_color(fill_config.color), index,
                                     to)

            if serie_config.dash:
                chart.set_line_style(index, serie_config.thickness,
                                     serie_config.dash, serie_config.dash)
            else:
                chart.set_line_style(index, serie_config.thickness)

            if serie_config.legend:
                legend.append(serie_config.legend)
                legend_set = True
            else:
                legend.append('')

            if serie_config.marks:
                mark_config = ChartConfig()
                mark_config.__dict__.update(serie_config.__dict__)
                mark_config.__dict__.update(serie_config.marks)
                mark_data = copy.copy(data[mark_config.serie.split(
                    '.')[0]]['series'][mark_config.serie.split('.')[1]])
                mark_data = compress_to(mark_data, config.nval, min_index,
                                        max_index)[0]
                for i, m in enumerate(mark_data):
                    if not m:
                        mark_data[i] = " "
                density = max(
                    1.0, 1.0 * mark_config.space * len("".join(mark_data)) *
                    mark_config.size / config.width)

                for i, v in enumerate(mark_data):
                    if (i + 1) % round(density) == 0:
                        if serie_data[i] != 0:
                            text = str(mark_data[i])
                        else:
                            text = " "
                        chart.add_marker(index, i, 't' + text,
                                         _valid_color(mark_config.color),
                                         mark_config.size)

            index = index + 1

        # Compute vertical range

        if config.axes:
            range_min_ref_units = 0
            if not chart_min == sys.maxint and not chart_max == -sys.maxint:
                range_min = chart_min - config.ymargin[0]
                range_max = chart_max + config.ymargin[1]
                range_min_target_units = math.floor(
                    converter.convert(measure, range_min))
                range_max_target_units = math.ceil(
                    converter.convert(measure, range_max))
                range_min_ref_units = converter.convert_back(
                    measure, range_min_target_units)
                range_max_ref_units = converter.convert_back(
                    measure, range_max_target_units)
                self.logger.debug("Y range: " + str(range_min_target_units) +
                                  " " + str(range_max_target_units))
                chart.set_axis_range(Axis.LEFT, range_min_target_units,
                                     range_max_target_units + 1)
                chart.add_data([range_min_ref_units, range_max_ref_units])
                colors.append("00000000")
            else:
                chart.set_axis_range(Axis.LEFT, 0, 100)
            chart.set_axis_style(
                0, _valid_color(config.text), config.size, 0,
                Axis.BOTH if config.ticks else Axis.AXIS_LINES)
        else:
            chart.set_axis_labels(Axis.LEFT, [])
            chart.set_axis_style(0, _valid_color(config.text), config.size, 0,
                                 Axis.TICK_MARKS, _valid_color(config.bgcolor))

        if config.zero and config.axes and range_min_ref_units < 0 and range_max_ref_units > 0:
            zero_config = ChartConfig()
            zero_config.__dict__.update(config.__dict__)
            zero_config.__dict__.update(config.zero)
            chart.add_data([0] * 2)
            colors.append(_valid_color(zero_config.color))
            chart.set_line_style(index, zero_config.thickness)

        chart.set_colours(colors)
        chart.fill_solid(Chart.BACKGROUND, _valid_color(config.bgcolor))

        if legend_set:
            chart.set_legend(legend)
            chart.set_legend_position(config.legend_pos)

        if self.labels:
            labels_data = copy.copy(data[self.labels.split('.')[0]]['series'][
                self.labels.split('.')[1]])
            labels_data = compress_to(labels_data, config.nval, None, None)[0]
            if config.axes:
                density = 1.0 * len(
                    "".join(labels_data)) * config.size / config.width

                if density > LABEL_DENSITY_THRESHOLD:
                    for i, v in enumerate(labels_data):
                        if i % round(density) != 0:
                            labels_data[i] = ' '
                chart.set_axis_labels(Axis.BOTTOM, labels_data)
                chart.set_axis_style(
                    1, _valid_color(config.text), config.size, 0,
                    Axis.BOTH if config.ticks else Axis.AXIS_LINES)
            else:
                chart.set_axis_labels(Axis.BOTTOM, [])
                chart.set_axis_style(1, _valid_color(config.text), config.size,
                                     0, Axis.TICK_MARKS,
                                     _valid_color(config.color))

        try:
            return chart.get_url() + "&chma=10,10,10,10"  # add a margin
        except:
            self.logger.exception("Could not render chart")
            return "http://chart.apis.google.com/chart?cht=lc&chs=" + str(
                config.width) + "x" + str(config.height)