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

How to define a fixed label on the edge of an axis? #714

Closed
moroshko opened this issue Jan 14, 2017 · 7 comments
Closed

How to define a fixed label on the edge of an axis? #714

moroshko opened this issue Jan 14, 2017 · 7 comments

Comments

@moroshko
Copy link

I have the following spec:

{
  "width": 400,
  "height": 100,
  "scales": [
    {
      "name": "x",
      "type": "time",
      "domain": [1484286340567, 1484372740567],
      "range": [0, 400]
    }
  ],
  "axes": [
    {
      "orient": "bottom",
      "scale": "x"
    }
  ]
}

that generates:

screenshot 2017-01-13 23 06 23

In my case, the scale domain will always be [now - 1day, now], so I'd like to always display the label Now at the right end of the axis:

----3am----6am----9am----12pm----3pm----6pm----9pm--Now

How could I achieve that? Example will be appreciated.

I use vega@3.0.0-beta.14.

@jheer
Copy link
Member

jheer commented Jan 14, 2017

You can introduce an additional text mark for custom labels. For example:

{
  "type": "text",
  "encode": {
    "enter": {
      "x": {"signal": "width"},
      "y": {"signal": "height"},
      "text": {"value": "Now"},
      "fontWeight": {"value": "bold"},
      "fontSize": {"value": 10}
    }
  }
}

Then adjust the positioning, align, baseline, etc as desired.

@jheer jheer closed this as completed Jan 14, 2017
@moroshko
Copy link
Author

The problem with this approach is that the Now label can collide with the right most label on the axis (if the current time is close to 9pm):

screenshot 2017-01-14 12 16 13

Is that possible to avoid this collision?
I'd probably expect the 9 PM label not to be rendered in this case.

Shall I use an ordinal scale and calculate all the axis labels myself?

@jheer
Copy link
Member

jheer commented Jan 14, 2017

This is what I was (obliquely) referring to about adjusting positioning, etc. There are various means of further positioning the label. One simple approach is to add a constant offset with the text dx property: "dx": {"value": 10}. Or, you could just bake it in as "x": {"signal": "width + 10"}.

@moroshko
Copy link
Author

Sorry, I probably didn't explain myself clearly.
I want the Now label to be positioned similarly to other labels, i.e. same y position as other labels, and x position where it should be (not 10 pixels to the right).
Basically, I just want to force vega to have an axis label at the end.
It that possible to ask vega to have a label at the right most edge, and automatically adjust other labels according to it?

P.S. Thanks a lot for a super fast response!

@jheer
Copy link
Member

jheer commented Jan 14, 2017

I see. If you happen to know the actual value of 'Now' you can override that label like so within your axis definition:

"axes": [
  {
    "orient": "bottom",
    "scale": "x",
    "encode": {
      "labels": {
        "update": {
          "text": {"signal": "datum.label === '9am' ? 'Now' : datum.label"}
         }
      }
    }
  }
]

Of course, you would need to replace '9am' with a dynamic, accurate "now" label. You can also check against datum.value which in this case should have the actual timestamp value.

@moroshko
Copy link
Author

Sorry, but that's not what I want.
I'm trying to build a realtime vizualization, where the time axis is moving similarly to this example.
The Now label should always be at the right edge of the axis, regardless of the current time.

@jheer
Copy link
Member

jheer commented Jan 15, 2017

Here's a different example that hides axis labels near the end of the scale range, configurable via the threshold signal. You could of course devise different filtering criteria, but hopefully this gives you enough to realize your use case.

{
  "width": 400,
  "height": 100,
  "signals": [
    {
      "name": "threshold",
      "value": 0.925
    }
  ],
  "scales": [
    {
      "name": "x",
      "type": "time",
      "domain": [1484286340567, 1484372740567],
      "range": "width"
    }
  ],
  "axes": [
    {
      "orient": "bottom",
      "scale": "x",
      "encode": {
        "labels": {
          "update": {
            "opacity": {"signal": "(datum.value - domain('x')[0]) / span(domain('x')) > threshold ? 0 : 1"}
          }
        }
      }
    }
  ],
  "marks": [
    {
      "type": "text",
      "encode": {
        "update": {
          "x": {"signal": "width"},
          "y": {"signal": "height + 8"},
          "text": {"value": "Now"},
          "align": {"value": "center"},
          "fontSize": {"value": 10},
          "fontWeight": {"value": "bold"},
          "baseline": {"value": "top"}
        }
      }
    }
  ]
}

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

No branches or pull requests

2 participants