6

Related to the question Creating bar chart from point layer using QGIS Geometry Generator, I am using with success the expressions proposed by user Taras in Solution 2 and for user Babel.

The two proposed solutions are working well, but I am confronted the same problem in both solutions.

I note that the display of objects depends on the objects within the extent of the view. Thus, to see the whole graph, all point objects must be in extent view. In this screenshot, all the points within the view extent are shown and therefore the whole graph is displayed:

enter image description here

However, if I pan the map up (or any other direction) and hide some points (outside the map view extent), the graph is incomplete (some bars disappear):

enter image description here

I understand the cause of this effect, but is there a solution to prevent this? In other words, is it possible that the result of the Geometry Generator expression is kept in the view even if its original point object is outside the view extent?

2
  • 3
    Unfortunately, it seems this is just how the rendering engine works (for now). See this discussion in the QGIS issues. I believe the only way to keep them - using this approach - would be to use the Geometry by Expression tool, with the same expression, and create a new layer for your bars. It is not as dynamic as the Geometry Generator approach, but they would remain visible.
    – Matt
    Commented Dec 19, 2023 at 15:00
  • 2
    My idea is to erase the spatial context and work with a pure attribute table, in which you store the X & Y information. Then you will need to create those points and calculate the extent of them. Afterwards, the procedure will be as before.
    – Taras
    Commented Dec 19, 2023 at 20:43

1 Answer 1

4

You can show bar charts created by Geometry Generator even for input features whose geometry is outside the map canvas, but, as others mentioned, it is not possible by default.

Just a few of the totally 345 points are visible in the upper right part of the map canvas, still, bar charts for all 345 points are visible. The virtual layer's Simple Marker symbol layer is set to invisible (Enable Symbol Layer box unchecked): enter image description here

The basic idea is to create a virtual layer as a copy of all attributes (without the geometries) of your layer and add a geometry that for sure is inside the map canvas. Then apply the Geometry Generator expression to this virtual layer.

The tricky part is creating a point on the virtual layer that is for sure inside the map canvas as the virtual layer has no direct access to the map canvas. See here for the whole procedure or in what follows for a step by step explanation.

  1. On the initial layer, create two new virtual fields called xmin and ymin for the current map canvas extent's x/y minimum values. Create a custom function currentExtent() for this, then calculate the values with x_min(currentExtent()) and y_min(currentExtent()).

  2. Use these xmin/ymin values on the virtual layer to create a point at the bottom left of the map canvas. Add all the attribute fields you need to create the bar chart, here order and value. Set these fieldnames in double quotes " to mask them and like this tell the virtual layer to treat them as field names as these are special names.

    The Virtual layer query looks like this:

    select pts."order", pts."value", make_point (pts.xmin,pts.ymin) 
    from points as pts
    
  3. You get a virtual layer with a point on the bottom left of your map canvas that shifts as you pan/zoom. You can delete the point marker style in the layer styling or uncheck the box Enable symbol layer, because this point is only for auxiliary purpose: we only want to show the bar charts.

  4. Add a Geometry Generator layer style with the following expression. I silghtly modified it so that the bars do not start at the bottom left of the canvas, but a bit shifted. The area within which the bars are shown is created as a negative buffer from the map canvas. Change the value of 20 (negative buffer of 1/20 (=5%) of the map canvas size) at the end of line 5:

     with_variable(
         'ext',
          buffer (
             @map_extent, 
             -1*((x_max(@map_extent)) - x_min(@map_extent))/20 -- -- change size of area for bar charts here
         ),
     with_variable(
         'ln',
         translate (
             make_point (x_min(@ext),y_min(@ext)),
             (order-0.5) * (x_max(@ext)-x_min(@ext)) / count ($id),
             0
         ),
     make_line (
         @ln,
         project(
             @ln,
             attribute (get_feature('points', 'order', "order"),'value') * (y_max(@ext)-y_min(@ext)) / maximum(value),
             0
         )
     )))
    

Like this, the bars will show even for the points that are outside the map canvas.

1
  • 1
    I think it is a brilliant idea the use of the virtual layer with the fields called 'xmin' and 'ymin'. It is absolutely great, and I hope this solution can help other users and other projects Commented Jan 8 at 7:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.