Opened 2 years ago

Closed 2 years ago

Last modified 2 years ago

#20419 closed New feature (wontfix)

Support a limited set of filter to ease writing SVG template

Reported by: sleroux Owned by: nobody
Component: Template system Version: master
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

The Django template system is able to process any kind of text document, including SVG.

But the standard filter provided by Django are mostly "text" oriented, and does not provide basic "mathematical" operations often required by SVG template authors.

Specifically, it appears that when producing SVG chart for example, one require often to scale from model data range to chart axis. With the added complexity that SVG y-axis grows downward -- whereas many charts y-axis grow upward. For now, the only solution is (a) to perform the scaling in the view, which throws out the separation of concern or (b) preferably, provide a custom filter.

Since I think this is a common pattern while producing SVG, it could be interesting to provide a standard "scaling" filter. Here is what I propose (a patch is attached):

@register.filter("map")
def map_filter(value, src_min, src_max, dst_min, dst_max):
    """map the value from [src_min,src_max] range to [dst_min, dst_max]
    range.

    Modeled after the corresponding map() function available (for
    example) in Processing http://processing.org/reference/map_.html
    """
    return dst_min + ( value - src_min ) * ( dst_max - dst_min) / ( src_max - src_min)

As stated in the comment, this is modeled after the corresponding Processing map() function, since our designer was more familiar with that language. Maybe, "scale()" could be less confusing for Python-aware people.

Attachments (1)

map_filter.patch (1.4 KB) - added by sleroux 2 years ago.

Download all attachments as: .zip

Change History (6)

Changed 2 years ago by sleroux

comment:1 Changed 2 years ago by sleroux

  • Has patch set
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

comment:2 Changed 2 years ago by sleroux

I didn't realize our Django version was patched to allow filters with multiple arguments. I will modify my proposal to pass all the args as a string instead... sorry about the noise.

-- Sylvain

comment:3 Changed 2 years ago by bmispelon

Hi,

Thank you for your report.

While django's template language can be used to render any text-based format, its builtin library of tags and filters is heavily biased towards outputting HTML.

Seeing how it's relatively easy to create a third-party application that defines custom template tags/filters, could you provide some more arguments as to why it makes sense to include this new template filter in django's core? Your current usecase seems quite specific and I find it hard to see how it could be useful in a more generic context.

We currently have the widthratio tag [1] that does something similar to what you're proposing. Could you address its shortcomings and the reasons why it doesn't fit your needs?

Personally, I'm -1 on this feature. While it's probably useful, I think it'd be better if it lived in a third-party application.

Also note that for a new feature to get merged, it needs to have tests and documentation. See the contributing guide [2] for more info.

[1] https://docs.djangoproject.com/en/1.5/ref/templates/builtins/#widthratio
[2] https://docs.djangoproject.com/en/1.5/internals/contributing/writing-code/submitting-patches/

comment:4 Changed 2 years ago by aaugustin

  • Resolution set to wontfix
  • Status changed from new to closed

Like Baptiste, I believe that the Django template language isn't an appropriate tool to render SVG.

I recommend using an existing SVG rendering library or even a generic XML library.

comment:5 Changed 2 years ago by sleroux

First, thank you for your replies!

I saw the 'widthratio' but I couldn't manage to use it to do what we need, as it assume both original and destination scale both have 0 for origin. In our particular case, that wasn't almost never the case. As an example, while drawing a line chart, we have to map temperature in the -55°C +125°C range to some vertical axis whose origin is not at "0px" (to gets things worse, (0,0) is the top-left of an SVG drawing).

As a matter of fact, it could be a better idea to extend "widthratio" to accept both 3 arguments as today, or 5:

{% widthratio value min_value max_value min_rang max_range %}

But, as you mention, maybe we are the only one using the Django template system to generate SVG? And having that specific need? I was thinking with the advent of HTML5 this could be a more common use case. But as for today you are probably right.

Last edited 2 years ago by sleroux (previous) (diff)
Note: See TracTickets for help on using tickets.
Back to Top