Skip to content

Commit

Permalink
Merge pull request #1301 from CartoDB/rename-sample-histogram
Browse files Browse the repository at this point in the history
Rename sampleHistogram to globalHistogram
  • Loading branch information
elenatorro authored Mar 20, 2019
2 parents b7808ee + 2a67645 commit 2602246
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 46 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Throw error when using `clusterCount` in a global classifier
- Label example with `clusterAVG` expression
- Label example with `clusterCount` expression
- Add `sampleHistogram` expression
- Add `globalHistogram` expression
- Add Animation examples
- Clean and reorganize examples in the documentation

Expand Down
16 changes: 8 additions & 8 deletions docs/guides/12-build-custom-charts.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
## Build custom charts

In the [Add legends](/developers/carto-vl/guides/add-legends/) guide, you saw how to add legends to a map using the [`getLegendsData`](/developers/carto-vl/reference/#expressionsrampgetlegenddata) method, and how to display widgets using histogram expressions in the [Add widgets](/developers/carto-vl/guides/add-widgets/) guide. In this guide, you will build upon those concepts and learn how to obtain and display information in custom charts using the `viewportHistogram` and `sampleHistogram` expressions and an external charting library.
In the [Add legends](/developers/carto-vl/guides/add-legends/) guide, you saw how to add legends to a map using the [`getLegendsData`](/developers/carto-vl/reference/#expressionsrampgetlegenddata) method, and how to display widgets using histogram expressions in the [Add widgets](/developers/carto-vl/guides/add-widgets/) guide. In this guide, you will build upon those concepts and learn how to obtain and display information in custom charts using the `viewportHistogram` and `globalHistogram` expressions and an external charting library.

### Overview

In the [previous guide](/developers/carto-vl/guides/add-widgets/) histogram widgets were built with CARTO's frontend framework [Airship](https://carto.com/airship/). As explained there, Airship widgets interact with CARTO VL directly, which means widgets are automatically connected to the map and can be configured accordingly. This guide takes a deeper dive into histogram expressions and the flexibility in CARTO VL to connect with external libraries. You will learn how to use histogram expressions to create bar charts for **categorical** data and histograms for **numeric** data using a [Vancouver Trees](https://team.carto.com/u/cartovl/tables/cartovl.vancouver_trees/public/map) dataset with the external charting library, [Chart.js](https://www.chartjs.org).

### Histogram expressions

CARTO VL has two expressions to create histograms: [`viewportHistogram`](/developers/carto-vl/reference/#cartoexpressionsviewporthistogram) and [`sampleHistogram`](/developers/carto-vl/reference/#cartoexpressionssamplehistogram). Both expressions return a list of values grouped by a column but differ in the way values are grouped. The `viewportHistogram` expression returns a list based off of features that are in the viewport, while the `sampleHistogram` expression returns a list based on a data sample.
CARTO VL has two expressions to create histograms: [`viewportHistogram`](/developers/carto-vl/reference/#cartoexpressionsviewporthistogram) and [`globalHistogram`](/developers/carto-vl/reference/#cartoexpressionsglobalhistogram). Both expressions return a list of values grouped by a column but differ in the way values are grouped. The `viewportHistogram` expression returns a list based off of features that are in the viewport, while the `globalHistogram` expression returns a list based on a data sample.

#### `viewportHistogram` vs `sampleHistogram`
#### `viewportHistogram` vs `globalHistogram`

The map below combines both `viewportHistogram` and `sampleHistogram` expressions to compare the information returned for viewport vs sample feature calculations. If you interact with the map, you'll see how the bars for `sampleHistogram` remain static, while the ones for `viewportHistogram` change depending on the features present in the viewport.
The map below combines both `viewportHistogram` and `globalHistogram` expressions to compare the information returned for viewport vs global feature calculations. If you interact with the map, you'll see how the bars for `globalHistogram` remain static, while the ones for `viewportHistogram` change depending on the features present in the viewport.

What you may notice is that if you zoom out, the `viewportHistogram` chart doesn't match the `sampleHistogram` chart. This is because the data returned for the `sampleHistogram`, as indicated by its name, is a **representative sample** of the data. Therefore, the results may vary since we're comparing the viewport data with a representative sample of the whole dataset.
What you may notice is that if you zoom out, the `viewportHistogram` chart doesn't match the `globalHistogram` chart. This is because the data returned for the `globalHistogram` is a **representative sample** of the data. Therefore, the results may vary since we're comparing the viewport data with a representative sample of the whole dataset.

**Note:**
If you need higher accuracy in your `sampleHistogram`, we recommend creating a [custom query](https://wiki.postgresql.org/wiki/Aggregate_Histogram) with a [`carto.source.SQL`](/developers/carto-vl/reference/#cartosourcesql) source.
If you need higher accuracy in your `globalHistogram`, we recommend creating a [custom query](https://wiki.postgresql.org/wiki/Aggregate_Histogram) with a [`carto.source.SQL`](/developers/carto-vl/reference/#cartosourcesql) source.

<div class="example-map">
<iframe
Expand All @@ -31,7 +31,7 @@ If you need higher accuracy in your `sampleHistogram`, we recommend creating a
</div>
You can explore this step [here](/developers/carto-vl/examples/maps/guides/build-custom-charts/step-1.html)

Now that you know the differences between viewport and sample histograms, next, let's look at using these expressions to draw charts.
Now that you know the differences between viewport and global histograms, next, let's look at using these expressions to draw charts.

### Bar chart for categories

Expand Down Expand Up @@ -196,7 +196,7 @@ In all of the examples above, you will notice that the bar colors are a solid de

What if you want to create a bar chart, and assign colors to each bar that correspond with the associated features on the map?

You can do this with a `ramp` expression, the [`getLegendData()`](/developers/carto-vl/reference/#expressionsrampgetlegenddata) method, and the [`getJoinedValues()`](/developers/carto-vl/reference/#expressionsviewporthistogramgetjoinedvalues) method which is part of `viewportHistogram` and `sampleHistogram`.
You can do this with a `ramp` expression, the [`getLegendData()`](/developers/carto-vl/reference/#expressionsrampgetlegenddata) method, and the [`getJoinedValues()`](/developers/carto-vl/reference/#expressionsviewporthistogramgetjoinedvalues) method which is part of `viewportHistogram` and `globalHistogram`.

The `ramp` expression (`@v_color`) is used to in two ways: to color the features on the map and to color the chart's bars with the same colors using the `getLegendData()` method:

Expand Down
10 changes: 5 additions & 5 deletions examples/guides/build-custom-charts/step-1.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ <h1>Tree Diameter</h1>
// Define the visualization
const viz = new carto.Viz(`
@v_viewportHistogram: viewportHistogram($diameter, [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7]])
@v_sampleHistogram: sampleHistogram($diameter, [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7]])
@v_globalHistogram: globalHistogram($diameter, [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7]])
color: #00718b
width: 5
strokeWidth: 0.5
Expand Down Expand Up @@ -119,16 +119,16 @@ <h1>Tree Diameter</h1>
layer.on('updated', () => {
// Save histograms variable
const viewportHistogram = layer.viz.variables.v_viewportHistogram;
const sampleHistogram = layer.viz.variables.v_sampleHistogram;
const globalHistogram = layer.viz.variables.v_globalHistogram;

// Get histograms data
const viewportHistogramData = viewportHistogram.value;
const sampleHistogramData = sampleHistogram.value;
const globalHistogramData = globalHistogram.value;

// Chart.js set up
const labels = viewportHistogramData.map(elem => elem.x);
const viewportData = viewportHistogramData.map(elem => elem.y);
const globalData = sampleHistogramData.map(elem => elem.y);
const globalData = globalHistogramData.map(elem => elem.y);
const viewportColor = '#00718b';
const globalColor = '#F2B701';

Expand Down Expand Up @@ -156,4 +156,4 @@ <h1>Tree Diameter</h1>
</script>
</body>

</html>
</html>
4 changes: 2 additions & 2 deletions src/renderer/viz/expressions.js
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ import ViewportSum from './expressions/aggregation/viewport/ViewportSum';
import ViewportCount from './expressions/aggregation/viewport/ViewportCount';
import ViewportPercentile from './expressions/aggregation/viewport/ViewportPercentile';
import ViewportHistogram from './expressions/histogram/ViewportHistogram';
import SampleHistogram from './expressions/histogram/SampleHistogram';
import GlobalHistogram from './expressions/histogram/GlobalHistogram';
import ViewportFeatures from './expressions/viewportFeatures';

import GlobalAvg from './expressions/aggregation/global/GlobalAvg';
Expand Down Expand Up @@ -719,7 +719,7 @@ export const globalMin = (...args) => new GlobalMin(...args);
export const globalSum = (...args) => new GlobalSum(...args);
export const globalCount = (...args) => new GlobalCount(...args);
export const globalPercentile = (...args) => new GlobalPercentile(...args);
export const sampleHistogram = (...args) => new SampleHistogram(...args);
export const globalHistogram = (...args) => new GlobalHistogram(...args);

export const zoom = (...args) => new Zoom(...args);
export const scaled = (...args) => new Scaled(...args);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@ import { OTHERS_LABEL, DEFAULT_OPTIONS } from '../constants';
* For numeric values of sizeOrBuckets, the minimum and maximum will be computed automatically and bars will be generated at regular intervals between the minimum and maximum.
* When providing sizeOrBuckets as a list of buckets, the values will get assigned to the first bucket matching the criteria [bucketMin <= value < bucketMax].
*
* The sampleHistogram can also be combined with the `top()` expression.
* The globalHistogram can also be combined with the `top()` expression.
*
* Histograms are useful to get insights and create widgets outside the scope of CARTO VL, see the following example for more info.
*
* @param {Number} input - expression to base the histogram
* @param {Number|Array} sizeOrBuckets - Optional (defaults to 20). Number of bars to use if `x` is a numeric expression; or user-defined buckets for numeric expressions.
* @return {SampleHistogram} SampleHistogram
* @return {GlobalHistogram} GlobalHistogram
*
* @example <caption>Create and use an histogram.</caption>
* const s = carto.expressions;
* const viz = new carto.Viz(
* variables: {
* categoryHistogram: s.sampleHistogram(s.prop('type')),
* numericHistogram: s.sampleHistogram(s.prop('amount'), 3, 1),
* userDefinedHistogram: s.sampleHistogram(s.prop('amount', [[0, 10], [10, 20], [20, 30]], 1),
* topCategoryHistogram: s.sampleHistogram(s.top(s.prop('type'), 3))
* categoryHistogram: s.globalHistogram(s.prop('type')),
* numericHistogram: s.globalHistogram(s.prop('amount'), 3, 1),
* userDefinedHistogram: s.globalHistogram(s.prop('amount', [[0, 10], [10, 20], [20, 30]], 1),
* topCategoryHistogram: s.globalHistogram(s.top(s.prop('type'), 3))
* }
* );
* // ...
Expand All @@ -42,10 +42,10 @@ import { OTHERS_LABEL, DEFAULT_OPTIONS } from '../constants';
*
* @example <caption>Create and use an histogram. (String)</caption>
* const viz = new carto.Viz(`
* \@categoryHistogram: sampleHistogram($type)
* \@numericHistogram: sampleHistogram($amount, 3, 1)
* \@userDefinedHistogram: sampleHistogram($amount, [[0, 10], [10, 20], [20, 30]], 1)
* \@topCategoryHistogram: sampleHistogram(top($type, 3))
* \@categoryHistogram: globalHistogram($type)
* \@numericHistogram: globalHistogram($amount, 3, 1)
* \@userDefinedHistogram: globalHistogram($amount, [[0, 10], [10, 20], [20, 30]], 1)
* \@topCategoryHistogram: globalHistogram(top($type, 3))
* `);
* // ...
* console.log(viz.variables.categoryHistogram.value);
Expand All @@ -57,27 +57,27 @@ import { OTHERS_LABEL, DEFAULT_OPTIONS } from '../constants';
* // There are 20 features with an amount between 0 and 10, 7 features with an amount between 10 and 20, and 3 features with an amount between 20 and 30
*
* @memberof carto.expressions
* @name sampleHistogram
* @name globalHistogram
* @function
* @api
*/

/**
* SampleHistogram Class
* GlobalHistogram Class
*
* Generates a histogram based on the samples from the metadata.
* This class is instanced automatically by using the `sampleHistogram` function. It is documented for its methods.
* Read more about histogram expression at {@link carto.expressions.sampleHistogram}.
* This class is instanced automatically by using the `globalHistogram` function. It is documented for its methods.
* Read more about histogram expression at {@link carto.expressions.globalHistogram}.
*
* @name expressions.SampleHistogram
* @name expressions.GlobalHistogram
* @abstract
* @hideconstructor
* @class
* @api
*/
export default class SampleHistogram extends Histogram {
export default class GlobalHistogram extends Histogram {
constructor (input, sizeOrBuckets = 20) {
checkMaxArguments(arguments, 3, 'sampleHistogram');
checkMaxArguments(arguments, 3, 'globalHistogram');
super({ input: implicitCast(input) });

this._sizeOrBuckets = sizeOrBuckets;
Expand All @@ -92,7 +92,7 @@ export default class SampleHistogram extends Histogram {
*
* @param {Array} values - Array of { key, value } pairs
* @return {Array} - { frequency, key, value }
* @memberof expressions.SampleHistogram
* @memberof expressions.GlobalHistogram
* @api
* @example <caption>Get joined data for a categorical property sorted by frequency.</caption>
* const numberOfWheels = [
Expand All @@ -103,7 +103,7 @@ export default class SampleHistogram extends Histogram {
*
* const s = carto.expressions;
* const viz = new carto.Viz({
* @histogram: s.sampleHistogram(s.prop('vehicles'))
* @histogram: s.globalHistogram(s.prop('vehicles'))
* });
*
* const data = viz.variables.histogram.getJoinedValues(numberOfWheels);
Expand All @@ -123,7 +123,7 @@ export default class SampleHistogram extends Histogram {
*
* const s = carto.expressions;
* const viz = new carto.Viz(`
* @histogram: sampleHistogram($vehicles)
* @histogram: globalHistogram($vehicles)
* `);
*
* const data = viz.variables.histogram.getJoinedValues(numberOfWheels);
Expand All @@ -137,7 +137,7 @@ export default class SampleHistogram extends Histogram {
* @example <caption>Get color values for the histogram when using a ramp.</caption>
* const s = carto.expressions;
* const viz = new carto.Viz(`
* @histogram: s.sampleHistogram(s.prop('vehicles'))
* @histogram: s.globalHistogram(s.prop('vehicles'))
* color: ramp(s.prop('vehicles'), s.palettes.PRISM)
* `);
*
Expand All @@ -153,7 +153,7 @@ export default class SampleHistogram extends Histogram {
* @example <caption>Get color values for the histogram when using a ramp. (String)</caption>
* const s = carto.expressions;
* const viz = new carto.Viz(`
* @histogram: sampleHistogram($vehicles)
* @histogram: globalHistogram($vehicles)
* color: ramp($vehicles, Prism)
* `);
*
Expand All @@ -170,7 +170,7 @@ export default class SampleHistogram extends Histogram {
*
* const s = carto.expressions;
* const viz = new carto.Viz(`
* @histogram: s.sampleHistogram(s.top(s.prop('vehicles'), 2))
* @histogram: s.globalHistogram(s.top(s.prop('vehicles'), 2))
* color: ramp(s.top(s.prop('vehicles'), 2)), s.palettes.PRISM, s.rgba(0, 128, 0, 1))
* `);
*
Expand All @@ -187,7 +187,7 @@ export default class SampleHistogram extends Histogram {
* @example <caption>Get color values for the histogram using a ramp with classified data (String).</caption>
* const s = carto.expressions;
* const viz = new carto.Viz(`
* @histogram: sampleHistogram(top($vehicles, 2))
* @histogram: globalHistogram(top($vehicles, 2))
* color: ramp((top($vehicles, 2)), Prism, green)
* `);
*
Expand All @@ -203,7 +203,7 @@ export default class SampleHistogram extends Histogram {
*
*/
getJoinedValues (values, options) {
checkArray('sampleHistogram.getJoinedValues', 'values', 0, values);
checkArray('globalHistogram.getJoinedValues', 'values', 0, values);

if (!values.length) {
return [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import carto from '../../../../src/index';
import * as util from '../../util';
import { OTHERS_LABEL } from '../../../../src/renderer/viz/expressions/constants';

describe('sampleHistogram', () => {
describe('globalHistogram', () => {
let div, map, source, viz, layer;

function createFeature (id, value) {
Expand Down Expand Up @@ -66,7 +66,7 @@ describe('sampleHistogram', () => {
];

it('should get correct data with categorical values', (done) => {
const histogramViz = '@histogram: sampleHistogram($value)';
const histogramViz = '@histogram: globalHistogram($value)';

createMapWith(histogramViz, categoryFeatures);

Expand All @@ -85,7 +85,7 @@ describe('sampleHistogram', () => {

it('should get correct data with categorical values in buckets', (done) => {
const top = 1;
const histogramViz = `@histogram: sampleHistogram(top($value, ${top}))`;
const histogramViz = `@histogram: globalHistogram(top($value, ${top}))`;
createMapWith(histogramViz, categoryFeatures);

layer.on('loaded', () => {
Expand All @@ -102,7 +102,7 @@ describe('sampleHistogram', () => {
const size = 4;
const min = 0;
const max = 100;
const histogramViz = `@histogram: sampleHistogram($value, ${size})`;
const histogramViz = `@histogram: globalHistogram($value, ${size})`;
createMapWith(histogramViz, numericFeatures);

layer.on('loaded', () => {
Expand All @@ -121,7 +121,7 @@ describe('sampleHistogram', () => {
it('should get correct data labeled when there are "others" values', (done) => {
const top = 1;
const histogramViz = `
@histogram: sampleHistogram(top($value, ${top}))
@histogram: globalHistogram(top($value, ${top}))
@color: ramp(top($value, ${top}), [ red, blue ], green )
`;

Expand Down

0 comments on commit 2602246

Please sign in to comment.